diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-25 13:09:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-25 13:09:31 -0400 |
commit | 25581ad107be24b89d805da51a03d616f8f3d1be (patch) | |
tree | 36e2bd32667b5dd5a39e1939c1c5162f18967715 /drivers | |
parent | 72cf2709bf8e0410800f118c4298bfbf8715b303 (diff) | |
parent | 7477ddaa4d2d69bbcd49e12990af158dbb03f2f2 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (244 commits)
V4L/DVB (4210b): git-dvb: tea575x-tuner build fix
V4L/DVB (4210a): git-dvb versus matroxfb
V4L/DVB (4209): Added some BTTV PCI IDs for newer boards
Fixes some sync issues between V4L/DVB development and GIT
V4L/DVB (4206): Cx88-blackbird: always set encoder height based on tvnorm->id
V4L/DVB (4205): Merge tda9887 module into tuner.
V4L/DVB (4203): Explicitly set the enum values.
V4L/DVB (4202): allow selecting CX2341x port mode
V4L/DVB (4200): Disable bitrate_mode when encoding mpeg-1.
V4L/DVB (4199): Add cx2341x-specific control array to cx2341x.c
V4L/DVB (4198): Avoid newer usages of obsoleted experimental MPEGCOMP API
V4L/DVB (4197): Port new MPEG API to saa7134-empress with saa6752hs
V4L/DVB (4196): Port cx88-blackbird to the new MPEG API.
V4L/DVB (4193): Update cx2341x fw encoding API doc.
V4L/DVB (4192): Use control helpers for saa7115, cx25840, msp3400.
V4L/DVB (4191): Add CX2341X MPEG encoder module.
V4L/DVB (4190): Add helper functions for control processing to v4l2-common.
V4L/DVB (4189): Add videodev support for VIDIOC_S/G/TRY_EXT_CTRLS.
V4L/DVB (4188): Add new MPEG control/ioctl definitions to videodev2.h
V4L/DVB (4186): Add support for the DNTV Live! mini DVB-T card.
...
Diffstat (limited to 'drivers')
263 files changed, 17515 insertions, 5750 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 344d83aae3ec..583d151b7486 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig | |||
@@ -25,7 +25,7 @@ config VIDEO_DEV | |||
25 | module will be called videodev. | 25 | module will be called videodev. |
26 | 26 | ||
27 | config VIDEO_V4L1 | 27 | config VIDEO_V4L1 |
28 | boolean "Enable Video For Linux API 1 (DEPRECATED)" | 28 | bool "Enable Video For Linux API 1 (DEPRECATED)" |
29 | depends on VIDEO_DEV | 29 | depends on VIDEO_DEV |
30 | select VIDEO_V4L1_COMPAT | 30 | select VIDEO_V4L1_COMPAT |
31 | default y | 31 | default y |
@@ -36,7 +36,7 @@ config VIDEO_V4L1 | |||
36 | If you are unsure as to whether this is required, answer Y. | 36 | If you are unsure as to whether this is required, answer Y. |
37 | 37 | ||
38 | config VIDEO_V4L1_COMPAT | 38 | config VIDEO_V4L1_COMPAT |
39 | boolean "Enable Video For Linux API 1 compatible Layer" | 39 | bool "Enable Video For Linux API 1 compatible Layer" |
40 | depends on VIDEO_DEV | 40 | depends on VIDEO_DEV |
41 | default y | 41 | default y |
42 | ---help--- | 42 | ---help--- |
@@ -82,6 +82,9 @@ config VIDEO_IR | |||
82 | config VIDEO_TVEEPROM | 82 | config VIDEO_TVEEPROM |
83 | tristate | 83 | tristate |
84 | 84 | ||
85 | config VIDEO_CX2341X | ||
86 | tristate | ||
87 | |||
85 | config USB_DABUSB | 88 | config USB_DABUSB |
86 | tristate "DABUSB driver" | 89 | tristate "DABUSB driver" |
87 | depends on USB | 90 | depends on USB |
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile index 61b89617a967..8e7448230643 100644 --- a/drivers/media/common/Makefile +++ b/drivers/media/common/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | saa7146-objs := saa7146_i2c.o saa7146_core.o | 1 | saa7146-objs := saa7146_i2c.o saa7146_core.o |
2 | saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o | 2 | saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o |
3 | ir-common-objs := ir-functions.o ir-keymaps.o | 3 | ir-common-objs := ir-functions.o ir-keymaps.o |
4 | 4 | ||
5 | obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o | 5 | obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o |
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index 397cff8b345b..8eaa88fd8b9b 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c | |||
@@ -269,4 +269,3 @@ EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); | |||
269 | * c-basic-offset: 8 | 269 | * c-basic-offset: 8 |
270 | * End: | 270 | * End: |
271 | */ | 271 | */ |
272 | |||
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index a294d5c2c73f..ca98d9478947 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c | |||
@@ -618,7 +618,7 @@ IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { | |||
618 | 618 | ||
619 | EXPORT_SYMBOL_GPL(ir_codes_em_terratec); | 619 | EXPORT_SYMBOL_GPL(ir_codes_em_terratec); |
620 | 620 | ||
621 | IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { | 621 | IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { |
622 | [ 0x3a ] = KEY_0, | 622 | [ 0x3a ] = KEY_0, |
623 | [ 0x31 ] = KEY_1, | 623 | [ 0x31 ] = KEY_1, |
624 | [ 0x32 ] = KEY_2, | 624 | [ 0x32 ] = KEY_2, |
@@ -670,7 +670,7 @@ IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { | |||
670 | [ 0x27 ] = KEY_RECORD, | 670 | [ 0x27 ] = KEY_RECORD, |
671 | }; | 671 | }; |
672 | 672 | ||
673 | EXPORT_SYMBOL_GPL(ir_codes_em_pinnacle_usb); | 673 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey); |
674 | 674 | ||
675 | IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { | 675 | IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { |
676 | [ 0x0f ] = KEY_0, | 676 | [ 0x0f ] = KEY_0, |
@@ -1263,34 +1263,51 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | |||
1263 | [ 0x0f ] = KEY_9, | 1263 | [ 0x0f ] = KEY_9, |
1264 | 1264 | ||
1265 | [ 0x00 ] = KEY_POWER, | 1265 | [ 0x00 ] = KEY_POWER, |
1266 | [ 0x02 ] = KEY_TUNER, /* TV/FM */ | 1266 | [ 0x1b ] = KEY_AUDIO, /* Audio Source */ |
1267 | [ 0x1e ] = KEY_VIDEO, | 1267 | [ 0x02 ] = KEY_TUNER, /* TV/FM, not on Y0400052 */ |
1268 | [ 0x1e ] = KEY_VIDEO, /* Video Source */ | ||
1269 | [ 0x16 ] = KEY_INFO, /* Display information */ | ||
1268 | [ 0x04 ] = KEY_VOLUMEUP, | 1270 | [ 0x04 ] = KEY_VOLUMEUP, |
1269 | [ 0x08 ] = KEY_VOLUMEDOWN, | 1271 | [ 0x08 ] = KEY_VOLUMEDOWN, |
1270 | [ 0x0c ] = KEY_CHANNELUP, | 1272 | [ 0x0c ] = KEY_CHANNELUP, |
1271 | [ 0x10 ] = KEY_CHANNELDOWN, | 1273 | [ 0x10 ] = KEY_CHANNELDOWN, |
1272 | [ 0x03 ] = KEY_ZOOM, /* fullscreen */ | 1274 | [ 0x03 ] = KEY_ZOOM, /* fullscreen */ |
1273 | [ 0x1f ] = KEY_SUBTITLE, /* closed caption/teletext */ | 1275 | [ 0x1f ] = KEY_TEXT, /* closed caption/teletext */ |
1274 | [ 0x20 ] = KEY_SLEEP, | 1276 | [ 0x20 ] = KEY_SLEEP, |
1277 | [ 0x29 ] = KEY_CLEAR, /* boss key */ | ||
1275 | [ 0x14 ] = KEY_MUTE, | 1278 | [ 0x14 ] = KEY_MUTE, |
1276 | [ 0x2b ] = KEY_RED, | 1279 | [ 0x2b ] = KEY_RED, |
1277 | [ 0x2c ] = KEY_GREEN, | 1280 | [ 0x2c ] = KEY_GREEN, |
1278 | [ 0x2d ] = KEY_YELLOW, | 1281 | [ 0x2d ] = KEY_YELLOW, |
1279 | [ 0x2e ] = KEY_BLUE, | 1282 | [ 0x2e ] = KEY_BLUE, |
1280 | [ 0x18 ] = KEY_KPPLUS, /* fine tune + */ | 1283 | [ 0x18 ] = KEY_KPPLUS, /* fine tune + , not on Y040052 */ |
1281 | [ 0x19 ] = KEY_KPMINUS, /* fine tune - */ | 1284 | [ 0x19 ] = KEY_KPMINUS, /* fine tune - , not on Y040052 */ |
1285 | [ 0x2a ] = KEY_MEDIA, /* PIP (Picture in picture */ | ||
1282 | [ 0x21 ] = KEY_DOT, | 1286 | [ 0x21 ] = KEY_DOT, |
1283 | [ 0x13 ] = KEY_ENTER, | 1287 | [ 0x13 ] = KEY_ENTER, |
1284 | [ 0x22 ] = KEY_BACK, | 1288 | [ 0x11 ] = KEY_LAST, /* Recall (last channel */ |
1289 | [ 0x22 ] = KEY_PREVIOUS, | ||
1285 | [ 0x23 ] = KEY_PLAYPAUSE, | 1290 | [ 0x23 ] = KEY_PLAYPAUSE, |
1286 | [ 0x24 ] = KEY_NEXT, | 1291 | [ 0x24 ] = KEY_NEXT, |
1292 | [ 0x25 ] = KEY_ARCHIVE, /* Time Shifting */ | ||
1287 | [ 0x26 ] = KEY_STOP, | 1293 | [ 0x26 ] = KEY_STOP, |
1288 | [ 0x27 ] = KEY_RECORD | 1294 | [ 0x27 ] = KEY_RECORD, |
1295 | [ 0x28 ] = KEY_SAVE, /* Screenshot */ | ||
1296 | [ 0x2f ] = KEY_MENU, | ||
1297 | [ 0x30 ] = KEY_CANCEL, | ||
1298 | [ 0x31 ] = KEY_CHANNEL, /* Channel Surf */ | ||
1299 | [ 0x32 ] = KEY_SUBTITLE, | ||
1300 | [ 0x33 ] = KEY_LANGUAGE, | ||
1301 | [ 0x34 ] = KEY_REWIND, | ||
1302 | [ 0x35 ] = KEY_FASTFORWARD, | ||
1303 | [ 0x36 ] = KEY_TV, | ||
1304 | [ 0x37 ] = KEY_RADIO, /* FM */ | ||
1305 | [ 0x38 ] = KEY_DVD | ||
1289 | }; | 1306 | }; |
1290 | 1307 | ||
1291 | EXPORT_SYMBOL_GPL(ir_codes_winfast); | 1308 | EXPORT_SYMBOL_GPL(ir_codes_winfast); |
1292 | 1309 | ||
1293 | IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { | 1310 | IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE] = { |
1294 | [ 0x59 ] = KEY_MUTE, | 1311 | [ 0x59 ] = KEY_MUTE, |
1295 | [ 0x4a ] = KEY_POWER, | 1312 | [ 0x4a ] = KEY_POWER, |
1296 | 1313 | ||
@@ -1348,7 +1365,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { | |||
1348 | [ 0x0a ] = KEY_BACKSPACE, | 1365 | [ 0x0a ] = KEY_BACKSPACE, |
1349 | }; | 1366 | }; |
1350 | 1367 | ||
1351 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle); | 1368 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color); |
1352 | 1369 | ||
1353 | /* Hauppauge: the newer, gray remotes (seems there are multiple | 1370 | /* Hauppauge: the newer, gray remotes (seems there are multiple |
1354 | * slightly different versions), shipped with cx88+ivtv cards. | 1371 | * slightly different versions), shipped with cx88+ivtv cards. |
@@ -1413,3 +1430,46 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { | |||
1413 | 1430 | ||
1414 | EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new); | 1431 | EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new); |
1415 | 1432 | ||
1433 | IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE] = { | ||
1434 | [ 0x1d ] = KEY_SWITCHVIDEOMODE, /* switch inputs */ | ||
1435 | [ 0x2a ] = KEY_FRONT, | ||
1436 | |||
1437 | [ 0x3e ] = KEY_1, | ||
1438 | [ 0x02 ] = KEY_2, | ||
1439 | [ 0x06 ] = KEY_3, | ||
1440 | [ 0x0a ] = KEY_4, | ||
1441 | [ 0x0e ] = KEY_5, | ||
1442 | [ 0x12 ] = KEY_6, | ||
1443 | [ 0x16 ] = KEY_7, | ||
1444 | [ 0x1a ] = KEY_8, | ||
1445 | [ 0x1e ] = KEY_9, | ||
1446 | [ 0x3a ] = KEY_0, | ||
1447 | [ 0x22 ] = KEY_NUMLOCK, /* -/-- */ | ||
1448 | [ 0x20 ] = KEY_REFRESH, | ||
1449 | |||
1450 | [ 0x03 ] = KEY_BRIGHTNESSDOWN, | ||
1451 | [ 0x28 ] = KEY_AUDIO, | ||
1452 | [ 0x3c ] = KEY_UP, | ||
1453 | [ 0x3f ] = KEY_LEFT, | ||
1454 | [ 0x2e ] = KEY_MUTE, | ||
1455 | [ 0x3b ] = KEY_RIGHT, | ||
1456 | [ 0x00 ] = KEY_DOWN, | ||
1457 | [ 0x07 ] = KEY_BRIGHTNESSUP, | ||
1458 | [ 0x2c ] = KEY_TEXT, | ||
1459 | |||
1460 | [ 0x37 ] = KEY_RECORD, | ||
1461 | [ 0x17 ] = KEY_PLAY, | ||
1462 | [ 0x13 ] = KEY_PAUSE, | ||
1463 | [ 0x26 ] = KEY_STOP, | ||
1464 | [ 0x18 ] = KEY_FASTFORWARD, | ||
1465 | [ 0x14 ] = KEY_REWIND, | ||
1466 | [ 0x33 ] = KEY_ZOOM, | ||
1467 | [ 0x32 ] = KEY_KEYBOARD, | ||
1468 | [ 0x30 ] = KEY_GOTO, /* Pointing arrow */ | ||
1469 | [ 0x36 ] = KEY_MACRO, /* Maximize/Minimize (yellow) */ | ||
1470 | [ 0x0b ] = KEY_RADIO, | ||
1471 | [ 0x10 ] = KEY_POWER, | ||
1472 | |||
1473 | }; | ||
1474 | |||
1475 | EXPORT_SYMBOL_GPL(ir_codes_npgtech); | ||
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 523ab3851c7b..0027acc5b8e9 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c | |||
@@ -501,6 +501,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) | |||
501 | 501 | ||
502 | return 0; | 502 | return 0; |
503 | } | 503 | } |
504 | EXPORT_SYMBOL_GPL(saa7146_vv_init); | ||
504 | 505 | ||
505 | int saa7146_vv_release(struct saa7146_dev* dev) | 506 | int saa7146_vv_release(struct saa7146_dev* dev) |
506 | { | 507 | { |
@@ -515,6 +516,7 @@ int saa7146_vv_release(struct saa7146_dev* dev) | |||
515 | 516 | ||
516 | return 0; | 517 | return 0; |
517 | } | 518 | } |
519 | EXPORT_SYMBOL_GPL(saa7146_vv_release); | ||
518 | 520 | ||
519 | int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | 521 | int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, |
520 | char *name, int type) | 522 | char *name, int type) |
@@ -553,6 +555,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | |||
553 | *vid = vfd; | 555 | *vid = vfd; |
554 | return 0; | 556 | return 0; |
555 | } | 557 | } |
558 | EXPORT_SYMBOL_GPL(saa7146_register_device); | ||
556 | 559 | ||
557 | int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) | 560 | int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) |
558 | { | 561 | { |
@@ -571,6 +574,7 @@ int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev | |||
571 | 574 | ||
572 | return 0; | 575 | return 0; |
573 | } | 576 | } |
577 | EXPORT_SYMBOL_GPL(saa7146_unregister_device); | ||
574 | 578 | ||
575 | static int __init saa7146_vv_init_module(void) | 579 | static int __init saa7146_vv_init_module(void) |
576 | { | 580 | { |
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c index 33bec8a6843b..2092e6c33dd2 100644 --- a/drivers/media/common/saa7146_hlp.c +++ b/drivers/media/common/saa7146_hlp.c | |||
@@ -641,6 +641,7 @@ void saa7146_set_hps_source_and_sync(struct saa7146_dev *dev, int source, int sy | |||
641 | vv->current_hps_source = source; | 641 | vv->current_hps_source = source; |
642 | vv->current_hps_sync = sync; | 642 | vv->current_hps_sync = sync; |
643 | } | 643 | } |
644 | EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync); | ||
644 | 645 | ||
645 | int saa7146_enable_overlay(struct saa7146_fh *fh) | 646 | int saa7146_enable_overlay(struct saa7146_fh *fh) |
646 | { | 647 | { |
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index e7079d1bd537..8393d472d3b8 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
@@ -318,6 +318,7 @@ int saa7146_start_preview(struct saa7146_fh *fh) | |||
318 | 318 | ||
319 | return 0; | 319 | return 0; |
320 | } | 320 | } |
321 | EXPORT_SYMBOL_GPL(saa7146_start_preview); | ||
321 | 322 | ||
322 | int saa7146_stop_preview(struct saa7146_fh *fh) | 323 | int saa7146_stop_preview(struct saa7146_fh *fh) |
323 | { | 324 | { |
@@ -352,6 +353,7 @@ int saa7146_stop_preview(struct saa7146_fh *fh) | |||
352 | 353 | ||
353 | return 0; | 354 | return 0; |
354 | } | 355 | } |
356 | EXPORT_SYMBOL_GPL(saa7146_stop_preview); | ||
355 | 357 | ||
356 | static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) | 358 | static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) |
357 | { | 359 | { |
diff --git a/drivers/media/common/saa7146_vv_ksyms.c b/drivers/media/common/saa7146_vv_ksyms.c deleted file mode 100644 index 62226eb4753b..000000000000 --- a/drivers/media/common/saa7146_vv_ksyms.c +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <media/saa7146_vv.h> | ||
3 | |||
4 | EXPORT_SYMBOL_GPL(saa7146_start_preview); | ||
5 | EXPORT_SYMBOL_GPL(saa7146_stop_preview); | ||
6 | |||
7 | EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync); | ||
8 | EXPORT_SYMBOL_GPL(saa7146_register_device); | ||
9 | EXPORT_SYMBOL_GPL(saa7146_unregister_device); | ||
10 | |||
11 | EXPORT_SYMBOL_GPL(saa7146_vv_init); | ||
12 | EXPORT_SYMBOL_GPL(saa7146_vv_release); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 9c7f122826e0..3be87c72e37b 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include "stv0297.h" | 14 | #include "stv0297.h" |
15 | #include "mt312.h" | 15 | #include "mt312.h" |
16 | #include "lgdt330x.h" | 16 | #include "lgdt330x.h" |
17 | #include "lg_h06xf.h" | ||
17 | #include "dvb-pll.h" | 18 | #include "dvb-pll.h" |
18 | 19 | ||
19 | /* lnb control */ | 20 | /* lnb control */ |
@@ -166,11 +167,12 @@ static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, | |||
166 | return 0; | 167 | return 0; |
167 | } | 168 | } |
168 | 169 | ||
169 | static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | 170 | static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
170 | { | 171 | { |
171 | u8 buf[4]; | 172 | u8 buf[4]; |
172 | u32 div; | 173 | u32 div; |
173 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | 174 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; |
175 | struct flexcop_device *fc = fe->dvb->priv; | ||
174 | 176 | ||
175 | div = params->frequency / 125; | 177 | div = params->frequency / 125; |
176 | 178 | ||
@@ -181,8 +183,11 @@ static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter | |||
181 | 183 | ||
182 | if (params->frequency < 1500000) buf[3] |= 0x10; | 184 | if (params->frequency < 1500000) buf[3] |= 0x10; |
183 | 185 | ||
184 | if (i2c_transfer(i2c, &msg, 1) != 1) | 186 | if (fe->ops.i2c_gate_ctrl) |
187 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
188 | if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) { | ||
185 | return -EIO; | 189 | return -EIO; |
190 | } | ||
186 | return 0; | 191 | return 0; |
187 | } | 192 | } |
188 | 193 | ||
@@ -241,7 +246,6 @@ static struct stv0299_config samsung_tbmu24112_config = { | |||
241 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 246 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
242 | .min_delay_ms = 100, | 247 | .min_delay_ms = 100, |
243 | .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, | 248 | .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, |
244 | .pll_set = samsung_tbmu24112_pll_set, | ||
245 | }; | 249 | }; |
246 | 250 | ||
247 | /* dvb-t mt352 */ | 251 | /* dvb-t mt352 */ |
@@ -264,11 +268,14 @@ static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) | |||
264 | return 0; | 268 | return 0; |
265 | } | 269 | } |
266 | 270 | ||
267 | static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) | 271 | static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) |
268 | { | 272 | { |
269 | u32 div; | 273 | u32 div; |
270 | unsigned char bs = 0; | 274 | unsigned char bs = 0; |
271 | 275 | ||
276 | if (buf_len < 5) | ||
277 | return -EINVAL; | ||
278 | |||
272 | #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ | 279 | #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ |
273 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | 280 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; |
274 | 281 | ||
@@ -276,19 +283,18 @@ static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_front | |||
276 | if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; | 283 | if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; |
277 | if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; | 284 | if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; |
278 | 285 | ||
279 | pllbuf[0] = 0xc2; /* Note: non-linux standard PLL i2c address */ | 286 | pllbuf[0] = 0x61; |
280 | pllbuf[1] = div >> 8; | 287 | pllbuf[1] = div >> 8; |
281 | pllbuf[2] = div & 0xff; | 288 | pllbuf[2] = div & 0xff; |
282 | pllbuf[3] = 0xcc; | 289 | pllbuf[3] = 0xcc; |
283 | pllbuf[4] = bs; | 290 | pllbuf[4] = bs; |
284 | 291 | ||
285 | return 0; | 292 | return 5; |
286 | } | 293 | } |
287 | 294 | ||
288 | static struct mt352_config samsung_tdtc9251dh0_config = { | 295 | static struct mt352_config samsung_tdtc9251dh0_config = { |
289 | .demod_address = 0x0f, | 296 | .demod_address = 0x0f, |
290 | .demod_init = samsung_tdtc9251dh0_demod_init, | 297 | .demod_init = samsung_tdtc9251dh0_demod_init, |
291 | .pll_set = samsung_tdtc9251dh0_pll_set, | ||
292 | }; | 298 | }; |
293 | 299 | ||
294 | static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) | 300 | static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) |
@@ -297,56 +303,21 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir | |||
297 | return request_firmware(fw, name, fc->dev); | 303 | return request_firmware(fw, name, fc->dev); |
298 | } | 304 | } |
299 | 305 | ||
300 | static int lgdt3303_pll_set(struct dvb_frontend* fe, | 306 | static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
301 | struct dvb_frontend_parameters* params) | ||
302 | { | 307 | { |
303 | struct flexcop_device *fc = fe->dvb->priv; | 308 | struct flexcop_device *fc = fe->dvb->priv; |
304 | u8 buf[4]; | 309 | return lg_h06xf_pll_set(fe, &fc->i2c_adap, params); |
305 | struct i2c_msg msg = | ||
306 | { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 }; | ||
307 | int err; | ||
308 | |||
309 | dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf, params->frequency, 0); | ||
310 | dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
311 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); | ||
312 | if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) { | ||
313 | printk(KERN_WARNING "lgdt3303: %s error " | ||
314 | "(addr %02x <- %02x, err = %i)\n", | ||
315 | __FUNCTION__, buf[0], buf[1], err); | ||
316 | if (err < 0) | ||
317 | return err; | ||
318 | else | ||
319 | return -EREMOTEIO; | ||
320 | } | ||
321 | |||
322 | buf[0] = 0x86 | 0x18; | ||
323 | buf[1] = 0x50; | ||
324 | msg.len = 2; | ||
325 | if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) { | ||
326 | printk(KERN_WARNING "lgdt3303: %s error " | ||
327 | "(addr %02x <- %02x, err = %i)\n", | ||
328 | __FUNCTION__, buf[0], buf[1], err); | ||
329 | if (err < 0) | ||
330 | return err; | ||
331 | else | ||
332 | return -EREMOTEIO; | ||
333 | } | ||
334 | |||
335 | return 0; | ||
336 | } | 310 | } |
337 | 311 | ||
338 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { | 312 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { |
339 | .demod_address = 0x59, | 313 | .demod_address = 0x59, |
340 | .demod_chip = LGDT3303, | 314 | .demod_chip = LGDT3303, |
341 | .serial_mpeg = 0x04, | 315 | .serial_mpeg = 0x04, |
342 | .pll_set = lgdt3303_pll_set, | ||
343 | .clock_polarity_flip = 1, | 316 | .clock_polarity_flip = 1, |
344 | }; | 317 | }; |
345 | 318 | ||
346 | static struct nxt200x_config samsung_tbmv_config = { | 319 | static struct nxt200x_config samsung_tbmv_config = { |
347 | .demod_address = 0x0a, | 320 | .demod_address = 0x0a, |
348 | .pll_address = 0xc2, | ||
349 | .pll_desc = &dvb_pll_samsung_tbmv, | ||
350 | }; | 321 | }; |
351 | 322 | ||
352 | static struct bcm3510_config air2pc_atsc_first_gen_config = { | 323 | static struct bcm3510_config air2pc_atsc_first_gen_config = { |
@@ -354,7 +325,7 @@ static struct bcm3510_config air2pc_atsc_first_gen_config = { | |||
354 | .request_firmware = flexcop_fe_request_firmware, | 325 | .request_firmware = flexcop_fe_request_firmware, |
355 | }; | 326 | }; |
356 | 327 | ||
357 | static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 328 | static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
358 | { | 329 | { |
359 | u8 buf[4]; | 330 | u8 buf[4]; |
360 | u32 div; | 331 | u32 div; |
@@ -371,6 +342,8 @@ static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct d | |||
371 | if (params->frequency < 1550000) | 342 | if (params->frequency < 1550000) |
372 | buf[3] |= 0x02; | 343 | buf[3] |= 0x02; |
373 | 344 | ||
345 | if (fe->ops.i2c_gate_ctrl) | ||
346 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
374 | if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) | 347 | if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) |
375 | return -EIO; | 348 | return -EIO; |
376 | return 0; | 349 | return 0; |
@@ -379,9 +352,52 @@ static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct d | |||
379 | static struct mt312_config skystar23_samsung_tbdu18132_config = { | 352 | static struct mt312_config skystar23_samsung_tbdu18132_config = { |
380 | 353 | ||
381 | .demod_address = 0x0e, | 354 | .demod_address = 0x0e, |
382 | .pll_set = skystar23_samsung_tbdu18132_pll_set, | ||
383 | }; | 355 | }; |
384 | 356 | ||
357 | static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, | ||
358 | struct dvb_frontend_parameters *fep) | ||
359 | { | ||
360 | struct flexcop_device *fc = fe->dvb->priv; | ||
361 | u8 buf[4]; | ||
362 | u16 div; | ||
363 | int ret; | ||
364 | |||
365 | /* 62.5 kHz * 10 */ | ||
366 | #define REF_FREQ 625 | ||
367 | #define FREQ_OFFSET 36125 | ||
368 | |||
369 | div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz | ||
370 | |||
371 | buf[0] = (u8)( div >> 8) & 0x7f; | ||
372 | buf[1] = (u8) div & 0xff; | ||
373 | |||
374 | /* F(osc) = N * Reference Freq. (62.5 kHz) | ||
375 | * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8 | ||
376 | * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0 | ||
377 | * byte 4 : 1 * * AGD R3 R2 R1 R0 | ||
378 | * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1 | ||
379 | * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */ | ||
380 | buf[2] = 0x95; | ||
381 | |||
382 | // Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5 | ||
383 | // 47 - 153 0 * 0 0 0 0 0 1 0x01 | ||
384 | // 153 - 430 0 * 0 0 0 0 1 0 0x02 | ||
385 | // 430 - 822 0 * 0 0 1 0 0 0 0x08 | ||
386 | // 822 - 862 1 * 0 0 1 0 0 0 0x88 | ||
387 | |||
388 | if (fep->frequency <= 153000000) buf[3] = 0x01; | ||
389 | else if (fep->frequency <= 430000000) buf[3] = 0x02; | ||
390 | else if (fep->frequency <= 822000000) buf[3] = 0x08; | ||
391 | else buf[3] = 0x88; | ||
392 | |||
393 | if (fe->ops.i2c_gate_ctrl) | ||
394 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
395 | deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]); | ||
396 | ret = fc->i2c_request(fc,FC_WRITE,FC_I2C_PORT_TUNER,0x61,buf[0],&buf[1],3); | ||
397 | deb_tuner("tuner write returned: %d\n",ret); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
385 | 401 | ||
386 | static u8 alps_tdee4_stv0297_inittab[] = { | 402 | static u8 alps_tdee4_stv0297_inittab[] = { |
387 | 0x80, 0x01, | 403 | 0x80, 0x01, |
@@ -490,7 +506,9 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
490 | 506 | ||
491 | /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ | 507 | /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ |
492 | if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { | 508 | if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { |
493 | ops = fc->fe->ops; | 509 | ops = &fc->fe->ops; |
510 | |||
511 | ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; | ||
494 | 512 | ||
495 | ops->set_voltage = flexcop_set_voltage; | 513 | ops->set_voltage = flexcop_set_voltage; |
496 | 514 | ||
@@ -503,16 +521,19 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
503 | /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ | 521 | /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ |
504 | if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) { | 522 | if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) { |
505 | fc->dev_type = FC_AIR_DVB; | 523 | fc->dev_type = FC_AIR_DVB; |
524 | fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; | ||
506 | info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); | 525 | info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); |
507 | } else | 526 | } else |
508 | /* try the air atsc 2nd generation (nxt2002) */ | 527 | /* try the air atsc 2nd generation (nxt2002) */ |
509 | if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { | 528 | if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { |
510 | fc->dev_type = FC_AIR_ATSC2; | 529 | fc->dev_type = FC_AIR_ATSC2; |
530 | dvb_pll_attach(fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_samsung_tbmv); | ||
511 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); | 531 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); |
512 | } else | 532 | } else |
513 | /* try the air atsc 3nd generation (lgdt3303) */ | 533 | /* try the air atsc 3nd generation (lgdt3303) */ |
514 | if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { | 534 | if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { |
515 | fc->dev_type = FC_AIR_ATSC3; | 535 | fc->dev_type = FC_AIR_ATSC3; |
536 | fc->fe->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; | ||
516 | info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); | 537 | info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); |
517 | } else | 538 | } else |
518 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ | 539 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ |
@@ -523,11 +544,14 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
523 | /* try the cable dvb (stv0297) */ | 544 | /* try the cable dvb (stv0297) */ |
524 | if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) { | 545 | if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) { |
525 | fc->dev_type = FC_CABLE; | 546 | fc->dev_type = FC_CABLE; |
547 | fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; | ||
526 | info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); | 548 | info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); |
527 | } else | 549 | } else |
528 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ | 550 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ |
529 | if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { | 551 | if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { |
530 | ops = fc->fe->ops; | 552 | ops = &fc->fe->ops; |
553 | |||
554 | ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params; | ||
531 | 555 | ||
532 | ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; | 556 | ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; |
533 | ops->diseqc_send_burst = flexcop_diseqc_send_burst; | 557 | ops->diseqc_send_burst = flexcop_diseqc_send_burst; |
@@ -547,7 +571,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
547 | } else { | 571 | } else { |
548 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { | 572 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { |
549 | err("frontend registration failed!"); | 573 | err("frontend registration failed!"); |
550 | ops = fc->fe->ops; | 574 | ops = &fc->fe->ops; |
551 | if (ops->release != NULL) | 575 | if (ops->release != NULL) |
552 | ops->release(fc->fe); | 576 | ops->release(fc->fe); |
553 | fc->fe = NULL; | 577 | fc->fe = NULL; |
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index 9bc40bdcc282..f04041702191 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c | |||
@@ -242,19 +242,16 @@ static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci) | |||
242 | if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0) | 242 | if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0) |
243 | return ret; | 243 | return ret; |
244 | 244 | ||
245 | if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) | 245 | if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) { |
246 | goto dma1_free; | 246 | flexcop_dma_free(&fc_pci->dma[0]); |
247 | return ret; | ||
248 | } | ||
247 | 249 | ||
248 | flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); | 250 | flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); |
249 | flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); | 251 | flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); |
250 | 252 | ||
251 | fc_pci->init_state |= FC_PCI_DMA_INIT; | 253 | fc_pci->init_state |= FC_PCI_DMA_INIT; |
252 | 254 | ||
253 | goto success; | ||
254 | dma1_free: | ||
255 | flexcop_dma_free(&fc_pci->dma[0]); | ||
256 | |||
257 | success: | ||
258 | return ret; | 255 | return ret; |
259 | } | 256 | } |
260 | 257 | ||
@@ -303,7 +300,7 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) | |||
303 | spin_lock_init(&fc_pci->irq_lock); | 300 | spin_lock_init(&fc_pci->irq_lock); |
304 | 301 | ||
305 | fc_pci->init_state |= FC_PCI_INIT; | 302 | fc_pci->init_state |= FC_PCI_INIT; |
306 | goto success; | 303 | return ret; |
307 | 304 | ||
308 | err_pci_iounmap: | 305 | err_pci_iounmap: |
309 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); | 306 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); |
@@ -312,8 +309,6 @@ err_pci_release_regions: | |||
312 | pci_release_regions(fc_pci->pdev); | 309 | pci_release_regions(fc_pci->pdev); |
313 | err_pci_disable_device: | 310 | err_pci_disable_device: |
314 | pci_disable_device(fc_pci->pdev); | 311 | pci_disable_device(fc_pci->pdev); |
315 | |||
316 | success: | ||
317 | return ret; | 312 | return ret; |
318 | } | 313 | } |
319 | 314 | ||
@@ -378,14 +373,14 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
378 | 373 | ||
379 | INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci); | 374 | INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci); |
380 | 375 | ||
381 | goto success; | 376 | return ret; |
377 | |||
382 | err_fc_exit: | 378 | err_fc_exit: |
383 | flexcop_device_exit(fc); | 379 | flexcop_device_exit(fc); |
384 | err_pci_exit: | 380 | err_pci_exit: |
385 | flexcop_pci_exit(fc_pci); | 381 | flexcop_pci_exit(fc_pci); |
386 | err_kfree: | 382 | err_kfree: |
387 | flexcop_device_kfree(fc); | 383 | flexcop_device_kfree(fc); |
388 | success: | ||
389 | return ret; | 384 | return ret; |
390 | } | 385 | } |
391 | 386 | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 06ec9fff0ec1..515954f96c9a 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c | |||
@@ -433,11 +433,10 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) | |||
433 | flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS); | 433 | flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS); |
434 | flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1); | 434 | flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1); |
435 | 435 | ||
436 | ret = 0; | 436 | return 0; |
437 | goto success; | 437 | |
438 | urb_error: | 438 | urb_error: |
439 | flexcop_usb_transfer_exit(fc_usb); | 439 | flexcop_usb_transfer_exit(fc_usb); |
440 | success: | ||
441 | return ret; | 440 | return ret; |
442 | } | 441 | } |
443 | 442 | ||
@@ -515,15 +514,14 @@ static int flexcop_usb_probe(struct usb_interface *intf, | |||
515 | goto err_fc_exit; | 514 | goto err_fc_exit; |
516 | 515 | ||
517 | info("%s successfully initialized and connected.",DRIVER_NAME); | 516 | info("%s successfully initialized and connected.",DRIVER_NAME); |
518 | ret = 0; | 517 | return 0; |
519 | goto success; | 518 | |
520 | err_fc_exit: | 519 | err_fc_exit: |
521 | flexcop_device_exit(fc); | 520 | flexcop_device_exit(fc); |
522 | err_usb_exit: | 521 | err_usb_exit: |
523 | flexcop_usb_exit(fc_usb); | 522 | flexcop_usb_exit(fc_usb); |
524 | err_kfree: | 523 | err_kfree: |
525 | flexcop_device_kfree(fc); | 524 | flexcop_device_kfree(fc); |
526 | success: | ||
527 | return ret; | 525 | return ret; |
528 | } | 526 | } |
529 | 527 | ||
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c index 56ba52470676..29ec4183118e 100644 --- a/drivers/media/dvb/b2c2/flexcop.c +++ b/drivers/media/dvb/b2c2/flexcop.c | |||
@@ -67,7 +67,7 @@ static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
67 | static int flexcop_dvb_init(struct flexcop_device *fc) | 67 | static int flexcop_dvb_init(struct flexcop_device *fc) |
68 | { | 68 | { |
69 | int ret; | 69 | int ret; |
70 | if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner)) < 0) { | 70 | if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner,fc->dev)) < 0) { |
71 | err("error registering DVB adapter"); | 71 | err("error registering DVB adapter"); |
72 | return ret; | 72 | return ret; |
73 | } | 73 | } |
@@ -116,7 +116,7 @@ static int flexcop_dvb_init(struct flexcop_device *fc) | |||
116 | dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx); | 116 | dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx); |
117 | 117 | ||
118 | fc->init_state |= FC_STATE_DVB_INIT; | 118 | fc->init_state |= FC_STATE_DVB_INIT; |
119 | goto success; | 119 | return 0; |
120 | 120 | ||
121 | err_connect_frontend: | 121 | err_connect_frontend: |
122 | fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); | 122 | fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); |
@@ -129,9 +129,6 @@ err_dmx_dev: | |||
129 | err_dmx: | 129 | err_dmx: |
130 | dvb_unregister_adapter(&fc->dvb_adapter); | 130 | dvb_unregister_adapter(&fc->dvb_adapter); |
131 | return ret; | 131 | return ret; |
132 | |||
133 | success: | ||
134 | return 0; | ||
135 | } | 132 | } |
136 | 133 | ||
137 | static void flexcop_dvb_exit(struct flexcop_device *fc) | 134 | static void flexcop_dvb_exit(struct flexcop_device *fc) |
@@ -279,11 +276,10 @@ int flexcop_device_initialize(struct flexcop_device *fc) | |||
279 | 276 | ||
280 | flexcop_device_name(fc,"initialization of","complete"); | 277 | flexcop_device_name(fc,"initialization of","complete"); |
281 | 278 | ||
282 | ret = 0; | 279 | return 0; |
283 | goto success; | 280 | |
284 | error: | 281 | error: |
285 | flexcop_device_exit(fc); | 282 | flexcop_device_exit(fc); |
286 | success: | ||
287 | return ret; | 283 | return ret; |
288 | } | 284 | } |
289 | EXPORT_SYMBOL(flexcop_device_initialize); | 285 | EXPORT_SYMBOL(flexcop_device_initialize); |
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index 5500f8a0ffe2..761fa6e7d762 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c | |||
@@ -63,8 +63,6 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off)."); | |||
63 | int bt878_num; | 63 | int bt878_num; |
64 | struct bt878 bt878[BT878_MAX]; | 64 | struct bt878 bt878[BT878_MAX]; |
65 | 65 | ||
66 | EXPORT_SYMBOL(bt878_debug); | ||
67 | EXPORT_SYMBOL(bt878_verbose); | ||
68 | EXPORT_SYMBOL(bt878_num); | 66 | EXPORT_SYMBOL(bt878_num); |
69 | EXPORT_SYMBOL(bt878); | 67 | EXPORT_SYMBOL(bt878); |
70 | 68 | ||
@@ -393,7 +391,9 @@ static struct cards card_list[] __devinitdata = { | |||
393 | { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, | 391 | { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, |
394 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, | 392 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, |
395 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, | 393 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, |
396 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, | 394 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" }, |
395 | { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }, | ||
396 | |||
397 | { 0, -1, NULL } | 397 | { 0, -1, NULL } |
398 | }; | 398 | }; |
399 | 399 | ||
@@ -417,6 +417,11 @@ static int __devinit bt878_probe(struct pci_dev *dev, | |||
417 | 417 | ||
418 | printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", | 418 | printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", |
419 | bt878_num); | 419 | bt878_num); |
420 | if (bt878_num >= BT878_MAX) { | ||
421 | printk(KERN_ERR "bt878: Too many devices inserted\n"); | ||
422 | result = -ENOMEM; | ||
423 | goto fail0; | ||
424 | } | ||
420 | if (pci_enable_device(dev)) | 425 | if (pci_enable_device(dev)) |
421 | return -EIO; | 426 | return -EIO; |
422 | 427 | ||
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 1cfa5e5035d8..d687a14ec0a7 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -38,6 +38,10 @@ static unsigned int dst_addons; | |||
38 | module_param(dst_addons, int, 0644); | 38 | module_param(dst_addons, int, 0644); |
39 | MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); | 39 | MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); |
40 | 40 | ||
41 | static unsigned int dst_algo; | ||
42 | module_param(dst_algo, int, 0644); | ||
43 | MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)"); | ||
44 | |||
41 | #define HAS_LOCK 1 | 45 | #define HAS_LOCK 1 |
42 | #define ATTEMPT_TUNE 2 | 46 | #define ATTEMPT_TUNE 2 |
43 | #define HAS_POWER 4 | 47 | #define HAS_POWER 4 |
@@ -47,20 +51,24 @@ MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); | |||
47 | #define DST_INFO 2 | 51 | #define DST_INFO 2 |
48 | #define DST_DEBUG 3 | 52 | #define DST_DEBUG 3 |
49 | 53 | ||
50 | #define dprintk(x, y, z, format, arg...) do { \ | 54 | #define dprintk(x, y, z, format, arg...) do { \ |
51 | if (z) { \ | 55 | if (z) { \ |
52 | if ((x > DST_ERROR) && (x > y)) \ | 56 | if ((x > DST_ERROR) && (x > y)) \ |
53 | printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \ | 57 | printk(KERN_ERR "dst(%d) %s: " format "\n", \ |
54 | else if ((x > DST_NOTICE) && (x > y)) \ | 58 | state->bt->nr, __func__ , ##arg); \ |
55 | printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \ | 59 | else if ((x > DST_NOTICE) && (x > y)) \ |
56 | else if ((x > DST_INFO) && (x > y)) \ | 60 | printk(KERN_NOTICE "dst(%d) %s: " format "\n", \ |
57 | printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \ | 61 | state->bt->nr, __func__ , ##arg); \ |
58 | else if ((x > DST_DEBUG) && (x > y)) \ | 62 | else if ((x > DST_INFO) && (x > y)) \ |
59 | printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \ | 63 | printk(KERN_INFO "dst(%d) %s: " format "\n", \ |
60 | } else { \ | 64 | state->bt->nr, __func__ , ##arg); \ |
61 | if (x > y) \ | 65 | else if ((x > DST_DEBUG) && (x > y)) \ |
62 | printk(format, ##arg); \ | 66 | printk(KERN_DEBUG "dst(%d) %s: " format "\n", \ |
63 | } \ | 67 | state->bt->nr, __func__ , ##arg); \ |
68 | } else { \ | ||
69 | if (x > y) \ | ||
70 | printk(format, ##arg); \ | ||
71 | } \ | ||
64 | } while(0) | 72 | } while(0) |
65 | 73 | ||
66 | 74 | ||
@@ -110,7 +118,7 @@ int dst_gpio_inb(struct dst_state *state, u8 *result) | |||
110 | 118 | ||
111 | *result = 0; | 119 | *result = 0; |
112 | if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { | 120 | if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { |
113 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)\n", err); | 121 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err); |
114 | return -EREMOTEIO; | 122 | return -EREMOTEIO; |
115 | } | 123 | } |
116 | *result = (u8) rd_packet.rd.value; | 124 | *result = (u8) rd_packet.rd.value; |
@@ -363,6 +371,17 @@ static int dst_set_freq(struct dst_state *state, u32 freq) | |||
363 | state->tx_tuna[2] = (freq >> 16) & 0xff; | 371 | state->tx_tuna[2] = (freq >> 16) & 0xff; |
364 | state->tx_tuna[3] = (freq >> 8) & 0xff; | 372 | state->tx_tuna[3] = (freq >> 8) & 0xff; |
365 | state->tx_tuna[4] = (u8) freq; | 373 | state->tx_tuna[4] = (u8) freq; |
374 | } else if (state->dst_type == DST_TYPE_IS_ATSC) { | ||
375 | freq = freq / 1000; | ||
376 | if (freq < 51000 || freq > 858000) | ||
377 | return -EINVAL; | ||
378 | state->tx_tuna[2] = (freq >> 16) & 0xff; | ||
379 | state->tx_tuna[3] = (freq >> 8) & 0xff; | ||
380 | state->tx_tuna[4] = (u8) freq; | ||
381 | state->tx_tuna[5] = 0x00; /* ATSC */ | ||
382 | state->tx_tuna[6] = 0x00; | ||
383 | if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG) | ||
384 | state->tx_tuna[7] = 0x00; /* Digital */ | ||
366 | } else | 385 | } else |
367 | return -EINVAL; | 386 | return -EINVAL; |
368 | 387 | ||
@@ -447,29 +466,41 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate) | |||
447 | } | 466 | } |
448 | dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); | 467 | dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); |
449 | srate /= 1000; | 468 | srate /= 1000; |
450 | if (state->type_flags & DST_TYPE_HAS_SYMDIV) { | 469 | if (state->dst_type == DST_TYPE_IS_SAT) { |
451 | sval = srate; | 470 | if (state->type_flags & DST_TYPE_HAS_SYMDIV) { |
452 | sval <<= 20; | 471 | sval = srate; |
453 | do_div(sval, 88000); | 472 | sval <<= 20; |
454 | symcalc = (u32) sval; | 473 | do_div(sval, 88000); |
455 | dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); | 474 | symcalc = (u32) sval; |
456 | state->tx_tuna[5] = (u8) (symcalc >> 12); | 475 | dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); |
457 | state->tx_tuna[6] = (u8) (symcalc >> 4); | 476 | state->tx_tuna[5] = (u8) (symcalc >> 12); |
458 | state->tx_tuna[7] = (u8) (symcalc << 4); | 477 | state->tx_tuna[6] = (u8) (symcalc >> 4); |
459 | } else { | 478 | state->tx_tuna[7] = (u8) (symcalc << 4); |
460 | state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; | 479 | } else { |
461 | state->tx_tuna[6] = (u8) (srate >> 8); | 480 | state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; |
462 | state->tx_tuna[7] = (u8) srate; | 481 | state->tx_tuna[6] = (u8) (srate >> 8); |
463 | } | 482 | state->tx_tuna[7] = (u8) srate; |
464 | state->tx_tuna[8] &= ~0x20; | 483 | } |
465 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { | 484 | state->tx_tuna[8] &= ~0x20; |
466 | if (srate > 8000) | 485 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { |
467 | state->tx_tuna[8] |= 0x20; | 486 | if (srate > 8000) |
487 | state->tx_tuna[8] |= 0x20; | ||
488 | } | ||
489 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
490 | dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name); | ||
491 | if (!strncmp(state->fw_name, "DCTNEW", 6)) { | ||
492 | state->tx_tuna[5] = (u8) (srate >> 8); | ||
493 | state->tx_tuna[6] = (u8) srate; | ||
494 | state->tx_tuna[7] = 0x00; | ||
495 | } else if (!strncmp(state->fw_name, "DCT-CI", 6)) { | ||
496 | state->tx_tuna[5] = 0x00; | ||
497 | state->tx_tuna[6] = (u8) (srate >> 8); | ||
498 | state->tx_tuna[7] = (u8) srate; | ||
499 | } | ||
468 | } | 500 | } |
469 | return 0; | 501 | return 0; |
470 | } | 502 | } |
471 | 503 | ||
472 | |||
473 | static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) | 504 | static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) |
474 | { | 505 | { |
475 | if (state->dst_type != DST_TYPE_IS_CABLE) | 506 | if (state->dst_type != DST_TYPE_IS_CABLE) |
@@ -490,7 +521,10 @@ static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulatio | |||
490 | state->tx_tuna[8] = 0x80; | 521 | state->tx_tuna[8] = 0x80; |
491 | break; | 522 | break; |
492 | case QAM_256: | 523 | case QAM_256: |
493 | state->tx_tuna[8] = 0x00; | 524 | if (!strncmp(state->fw_name, "DCTNEW", 6)) |
525 | state->tx_tuna[8] = 0xff; | ||
526 | else if (!strncmp(state->fw_name, "DCT-CI", 6)) | ||
527 | state->tx_tuna[8] = 0x00; | ||
494 | break; | 528 | break; |
495 | case QPSK: | 529 | case QPSK: |
496 | case QAM_AUTO: | 530 | case QAM_AUTO: |
@@ -523,13 +557,19 @@ u8 dst_check_sum(u8 *buf, u32 len) | |||
523 | } | 557 | } |
524 | EXPORT_SYMBOL(dst_check_sum); | 558 | EXPORT_SYMBOL(dst_check_sum); |
525 | 559 | ||
526 | static void dst_type_flags_print(u32 type_flags) | 560 | static void dst_type_flags_print(struct dst_state *state) |
527 | { | 561 | { |
562 | u32 type_flags = state->type_flags; | ||
563 | |||
528 | dprintk(verbose, DST_ERROR, 0, "DST type flags :"); | 564 | dprintk(verbose, DST_ERROR, 0, "DST type flags :"); |
529 | if (type_flags & DST_TYPE_HAS_NEWTUNE) | 565 | if (type_flags & DST_TYPE_HAS_TS188) |
530 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_NEWTUNE); | 566 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188); |
567 | if (type_flags & DST_TYPE_HAS_NEWTUNE_2) | ||
568 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2); | ||
531 | if (type_flags & DST_TYPE_HAS_TS204) | 569 | if (type_flags & DST_TYPE_HAS_TS204) |
532 | dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); | 570 | dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); |
571 | if (type_flags & DST_TYPE_HAS_VLF) | ||
572 | dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF); | ||
533 | if (type_flags & DST_TYPE_HAS_SYMDIV) | 573 | if (type_flags & DST_TYPE_HAS_SYMDIV) |
534 | dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); | 574 | dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); |
535 | if (type_flags & DST_TYPE_HAS_FW_1) | 575 | if (type_flags & DST_TYPE_HAS_FW_1) |
@@ -542,7 +582,7 @@ static void dst_type_flags_print(u32 type_flags) | |||
542 | } | 582 | } |
543 | 583 | ||
544 | 584 | ||
545 | static int dst_type_print(u8 type) | 585 | static int dst_type_print(struct dst_state *state, u8 type) |
546 | { | 586 | { |
547 | char *otype; | 587 | char *otype; |
548 | switch (type) { | 588 | switch (type) { |
@@ -558,6 +598,10 @@ static int dst_type_print(u8 type) | |||
558 | otype = "cable"; | 598 | otype = "cable"; |
559 | break; | 599 | break; |
560 | 600 | ||
601 | case DST_TYPE_IS_ATSC: | ||
602 | otype = "atsc"; | ||
603 | break; | ||
604 | |||
561 | default: | 605 | default: |
562 | dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); | 606 | dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); |
563 | return -EINVAL; | 607 | return -EINVAL; |
@@ -567,6 +611,127 @@ static int dst_type_print(u8 type) | |||
567 | return 0; | 611 | return 0; |
568 | } | 612 | } |
569 | 613 | ||
614 | struct tuner_types tuner_list[] = { | ||
615 | { | ||
616 | .tuner_type = TUNER_TYPE_L64724, | ||
617 | .tuner_name = "L 64724", | ||
618 | .board_name = "UNKNOWN", | ||
619 | .fw_name = "UNKNOWN" | ||
620 | }, | ||
621 | |||
622 | { | ||
623 | .tuner_type = TUNER_TYPE_STV0299, | ||
624 | .tuner_name = "STV 0299", | ||
625 | .board_name = "VP1020", | ||
626 | .fw_name = "DST-MOT" | ||
627 | }, | ||
628 | |||
629 | { | ||
630 | .tuner_type = TUNER_TYPE_STV0299, | ||
631 | .tuner_name = "STV 0299", | ||
632 | .board_name = "VP1020", | ||
633 | .fw_name = "DST-03T" | ||
634 | }, | ||
635 | |||
636 | { | ||
637 | .tuner_type = TUNER_TYPE_MB86A15, | ||
638 | .tuner_name = "MB 86A15", | ||
639 | .board_name = "VP1022", | ||
640 | .fw_name = "DST-03T" | ||
641 | }, | ||
642 | |||
643 | { | ||
644 | .tuner_type = TUNER_TYPE_MB86A15, | ||
645 | .tuner_name = "MB 86A15", | ||
646 | .board_name = "VP1025", | ||
647 | .fw_name = "DST-03T" | ||
648 | }, | ||
649 | |||
650 | { | ||
651 | .tuner_type = TUNER_TYPE_STV0299, | ||
652 | .tuner_name = "STV 0299", | ||
653 | .board_name = "VP1030", | ||
654 | .fw_name = "DST-CI" | ||
655 | }, | ||
656 | |||
657 | { | ||
658 | .tuner_type = TUNER_TYPE_STV0299, | ||
659 | .tuner_name = "STV 0299", | ||
660 | .board_name = "VP1030", | ||
661 | .fw_name = "DSTMCI" | ||
662 | }, | ||
663 | |||
664 | { | ||
665 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
666 | .tuner_name = "UNKNOWN", | ||
667 | .board_name = "VP2021", | ||
668 | .fw_name = "DCTNEW" | ||
669 | }, | ||
670 | |||
671 | { | ||
672 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
673 | .tuner_name = "UNKNOWN", | ||
674 | .board_name = "VP2030", | ||
675 | .fw_name = "DCT-CI" | ||
676 | }, | ||
677 | |||
678 | { | ||
679 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
680 | .tuner_name = "UNKNOWN", | ||
681 | .board_name = "VP2031", | ||
682 | .fw_name = "DCT-CI" | ||
683 | }, | ||
684 | |||
685 | { | ||
686 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
687 | .tuner_name = "UNKNOWN", | ||
688 | .board_name = "VP2040", | ||
689 | .fw_name = "DCT-CI" | ||
690 | }, | ||
691 | |||
692 | { | ||
693 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
694 | .tuner_name = "UNKNOWN", | ||
695 | .board_name = "VP3020", | ||
696 | .fw_name = "DTTFTA" | ||
697 | }, | ||
698 | |||
699 | { | ||
700 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
701 | .tuner_name = "UNKNOWN", | ||
702 | .board_name = "VP3021", | ||
703 | .fw_name = "DTTFTA" | ||
704 | }, | ||
705 | |||
706 | { | ||
707 | .tuner_type = TUNER_TYPE_TDA10046, | ||
708 | .tuner_name = "TDA10046", | ||
709 | .board_name = "VP3040", | ||
710 | .fw_name = "DTT-CI" | ||
711 | }, | ||
712 | |||
713 | { | ||
714 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
715 | .tuner_name = "UNKNOWN", | ||
716 | .board_name = "VP3051", | ||
717 | .fw_name = "DTTNXT" | ||
718 | }, | ||
719 | |||
720 | { | ||
721 | .tuner_type = TUNER_TYPE_NXT200x, | ||
722 | .tuner_name = "NXT200x", | ||
723 | .board_name = "VP3220", | ||
724 | .fw_name = "ATSCDI" | ||
725 | }, | ||
726 | |||
727 | { | ||
728 | .tuner_type = TUNER_TYPE_NXT200x, | ||
729 | .tuner_name = "NXT200x", | ||
730 | .board_name = "VP3250", | ||
731 | .fw_name = "ATSCAD" | ||
732 | }, | ||
733 | }; | ||
734 | |||
570 | /* | 735 | /* |
571 | Known cards list | 736 | Known cards list |
572 | Satellite | 737 | Satellite |
@@ -608,7 +773,8 @@ static struct dst_types dst_tlist[] = { | |||
608 | .offset = 0, | 773 | .offset = 0, |
609 | .dst_type = DST_TYPE_IS_SAT, | 774 | .dst_type = DST_TYPE_IS_SAT, |
610 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, | 775 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, |
611 | .dst_feature = 0 | 776 | .dst_feature = 0, |
777 | .tuner_type = 0 | ||
612 | }, /* obsolete */ | 778 | }, /* obsolete */ |
613 | 779 | ||
614 | { | 780 | { |
@@ -616,15 +782,17 @@ static struct dst_types dst_tlist[] = { | |||
616 | .offset = 0, | 782 | .offset = 0, |
617 | .dst_type = DST_TYPE_IS_SAT, | 783 | .dst_type = DST_TYPE_IS_SAT, |
618 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | 784 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, |
619 | .dst_feature = 0 | 785 | .dst_feature = 0, |
786 | .tuner_type = 0 | ||
620 | }, /* obsolete */ | 787 | }, /* obsolete */ |
621 | 788 | ||
622 | { | 789 | { |
623 | .device_id = "DST-030", | 790 | .device_id = "DST-030", |
624 | .offset = 0, | 791 | .offset = 0, |
625 | .dst_type = DST_TYPE_IS_SAT, | 792 | .dst_type = DST_TYPE_IS_SAT, |
626 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | 793 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, |
627 | .dst_feature = 0 | 794 | .dst_feature = 0, |
795 | .tuner_type = 0 | ||
628 | }, /* obsolete */ | 796 | }, /* obsolete */ |
629 | 797 | ||
630 | { | 798 | { |
@@ -633,7 +801,8 @@ static struct dst_types dst_tlist[] = { | |||
633 | .dst_type = DST_TYPE_IS_SAT, | 801 | .dst_type = DST_TYPE_IS_SAT, |
634 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, | 802 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, |
635 | .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 | 803 | .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 |
636 | | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO | 804 | | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO, |
805 | .tuner_type = TUNER_TYPE_MULTI | ||
637 | }, | 806 | }, |
638 | 807 | ||
639 | { | 808 | { |
@@ -641,57 +810,63 @@ static struct dst_types dst_tlist[] = { | |||
641 | .offset = 0, | 810 | .offset = 0, |
642 | .dst_type = DST_TYPE_IS_SAT, | 811 | .dst_type = DST_TYPE_IS_SAT, |
643 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | 812 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, |
644 | .dst_feature = 0 | 813 | .dst_feature = 0, |
814 | .tuner_type = 0 | ||
645 | }, /* obsolete */ | 815 | }, /* obsolete */ |
646 | 816 | ||
647 | { | 817 | { |
648 | .device_id = "DST-CI", | 818 | .device_id = "DST-CI", |
649 | .offset = 1, | 819 | .offset = 1, |
650 | .dst_type = DST_TYPE_IS_SAT, | 820 | .dst_type = DST_TYPE_IS_SAT, |
651 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | 821 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1, |
652 | .dst_feature = DST_TYPE_HAS_CA | 822 | .dst_feature = DST_TYPE_HAS_CA, |
823 | .tuner_type = 0 | ||
653 | }, /* An OEM board */ | 824 | }, /* An OEM board */ |
654 | 825 | ||
655 | { | 826 | { |
656 | .device_id = "DSTMCI", | 827 | .device_id = "DSTMCI", |
657 | .offset = 1, | 828 | .offset = 1, |
658 | .dst_type = DST_TYPE_IS_SAT, | 829 | .dst_type = DST_TYPE_IS_SAT, |
659 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT, | 830 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF, |
660 | .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | 831 | .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 |
661 | | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC | 832 | | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC, |
833 | .tuner_type = TUNER_TYPE_MULTI | ||
662 | }, | 834 | }, |
663 | 835 | ||
664 | { | 836 | { |
665 | .device_id = "DSTFCI", | 837 | .device_id = "DSTFCI", |
666 | .offset = 1, | 838 | .offset = 1, |
667 | .dst_type = DST_TYPE_IS_SAT, | 839 | .dst_type = DST_TYPE_IS_SAT, |
668 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | 840 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, |
669 | .dst_feature = 0 | 841 | .dst_feature = 0, |
842 | .tuner_type = 0 | ||
670 | }, /* unknown to vendor */ | 843 | }, /* unknown to vendor */ |
671 | 844 | ||
672 | { | 845 | { |
673 | .device_id = "DCT-CI", | 846 | .device_id = "DCT-CI", |
674 | .offset = 1, | 847 | .offset = 1, |
675 | .dst_type = DST_TYPE_IS_CABLE, | 848 | .dst_type = DST_TYPE_IS_CABLE, |
676 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1 | 849 | .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF, |
677 | | DST_TYPE_HAS_FW_2, | 850 | .dst_feature = DST_TYPE_HAS_CA, |
678 | .dst_feature = DST_TYPE_HAS_CA | 851 | .tuner_type = 0 |
679 | }, | 852 | }, |
680 | 853 | ||
681 | { | 854 | { |
682 | .device_id = "DCTNEW", | 855 | .device_id = "DCTNEW", |
683 | .offset = 1, | 856 | .offset = 1, |
684 | .dst_type = DST_TYPE_IS_CABLE, | 857 | .dst_type = DST_TYPE_IS_CABLE, |
685 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD, | 858 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE, |
686 | .dst_feature = 0 | 859 | .dst_feature = 0, |
860 | .tuner_type = 0 | ||
687 | }, | 861 | }, |
688 | 862 | ||
689 | { | 863 | { |
690 | .device_id = "DTT-CI", | 864 | .device_id = "DTT-CI", |
691 | .offset = 1, | 865 | .offset = 1, |
692 | .dst_type = DST_TYPE_IS_TERR, | 866 | .dst_type = DST_TYPE_IS_TERR, |
693 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE, | 867 | .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF, |
694 | .dst_feature = DST_TYPE_HAS_CA | 868 | .dst_feature = DST_TYPE_HAS_CA, |
869 | .tuner_type = 0 | ||
695 | }, | 870 | }, |
696 | 871 | ||
697 | { | 872 | { |
@@ -699,7 +874,8 @@ static struct dst_types dst_tlist[] = { | |||
699 | .offset = 1, | 874 | .offset = 1, |
700 | .dst_type = DST_TYPE_IS_TERR, | 875 | .dst_type = DST_TYPE_IS_TERR, |
701 | .type_flags = DST_TYPE_HAS_FW_2, | 876 | .type_flags = DST_TYPE_HAS_FW_2, |
702 | .dst_feature = 0 | 877 | .dst_feature = 0, |
878 | .tuner_type = 0 | ||
703 | }, | 879 | }, |
704 | 880 | ||
705 | { | 881 | { |
@@ -707,7 +883,8 @@ static struct dst_types dst_tlist[] = { | |||
707 | .offset = 1, | 883 | .offset = 1, |
708 | .dst_type = DST_TYPE_IS_TERR, | 884 | .dst_type = DST_TYPE_IS_TERR, |
709 | .type_flags = DST_TYPE_HAS_FW_2, | 885 | .type_flags = DST_TYPE_HAS_FW_2, |
710 | .dst_feature = DST_TYPE_HAS_ANALOG | 886 | .dst_feature = DST_TYPE_HAS_ANALOG, |
887 | .tuner_type = 0 | ||
711 | }, | 888 | }, |
712 | 889 | ||
713 | { | 890 | { |
@@ -715,15 +892,17 @@ static struct dst_types dst_tlist[] = { | |||
715 | .offset = 1, | 892 | .offset = 1, |
716 | .dst_type = DST_TYPE_IS_ATSC, | 893 | .dst_type = DST_TYPE_IS_ATSC, |
717 | .type_flags = DST_TYPE_HAS_FW_2, | 894 | .type_flags = DST_TYPE_HAS_FW_2, |
718 | .dst_feature = 0 | 895 | .dst_feature = 0, |
896 | .tuner_type = 0 | ||
719 | }, | 897 | }, |
720 | 898 | ||
721 | { | 899 | { |
722 | .device_id = "ATSCAD", | 900 | .device_id = "ATSCAD", |
723 | .offset = 1, | 901 | .offset = 1, |
724 | .dst_type = DST_TYPE_IS_ATSC, | 902 | .dst_type = DST_TYPE_IS_ATSC, |
725 | .type_flags = DST_TYPE_HAS_FW_2, | 903 | .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, |
726 | .dst_feature = 0 | 904 | .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG, |
905 | .tuner_type = 0 | ||
727 | }, | 906 | }, |
728 | 907 | ||
729 | { } | 908 | { } |
@@ -768,6 +947,9 @@ static int dst_fw_ver(struct dst_state *state) | |||
768 | 947 | ||
769 | static int dst_card_type(struct dst_state *state) | 948 | static int dst_card_type(struct dst_state *state) |
770 | { | 949 | { |
950 | int j; | ||
951 | struct tuner_types *p_tuner_list = NULL; | ||
952 | |||
771 | u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 953 | u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
772 | get_type[7] = dst_check_sum(get_type, 7); | 954 | get_type[7] = dst_check_sum(get_type, 7); |
773 | if (dst_command(state, get_type, 8) < 0) { | 955 | if (dst_command(state, get_type, 8) < 0) { |
@@ -775,9 +957,17 @@ static int dst_card_type(struct dst_state *state) | |||
775 | return -1; | 957 | return -1; |
776 | } | 958 | } |
777 | memset(&state->card_info, '\0', 8); | 959 | memset(&state->card_info, '\0', 8); |
778 | memcpy(&state->card_info, &state->rxbuffer, 8); | 960 | memcpy(&state->card_info, &state->rxbuffer, 7); |
779 | dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); | 961 | dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); |
780 | 962 | ||
963 | for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { | ||
964 | if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) { | ||
965 | state->tuner_type = p_tuner_list->tuner_type; | ||
966 | dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]", | ||
967 | p_tuner_list->tuner_name, p_tuner_list->tuner_type); | ||
968 | } | ||
969 | } | ||
970 | |||
781 | return 0; | 971 | return 0; |
782 | } | 972 | } |
783 | 973 | ||
@@ -790,12 +980,64 @@ static int dst_get_vendor(struct dst_state *state) | |||
790 | return -1; | 980 | return -1; |
791 | } | 981 | } |
792 | memset(&state->vendor, '\0', 8); | 982 | memset(&state->vendor, '\0', 8); |
793 | memcpy(&state->vendor, &state->rxbuffer, 8); | 983 | memcpy(&state->vendor, &state->rxbuffer, 7); |
794 | dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); | 984 | dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); |
795 | 985 | ||
796 | return 0; | 986 | return 0; |
797 | } | 987 | } |
798 | 988 | ||
989 | static void debug_dst_buffer(struct dst_state *state) | ||
990 | { | ||
991 | int i; | ||
992 | |||
993 | if (verbose > 2) { | ||
994 | printk("%s: [", __func__); | ||
995 | for (i = 0; i < 8; i++) | ||
996 | printk(" %02x", state->rxbuffer[i]); | ||
997 | printk("]\n"); | ||
998 | } | ||
999 | } | ||
1000 | |||
1001 | static int dst_check_stv0299(struct dst_state *state) | ||
1002 | { | ||
1003 | u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
1004 | |||
1005 | check_stv0299[7] = dst_check_sum(check_stv0299, 7); | ||
1006 | if (dst_command(state, check_stv0299, 8) < 0) { | ||
1007 | dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed"); | ||
1008 | return -1; | ||
1009 | } | ||
1010 | debug_dst_buffer(state); | ||
1011 | |||
1012 | if (memcmp(&check_stv0299, &state->rxbuffer, 8)) { | ||
1013 | dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM"); | ||
1014 | state->tuner_type = TUNER_TYPE_STV0299; | ||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | return -1; | ||
1019 | } | ||
1020 | |||
1021 | static int dst_check_mb86a15(struct dst_state *state) | ||
1022 | { | ||
1023 | u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
1024 | |||
1025 | check_mb86a15[7] = dst_check_sum(check_mb86a15, 7); | ||
1026 | if (dst_command(state, check_mb86a15, 8) < 0) { | ||
1027 | dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed"); | ||
1028 | return -1; | ||
1029 | } | ||
1030 | debug_dst_buffer(state); | ||
1031 | |||
1032 | if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) { | ||
1033 | dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM"); | ||
1034 | state->tuner_type = TUNER_TYPE_MB86A15; | ||
1035 | return 0; | ||
1036 | } | ||
1037 | |||
1038 | return -1; | ||
1039 | } | ||
1040 | |||
799 | static int dst_get_tuner_info(struct dst_state *state) | 1041 | static int dst_get_tuner_info(struct dst_state *state) |
800 | { | 1042 | { |
801 | u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 1043 | u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
@@ -803,60 +1045,59 @@ static int dst_get_tuner_info(struct dst_state *state) | |||
803 | 1045 | ||
804 | get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); | 1046 | get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); |
805 | get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); | 1047 | get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); |
1048 | dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE"); | ||
806 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | 1049 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { |
807 | if (dst_command(state, get_tuner_2, 8) < 0) { | 1050 | if (dst_command(state, get_tuner_1, 8) < 0) { |
808 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | 1051 | dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported"); |
809 | return -1; | 1052 | goto force; |
810 | } | 1053 | } |
811 | } else { | 1054 | } else { |
812 | if (dst_command(state, get_tuner_1, 8) < 0) { | 1055 | if (dst_command(state, get_tuner_2, 8) < 0) { |
813 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | 1056 | dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported"); |
814 | return -1; | 1057 | goto force; |
815 | } | 1058 | } |
816 | } | 1059 | } |
817 | memset(&state->board_info, '\0', 8); | 1060 | memset(&state->board_info, '\0', 8); |
818 | memcpy(&state->board_info, &state->rxbuffer, 8); | 1061 | memcpy(&state->board_info, &state->rxbuffer, 8); |
819 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | 1062 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { |
820 | if (state->board_info[1] == 0x0b) { | 1063 | dprintk(verbose, DST_ERROR, 1, "DST type has TS=188"); |
821 | if (state->type_flags & DST_TYPE_HAS_TS204) | 1064 | } |
822 | state->type_flags &= ~DST_TYPE_HAS_TS204; | 1065 | if (state->board_info[0] == 0xbc) { |
823 | state->type_flags |= DST_TYPE_HAS_NEWTUNE; | 1066 | if (state->type_flags != DST_TYPE_IS_ATSC) |
824 | dprintk(verbose, DST_INFO, 1, "DST type has TS=188"); | 1067 | state->type_flags |= DST_TYPE_HAS_TS188; |
825 | } else { | 1068 | else |
826 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | 1069 | state->type_flags |= DST_TYPE_HAS_NEWTUNE_2; |
827 | state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; | 1070 | |
828 | state->type_flags |= DST_TYPE_HAS_TS204; | 1071 | if (state->board_info[1] == 0x01) { |
829 | dprintk(verbose, DST_INFO, 1, "DST type has TS=204"); | 1072 | state->dst_hw_cap |= DST_TYPE_HAS_DBOARD; |
830 | } | 1073 | dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard"); |
831 | } else { | ||
832 | if (state->board_info[0] == 0xbc) { | ||
833 | if (state->type_flags & DST_TYPE_HAS_TS204) | ||
834 | state->type_flags &= ~DST_TYPE_HAS_TS204; | ||
835 | state->type_flags |= DST_TYPE_HAS_NEWTUNE; | ||
836 | dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]); | ||
837 | |||
838 | } else if (state->board_info[0] == 0xcc) { | ||
839 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | ||
840 | state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; | ||
841 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
842 | dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]); | ||
843 | } | 1074 | } |
844 | } | 1075 | } |
845 | 1076 | ||
846 | return 0; | 1077 | return 0; |
1078 | force: | ||
1079 | if (!strncmp(state->fw_name, "DCT-CI", 6)) { | ||
1080 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
1081 | dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name); | ||
1082 | } | ||
1083 | |||
1084 | return -1; | ||
847 | } | 1085 | } |
848 | 1086 | ||
849 | static int dst_get_device_id(struct dst_state *state) | 1087 | static int dst_get_device_id(struct dst_state *state) |
850 | { | 1088 | { |
851 | u8 reply; | 1089 | u8 reply; |
852 | 1090 | ||
853 | int i; | 1091 | int i, j; |
854 | struct dst_types *p_dst_type; | 1092 | struct dst_types *p_dst_type = NULL; |
1093 | struct tuner_types *p_tuner_list = NULL; | ||
1094 | |||
855 | u8 use_dst_type = 0; | 1095 | u8 use_dst_type = 0; |
856 | u32 use_type_flags = 0; | 1096 | u32 use_type_flags = 0; |
857 | 1097 | ||
858 | static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; | 1098 | static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; |
859 | 1099 | ||
1100 | state->tuner_type = 0; | ||
860 | device_type[7] = dst_check_sum(device_type, 7); | 1101 | device_type[7] = dst_check_sum(device_type, 7); |
861 | 1102 | ||
862 | if (write_dst(state, device_type, FIXED_COMM)) | 1103 | if (write_dst(state, device_type, FIXED_COMM)) |
@@ -888,8 +1129,34 @@ static int dst_get_device_id(struct dst_state *state) | |||
888 | 1129 | ||
889 | /* Card capabilities */ | 1130 | /* Card capabilities */ |
890 | state->dst_hw_cap = p_dst_type->dst_feature; | 1131 | state->dst_hw_cap = p_dst_type->dst_feature; |
891 | dprintk(verbose, DST_ERROR, 1, "Recognise [%s]\n", p_dst_type->device_id); | 1132 | dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id); |
892 | 1133 | strncpy(&state->fw_name[0], p_dst_type->device_id, 6); | |
1134 | /* Multiple tuners */ | ||
1135 | if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) { | ||
1136 | switch (use_dst_type) { | ||
1137 | case DST_TYPE_IS_SAT: | ||
1138 | /* STV0299 check */ | ||
1139 | if (dst_check_stv0299(state) < 0) { | ||
1140 | dprintk(verbose, DST_ERROR, 1, "Unsupported"); | ||
1141 | state->tuner_type = TUNER_TYPE_MB86A15; | ||
1142 | } | ||
1143 | break; | ||
1144 | default: | ||
1145 | break; | ||
1146 | } | ||
1147 | if (dst_check_mb86a15(state) < 0) | ||
1148 | dprintk(verbose, DST_ERROR, 1, "Unsupported"); | ||
1149 | /* Single tuner */ | ||
1150 | } else { | ||
1151 | state->tuner_type = p_dst_type->tuner_type; | ||
1152 | } | ||
1153 | for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { | ||
1154 | if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) && | ||
1155 | p_tuner_list->tuner_type == state->tuner_type) { | ||
1156 | dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]", | ||
1157 | p_dst_type->device_id, p_tuner_list->tuner_name); | ||
1158 | } | ||
1159 | } | ||
893 | break; | 1160 | break; |
894 | } | 1161 | } |
895 | } | 1162 | } |
@@ -900,10 +1167,10 @@ static int dst_get_device_id(struct dst_state *state) | |||
900 | use_dst_type = DST_TYPE_IS_SAT; | 1167 | use_dst_type = DST_TYPE_IS_SAT; |
901 | use_type_flags = DST_TYPE_HAS_SYMDIV; | 1168 | use_type_flags = DST_TYPE_HAS_SYMDIV; |
902 | } | 1169 | } |
903 | dst_type_print(use_dst_type); | 1170 | dst_type_print(state, use_dst_type); |
904 | state->type_flags = use_type_flags; | 1171 | state->type_flags = use_type_flags; |
905 | state->dst_type = use_dst_type; | 1172 | state->dst_type = use_dst_type; |
906 | dst_type_flags_print(state->type_flags); | 1173 | dst_type_flags_print(state); |
907 | 1174 | ||
908 | return 0; | 1175 | return 0; |
909 | } | 1176 | } |
@@ -911,15 +1178,15 @@ static int dst_get_device_id(struct dst_state *state) | |||
911 | static int dst_probe(struct dst_state *state) | 1178 | static int dst_probe(struct dst_state *state) |
912 | { | 1179 | { |
913 | mutex_init(&state->dst_mutex); | 1180 | mutex_init(&state->dst_mutex); |
914 | if ((rdc_8820_reset(state)) < 0) { | 1181 | if (dst_addons & DST_TYPE_HAS_CA) { |
915 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); | 1182 | if ((rdc_8820_reset(state)) < 0) { |
916 | return -1; | 1183 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); |
917 | } | 1184 | return -1; |
918 | if (dst_addons & DST_TYPE_HAS_CA) | 1185 | } |
919 | msleep(4000); | 1186 | msleep(4000); |
920 | else | 1187 | } else { |
921 | msleep(100); | 1188 | msleep(100); |
922 | 1189 | } | |
923 | if ((dst_comm_init(state)) < 0) { | 1190 | if ((dst_comm_init(state)) < 0) { |
924 | dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); | 1191 | dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); |
925 | return -1; | 1192 | return -1; |
@@ -931,7 +1198,6 @@ static int dst_probe(struct dst_state *state) | |||
931 | } | 1198 | } |
932 | if (dst_get_mac(state) < 0) { | 1199 | if (dst_get_mac(state) < 0) { |
933 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); | 1200 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); |
934 | return 0; | ||
935 | } | 1201 | } |
936 | if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { | 1202 | if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { |
937 | if (dst_get_tuner_info(state) < 0) | 1203 | if (dst_get_tuner_info(state) < 0) |
@@ -1048,6 +1314,10 @@ static int dst_get_signal(struct dst_state *state) | |||
1048 | state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; | 1314 | state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; |
1049 | state->decode_strength = state->rxbuffer[4] << 8; | 1315 | state->decode_strength = state->rxbuffer[4] << 8; |
1050 | state->decode_snr = state->rxbuffer[3] << 8; | 1316 | state->decode_snr = state->rxbuffer[3] << 8; |
1317 | } else if (state->dst_type == DST_TYPE_IS_ATSC) { | ||
1318 | state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0; | ||
1319 | state->decode_strength = state->rxbuffer[4] << 8; | ||
1320 | state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3]; | ||
1051 | } | 1321 | } |
1052 | state->cur_jiff = jiffies; | 1322 | state->cur_jiff = jiffies; |
1053 | } | 1323 | } |
@@ -1078,8 +1348,9 @@ static int dst_get_tuna(struct dst_state *state) | |||
1078 | state->diseq_flags &= ~(HAS_LOCK); | 1348 | state->diseq_flags &= ~(HAS_LOCK); |
1079 | if (!dst_wait_dst_ready(state, NO_DELAY)) | 1349 | if (!dst_wait_dst_ready(state, NO_DELAY)) |
1080 | return -EIO; | 1350 | return -EIO; |
1081 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | 1351 | if ((state->type_flags & DST_TYPE_HAS_VLF) && |
1082 | /* how to get variable length reply ???? */ | 1352 | !(state->dst_type == DST_TYPE_IS_ATSC)) |
1353 | |||
1083 | retval = read_dst(state, state->rx_tuna, 10); | 1354 | retval = read_dst(state, state->rx_tuna, 10); |
1084 | else | 1355 | else |
1085 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); | 1356 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); |
@@ -1087,7 +1358,10 @@ static int dst_get_tuna(struct dst_state *state) | |||
1087 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); | 1358 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); |
1088 | return retval; | 1359 | return retval; |
1089 | } | 1360 | } |
1090 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1361 | if ((state->type_flags & DST_TYPE_HAS_VLF) && |
1362 | !(state->dst_type == DST_TYPE_IS_CABLE) && | ||
1363 | !(state->dst_type == DST_TYPE_IS_ATSC)) { | ||
1364 | |||
1091 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { | 1365 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { |
1092 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); | 1366 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); |
1093 | return -EIO; | 1367 | return -EIO; |
@@ -1133,7 +1407,10 @@ static int dst_write_tuna(struct dvb_frontend *fe) | |||
1133 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); | 1407 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); |
1134 | goto error; | 1408 | goto error; |
1135 | } | 1409 | } |
1136 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1410 | // if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { |
1411 | if ((state->type_flags & DST_TYPE_HAS_VLF) && | ||
1412 | (!(state->dst_type == DST_TYPE_IS_ATSC))) { | ||
1413 | |||
1137 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); | 1414 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); |
1138 | retval = write_dst(state, &state->tx_tuna[0], 10); | 1415 | retval = write_dst(state, &state->tx_tuna[0], 10); |
1139 | } else { | 1416 | } else { |
@@ -1189,9 +1466,12 @@ static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd | |||
1189 | 1466 | ||
1190 | if (state->dst_type != DST_TYPE_IS_SAT) | 1467 | if (state->dst_type != DST_TYPE_IS_SAT) |
1191 | return 0; | 1468 | return 0; |
1192 | if (cmd->msg_len == 0 || cmd->msg_len > 4) | 1469 | if (cmd->msg_len > 0 && cmd->msg_len < 5) |
1470 | memcpy(&paket[3], cmd->msg, cmd->msg_len); | ||
1471 | else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5) | ||
1472 | memcpy(&paket[2], cmd->msg, cmd->msg_len); | ||
1473 | else | ||
1193 | return -EINVAL; | 1474 | return -EINVAL; |
1194 | memcpy(&paket[3], cmd->msg, cmd->msg_len); | ||
1195 | paket[7] = dst_check_sum(&paket[0], 7); | 1475 | paket[7] = dst_check_sum(&paket[0], 7); |
1196 | dst_command(state, paket, 8); | 1476 | dst_command(state, paket, 8); |
1197 | return 0; | 1477 | return 0; |
@@ -1287,8 +1567,9 @@ static int dst_init(struct dvb_frontend *fe) | |||
1287 | static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; | 1567 | static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; |
1288 | static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | 1568 | static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; |
1289 | static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | 1569 | static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; |
1290 | static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1291 | static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | 1570 | static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; |
1571 | static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1572 | static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1292 | 1573 | ||
1293 | state->inversion = INVERSION_OFF; | 1574 | state->inversion = INVERSION_OFF; |
1294 | state->voltage = SEC_VOLTAGE_13; | 1575 | state->voltage = SEC_VOLTAGE_13; |
@@ -1298,11 +1579,13 @@ static int dst_init(struct dvb_frontend *fe) | |||
1298 | state->bandwidth = BANDWIDTH_7_MHZ; | 1579 | state->bandwidth = BANDWIDTH_7_MHZ; |
1299 | state->cur_jiff = jiffies; | 1580 | state->cur_jiff = jiffies; |
1300 | if (state->dst_type == DST_TYPE_IS_SAT) | 1581 | if (state->dst_type == DST_TYPE_IS_SAT) |
1301 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); | 1582 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); |
1302 | else if (state->dst_type == DST_TYPE_IS_TERR) | 1583 | else if (state->dst_type == DST_TYPE_IS_TERR) |
1303 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); | 1584 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); |
1304 | else if (state->dst_type == DST_TYPE_IS_CABLE) | 1585 | else if (state->dst_type == DST_TYPE_IS_CABLE) |
1305 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); | 1586 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); |
1587 | else if (state->dst_type == DST_TYPE_IS_ATSC) | ||
1588 | memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner)); | ||
1306 | 1589 | ||
1307 | return 0; | 1590 | return 0; |
1308 | } | 1591 | } |
@@ -1341,7 +1624,36 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
1341 | return 0; | 1624 | return 0; |
1342 | } | 1625 | } |
1343 | 1626 | ||
1344 | static int dst_set_frontend(struct dvb_frontend* fe, | 1627 | static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) |
1628 | { | ||
1629 | struct dst_state *state = fe->demodulator_priv; | ||
1630 | |||
1631 | if (p != NULL) { | ||
1632 | dst_set_freq(state, p->frequency); | ||
1633 | dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); | ||
1634 | |||
1635 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
1636 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | ||
1637 | dst_set_inversion(state, p->inversion); | ||
1638 | dst_set_fec(state, p->u.qpsk.fec_inner); | ||
1639 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); | ||
1640 | dst_set_polarization(state); | ||
1641 | dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); | ||
1642 | |||
1643 | } else if (state->dst_type == DST_TYPE_IS_TERR) | ||
1644 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); | ||
1645 | else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
1646 | dst_set_fec(state, p->u.qam.fec_inner); | ||
1647 | dst_set_symbolrate(state, p->u.qam.symbol_rate); | ||
1648 | dst_set_modulation(state, p->u.qam.modulation); | ||
1649 | } | ||
1650 | dst_write_tuna(fe); | ||
1651 | } | ||
1652 | |||
1653 | return 0; | ||
1654 | } | ||
1655 | |||
1656 | static int dst_tune_frontend(struct dvb_frontend* fe, | ||
1345 | struct dvb_frontend_parameters* p, | 1657 | struct dvb_frontend_parameters* p, |
1346 | unsigned int mode_flags, | 1658 | unsigned int mode_flags, |
1347 | int *delay, | 1659 | int *delay, |
@@ -1378,6 +1690,11 @@ static int dst_set_frontend(struct dvb_frontend* fe, | |||
1378 | return 0; | 1690 | return 0; |
1379 | } | 1691 | } |
1380 | 1692 | ||
1693 | static int dst_get_tuning_algo(struct dvb_frontend *fe) | ||
1694 | { | ||
1695 | return dst_algo; | ||
1696 | } | ||
1697 | |||
1381 | static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | 1698 | static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) |
1382 | { | 1699 | { |
1383 | struct dst_state *state = fe->demodulator_priv; | 1700 | struct dst_state *state = fe->demodulator_priv; |
@@ -1408,6 +1725,7 @@ static void dst_release(struct dvb_frontend *fe) | |||
1408 | static struct dvb_frontend_ops dst_dvbt_ops; | 1725 | static struct dvb_frontend_ops dst_dvbt_ops; |
1409 | static struct dvb_frontend_ops dst_dvbs_ops; | 1726 | static struct dvb_frontend_ops dst_dvbs_ops; |
1410 | static struct dvb_frontend_ops dst_dvbc_ops; | 1727 | static struct dvb_frontend_ops dst_dvbc_ops; |
1728 | static struct dvb_frontend_ops dst_atsc_ops; | ||
1411 | 1729 | ||
1412 | struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) | 1730 | struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) |
1413 | { | 1731 | { |
@@ -1417,24 +1735,25 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad | |||
1417 | return NULL; | 1735 | return NULL; |
1418 | } | 1736 | } |
1419 | /* determine settings based on type */ | 1737 | /* determine settings based on type */ |
1738 | /* create dvb_frontend */ | ||
1420 | switch (state->dst_type) { | 1739 | switch (state->dst_type) { |
1421 | case DST_TYPE_IS_TERR: | 1740 | case DST_TYPE_IS_TERR: |
1422 | memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); | 1741 | memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); |
1423 | break; | 1742 | break; |
1424 | case DST_TYPE_IS_CABLE: | 1743 | case DST_TYPE_IS_CABLE: |
1425 | memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); | 1744 | memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); |
1426 | break; | 1745 | break; |
1427 | case DST_TYPE_IS_SAT: | 1746 | case DST_TYPE_IS_SAT: |
1428 | memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); | 1747 | memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); |
1748 | break; | ||
1749 | case DST_TYPE_IS_ATSC: | ||
1750 | memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops)); | ||
1429 | break; | 1751 | break; |
1430 | default: | 1752 | default: |
1431 | dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); | 1753 | dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); |
1432 | kfree(state); | 1754 | kfree(state); |
1433 | return NULL; | 1755 | return NULL; |
1434 | } | 1756 | } |
1435 | |||
1436 | /* create dvb_frontend */ | ||
1437 | state->frontend.ops = &state->ops; | ||
1438 | state->frontend.demodulator_priv = state; | 1757 | state->frontend.demodulator_priv = state; |
1439 | 1758 | ||
1440 | return state; /* Manu (DST is a card not a frontend) */ | 1759 | return state; /* Manu (DST is a card not a frontend) */ |
@@ -1455,8 +1774,10 @@ static struct dvb_frontend_ops dst_dvbt_ops = { | |||
1455 | 1774 | ||
1456 | .release = dst_release, | 1775 | .release = dst_release, |
1457 | .init = dst_init, | 1776 | .init = dst_init, |
1458 | .tune = dst_set_frontend, | 1777 | .tune = dst_tune_frontend, |
1778 | .set_frontend = dst_set_frontend, | ||
1459 | .get_frontend = dst_get_frontend, | 1779 | .get_frontend = dst_get_frontend, |
1780 | .get_frontend_algo = dst_get_tuning_algo, | ||
1460 | .read_status = dst_read_status, | 1781 | .read_status = dst_read_status, |
1461 | .read_signal_strength = dst_read_signal_strength, | 1782 | .read_signal_strength = dst_read_signal_strength, |
1462 | .read_snr = dst_read_snr, | 1783 | .read_snr = dst_read_snr, |
@@ -1479,8 +1800,10 @@ static struct dvb_frontend_ops dst_dvbs_ops = { | |||
1479 | 1800 | ||
1480 | .release = dst_release, | 1801 | .release = dst_release, |
1481 | .init = dst_init, | 1802 | .init = dst_init, |
1482 | .tune = dst_set_frontend, | 1803 | .tune = dst_tune_frontend, |
1804 | .set_frontend = dst_set_frontend, | ||
1483 | .get_frontend = dst_get_frontend, | 1805 | .get_frontend = dst_get_frontend, |
1806 | .get_frontend_algo = dst_get_tuning_algo, | ||
1484 | .read_status = dst_read_status, | 1807 | .read_status = dst_read_status, |
1485 | .read_signal_strength = dst_read_signal_strength, | 1808 | .read_signal_strength = dst_read_signal_strength, |
1486 | .read_snr = dst_read_snr, | 1809 | .read_snr = dst_read_snr, |
@@ -1506,13 +1829,38 @@ static struct dvb_frontend_ops dst_dvbc_ops = { | |||
1506 | 1829 | ||
1507 | .release = dst_release, | 1830 | .release = dst_release, |
1508 | .init = dst_init, | 1831 | .init = dst_init, |
1509 | .tune = dst_set_frontend, | 1832 | .tune = dst_tune_frontend, |
1833 | .set_frontend = dst_set_frontend, | ||
1834 | .get_frontend = dst_get_frontend, | ||
1835 | .get_frontend_algo = dst_get_tuning_algo, | ||
1836 | .read_status = dst_read_status, | ||
1837 | .read_signal_strength = dst_read_signal_strength, | ||
1838 | .read_snr = dst_read_snr, | ||
1839 | }; | ||
1840 | |||
1841 | static struct dvb_frontend_ops dst_atsc_ops = { | ||
1842 | .info = { | ||
1843 | .name = "DST ATSC", | ||
1844 | .type = FE_ATSC, | ||
1845 | .frequency_stepsize = 62500, | ||
1846 | .frequency_min = 510000000, | ||
1847 | .frequency_max = 858000000, | ||
1848 | .symbol_rate_min = 1000000, | ||
1849 | .symbol_rate_max = 45000000, | ||
1850 | .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | ||
1851 | }, | ||
1852 | |||
1853 | .release = dst_release, | ||
1854 | .init = dst_init, | ||
1855 | .tune = dst_tune_frontend, | ||
1856 | .set_frontend = dst_set_frontend, | ||
1510 | .get_frontend = dst_get_frontend, | 1857 | .get_frontend = dst_get_frontend, |
1858 | .get_frontend_algo = dst_get_tuning_algo, | ||
1511 | .read_status = dst_read_status, | 1859 | .read_status = dst_read_status, |
1512 | .read_signal_strength = dst_read_signal_strength, | 1860 | .read_signal_strength = dst_read_signal_strength, |
1513 | .read_snr = dst_read_snr, | 1861 | .read_snr = dst_read_snr, |
1514 | }; | 1862 | }; |
1515 | 1863 | ||
1516 | MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); | 1864 | MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver"); |
1517 | MODULE_AUTHOR("Jamie Honan, Manu Abraham"); | 1865 | MODULE_AUTHOR("Jamie Honan, Manu Abraham"); |
1518 | MODULE_LICENSE("GPL"); | 1866 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index f6b49a801eba..fa923b9b346e 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
@@ -68,6 +68,13 @@ static int ca_set_pid(void) | |||
68 | return -EOPNOTSUPP; | 68 | return -EOPNOTSUPP; |
69 | } | 69 | } |
70 | 70 | ||
71 | static void put_command_and_length(u8 *data, int command, int length) | ||
72 | { | ||
73 | data[0] = (command >> 16) & 0xff; | ||
74 | data[1] = (command >> 8) & 0xff; | ||
75 | data[2] = command & 0xff; | ||
76 | data[3] = length; | ||
77 | } | ||
71 | 78 | ||
72 | static void put_checksum(u8 *check_string, int length) | 79 | static void put_checksum(u8 *check_string, int length) |
73 | { | 80 | { |
@@ -124,15 +131,18 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, | |||
124 | u8 dst_ca_comm_err = 0; | 131 | u8 dst_ca_comm_err = 0; |
125 | 132 | ||
126 | while (dst_ca_comm_err < RETRIES) { | 133 | while (dst_ca_comm_err < RETRIES) { |
127 | dst_comm_init(state); | ||
128 | dprintk(verbose, DST_CA_NOTICE, 1, " Put Command"); | 134 | dprintk(verbose, DST_CA_NOTICE, 1, " Put Command"); |
129 | if (dst_ci_command(state, data, ca_string, len, read)) { // If error | 135 | if (dst_ci_command(state, data, ca_string, len, read)) { // If error |
130 | dst_error_recovery(state); | 136 | dst_error_recovery(state); |
131 | dst_ca_comm_err++; // work required here. | 137 | dst_ca_comm_err++; // work required here. |
138 | } else { | ||
139 | break; | ||
132 | } | 140 | } |
133 | break; | ||
134 | } | 141 | } |
135 | 142 | ||
143 | if(dst_ca_comm_err == RETRIES) | ||
144 | return -1; | ||
145 | |||
136 | return 0; | 146 | return 0; |
137 | } | 147 | } |
138 | 148 | ||
@@ -140,6 +150,7 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, | |||
140 | 150 | ||
141 | static int ca_get_app_info(struct dst_state *state) | 151 | static int ca_get_app_info(struct dst_state *state) |
142 | { | 152 | { |
153 | int length, str_length; | ||
143 | static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff}; | 154 | static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff}; |
144 | 155 | ||
145 | put_checksum(&command[0], command[0]); | 156 | put_checksum(&command[0], command[0]); |
@@ -154,6 +165,68 @@ static int ca_get_app_info(struct dst_state *state) | |||
154 | (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12])); | 165 | (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12])); |
155 | dprintk(verbose, DST_CA_INFO, 1, " =================================================================================================="); | 166 | dprintk(verbose, DST_CA_INFO, 1, " =================================================================================================="); |
156 | 167 | ||
168 | // Transform dst message to correct application_info message | ||
169 | length = state->messages[5]; | ||
170 | str_length = length - 6; | ||
171 | if (str_length < 0) { | ||
172 | str_length = 0; | ||
173 | dprintk(verbose, DST_CA_ERROR, 1, "Invalid string length returned in ca_get_app_info(). Recovering."); | ||
174 | } | ||
175 | |||
176 | // First, the command and length fields | ||
177 | put_command_and_length(&state->messages[0], CA_APP_INFO, length); | ||
178 | |||
179 | // Copy application_type, application_manufacturer and manufacturer_code | ||
180 | memcpy(&state->messages[4], &state->messages[7], 5); | ||
181 | |||
182 | // Set string length and copy string | ||
183 | state->messages[9] = str_length; | ||
184 | memcpy(&state->messages[10], &state->messages[12], str_length); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int ca_get_ca_info(struct dst_state *state) | ||
190 | { | ||
191 | int srcPtr, dstPtr, i, num_ids; | ||
192 | static u8 slot_command[8] = {0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff}; | ||
193 | const int in_system_id_pos = 8, out_system_id_pos = 4, in_num_ids_pos = 7; | ||
194 | |||
195 | put_checksum(&slot_command[0], slot_command[0]); | ||
196 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), state->messages, GET_REPLY)) < 0) { | ||
197 | dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); | ||
198 | return -1; | ||
199 | } | ||
200 | dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); | ||
201 | |||
202 | // Print raw data | ||
203 | dprintk(verbose, DST_CA_INFO, 0, " DST data = ["); | ||
204 | for (i = 0; i < state->messages[0] + 1; i++) { | ||
205 | dprintk(verbose, DST_CA_INFO, 0, " 0x%02x", state->messages[i]); | ||
206 | } | ||
207 | dprintk(verbose, DST_CA_INFO, 0, "]\n"); | ||
208 | |||
209 | // Set the command and length of the output | ||
210 | num_ids = state->messages[in_num_ids_pos]; | ||
211 | if (num_ids >= 100) { | ||
212 | num_ids = 100; | ||
213 | dprintk(verbose, DST_CA_ERROR, 1, "Invalid number of ids (>100). Recovering."); | ||
214 | } | ||
215 | put_command_and_length(&state->messages[0], CA_INFO, num_ids * 2); | ||
216 | |||
217 | dprintk(verbose, DST_CA_INFO, 0, " CA_INFO = ["); | ||
218 | srcPtr = in_system_id_pos; | ||
219 | dstPtr = out_system_id_pos; | ||
220 | for(i = 0; i < num_ids; i++) { | ||
221 | dprintk(verbose, DST_CA_INFO, 0, " 0x%02x%02x", state->messages[srcPtr + 0], state->messages[srcPtr + 1]); | ||
222 | // Append to output | ||
223 | state->messages[dstPtr + 0] = state->messages[srcPtr + 0]; | ||
224 | state->messages[dstPtr + 1] = state->messages[srcPtr + 1]; | ||
225 | srcPtr += 2; | ||
226 | dstPtr += 2; | ||
227 | } | ||
228 | dprintk(verbose, DST_CA_INFO, 0, "]\n"); | ||
229 | |||
157 | return 0; | 230 | return 0; |
158 | } | 231 | } |
159 | 232 | ||
@@ -174,7 +247,7 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, | |||
174 | 247 | ||
175 | dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]); | 248 | dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]); |
176 | dprintk(verbose, DST_CA_INFO, 0, "===================================\n"); | 249 | dprintk(verbose, DST_CA_INFO, 0, "===================================\n"); |
177 | for (i = 0; i < 8; i++) | 250 | for (i = 0; i < slot_cap[0] + 1; i++) |
178 | dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]); | 251 | dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]); |
179 | dprintk(verbose, DST_CA_INFO, 0, "\n"); | 252 | dprintk(verbose, DST_CA_INFO, 0, "\n"); |
180 | 253 | ||
@@ -260,6 +333,11 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
260 | if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) | 333 | if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) |
261 | return -EFAULT; | 334 | return -EFAULT; |
262 | break; | 335 | break; |
336 | case CA_INFO: | ||
337 | memcpy(p_ca_message->msg, state->messages, 128); | ||
338 | if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) | ||
339 | return -EFAULT; | ||
340 | break; | ||
263 | } | 341 | } |
264 | } | 342 | } |
265 | 343 | ||
@@ -302,7 +380,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l | |||
302 | rdc_reset_state(state); | 380 | rdc_reset_state(state); |
303 | return -1; | 381 | return -1; |
304 | } | 382 | } |
305 | dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command succes."); | 383 | dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success."); |
306 | 384 | ||
307 | return 0; | 385 | return 0; |
308 | } | 386 | } |
@@ -340,6 +418,7 @@ static int debug_string(u8 *msg, u32 length, u32 offset) | |||
340 | return 0; | 418 | return 0; |
341 | } | 419 | } |
342 | 420 | ||
421 | |||
343 | static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) | 422 | static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) |
344 | { | 423 | { |
345 | u32 length = 0; | 424 | u32 length = 0; |
@@ -455,6 +534,16 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
455 | } | 534 | } |
456 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); | 535 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); |
457 | break; | 536 | break; |
537 | case CA_INFO_ENQUIRY: | ||
538 | dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information"); | ||
539 | |||
540 | if ((ca_get_ca_info(state)) < 0) { | ||
541 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !"); | ||
542 | result = -1; | ||
543 | goto free_mem_and_exit; | ||
544 | } | ||
545 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !"); | ||
546 | break; | ||
458 | } | 547 | } |
459 | } | 548 | } |
460 | free_mem_and_exit: | 549 | free_mem_and_exit: |
@@ -473,18 +562,15 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
473 | void __user *arg = (void __user *)ioctl_arg; | 562 | void __user *arg = (void __user *)ioctl_arg; |
474 | int result = 0; | 563 | int result = 0; |
475 | 564 | ||
476 | if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { | 565 | p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL); |
477 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | 566 | p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL); |
478 | return -ENOMEM; | 567 | p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL); |
479 | } | 568 | if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) { |
480 | if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) { | ||
481 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | 569 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); |
482 | return -ENOMEM; | 570 | result = -ENOMEM; |
483 | } | 571 | goto free_mem_and_exit; |
484 | if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) { | ||
485 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | ||
486 | return -ENOMEM; | ||
487 | } | 572 | } |
573 | |||
488 | /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ | 574 | /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ |
489 | switch (cmd) { | 575 | switch (cmd) { |
490 | case CA_SEND_MSG: | 576 | case CA_SEND_MSG: |
@@ -582,7 +668,7 @@ static int dst_ca_release(struct inode *inode, struct file *file) | |||
582 | 668 | ||
583 | static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) | 669 | static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) |
584 | { | 670 | { |
585 | int bytes_read = 0; | 671 | ssize_t bytes_read = 0; |
586 | 672 | ||
587 | dprintk(verbose, DST_CA_DEBUG, 1, " Device read."); | 673 | dprintk(verbose, DST_CA_DEBUG, 1, " Device read."); |
588 | 674 | ||
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h index 51d4e043716c..0677b047b3a7 100644 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ b/drivers/media/dvb/bt8xx/dst_common.h | |||
@@ -42,7 +42,7 @@ | |||
42 | #define DST_TYPE_IS_CABLE 2 | 42 | #define DST_TYPE_IS_CABLE 2 |
43 | #define DST_TYPE_IS_ATSC 3 | 43 | #define DST_TYPE_IS_ATSC 3 |
44 | 44 | ||
45 | #define DST_TYPE_HAS_NEWTUNE 1 | 45 | #define DST_TYPE_HAS_TS188 1 |
46 | #define DST_TYPE_HAS_TS204 2 | 46 | #define DST_TYPE_HAS_TS204 2 |
47 | #define DST_TYPE_HAS_SYMDIV 4 | 47 | #define DST_TYPE_HAS_SYMDIV 4 |
48 | #define DST_TYPE_HAS_FW_1 8 | 48 | #define DST_TYPE_HAS_FW_1 8 |
@@ -52,6 +52,9 @@ | |||
52 | #define DST_TYPE_HAS_OBS_REGS 128 | 52 | #define DST_TYPE_HAS_OBS_REGS 128 |
53 | #define DST_TYPE_HAS_INC_COUNT 256 | 53 | #define DST_TYPE_HAS_INC_COUNT 256 |
54 | #define DST_TYPE_HAS_MULTI_FE 512 | 54 | #define DST_TYPE_HAS_MULTI_FE 512 |
55 | #define DST_TYPE_HAS_NEWTUNE_2 1024 | ||
56 | #define DST_TYPE_HAS_DBOARD 2048 | ||
57 | #define DST_TYPE_HAS_VLF 4096 | ||
55 | 58 | ||
56 | /* Card capability list */ | 59 | /* Card capability list */ |
57 | 60 | ||
@@ -64,6 +67,20 @@ | |||
64 | #define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ | 67 | #define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ |
65 | #define DST_TYPE_HAS_SESSION 128 | 68 | #define DST_TYPE_HAS_SESSION 128 |
66 | 69 | ||
70 | #define TUNER_TYPE_MULTI 1 | ||
71 | #define TUNER_TYPE_UNKNOWN 2 | ||
72 | /* DVB-S */ | ||
73 | #define TUNER_TYPE_L64724 4 | ||
74 | #define TUNER_TYPE_STV0299 8 | ||
75 | #define TUNER_TYPE_MB86A15 16 | ||
76 | |||
77 | /* DVB-T */ | ||
78 | #define TUNER_TYPE_TDA10046 32 | ||
79 | |||
80 | /* ATSC */ | ||
81 | #define TUNER_TYPE_NXT200x 64 | ||
82 | |||
83 | |||
67 | #define RDC_8820_PIO_0_DISABLE 0 | 84 | #define RDC_8820_PIO_0_DISABLE 0 |
68 | #define RDC_8820_PIO_0_ENABLE 1 | 85 | #define RDC_8820_PIO_0_ENABLE 1 |
69 | #define RDC_8820_INT 2 | 86 | #define RDC_8820_INT 2 |
@@ -84,8 +101,6 @@ struct dst_state { | |||
84 | 101 | ||
85 | struct bt878* bt; | 102 | struct bt878* bt; |
86 | 103 | ||
87 | struct dvb_frontend_ops ops; | ||
88 | |||
89 | /* configuration settings */ | 104 | /* configuration settings */ |
90 | const struct dst_config* config; | 105 | const struct dst_config* config; |
91 | 106 | ||
@@ -121,8 +136,17 @@ struct dst_state { | |||
121 | u8 card_info[8]; | 136 | u8 card_info[8]; |
122 | u8 vendor[8]; | 137 | u8 vendor[8]; |
123 | u8 board_info[8]; | 138 | u8 board_info[8]; |
124 | 139 | u32 tuner_type; | |
140 | char *tuner_name; | ||
125 | struct mutex dst_mutex; | 141 | struct mutex dst_mutex; |
142 | u8 fw_name[8]; | ||
143 | }; | ||
144 | |||
145 | struct tuner_types { | ||
146 | u32 tuner_type; | ||
147 | char *tuner_name; | ||
148 | char *board_name; | ||
149 | char *fw_name; | ||
126 | }; | 150 | }; |
127 | 151 | ||
128 | struct dst_types { | 152 | struct dst_types { |
@@ -131,6 +155,7 @@ struct dst_types { | |||
131 | u8 dst_type; | 155 | u8 dst_type; |
132 | u32 type_flags; | 156 | u32 type_flags; |
133 | u32 dst_feature; | 157 | u32 dst_feature; |
158 | u32 tuner_type; | ||
134 | }; | 159 | }; |
135 | 160 | ||
136 | struct dst_config | 161 | struct dst_config |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index ccc7b2eb4a2d..b715b972d2fc 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
@@ -147,12 +147,15 @@ static int thomson_dtt7579_demod_init(struct dvb_frontend* fe) | |||
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | 149 | ||
150 | static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) | 150 | static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) |
151 | { | 151 | { |
152 | u32 div; | 152 | u32 div; |
153 | unsigned char bs = 0; | 153 | unsigned char bs = 0; |
154 | unsigned char cp = 0; | 154 | unsigned char cp = 0; |
155 | 155 | ||
156 | if (buf_len < 5) | ||
157 | return -EINVAL; | ||
158 | |||
156 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | 159 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; |
157 | 160 | ||
158 | if (params->frequency < 542000000) | 161 | if (params->frequency < 542000000) |
@@ -169,22 +172,25 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_ | |||
169 | else | 172 | else |
170 | bs = 0x08; | 173 | bs = 0x08; |
171 | 174 | ||
172 | pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address | 175 | pllbuf[0] = 0x60; |
173 | pllbuf[1] = div >> 8; | 176 | pllbuf[1] = div >> 8; |
174 | pllbuf[2] = div & 0xff; | 177 | pllbuf[2] = div & 0xff; |
175 | pllbuf[3] = cp; | 178 | pllbuf[3] = cp; |
176 | pllbuf[4] = bs; | 179 | pllbuf[4] = bs; |
177 | 180 | ||
178 | return 0; | 181 | return 5; |
179 | } | 182 | } |
180 | 183 | ||
181 | static struct mt352_config thomson_dtt7579_config = { | 184 | static struct mt352_config thomson_dtt7579_config = { |
182 | .demod_address = 0x0f, | 185 | .demod_address = 0x0f, |
183 | .demod_init = thomson_dtt7579_demod_init, | 186 | .demod_init = thomson_dtt7579_demod_init, |
184 | .pll_set = thomson_dtt7579_pll_set, | ||
185 | }; | 187 | }; |
186 | 188 | ||
187 | static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 189 | static struct zl10353_config thomson_dtt7579_zl10353_config = { |
190 | .demod_address = 0x0f, | ||
191 | }; | ||
192 | |||
193 | static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | ||
188 | { | 194 | { |
189 | u32 freq = params->frequency; | 195 | u32 freq = params->frequency; |
190 | 196 | ||
@@ -237,7 +243,7 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
237 | return 0; | 243 | return 0; |
238 | } | 244 | } |
239 | 245 | ||
240 | static int pinnsat_pll_init(struct dvb_frontend* fe) | 246 | static int pinnsat_tuner_init(struct dvb_frontend* fe) |
241 | { | 247 | { |
242 | struct dvb_bt8xx_card *card = fe->dvb->priv; | 248 | struct dvb_bt8xx_card *card = fe->dvb->priv; |
243 | 249 | ||
@@ -247,7 +253,7 @@ static int pinnsat_pll_init(struct dvb_frontend* fe) | |||
247 | return 0; | 253 | return 0; |
248 | } | 254 | } |
249 | 255 | ||
250 | static int pinnsat_pll_sleep(struct dvb_frontend* fe) | 256 | static int pinnsat_tuner_sleep(struct dvb_frontend* fe) |
251 | { | 257 | { |
252 | struct dvb_bt8xx_card *card = fe->dvb->priv; | 258 | struct dvb_bt8xx_card *card = fe->dvb->priv; |
253 | 259 | ||
@@ -258,12 +264,9 @@ static int pinnsat_pll_sleep(struct dvb_frontend* fe) | |||
258 | 264 | ||
259 | static struct cx24110_config pctvsat_config = { | 265 | static struct cx24110_config pctvsat_config = { |
260 | .demod_address = 0x55, | 266 | .demod_address = 0x55, |
261 | .pll_init = pinnsat_pll_init, | ||
262 | .pll_set = cx24108_pll_set, | ||
263 | .pll_sleep = pinnsat_pll_sleep, | ||
264 | }; | 267 | }; |
265 | 268 | ||
266 | static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 269 | static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
267 | { | 270 | { |
268 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; | 271 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; |
269 | u8 cfg, cpump, band_select; | 272 | u8 cfg, cpump, band_select; |
@@ -297,6 +300,8 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front | |||
297 | data[2] = ((div >> 10) & 0x60) | cfg; | 300 | data[2] = ((div >> 10) & 0x60) | cfg; |
298 | data[3] = (cpump << 6) | band_select; | 301 | data[3] = (cpump << 6) | band_select; |
299 | 302 | ||
303 | if (fe->ops.i2c_gate_ctrl) | ||
304 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
300 | i2c_transfer(card->i2c_adapter, &msg, 1); | 305 | i2c_transfer(card->i2c_adapter, &msg, 1); |
301 | return (div * 166666 - 36000000); | 306 | return (div * 166666 - 36000000); |
302 | } | 307 | } |
@@ -310,7 +315,6 @@ static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const s | |||
310 | 315 | ||
311 | static struct sp887x_config microtune_mt7202dtf_config = { | 316 | static struct sp887x_config microtune_mt7202dtf_config = { |
312 | .demod_address = 0x70, | 317 | .demod_address = 0x70, |
313 | .pll_set = microtune_mt7202dtf_pll_set, | ||
314 | .request_firmware = microtune_mt7202dtf_request_firmware, | 318 | .request_firmware = microtune_mt7202dtf_request_firmware, |
315 | }; | 319 | }; |
316 | 320 | ||
@@ -337,12 +341,14 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) | |||
337 | return 0; | 341 | return 0; |
338 | } | 342 | } |
339 | 343 | ||
340 | static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) | 344 | static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) |
341 | { | 345 | { |
342 | u32 div; | 346 | u32 div; |
343 | unsigned char bs = 0; | 347 | unsigned char bs = 0; |
344 | unsigned char cp = 0; | 348 | unsigned char cp = 0; |
345 | 349 | ||
350 | if (buf_len < 5) return -EINVAL; | ||
351 | |||
346 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | 352 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; |
347 | 353 | ||
348 | if (params->frequency < 150000000) | 354 | if (params->frequency < 150000000) |
@@ -383,19 +389,18 @@ static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct | |||
383 | else | 389 | else |
384 | bs = 0x08; | 390 | bs = 0x08; |
385 | 391 | ||
386 | pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address | 392 | pllbuf[0] = 0x61; |
387 | pllbuf[1] = div >> 8; | 393 | pllbuf[1] = div >> 8; |
388 | pllbuf[2] = div & 0xff; | 394 | pllbuf[2] = div & 0xff; |
389 | pllbuf[3] = cp; | 395 | pllbuf[3] = cp; |
390 | pllbuf[4] = bs; | 396 | pllbuf[4] = bs; |
391 | 397 | ||
392 | return 0; | 398 | return 5; |
393 | } | 399 | } |
394 | 400 | ||
395 | static struct mt352_config advbt771_samsung_tdtc9251dh0_config = { | 401 | static struct mt352_config advbt771_samsung_tdtc9251dh0_config = { |
396 | .demod_address = 0x0f, | 402 | .demod_address = 0x0f, |
397 | .demod_init = advbt771_samsung_tdtc9251dh0_demod_init, | 403 | .demod_init = advbt771_samsung_tdtc9251dh0_demod_init, |
398 | .pll_set = advbt771_samsung_tdtc9251dh0_pll_set, | ||
399 | }; | 404 | }; |
400 | 405 | ||
401 | static struct dst_config dst_config = { | 406 | static struct dst_config dst_config = { |
@@ -455,7 +460,7 @@ static struct or51211_config or51211_config = { | |||
455 | .sleep = or51211_sleep, | 460 | .sleep = or51211_sleep, |
456 | }; | 461 | }; |
457 | 462 | ||
458 | static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 463 | static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
459 | { | 464 | { |
460 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; | 465 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; |
461 | u8 buf[4]; | 466 | u8 buf[4]; |
@@ -478,6 +483,8 @@ static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
478 | else | 483 | else |
479 | return -EINVAL; | 484 | return -EINVAL; |
480 | 485 | ||
486 | if (fe->ops.i2c_gate_ctrl) | ||
487 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
481 | i2c_transfer(card->i2c_adapter, &msg, 1); | 488 | i2c_transfer(card->i2c_adapter, &msg, 1); |
482 | return 0; | 489 | return 0; |
483 | } | 490 | } |
@@ -485,7 +492,6 @@ static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
485 | static struct nxt6000_config vp3021_alps_tded4_config = { | 492 | static struct nxt6000_config vp3021_alps_tded4_config = { |
486 | .demod_address = 0x0a, | 493 | .demod_address = 0x0a, |
487 | .clock_inversion = 1, | 494 | .clock_inversion = 1, |
488 | .pll_set = vp3021_alps_tded4_pll_set, | ||
489 | }; | 495 | }; |
490 | 496 | ||
491 | static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) | 497 | static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) |
@@ -506,14 +512,17 @@ static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) | |||
506 | return 0; | 512 | return 0; |
507 | } | 513 | } |
508 | 514 | ||
509 | static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) | 515 | static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) |
510 | { | 516 | { |
511 | u32 div; | 517 | u32 div; |
512 | struct dvb_ofdm_parameters *op = ¶ms->u.ofdm; | 518 | struct dvb_ofdm_parameters *op = ¶ms->u.ofdm; |
513 | 519 | ||
520 | if (buf_len < 5) | ||
521 | return -EINVAL; | ||
522 | |||
514 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | 523 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; |
515 | 524 | ||
516 | pllbuf[0] = 0xc2; | 525 | pllbuf[0] = 0x61; |
517 | pllbuf[1] = (div >> 8) & 0x7F; | 526 | pllbuf[1] = (div >> 8) & 0x7F; |
518 | pllbuf[2] = div & 0xFF; | 527 | pllbuf[2] = div & 0xFF; |
519 | pllbuf[3] = 0x85; | 528 | pllbuf[3] = 0x85; |
@@ -530,7 +539,7 @@ static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
530 | if (op->bandwidth == 8) | 539 | if (op->bandwidth == 8) |
531 | pllbuf[4] |= 0x04; | 540 | pllbuf[4] |= 0x04; |
532 | 541 | ||
533 | return 0; | 542 | return 5; |
534 | } | 543 | } |
535 | 544 | ||
536 | static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) | 545 | static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) |
@@ -557,43 +566,18 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) | |||
557 | static struct mt352_config digitv_alps_tded4_config = { | 566 | static struct mt352_config digitv_alps_tded4_config = { |
558 | .demod_address = 0x0a, | 567 | .demod_address = 0x0a, |
559 | .demod_init = digitv_alps_tded4_demod_init, | 568 | .demod_init = digitv_alps_tded4_demod_init, |
560 | .pll_set = digitv_alps_tded4_pll_set, | ||
561 | }; | 569 | }; |
562 | 570 | ||
563 | static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 571 | static int tdvs_tua6034_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
564 | { | 572 | { |
565 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; | 573 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; |
566 | u8 buf[4]; | 574 | return lg_h06xf_pll_set(fe, card->i2c_adapter, params); |
567 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
568 | int err; | ||
569 | |||
570 | dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0); | ||
571 | dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
572 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); | ||
573 | if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) { | ||
574 | printk(KERN_WARNING "dvb-bt8xx: %s error " | ||
575 | "(addr %02x <- %02x, err = %i)\n", | ||
576 | __FUNCTION__, buf[0], buf[1], err); | ||
577 | if (err < 0) | ||
578 | return err; | ||
579 | else | ||
580 | return -EREMOTEIO; | ||
581 | } | ||
582 | |||
583 | /* Set the Auxiliary Byte. */ | ||
584 | buf[2] &= ~0x20; | ||
585 | buf[2] |= 0x18; | ||
586 | buf[3] = 0x50; | ||
587 | i2c_transfer(card->i2c_adapter, &msg, 1); | ||
588 | |||
589 | return 0; | ||
590 | } | 575 | } |
591 | 576 | ||
592 | static struct lgdt330x_config tdvs_tua6034_config = { | 577 | static struct lgdt330x_config tdvs_tua6034_config = { |
593 | .demod_address = 0x0e, | 578 | .demod_address = 0x0e, |
594 | .demod_chip = LGDT3303, | 579 | .demod_chip = LGDT3303, |
595 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | 580 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ |
596 | .pll_set = tdvs_tua6034_pll_set, | ||
597 | }; | 581 | }; |
598 | 582 | ||
599 | static void lgdt330x_reset(struct dvb_bt8xx_card *bt) | 583 | static void lgdt330x_reset(struct dvb_bt8xx_card *bt) |
@@ -617,17 +601,25 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
617 | switch(type) { | 601 | switch(type) { |
618 | case BTTV_BOARD_DVICO_DVBT_LITE: | 602 | case BTTV_BOARD_DVICO_DVBT_LITE: |
619 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); | 603 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); |
604 | |||
605 | if (card->fe == NULL) | ||
606 | card->fe = zl10353_attach(&thomson_dtt7579_zl10353_config, | ||
607 | card->i2c_adapter); | ||
608 | |||
620 | if (card->fe != NULL) { | 609 | if (card->fe != NULL) { |
621 | card->fe->ops->info.frequency_min = 174000000; | 610 | card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs; |
622 | card->fe->ops->info.frequency_max = 862000000; | 611 | card->fe->ops.info.frequency_min = 174000000; |
612 | card->fe->ops.info.frequency_max = 862000000; | ||
623 | } | 613 | } |
624 | break; | 614 | break; |
625 | 615 | ||
626 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: | 616 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: |
627 | lgdt330x_reset(card); | 617 | lgdt330x_reset(card); |
628 | card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); | 618 | card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); |
629 | if (card->fe != NULL) | 619 | if (card->fe != NULL) { |
620 | card->fe->ops.tuner_ops.set_params = tdvs_tua6034_tuner_set_params; | ||
630 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); | 621 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); |
622 | } | ||
631 | break; | 623 | break; |
632 | 624 | ||
633 | case BTTV_BOARD_NEBULA_DIGITV: | 625 | case BTTV_BOARD_NEBULA_DIGITV: |
@@ -640,6 +632,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
640 | digitv_alps_tded4_reset(card); | 632 | digitv_alps_tded4_reset(card); |
641 | card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); | 633 | card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); |
642 | if (card->fe != NULL) { | 634 | if (card->fe != NULL) { |
635 | card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params; | ||
643 | dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); | 636 | dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); |
644 | break; | 637 | break; |
645 | } | 638 | } |
@@ -648,19 +641,25 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
648 | digitv_alps_tded4_reset(card); | 641 | digitv_alps_tded4_reset(card); |
649 | card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter); | 642 | card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter); |
650 | 643 | ||
651 | if (card->fe != NULL) | 644 | if (card->fe != NULL) { |
645 | card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs; | ||
652 | dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); | 646 | dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); |
647 | } | ||
653 | break; | 648 | break; |
654 | 649 | ||
655 | case BTTV_BOARD_AVDVBT_761: | 650 | case BTTV_BOARD_AVDVBT_761: |
656 | card->fe = sp887x_attach(µtune_mt7202dtf_config, card->i2c_adapter); | 651 | card->fe = sp887x_attach(µtune_mt7202dtf_config, card->i2c_adapter); |
652 | if (card->fe) { | ||
653 | card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params; | ||
654 | } | ||
657 | break; | 655 | break; |
658 | 656 | ||
659 | case BTTV_BOARD_AVDVBT_771: | 657 | case BTTV_BOARD_AVDVBT_771: |
660 | card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); | 658 | card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); |
661 | if (card->fe != NULL) { | 659 | if (card->fe != NULL) { |
662 | card->fe->ops->info.frequency_min = 174000000; | 660 | card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs; |
663 | card->fe->ops->info.frequency_max = 862000000; | 661 | card->fe->ops.info.frequency_min = 174000000; |
662 | card->fe->ops.info.frequency_max = 862000000; | ||
664 | } | 663 | } |
665 | break; | 664 | break; |
666 | 665 | ||
@@ -687,6 +686,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
687 | 686 | ||
688 | case BTTV_BOARD_PINNACLESAT: | 687 | case BTTV_BOARD_PINNACLESAT: |
689 | card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); | 688 | card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); |
689 | if (card->fe) { | ||
690 | card->fe->ops.tuner_ops.init = pinnsat_tuner_init; | ||
691 | card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep; | ||
692 | card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params; | ||
693 | } | ||
690 | break; | 694 | break; |
691 | 695 | ||
692 | case BTTV_BOARD_PC_HDTV: | 696 | case BTTV_BOARD_PC_HDTV: |
@@ -703,8 +707,8 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
703 | else | 707 | else |
704 | if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { | 708 | if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { |
705 | printk("dvb-bt8xx: Frontend registration failed!\n"); | 709 | printk("dvb-bt8xx: Frontend registration failed!\n"); |
706 | if (card->fe->ops->release) | 710 | if (card->fe->ops.release) |
707 | card->fe->ops->release(card->fe); | 711 | card->fe->ops.release(card->fe); |
708 | card->fe = NULL; | 712 | card->fe = NULL; |
709 | } | 713 | } |
710 | } | 714 | } |
@@ -713,7 +717,7 @@ static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) | |||
713 | { | 717 | { |
714 | int result; | 718 | int result; |
715 | 719 | ||
716 | if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) { | 720 | if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE, &card->bt->dev->dev)) < 0) { |
717 | printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); | 721 | printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); |
718 | return result; | 722 | return result; |
719 | } | 723 | } |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h index 00dd9fa54c82..4745a9017a19 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h | |||
@@ -37,6 +37,8 @@ | |||
37 | #include "cx24110.h" | 37 | #include "cx24110.h" |
38 | #include "or51211.h" | 38 | #include "or51211.h" |
39 | #include "lgdt330x.h" | 39 | #include "lgdt330x.h" |
40 | #include "lg_h06xf.h" | ||
41 | #include "zl10353.h" | ||
40 | 42 | ||
41 | struct dvb_bt8xx_card { | 43 | struct dvb_bt8xx_card { |
42 | struct mutex lock; | 44 | struct mutex lock; |
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig index 6018fcdba1e6..b5cdd57ec6f5 100644 --- a/drivers/media/dvb/cinergyT2/Kconfig +++ b/drivers/media/dvb/cinergyT2/Kconfig | |||
@@ -64,7 +64,7 @@ config DVB_CINERGYT2_QUERY_INTERVAL | |||
64 | config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE | 64 | config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE |
65 | bool "Register the onboard IR Remote Control Receiver as Input Device" | 65 | bool "Register the onboard IR Remote Control Receiver as Input Device" |
66 | depends on DVB_CINERGYT2_TUNING | 66 | depends on DVB_CINERGYT2_TUNING |
67 | default "yes" | 67 | default y |
68 | help | 68 | help |
69 | Enable this option if you want to use the onboard Infrared Remote | 69 | Enable this option if you want to use the onboard Infrared Remote |
70 | Control Receiver as Linux-Input device. | 70 | Control Receiver as Linux-Input device. |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 9325d039ea65..1b8953600425 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -544,15 +544,19 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct | |||
544 | { | 544 | { |
545 | struct dvb_device *dvbdev = file->private_data; | 545 | struct dvb_device *dvbdev = file->private_data; |
546 | struct cinergyt2 *cinergyt2 = dvbdev->priv; | 546 | struct cinergyt2 *cinergyt2 = dvbdev->priv; |
547 | unsigned int mask = 0; | ||
547 | 548 | ||
548 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) | 549 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
549 | return -ERESTARTSYS; | 550 | return -ERESTARTSYS; |
550 | 551 | ||
551 | poll_wait(file, &cinergyt2->poll_wq, wait); | 552 | poll_wait(file, &cinergyt2->poll_wq, wait); |
552 | 553 | ||
554 | if (cinergyt2->pending_fe_events != 0) | ||
555 | mask |= (POLLIN | POLLRDNORM | POLLPRI); | ||
556 | |||
553 | mutex_unlock(&cinergyt2->sem); | 557 | mutex_unlock(&cinergyt2->sem); |
554 | 558 | ||
555 | return (POLLIN | POLLRDNORM | POLLPRI); | 559 | return mask; |
556 | } | 560 | } |
557 | 561 | ||
558 | 562 | ||
@@ -902,7 +906,7 @@ static int cinergyt2_probe (struct usb_interface *intf, | |||
902 | return -ENOMEM; | 906 | return -ENOMEM; |
903 | } | 907 | } |
904 | 908 | ||
905 | if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE)) < 0) { | 909 | if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE, &cinergyt2->udev->dev)) < 0) { |
906 | kfree(cinergyt2); | 910 | kfree(cinergyt2); |
907 | return err; | 911 | return err; |
908 | } | 912 | } |
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile index 7adb50c1e8eb..11054657fdb5 100644 --- a/drivers/media/dvb/dvb-core/Makefile +++ b/drivers/media/dvb/dvb-core/Makefile | |||
@@ -2,8 +2,8 @@ | |||
2 | # Makefile for the kernel DVB device drivers. | 2 | # Makefile for the kernel DVB device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ | 5 | dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ |
6 | dvb_ca_en50221.o dvb_frontend.o \ | 6 | dvb_ca_en50221.o dvb_frontend.o \ |
7 | dvb_net.o dvb_ringbuffer.o | 7 | dvb_net.o dvb_ringbuffer.o dvb_math.o |
8 | 8 | ||
9 | obj-$(CONFIG_DVB_CORE) += dvb-core.o | 9 | obj-$(CONFIG_DVB_CORE) += dvb-core.o |
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 04578df3f249..988499dfddf8 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c | |||
@@ -872,9 +872,6 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, | |||
872 | mutex_unlock(&dmxdevfilter->mutex); | 872 | mutex_unlock(&dmxdevfilter->mutex); |
873 | break; | 873 | break; |
874 | 874 | ||
875 | case DMX_GET_EVENT: | ||
876 | break; | ||
877 | |||
878 | case DMX_GET_PES_PIDS: | 875 | case DMX_GET_PES_PIDS: |
879 | if (!dmxdev->demux->get_pes_pids) { | 876 | if (!dmxdev->demux->get_pes_pids) { |
880 | ret = -EINVAL; | 877 | ret = -EINVAL; |
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 00347a750681..2a03bf53cb29 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c | |||
@@ -1060,8 +1060,18 @@ static int dvb_ca_en50221_thread(void *data) | |||
1060 | break; | 1060 | break; |
1061 | 1061 | ||
1062 | case DVB_CA_SLOTSTATE_VALIDATE: | 1062 | case DVB_CA_SLOTSTATE_VALIDATE: |
1063 | if (dvb_ca_en50221_parse_attributes(ca, slot) | 1063 | if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) { |
1064 | != 0) { | 1064 | /* we need this extra check for annoying interfaces like the budget-av */ |
1065 | if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && | ||
1066 | (ca->pub->poll_slot_status)) { | ||
1067 | int status = ca->pub->poll_slot_status(ca->pub, slot, 0); | ||
1068 | if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { | ||
1069 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; | ||
1070 | dvb_ca_en50221_thread_update_delay(ca); | ||
1071 | break; | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1065 | printk("dvb_ca adapter %d: Invalid PC card inserted :(\n", | 1075 | printk("dvb_ca adapter %d: Invalid PC card inserted :(\n", |
1066 | ca->dvbdev->adapter->num); | 1076 | ca->dvbdev->adapter->num); |
1067 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; | 1077 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; |
@@ -1108,6 +1118,17 @@ static int dvb_ca_en50221_thread(void *data) | |||
1108 | 1118 | ||
1109 | case DVB_CA_SLOTSTATE_LINKINIT: | 1119 | case DVB_CA_SLOTSTATE_LINKINIT: |
1110 | if (dvb_ca_en50221_link_init(ca, slot) != 0) { | 1120 | if (dvb_ca_en50221_link_init(ca, slot) != 0) { |
1121 | /* we need this extra check for annoying interfaces like the budget-av */ | ||
1122 | if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && | ||
1123 | (ca->pub->poll_slot_status)) { | ||
1124 | int status = ca->pub->poll_slot_status(ca->pub, slot, 0); | ||
1125 | if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { | ||
1126 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; | ||
1127 | dvb_ca_en50221_thread_update_delay(ca); | ||
1128 | break; | ||
1129 | } | ||
1130 | } | ||
1131 | |||
1111 | printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num); | 1132 | printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num); |
1112 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; | 1133 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; |
1113 | dvb_ca_en50221_thread_update_delay(ca); | 1134 | dvb_ca_en50221_thread_update_delay(ca); |
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index 83ec5e06c482..fcff5eab21a3 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c | |||
@@ -473,7 +473,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) | |||
473 | goto bailout; | 473 | goto bailout; |
474 | } | 474 | } |
475 | memcpy(&demux->tsbuf[i], buf, j); | 475 | memcpy(&demux->tsbuf[i], buf, j); |
476 | if ((demux->tsbuf[0] == 0x47) | (demux->tsbuf[0] == 0xB8)) { | 476 | if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) { |
477 | memcpy(tmppack, demux->tsbuf, 188); | 477 | memcpy(tmppack, demux->tsbuf, 188); |
478 | if (tmppack[0] == 0xB8) | 478 | if (tmppack[0] == 0xB8) |
479 | tmppack[0] = 0x47; | 479 | tmppack[0] = 0x47; |
@@ -484,7 +484,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) | |||
484 | } | 484 | } |
485 | 485 | ||
486 | while (p < count) { | 486 | while (p < count) { |
487 | if ((buf[p] == 0x47) | (buf[p] == 0xB8)) { | 487 | if ((buf[p] == 0x47) || (buf[p] == 0xB8)) { |
488 | if (count - p >= 204) { | 488 | if (count - p >= 204) { |
489 | memcpy(tmppack, &buf[p], 188); | 489 | memcpy(tmppack, &buf[p], 188); |
490 | if (tmppack[0] == 0xB8) | 490 | if (tmppack[0] == 0xB8) |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index a051790161b0..3152a54a2539 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AU | |||
56 | module_param(dvb_override_tune_delay, int, 0644); | 56 | module_param(dvb_override_tune_delay, int, 0644); |
57 | MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); | 57 | MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); |
58 | module_param(dvb_powerdown_on_sleep, int, 0644); | 58 | module_param(dvb_powerdown_on_sleep, int, 0644); |
59 | MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)"); | 59 | MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)"); |
60 | 60 | ||
61 | #define dprintk if (dvb_frontend_debug) printk | 61 | #define dprintk if (dvb_frontend_debug) printk |
62 | 62 | ||
@@ -72,6 +72,8 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB vola | |||
72 | #define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) | 72 | #define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) |
73 | #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) | 73 | #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) |
74 | #define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) | 74 | #define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) |
75 | |||
76 | #define FE_ALGO_HW 1 | ||
75 | /* | 77 | /* |
76 | * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling. | 78 | * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling. |
77 | * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune. | 79 | * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune. |
@@ -151,8 +153,8 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) | |||
151 | sizeof (struct dvb_frontend_parameters)); | 153 | sizeof (struct dvb_frontend_parameters)); |
152 | 154 | ||
153 | if (status & FE_HAS_LOCK) | 155 | if (status & FE_HAS_LOCK) |
154 | if (fe->ops->get_frontend) | 156 | if (fe->ops.get_frontend) |
155 | fe->ops->get_frontend(fe, &e->parameters); | 157 | fe->ops.get_frontend(fe, &e->parameters); |
156 | 158 | ||
157 | events->eventw = wp; | 159 | events->eventw = wp; |
158 | 160 | ||
@@ -211,10 +213,15 @@ static void dvb_frontend_init(struct dvb_frontend *fe) | |||
211 | { | 213 | { |
212 | dprintk ("DVB: initialising frontend %i (%s)...\n", | 214 | dprintk ("DVB: initialising frontend %i (%s)...\n", |
213 | fe->dvb->num, | 215 | fe->dvb->num, |
214 | fe->ops->info.name); | 216 | fe->ops.info.name); |
215 | 217 | ||
216 | if (fe->ops->init) | 218 | if (fe->ops.init) |
217 | fe->ops->init(fe); | 219 | fe->ops.init(fe); |
220 | if (fe->ops.tuner_ops.init) { | ||
221 | fe->ops.tuner_ops.init(fe); | ||
222 | if (fe->ops.i2c_gate_ctrl) | ||
223 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
224 | } | ||
218 | } | 225 | } |
219 | 226 | ||
220 | void dvb_frontend_reinitialise(struct dvb_frontend *fe) | 227 | void dvb_frontend_reinitialise(struct dvb_frontend *fe) |
@@ -259,7 +266,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra | |||
259 | u32 original_frequency = fepriv->parameters.frequency; | 266 | u32 original_frequency = fepriv->parameters.frequency; |
260 | 267 | ||
261 | /* are we using autoinversion? */ | 268 | /* are we using autoinversion? */ |
262 | autoinversion = ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && | 269 | autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && |
263 | (fepriv->parameters.inversion == INVERSION_AUTO)); | 270 | (fepriv->parameters.inversion == INVERSION_AUTO)); |
264 | 271 | ||
265 | /* setup parameters correctly */ | 272 | /* setup parameters correctly */ |
@@ -329,8 +336,8 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra | |||
329 | fepriv->parameters.frequency += fepriv->lnb_drift; | 336 | fepriv->parameters.frequency += fepriv->lnb_drift; |
330 | if (autoinversion) | 337 | if (autoinversion) |
331 | fepriv->parameters.inversion = fepriv->inversion; | 338 | fepriv->parameters.inversion = fepriv->inversion; |
332 | if (fe->ops->set_frontend) | 339 | if (fe->ops.set_frontend) |
333 | fe->ops->set_frontend(fe, &fepriv->parameters); | 340 | fe->ops.set_frontend(fe, &fepriv->parameters); |
334 | 341 | ||
335 | fepriv->parameters.frequency = original_frequency; | 342 | fepriv->parameters.frequency = original_frequency; |
336 | fepriv->parameters.inversion = original_inversion; | 343 | fepriv->parameters.inversion = original_inversion; |
@@ -354,8 +361,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | |||
354 | /* in SCAN mode, we just set the frontend when asked and leave it alone */ | 361 | /* in SCAN mode, we just set the frontend when asked and leave it alone */ |
355 | if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { | 362 | if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { |
356 | if (fepriv->state & FESTATE_RETUNE) { | 363 | if (fepriv->state & FESTATE_RETUNE) { |
357 | if (fe->ops->set_frontend) | 364 | if (fe->ops.set_frontend) |
358 | fe->ops->set_frontend(fe, &fepriv->parameters); | 365 | fe->ops.set_frontend(fe, &fepriv->parameters); |
359 | fepriv->state = FESTATE_TUNED; | 366 | fepriv->state = FESTATE_TUNED; |
360 | } | 367 | } |
361 | fepriv->delay = 3*HZ; | 368 | fepriv->delay = 3*HZ; |
@@ -367,8 +374,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | |||
367 | if (fepriv->state & FESTATE_RETUNE) { | 374 | if (fepriv->state & FESTATE_RETUNE) { |
368 | s = 0; | 375 | s = 0; |
369 | } else { | 376 | } else { |
370 | if (fe->ops->read_status) | 377 | if (fe->ops.read_status) |
371 | fe->ops->read_status(fe, &s); | 378 | fe->ops.read_status(fe, &s); |
372 | if (s != fepriv->status) { | 379 | if (s != fepriv->status) { |
373 | dvb_frontend_add_event(fe, s); | 380 | dvb_frontend_add_event(fe, s); |
374 | fepriv->status = s; | 381 | fepriv->status = s; |
@@ -381,7 +388,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | |||
381 | fepriv->state = FESTATE_TUNED; | 388 | fepriv->state = FESTATE_TUNED; |
382 | 389 | ||
383 | /* if we're tuned, then we have determined the correct inversion */ | 390 | /* if we're tuned, then we have determined the correct inversion */ |
384 | if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && | 391 | if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && |
385 | (fepriv->parameters.inversion == INVERSION_AUTO)) { | 392 | (fepriv->parameters.inversion == INVERSION_AUTO)) { |
386 | fepriv->parameters.inversion = fepriv->inversion; | 393 | fepriv->parameters.inversion = fepriv->inversion; |
387 | } | 394 | } |
@@ -405,7 +412,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | |||
405 | /* don't actually do anything if we're in the LOSTLOCK state, | 412 | /* don't actually do anything if we're in the LOSTLOCK state, |
406 | * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ | 413 | * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ |
407 | if ((fepriv->state & FESTATE_LOSTLOCK) && | 414 | if ((fepriv->state & FESTATE_LOSTLOCK) && |
408 | (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { | 415 | (fe->ops.info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { |
409 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | 416 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); |
410 | return; | 417 | return; |
411 | } | 418 | } |
@@ -540,16 +547,16 @@ static int dvb_frontend_thread(void *data) | |||
540 | if (fepriv->reinitialise) { | 547 | if (fepriv->reinitialise) { |
541 | dvb_frontend_init(fe); | 548 | dvb_frontend_init(fe); |
542 | if (fepriv->tone != -1) { | 549 | if (fepriv->tone != -1) { |
543 | fe->ops->set_tone(fe, fepriv->tone); | 550 | fe->ops.set_tone(fe, fepriv->tone); |
544 | } | 551 | } |
545 | if (fepriv->voltage != -1) { | 552 | if (fepriv->voltage != -1) { |
546 | fe->ops->set_voltage(fe, fepriv->voltage); | 553 | fe->ops.set_voltage(fe, fepriv->voltage); |
547 | } | 554 | } |
548 | fepriv->reinitialise = 0; | 555 | fepriv->reinitialise = 0; |
549 | } | 556 | } |
550 | 557 | ||
551 | /* do an iteration of the tuning loop */ | 558 | /* do an iteration of the tuning loop */ |
552 | if (fe->ops->tune) { | 559 | if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) { |
553 | /* have we been asked to retune? */ | 560 | /* have we been asked to retune? */ |
554 | params = NULL; | 561 | params = NULL; |
555 | if (fepriv->state & FESTATE_RETUNE) { | 562 | if (fepriv->state & FESTATE_RETUNE) { |
@@ -557,7 +564,7 @@ static int dvb_frontend_thread(void *data) | |||
557 | fepriv->state = FESTATE_TUNED; | 564 | fepriv->state = FESTATE_TUNED; |
558 | } | 565 | } |
559 | 566 | ||
560 | fe->ops->tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); | 567 | fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); |
561 | if (s != fepriv->status) { | 568 | if (s != fepriv->status) { |
562 | dvb_frontend_add_event(fe, s); | 569 | dvb_frontend_add_event(fe, s); |
563 | fepriv->status = s; | 570 | fepriv->status = s; |
@@ -569,10 +576,15 @@ static int dvb_frontend_thread(void *data) | |||
569 | 576 | ||
570 | if (dvb_shutdown_timeout) { | 577 | if (dvb_shutdown_timeout) { |
571 | if (dvb_powerdown_on_sleep) | 578 | if (dvb_powerdown_on_sleep) |
572 | if (fe->ops->set_voltage) | 579 | if (fe->ops.set_voltage) |
573 | fe->ops->set_voltage(fe, SEC_VOLTAGE_OFF); | 580 | fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); |
574 | if (fe->ops->sleep) | 581 | if (fe->ops.tuner_ops.sleep) { |
575 | fe->ops->sleep(fe); | 582 | fe->ops.tuner_ops.sleep(fe); |
583 | if (fe->ops.i2c_gate_ctrl) | ||
584 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
585 | } | ||
586 | if (fe->ops.sleep) | ||
587 | fe->ops.sleep(fe); | ||
576 | } | 588 | } |
577 | 589 | ||
578 | fepriv->thread_pid = 0; | 590 | fepriv->thread_pid = 0; |
@@ -724,7 +736,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
724 | switch (cmd) { | 736 | switch (cmd) { |
725 | case FE_GET_INFO: { | 737 | case FE_GET_INFO: { |
726 | struct dvb_frontend_info* info = parg; | 738 | struct dvb_frontend_info* info = parg; |
727 | memcpy(info, &fe->ops->info, sizeof(struct dvb_frontend_info)); | 739 | memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info)); |
728 | 740 | ||
729 | /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't | 741 | /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't |
730 | * do it, it is done for it. */ | 742 | * do it, it is done for it. */ |
@@ -744,58 +756,58 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
744 | break; | 756 | break; |
745 | } | 757 | } |
746 | 758 | ||
747 | if (fe->ops->read_status) | 759 | if (fe->ops.read_status) |
748 | err = fe->ops->read_status(fe, status); | 760 | err = fe->ops.read_status(fe, status); |
749 | break; | 761 | break; |
750 | } | 762 | } |
751 | case FE_READ_BER: | 763 | case FE_READ_BER: |
752 | if (fe->ops->read_ber) | 764 | if (fe->ops.read_ber) |
753 | err = fe->ops->read_ber(fe, (__u32*) parg); | 765 | err = fe->ops.read_ber(fe, (__u32*) parg); |
754 | break; | 766 | break; |
755 | 767 | ||
756 | case FE_READ_SIGNAL_STRENGTH: | 768 | case FE_READ_SIGNAL_STRENGTH: |
757 | if (fe->ops->read_signal_strength) | 769 | if (fe->ops.read_signal_strength) |
758 | err = fe->ops->read_signal_strength(fe, (__u16*) parg); | 770 | err = fe->ops.read_signal_strength(fe, (__u16*) parg); |
759 | break; | 771 | break; |
760 | 772 | ||
761 | case FE_READ_SNR: | 773 | case FE_READ_SNR: |
762 | if (fe->ops->read_snr) | 774 | if (fe->ops.read_snr) |
763 | err = fe->ops->read_snr(fe, (__u16*) parg); | 775 | err = fe->ops.read_snr(fe, (__u16*) parg); |
764 | break; | 776 | break; |
765 | 777 | ||
766 | case FE_READ_UNCORRECTED_BLOCKS: | 778 | case FE_READ_UNCORRECTED_BLOCKS: |
767 | if (fe->ops->read_ucblocks) | 779 | if (fe->ops.read_ucblocks) |
768 | err = fe->ops->read_ucblocks(fe, (__u32*) parg); | 780 | err = fe->ops.read_ucblocks(fe, (__u32*) parg); |
769 | break; | 781 | break; |
770 | 782 | ||
771 | 783 | ||
772 | case FE_DISEQC_RESET_OVERLOAD: | 784 | case FE_DISEQC_RESET_OVERLOAD: |
773 | if (fe->ops->diseqc_reset_overload) { | 785 | if (fe->ops.diseqc_reset_overload) { |
774 | err = fe->ops->diseqc_reset_overload(fe); | 786 | err = fe->ops.diseqc_reset_overload(fe); |
775 | fepriv->state = FESTATE_DISEQC; | 787 | fepriv->state = FESTATE_DISEQC; |
776 | fepriv->status = 0; | 788 | fepriv->status = 0; |
777 | } | 789 | } |
778 | break; | 790 | break; |
779 | 791 | ||
780 | case FE_DISEQC_SEND_MASTER_CMD: | 792 | case FE_DISEQC_SEND_MASTER_CMD: |
781 | if (fe->ops->diseqc_send_master_cmd) { | 793 | if (fe->ops.diseqc_send_master_cmd) { |
782 | err = fe->ops->diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg); | 794 | err = fe->ops.diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg); |
783 | fepriv->state = FESTATE_DISEQC; | 795 | fepriv->state = FESTATE_DISEQC; |
784 | fepriv->status = 0; | 796 | fepriv->status = 0; |
785 | } | 797 | } |
786 | break; | 798 | break; |
787 | 799 | ||
788 | case FE_DISEQC_SEND_BURST: | 800 | case FE_DISEQC_SEND_BURST: |
789 | if (fe->ops->diseqc_send_burst) { | 801 | if (fe->ops.diseqc_send_burst) { |
790 | err = fe->ops->diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg); | 802 | err = fe->ops.diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg); |
791 | fepriv->state = FESTATE_DISEQC; | 803 | fepriv->state = FESTATE_DISEQC; |
792 | fepriv->status = 0; | 804 | fepriv->status = 0; |
793 | } | 805 | } |
794 | break; | 806 | break; |
795 | 807 | ||
796 | case FE_SET_TONE: | 808 | case FE_SET_TONE: |
797 | if (fe->ops->set_tone) { | 809 | if (fe->ops.set_tone) { |
798 | err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); | 810 | err = fe->ops.set_tone(fe, (fe_sec_tone_mode_t) parg); |
799 | fepriv->tone = (fe_sec_tone_mode_t) parg; | 811 | fepriv->tone = (fe_sec_tone_mode_t) parg; |
800 | fepriv->state = FESTATE_DISEQC; | 812 | fepriv->state = FESTATE_DISEQC; |
801 | fepriv->status = 0; | 813 | fepriv->status = 0; |
@@ -803,8 +815,8 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
803 | break; | 815 | break; |
804 | 816 | ||
805 | case FE_SET_VOLTAGE: | 817 | case FE_SET_VOLTAGE: |
806 | if (fe->ops->set_voltage) { | 818 | if (fe->ops.set_voltage) { |
807 | err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg); | 819 | err = fe->ops.set_voltage(fe, (fe_sec_voltage_t) parg); |
808 | fepriv->voltage = (fe_sec_voltage_t) parg; | 820 | fepriv->voltage = (fe_sec_voltage_t) parg; |
809 | fepriv->state = FESTATE_DISEQC; | 821 | fepriv->state = FESTATE_DISEQC; |
810 | fepriv->status = 0; | 822 | fepriv->status = 0; |
@@ -812,11 +824,11 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
812 | break; | 824 | break; |
813 | 825 | ||
814 | case FE_DISHNETWORK_SEND_LEGACY_CMD: | 826 | case FE_DISHNETWORK_SEND_LEGACY_CMD: |
815 | if (fe->ops->dishnetwork_send_legacy_command) { | 827 | if (fe->ops.dishnetwork_send_legacy_command) { |
816 | err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned long) parg); | 828 | err = fe->ops.dishnetwork_send_legacy_command(fe, (unsigned long) parg); |
817 | fepriv->state = FESTATE_DISEQC; | 829 | fepriv->state = FESTATE_DISEQC; |
818 | fepriv->status = 0; | 830 | fepriv->status = 0; |
819 | } else if (fe->ops->set_voltage) { | 831 | } else if (fe->ops.set_voltage) { |
820 | /* | 832 | /* |
821 | * NOTE: This is a fallback condition. Some frontends | 833 | * NOTE: This is a fallback condition. Some frontends |
822 | * (stv0299 for instance) take longer than 8msec to | 834 | * (stv0299 for instance) take longer than 8msec to |
@@ -846,7 +858,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
846 | /* before sending a command, initialize by sending | 858 | /* before sending a command, initialize by sending |
847 | * a 32ms 18V to the switch | 859 | * a 32ms 18V to the switch |
848 | */ | 860 | */ |
849 | fe->ops->set_voltage(fe, SEC_VOLTAGE_18); | 861 | fe->ops.set_voltage(fe, SEC_VOLTAGE_18); |
850 | dvb_frontend_sleep_until(&nexttime, 32000); | 862 | dvb_frontend_sleep_until(&nexttime, 32000); |
851 | 863 | ||
852 | for (i = 0; i < 9; i++) { | 864 | for (i = 0; i < 9; i++) { |
@@ -854,7 +866,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
854 | do_gettimeofday(&tv[i + 1]); | 866 | do_gettimeofday(&tv[i + 1]); |
855 | if ((cmd & 0x01) != last) { | 867 | if ((cmd & 0x01) != last) { |
856 | /* set voltage to (last ? 13V : 18V) */ | 868 | /* set voltage to (last ? 13V : 18V) */ |
857 | fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); | 869 | fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); |
858 | last = (last) ? 0 : 1; | 870 | last = (last) ? 0 : 1; |
859 | } | 871 | } |
860 | cmd = cmd >> 1; | 872 | cmd = cmd >> 1; |
@@ -874,13 +886,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
874 | break; | 886 | break; |
875 | 887 | ||
876 | case FE_DISEQC_RECV_SLAVE_REPLY: | 888 | case FE_DISEQC_RECV_SLAVE_REPLY: |
877 | if (fe->ops->diseqc_recv_slave_reply) | 889 | if (fe->ops.diseqc_recv_slave_reply) |
878 | err = fe->ops->diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg); | 890 | err = fe->ops.diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg); |
879 | break; | 891 | break; |
880 | 892 | ||
881 | case FE_ENABLE_HIGH_LNB_VOLTAGE: | 893 | case FE_ENABLE_HIGH_LNB_VOLTAGE: |
882 | if (fe->ops->enable_high_lnb_voltage) | 894 | if (fe->ops.enable_high_lnb_voltage) |
883 | err = fe->ops->enable_high_lnb_voltage(fe, (long) parg); | 895 | err = fe->ops.enable_high_lnb_voltage(fe, (long) parg); |
884 | break; | 896 | break; |
885 | 897 | ||
886 | case FE_SET_FRONTEND: { | 898 | case FE_SET_FRONTEND: { |
@@ -898,7 +910,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
898 | fepriv->parameters.inversion = INVERSION_AUTO; | 910 | fepriv->parameters.inversion = INVERSION_AUTO; |
899 | fetunesettings.parameters.inversion = INVERSION_AUTO; | 911 | fetunesettings.parameters.inversion = INVERSION_AUTO; |
900 | } | 912 | } |
901 | if (fe->ops->info.type == FE_OFDM) { | 913 | if (fe->ops.info.type == FE_OFDM) { |
902 | /* without hierachical coding code_rate_LP is irrelevant, | 914 | /* without hierachical coding code_rate_LP is irrelevant, |
903 | * so we tolerate the otherwise invalid FEC_NONE setting */ | 915 | * so we tolerate the otherwise invalid FEC_NONE setting */ |
904 | if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && | 916 | if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && |
@@ -907,13 +919,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
907 | } | 919 | } |
908 | 920 | ||
909 | /* get frontend-specific tuning settings */ | 921 | /* get frontend-specific tuning settings */ |
910 | if (fe->ops->get_tune_settings && (fe->ops->get_tune_settings(fe, &fetunesettings) == 0)) { | 922 | if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) { |
911 | fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; | 923 | fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; |
912 | fepriv->max_drift = fetunesettings.max_drift; | 924 | fepriv->max_drift = fetunesettings.max_drift; |
913 | fepriv->step_size = fetunesettings.step_size; | 925 | fepriv->step_size = fetunesettings.step_size; |
914 | } else { | 926 | } else { |
915 | /* default values */ | 927 | /* default values */ |
916 | switch(fe->ops->info.type) { | 928 | switch(fe->ops.info.type) { |
917 | case FE_QPSK: | 929 | case FE_QPSK: |
918 | fepriv->min_delay = HZ/20; | 930 | fepriv->min_delay = HZ/20; |
919 | fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000; | 931 | fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000; |
@@ -928,11 +940,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
928 | 940 | ||
929 | case FE_OFDM: | 941 | case FE_OFDM: |
930 | fepriv->min_delay = HZ/20; | 942 | fepriv->min_delay = HZ/20; |
931 | fepriv->step_size = fe->ops->info.frequency_stepsize * 2; | 943 | fepriv->step_size = fe->ops.info.frequency_stepsize * 2; |
932 | fepriv->max_drift = (fe->ops->info.frequency_stepsize * 2) + 1; | 944 | fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; |
933 | break; | 945 | break; |
934 | case FE_ATSC: | 946 | case FE_ATSC: |
935 | printk("dvb-core: FE_ATSC not handled yet.\n"); | 947 | fepriv->min_delay = HZ/20; |
948 | fepriv->step_size = 0; | ||
949 | fepriv->max_drift = 0; | ||
936 | break; | 950 | break; |
937 | } | 951 | } |
938 | } | 952 | } |
@@ -952,9 +966,9 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
952 | break; | 966 | break; |
953 | 967 | ||
954 | case FE_GET_FRONTEND: | 968 | case FE_GET_FRONTEND: |
955 | if (fe->ops->get_frontend) { | 969 | if (fe->ops.get_frontend) { |
956 | memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); | 970 | memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); |
957 | err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); | 971 | err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg); |
958 | } | 972 | } |
959 | break; | 973 | break; |
960 | 974 | ||
@@ -1067,7 +1081,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, | |||
1067 | 1081 | ||
1068 | printk ("DVB: registering frontend %i (%s)...\n", | 1082 | printk ("DVB: registering frontend %i (%s)...\n", |
1069 | fe->dvb->num, | 1083 | fe->dvb->num, |
1070 | fe->ops->info.name); | 1084 | fe->ops.info.name); |
1071 | 1085 | ||
1072 | dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, | 1086 | dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, |
1073 | fe, DVB_DEVICE_FRONTEND); | 1087 | fe, DVB_DEVICE_FRONTEND); |
@@ -1085,10 +1099,15 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) | |||
1085 | mutex_lock(&frontend_mutex); | 1099 | mutex_lock(&frontend_mutex); |
1086 | dvb_unregister_device (fepriv->dvbdev); | 1100 | dvb_unregister_device (fepriv->dvbdev); |
1087 | dvb_frontend_stop (fe); | 1101 | dvb_frontend_stop (fe); |
1088 | if (fe->ops->release) | 1102 | if (fe->ops.tuner_ops.release) { |
1089 | fe->ops->release(fe); | 1103 | fe->ops.tuner_ops.release(fe); |
1104 | if (fe->ops.i2c_gate_ctrl) | ||
1105 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
1106 | } | ||
1107 | if (fe->ops.release) | ||
1108 | fe->ops.release(fe); | ||
1090 | else | 1109 | else |
1091 | printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name); | 1110 | printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops.info.name); |
1092 | /* fe is invalid now */ | 1111 | /* fe is invalid now */ |
1093 | kfree(fepriv); | 1112 | kfree(fepriv); |
1094 | mutex_unlock(&frontend_mutex); | 1113 | mutex_unlock(&frontend_mutex); |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 5926a3b745c9..2887e2b862a4 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h | |||
@@ -49,6 +49,44 @@ struct dvb_frontend_tune_settings { | |||
49 | 49 | ||
50 | struct dvb_frontend; | 50 | struct dvb_frontend; |
51 | 51 | ||
52 | struct dvb_tuner_info { | ||
53 | char name[128]; | ||
54 | |||
55 | u32 frequency_min; | ||
56 | u32 frequency_max; | ||
57 | u32 frequency_step; | ||
58 | |||
59 | u32 bandwidth_min; | ||
60 | u32 bandwidth_max; | ||
61 | u32 bandwidth_step; | ||
62 | }; | ||
63 | |||
64 | struct dvb_tuner_ops { | ||
65 | |||
66 | struct dvb_tuner_info info; | ||
67 | |||
68 | int (*release)(struct dvb_frontend *fe); | ||
69 | int (*init)(struct dvb_frontend *fe); | ||
70 | int (*sleep)(struct dvb_frontend *fe); | ||
71 | |||
72 | /** This is for simple PLLs - set all parameters in one go. */ | ||
73 | int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); | ||
74 | |||
75 | /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */ | ||
76 | int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len); | ||
77 | |||
78 | int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency); | ||
79 | int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); | ||
80 | |||
81 | #define TUNER_STATUS_LOCKED 1 | ||
82 | int (*get_status)(struct dvb_frontend *fe, u32 *status); | ||
83 | |||
84 | /** These are provided seperately from set_params in order to facilitate silicon | ||
85 | * tuners which require sophisticated tuning loops, controlling each parameter seperately. */ | ||
86 | int (*set_frequency)(struct dvb_frontend *fe, u32 frequency); | ||
87 | int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); | ||
88 | }; | ||
89 | |||
52 | struct dvb_frontend_ops { | 90 | struct dvb_frontend_ops { |
53 | 91 | ||
54 | struct dvb_frontend_info info; | 92 | struct dvb_frontend_info info; |
@@ -64,6 +102,8 @@ struct dvb_frontend_ops { | |||
64 | unsigned int mode_flags, | 102 | unsigned int mode_flags, |
65 | int *delay, | 103 | int *delay, |
66 | fe_status_t *status); | 104 | fe_status_t *status); |
105 | /* get frontend tuning algorithm from the module */ | ||
106 | int (*get_frontend_algo)(struct dvb_frontend *fe); | ||
67 | 107 | ||
68 | /* these two are only used for the swzigzag code */ | 108 | /* these two are only used for the swzigzag code */ |
69 | int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | 109 | int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
@@ -86,6 +126,8 @@ struct dvb_frontend_ops { | |||
86 | int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); | 126 | int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); |
87 | int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); | 127 | int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); |
88 | int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); | 128 | int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); |
129 | |||
130 | struct dvb_tuner_ops tuner_ops; | ||
89 | }; | 131 | }; |
90 | 132 | ||
91 | #define MAX_EVENT 8 | 133 | #define MAX_EVENT 8 |
@@ -100,9 +142,10 @@ struct dvb_fe_events { | |||
100 | }; | 142 | }; |
101 | 143 | ||
102 | struct dvb_frontend { | 144 | struct dvb_frontend { |
103 | struct dvb_frontend_ops* ops; | 145 | struct dvb_frontend_ops ops; |
104 | struct dvb_adapter *dvb; | 146 | struct dvb_adapter *dvb; |
105 | void* demodulator_priv; | 147 | void* demodulator_priv; |
148 | void* tuner_priv; | ||
106 | void* frontend_priv; | 149 | void* frontend_priv; |
107 | void* misc_priv; | 150 | void* misc_priv; |
108 | }; | 151 | }; |
diff --git a/drivers/media/dvb/dvb-core/dvb_math.c b/drivers/media/dvb/dvb-core/dvb_math.c new file mode 100644 index 000000000000..beb7c93aa6cb --- /dev/null +++ b/drivers/media/dvb/dvb-core/dvb_math.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * dvb-math provides some complex fixed-point math | ||
3 | * operations shared between the dvb related stuff | ||
4 | * | ||
5 | * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com) | ||
6 | * | ||
7 | * This library is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Lesser General Public License as | ||
9 | * published by the Free Software Foundation; either version 2.1 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/bitops.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <asm/bug.h> | ||
26 | #include "dvb_math.h" | ||
27 | |||
28 | static const unsigned short logtable[256] = { | ||
29 | 0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7, | ||
30 | 0x0b5d, 0x0cc3, 0x0e27, 0x0f8a, 0x10eb, 0x124b, 0x13aa, 0x1508, | ||
31 | 0x1664, 0x17bf, 0x1919, 0x1a71, 0x1bc8, 0x1d1e, 0x1e73, 0x1fc6, | ||
32 | 0x2119, 0x226a, 0x23ba, 0x2508, 0x2656, 0x27a2, 0x28ed, 0x2a37, | ||
33 | 0x2b80, 0x2cc8, 0x2e0f, 0x2f54, 0x3098, 0x31dc, 0x331e, 0x345f, | ||
34 | 0x359f, 0x36de, 0x381b, 0x3958, 0x3a94, 0x3bce, 0x3d08, 0x3e41, | ||
35 | 0x3f78, 0x40af, 0x41e4, 0x4319, 0x444c, 0x457f, 0x46b0, 0x47e1, | ||
36 | 0x4910, 0x4a3f, 0x4b6c, 0x4c99, 0x4dc5, 0x4eef, 0x5019, 0x5142, | ||
37 | 0x526a, 0x5391, 0x54b7, 0x55dc, 0x5700, 0x5824, 0x5946, 0x5a68, | ||
38 | 0x5b89, 0x5ca8, 0x5dc7, 0x5ee5, 0x6003, 0x611f, 0x623a, 0x6355, | ||
39 | 0x646f, 0x6588, 0x66a0, 0x67b7, 0x68ce, 0x69e4, 0x6af8, 0x6c0c, | ||
40 | 0x6d20, 0x6e32, 0x6f44, 0x7055, 0x7165, 0x7274, 0x7383, 0x7490, | ||
41 | 0x759d, 0x76aa, 0x77b5, 0x78c0, 0x79ca, 0x7ad3, 0x7bdb, 0x7ce3, | ||
42 | 0x7dea, 0x7ef0, 0x7ff6, 0x80fb, 0x81ff, 0x8302, 0x8405, 0x8507, | ||
43 | 0x8608, 0x8709, 0x8809, 0x8908, 0x8a06, 0x8b04, 0x8c01, 0x8cfe, | ||
44 | 0x8dfa, 0x8ef5, 0x8fef, 0x90e9, 0x91e2, 0x92db, 0x93d2, 0x94ca, | ||
45 | 0x95c0, 0x96b6, 0x97ab, 0x98a0, 0x9994, 0x9a87, 0x9b7a, 0x9c6c, | ||
46 | 0x9d5e, 0x9e4f, 0x9f3f, 0xa02e, 0xa11e, 0xa20c, 0xa2fa, 0xa3e7, | ||
47 | 0xa4d4, 0xa5c0, 0xa6ab, 0xa796, 0xa881, 0xa96a, 0xaa53, 0xab3c, | ||
48 | 0xac24, 0xad0c, 0xadf2, 0xaed9, 0xafbe, 0xb0a4, 0xb188, 0xb26c, | ||
49 | 0xb350, 0xb433, 0xb515, 0xb5f7, 0xb6d9, 0xb7ba, 0xb89a, 0xb97a, | ||
50 | 0xba59, 0xbb38, 0xbc16, 0xbcf4, 0xbdd1, 0xbead, 0xbf8a, 0xc065, | ||
51 | 0xc140, 0xc21b, 0xc2f5, 0xc3cf, 0xc4a8, 0xc580, 0xc658, 0xc730, | ||
52 | 0xc807, 0xc8de, 0xc9b4, 0xca8a, 0xcb5f, 0xcc34, 0xcd08, 0xcddc, | ||
53 | 0xceaf, 0xcf82, 0xd054, 0xd126, 0xd1f7, 0xd2c8, 0xd399, 0xd469, | ||
54 | 0xd538, 0xd607, 0xd6d6, 0xd7a4, 0xd872, 0xd93f, 0xda0c, 0xdad9, | ||
55 | 0xdba5, 0xdc70, 0xdd3b, 0xde06, 0xded0, 0xdf9a, 0xe063, 0xe12c, | ||
56 | 0xe1f5, 0xe2bd, 0xe385, 0xe44c, 0xe513, 0xe5d9, 0xe69f, 0xe765, | ||
57 | 0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83, | ||
58 | 0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387, | ||
59 | 0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973, | ||
60 | 0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47 | ||
61 | }; | ||
62 | |||
63 | unsigned int intlog2(u32 value) | ||
64 | { | ||
65 | /** | ||
66 | * returns: log2(value) * 2^24 | ||
67 | * wrong result if value = 0 (log2(0) is undefined) | ||
68 | */ | ||
69 | unsigned int msb; | ||
70 | unsigned int logentry; | ||
71 | unsigned int significand; | ||
72 | unsigned int interpolation; | ||
73 | |||
74 | if (unlikely(value == 0)) { | ||
75 | WARN_ON(1); | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | /* first detect the msb (count begins at 0) */ | ||
80 | msb = fls(value) - 1; | ||
81 | |||
82 | /** | ||
83 | * now we use a logtable after the following method: | ||
84 | * | ||
85 | * log2(2^x * y) * 2^24 = x * 2^24 + log2(y) * 2^24 | ||
86 | * where x = msb and therefore 1 <= y < 2 | ||
87 | * first y is determined by shifting the value left | ||
88 | * so that msb is bit 31 | ||
89 | * 0x00231f56 -> 0x8C7D5800 | ||
90 | * the result is y * 2^31 -> "significand" | ||
91 | * then the highest 9 bits are used for a table lookup | ||
92 | * the highest bit is discarded because it's always set | ||
93 | * the highest nine bits in our example are 100011000 | ||
94 | * so we would use the entry 0x18 | ||
95 | */ | ||
96 | significand = value << (31 - msb); | ||
97 | logentry = (significand >> 23) & 0xff; | ||
98 | |||
99 | /** | ||
100 | * last step we do is interpolation because of the | ||
101 | * limitations of the log table the error is that part of | ||
102 | * the significand which isn't used for lookup then we | ||
103 | * compute the ratio between the error and the next table entry | ||
104 | * and interpolate it between the log table entry used and the | ||
105 | * next one the biggest error possible is 0x7fffff | ||
106 | * (in our example it's 0x7D5800) | ||
107 | * needed value for next table entry is 0x800000 | ||
108 | * so the interpolation is | ||
109 | * (error / 0x800000) * (logtable_next - logtable_current) | ||
110 | * in the implementation the division is moved to the end for | ||
111 | * better accuracy there is also an overflow correction if | ||
112 | * logtable_next is 256 | ||
113 | */ | ||
114 | interpolation = ((significand & 0x7fffff) * | ||
115 | ((logtable[(logentry + 1) & 0xff] - | ||
116 | logtable[logentry]) & 0xffff)) >> 15; | ||
117 | |||
118 | /* now we return the result */ | ||
119 | return ((msb << 24) + (logtable[logentry] << 8) + interpolation); | ||
120 | } | ||
121 | EXPORT_SYMBOL(intlog2); | ||
122 | |||
123 | unsigned int intlog10(u32 value) | ||
124 | { | ||
125 | /** | ||
126 | * returns: log10(value) * 2^24 | ||
127 | * wrong result if value = 0 (log10(0) is undefined) | ||
128 | */ | ||
129 | u64 log; | ||
130 | |||
131 | if (unlikely(value == 0)) { | ||
132 | WARN_ON(1); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | log = intlog2(value); | ||
137 | |||
138 | /** | ||
139 | * we use the following method: | ||
140 | * log10(x) = log2(x) * log10(2) | ||
141 | */ | ||
142 | |||
143 | return (log * 646456993) >> 31; | ||
144 | } | ||
145 | EXPORT_SYMBOL(intlog10); | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_math.h b/drivers/media/dvb/dvb-core/dvb_math.h new file mode 100644 index 000000000000..aecc867e9404 --- /dev/null +++ b/drivers/media/dvb/dvb-core/dvb_math.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * dvb-math provides some complex fixed-point math | ||
3 | * operations shared between the dvb related stuff | ||
4 | * | ||
5 | * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com) | ||
6 | * | ||
7 | * This library is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Lesser General Public License as | ||
9 | * published by the Free Software Foundation; either version 2.1 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef __DVB_MATH_H | ||
23 | #define __DVB_MATH_H | ||
24 | |||
25 | #include <linux/types.h> | ||
26 | |||
27 | /** | ||
28 | * computes log2 of a value; the result is shifted left by 24 bits | ||
29 | * | ||
30 | * to use rational values you can use the following method: | ||
31 | * intlog2(value) = intlog2(value * 2^x) - x * 2^24 | ||
32 | * | ||
33 | * example: intlog2(8) will give 3 << 24 = 3 * 2^24 | ||
34 | * example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24 | ||
35 | * example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24 | ||
36 | * | ||
37 | * @param value The value (must be != 0) | ||
38 | * @return log2(value) * 2^24 | ||
39 | */ | ||
40 | extern unsigned int intlog2(u32 value); | ||
41 | |||
42 | /** | ||
43 | * computes log10 of a value; the result is shifted left by 24 bits | ||
44 | * | ||
45 | * to use rational values you can use the following method: | ||
46 | * intlog10(value) = intlog10(value * 10^x) - x * 2^24 | ||
47 | * | ||
48 | * example: intlog10(1000) will give 3 << 24 = 3 * 2^24 | ||
49 | * due to the implementation intlog10(1000) might be not exactly 3 * 2^24 | ||
50 | * | ||
51 | * look at intlog2 for similar examples | ||
52 | * | ||
53 | * @param value The value (must be != 0) | ||
54 | * @return log10(value) * 2^24 | ||
55 | */ | ||
56 | extern unsigned int intlog10(u32 value); | ||
57 | |||
58 | #endif | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 9fd87521a163..8859ab74f0fe 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * Hilmar Linder <hlinder@cosy.sbg.ac.at> | 12 | * Hilmar Linder <hlinder@cosy.sbg.ac.at> |
13 | * and Wolfram Stering <wstering@cosy.sbg.ac.at> | 13 | * and Wolfram Stering <wstering@cosy.sbg.ac.at> |
14 | * | 14 | * |
15 | * ULE Decaps according to draft-ietf-ipdvb-ule-03.txt. | 15 | * ULE Decaps according to RFC 4326. |
16 | * | 16 | * |
17 | * This program is free software; you can redistribute it and/or | 17 | * This program is free software; you can redistribute it and/or |
18 | * modify it under the terms of the GNU General Public License | 18 | * modify it under the terms of the GNU General Public License |
@@ -42,6 +42,9 @@ | |||
42 | * Bugfixes and robustness improvements. | 42 | * Bugfixes and robustness improvements. |
43 | * Filtering on dest MAC addresses, if present (D-Bit = 0) | 43 | * Filtering on dest MAC addresses, if present (D-Bit = 0) |
44 | * ULE_DEBUG compile-time option. | 44 | * ULE_DEBUG compile-time option. |
45 | * Apr 2006: cp v3: Bugfixes and compliency with RFC 4326 (ULE) by | ||
46 | * Christian Praehauser <cpraehaus@cosy.sbg.ac.at>, | ||
47 | * Paris Lodron University of Salzburg. | ||
45 | */ | 48 | */ |
46 | 49 | ||
47 | /* | 50 | /* |
@@ -49,9 +52,6 @@ | |||
49 | * | 52 | * |
50 | * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero. | 53 | * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero. |
51 | * | 54 | * |
52 | * TS_FEED callback is called once for every single TS cell although it is | ||
53 | * registered (in dvb_net_feed_start()) for 100 TS cells (used for dvb_net_ule()). | ||
54 | * | ||
55 | */ | 55 | */ |
56 | 56 | ||
57 | #include <linux/module.h> | 57 | #include <linux/module.h> |
@@ -89,6 +89,9 @@ static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt ) | |||
89 | 89 | ||
90 | #ifdef ULE_DEBUG | 90 | #ifdef ULE_DEBUG |
91 | 91 | ||
92 | #define MAC_ADDR_PRINTFMT "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" | ||
93 | #define MAX_ADDR_PRINTFMT_ARGS(macap) (macap)[0],(macap)[1],(macap)[2],(macap)[3],(macap)[4],(macap)[5] | ||
94 | |||
92 | #define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) | 95 | #define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) |
93 | 96 | ||
94 | static void hexdump( const unsigned char *buf, unsigned short len ) | 97 | static void hexdump( const unsigned char *buf, unsigned short len ) |
@@ -214,6 +217,8 @@ static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb, | |||
214 | #define ULE_TEST 0 | 217 | #define ULE_TEST 0 |
215 | #define ULE_BRIDGED 1 | 218 | #define ULE_BRIDGED 1 |
216 | 219 | ||
220 | #define ULE_OPTEXTHDR_PADDING 0 | ||
221 | |||
217 | static int ule_test_sndu( struct dvb_net_priv *p ) | 222 | static int ule_test_sndu( struct dvb_net_priv *p ) |
218 | { | 223 | { |
219 | return -1; | 224 | return -1; |
@@ -221,14 +226,28 @@ static int ule_test_sndu( struct dvb_net_priv *p ) | |||
221 | 226 | ||
222 | static int ule_bridged_sndu( struct dvb_net_priv *p ) | 227 | static int ule_bridged_sndu( struct dvb_net_priv *p ) |
223 | { | 228 | { |
224 | /* BRIDGE SNDU handling sucks in draft-ietf-ipdvb-ule-03.txt. | 229 | struct ethhdr *hdr = (struct ethhdr*) p->ule_next_hdr; |
225 | * This has to be the last extension header, otherwise it won't work. | 230 | if(ntohs(hdr->h_proto) < 1536) { |
226 | * Blame the authors! | 231 | int framelen = p->ule_sndu_len - ((p->ule_next_hdr+sizeof(struct ethhdr)) - p->ule_skb->data); |
232 | /* A frame Type < 1536 for a bridged frame, introduces a LLC Length field. */ | ||
233 | if(framelen != ntohs(hdr->h_proto)) { | ||
234 | return -1; | ||
235 | } | ||
236 | } | ||
237 | /* Note: | ||
238 | * From RFC4326: | ||
239 | * "A bridged SNDU is a Mandatory Extension Header of Type 1. | ||
240 | * It must be the final (or only) extension header specified in the header chain of a SNDU." | ||
241 | * The 'ule_bridged' flag will cause the extension header processing loop to terminate. | ||
227 | */ | 242 | */ |
228 | p->ule_bridged = 1; | 243 | p->ule_bridged = 1; |
229 | return 0; | 244 | return 0; |
230 | } | 245 | } |
231 | 246 | ||
247 | static int ule_exthdr_padding(struct dvb_net_priv *p) | ||
248 | { | ||
249 | return 0; | ||
250 | } | ||
232 | 251 | ||
233 | /** Handle ULE extension headers. | 252 | /** Handle ULE extension headers. |
234 | * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding. | 253 | * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding. |
@@ -242,7 +261,8 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) | |||
242 | { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, }; | 261 | { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, }; |
243 | 262 | ||
244 | /* Table of optional extension header handlers. The header type is the index. */ | 263 | /* Table of optional extension header handlers. The header type is the index. */ |
245 | static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) = { NULL, }; | 264 | static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) = |
265 | { [0] = ule_exthdr_padding, [1] = NULL, }; | ||
246 | 266 | ||
247 | int ext_len = 0; | 267 | int ext_len = 0; |
248 | unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8; | 268 | unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8; |
@@ -253,25 +273,31 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) | |||
253 | /* Mandatory extension header */ | 273 | /* Mandatory extension header */ |
254 | if (ule_mandatory_ext_handlers[htype]) { | 274 | if (ule_mandatory_ext_handlers[htype]) { |
255 | ext_len = ule_mandatory_ext_handlers[htype]( p ); | 275 | ext_len = ule_mandatory_ext_handlers[htype]( p ); |
256 | p->ule_next_hdr += ext_len; | 276 | if(ext_len >= 0) { |
257 | if (! p->ule_bridged) { | 277 | p->ule_next_hdr += ext_len; |
258 | p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr ); | 278 | if (!p->ule_bridged) { |
259 | p->ule_next_hdr += 2; | 279 | p->ule_sndu_type = ntohs(*(unsigned short *)p->ule_next_hdr); |
260 | } else { | 280 | p->ule_next_hdr += 2; |
261 | p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN)) ); | 281 | } else { |
262 | /* This assures the extension handling loop will terminate. */ | 282 | p->ule_sndu_type = ntohs(*(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN))); |
283 | /* This assures the extension handling loop will terminate. */ | ||
284 | } | ||
263 | } | 285 | } |
286 | // else: extension handler failed or SNDU should be discarded | ||
264 | } else | 287 | } else |
265 | ext_len = -1; /* SNDU has to be discarded. */ | 288 | ext_len = -1; /* SNDU has to be discarded. */ |
266 | } else { | 289 | } else { |
267 | /* Optional extension header. Calculate the length. */ | 290 | /* Optional extension header. Calculate the length. */ |
268 | ext_len = hlen << 2; | 291 | ext_len = hlen << 1; |
269 | /* Process the optional extension header according to its type. */ | 292 | /* Process the optional extension header according to its type. */ |
270 | if (ule_optional_ext_handlers[htype]) | 293 | if (ule_optional_ext_handlers[htype]) |
271 | (void)ule_optional_ext_handlers[htype]( p ); | 294 | (void)ule_optional_ext_handlers[htype]( p ); |
272 | p->ule_next_hdr += ext_len; | 295 | p->ule_next_hdr += ext_len; |
273 | p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr ); | 296 | p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr-2) ); |
274 | p->ule_next_hdr += 2; | 297 | /* |
298 | * note: the length of the next header type is included in the | ||
299 | * length of THIS optional extension header | ||
300 | */ | ||
275 | } | 301 | } |
276 | 302 | ||
277 | return ext_len; | 303 | return ext_len; |
@@ -284,8 +310,14 @@ static int handle_ule_extensions( struct dvb_net_priv *p ) | |||
284 | p->ule_next_hdr = p->ule_skb->data; | 310 | p->ule_next_hdr = p->ule_skb->data; |
285 | do { | 311 | do { |
286 | l = handle_one_ule_extension( p ); | 312 | l = handle_one_ule_extension( p ); |
287 | if (l == -1) return -1; /* Stop extension header processing and discard SNDU. */ | 313 | if (l < 0) |
314 | return l; /* Stop extension header processing and discard SNDU. */ | ||
288 | total_ext_len += l; | 315 | total_ext_len += l; |
316 | #ifdef ULE_DEBUG | ||
317 | dprintk("handle_ule_extensions: ule_next_hdr=%p, ule_sndu_type=%i, " | ||
318 | "l=%i, total_ext_len=%i\n", p->ule_next_hdr, | ||
319 | (int) p->ule_sndu_type, l, total_ext_len); | ||
320 | #endif | ||
289 | 321 | ||
290 | } while (p->ule_sndu_type < 1536); | 322 | } while (p->ule_sndu_type < 1536); |
291 | 323 | ||
@@ -355,8 +387,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
355 | if (priv->ule_skb) { | 387 | if (priv->ule_skb) { |
356 | dev_kfree_skb( priv->ule_skb ); | 388 | dev_kfree_skb( priv->ule_skb ); |
357 | /* Prepare for next SNDU. */ | 389 | /* Prepare for next SNDU. */ |
358 | ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; | 390 | priv->stats.rx_errors++; |
359 | ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++; | 391 | priv->stats.rx_frame_errors++; |
360 | } | 392 | } |
361 | reset_ule(priv); | 393 | reset_ule(priv); |
362 | priv->need_pusi = 1; | 394 | priv->need_pusi = 1; |
@@ -396,27 +428,25 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
396 | } | 428 | } |
397 | } | 429 | } |
398 | 430 | ||
399 | /* Check continuity counter. */ | ||
400 | if (new_ts) { | 431 | if (new_ts) { |
432 | /* Check continuity counter. */ | ||
401 | if ((ts[3] & 0x0F) == priv->tscc) | 433 | if ((ts[3] & 0x0F) == priv->tscc) |
402 | priv->tscc = (priv->tscc + 1) & 0x0F; | 434 | priv->tscc = (priv->tscc + 1) & 0x0F; |
403 | else { | 435 | else { |
404 | /* TS discontinuity handling: */ | 436 | /* TS discontinuity handling: */ |
405 | printk(KERN_WARNING "%lu: TS discontinuity: got %#x, " | 437 | printk(KERN_WARNING "%lu: TS discontinuity: got %#x, " |
406 | "exptected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc); | 438 | "expected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc); |
407 | /* Drop partly decoded SNDU, reset state, resync on PUSI. */ | 439 | /* Drop partly decoded SNDU, reset state, resync on PUSI. */ |
408 | if (priv->ule_skb) { | 440 | if (priv->ule_skb) { |
409 | dev_kfree_skb( priv->ule_skb ); | 441 | dev_kfree_skb( priv->ule_skb ); |
410 | /* Prepare for next SNDU. */ | 442 | /* Prepare for next SNDU. */ |
411 | // reset_ule(priv); moved to below. | 443 | // reset_ule(priv); moved to below. |
412 | ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; | 444 | priv->stats.rx_errors++; |
413 | ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++; | 445 | priv->stats.rx_frame_errors++; |
414 | } | 446 | } |
415 | reset_ule(priv); | 447 | reset_ule(priv); |
416 | /* skip to next PUSI. */ | 448 | /* skip to next PUSI. */ |
417 | priv->need_pusi = 1; | 449 | priv->need_pusi = 1; |
418 | ts += TS_SZ; | ||
419 | priv->ts_count++; | ||
420 | continue; | 450 | continue; |
421 | } | 451 | } |
422 | /* If we still have an incomplete payload, but PUSI is | 452 | /* If we still have an incomplete payload, but PUSI is |
@@ -425,7 +455,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
425 | * cells (continuity counter wrap). */ | 455 | * cells (continuity counter wrap). */ |
426 | if (ts[1] & TS_PUSI) { | 456 | if (ts[1] & TS_PUSI) { |
427 | if (! priv->need_pusi) { | 457 | if (! priv->need_pusi) { |
428 | if (*from_where > 181) { | 458 | if (!(*from_where < (ts_remain-1)) || *from_where != priv->ule_sndu_remain) { |
429 | /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */ | 459 | /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */ |
430 | printk(KERN_WARNING "%lu: Invalid pointer " | 460 | printk(KERN_WARNING "%lu: Invalid pointer " |
431 | "field: %u.\n", priv->ts_count, *from_where); | 461 | "field: %u.\n", priv->ts_count, *from_where); |
@@ -438,8 +468,6 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
438 | } | 468 | } |
439 | reset_ule(priv); | 469 | reset_ule(priv); |
440 | priv->need_pusi = 1; | 470 | priv->need_pusi = 1; |
441 | ts += TS_SZ; | ||
442 | priv->ts_count++; | ||
443 | continue; | 471 | continue; |
444 | } | 472 | } |
445 | /* Skip pointer field (we're processing a | 473 | /* Skip pointer field (we're processing a |
@@ -452,8 +480,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
452 | if (priv->ule_sndu_remain > 183) { | 480 | if (priv->ule_sndu_remain > 183) { |
453 | /* Current SNDU lacks more data than there could be available in the | 481 | /* Current SNDU lacks more data than there could be available in the |
454 | * current TS cell. */ | 482 | * current TS cell. */ |
455 | ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; | 483 | priv->stats.rx_errors++; |
456 | ((struct dvb_net_priv *) dev->priv)->stats.rx_length_errors++; | 484 | priv->stats.rx_length_errors++; |
457 | printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but " | 485 | printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but " |
458 | "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", | 486 | "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", |
459 | priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain); | 487 | priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain); |
@@ -492,9 +520,11 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
492 | } else | 520 | } else |
493 | priv->ule_dbit = 0; | 521 | priv->ule_dbit = 0; |
494 | 522 | ||
495 | if (priv->ule_sndu_len > 32763) { | 523 | if (priv->ule_sndu_len < 5) { |
496 | printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. " | 524 | printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. " |
497 | "Resyncing.\n", priv->ts_count, priv->ule_sndu_len); | 525 | "Resyncing.\n", priv->ts_count, priv->ule_sndu_len); |
526 | priv->stats.rx_errors++; | ||
527 | priv->stats.rx_length_errors++; | ||
498 | priv->ule_sndu_len = 0; | 528 | priv->ule_sndu_len = 0; |
499 | priv->need_pusi = 1; | 529 | priv->need_pusi = 1; |
500 | new_ts = 1; | 530 | new_ts = 1; |
@@ -608,58 +638,103 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
608 | ule_dump = 1; | 638 | ule_dump = 1; |
609 | #endif | 639 | #endif |
610 | 640 | ||
611 | ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; | 641 | priv->stats.rx_errors++; |
612 | ((struct dvb_net_priv *) dev->priv)->stats.rx_crc_errors++; | 642 | priv->stats.rx_crc_errors++; |
613 | dev_kfree_skb(priv->ule_skb); | 643 | dev_kfree_skb(priv->ule_skb); |
614 | } else { | 644 | } else { |
615 | /* CRC32 verified OK. */ | 645 | /* CRC32 verified OK. */ |
646 | u8 dest_addr[ETH_ALEN]; | ||
647 | static const u8 bc_addr[ETH_ALEN] = | ||
648 | { [ 0 ... ETH_ALEN-1] = 0xff }; | ||
649 | |||
650 | /* CRC32 was OK. Remove it from skb. */ | ||
651 | priv->ule_skb->tail -= 4; | ||
652 | priv->ule_skb->len -= 4; | ||
653 | |||
654 | if (!priv->ule_dbit) { | ||
655 | /* | ||
656 | * The destination MAC address is the | ||
657 | * next data in the skb. It comes | ||
658 | * before any extension headers. | ||
659 | * | ||
660 | * Check if the payload of this SNDU | ||
661 | * should be passed up the stack. | ||
662 | */ | ||
663 | register int drop = 0; | ||
664 | if (priv->rx_mode != RX_MODE_PROMISC) { | ||
665 | if (priv->ule_skb->data[0] & 0x01) { | ||
666 | /* multicast or broadcast */ | ||
667 | if (memcmp(priv->ule_skb->data, bc_addr, ETH_ALEN)) { | ||
668 | /* multicast */ | ||
669 | if (priv->rx_mode == RX_MODE_MULTI) { | ||
670 | int i; | ||
671 | for(i = 0; i < priv->multi_num && memcmp(priv->ule_skb->data, priv->multi_macs[i], ETH_ALEN); i++) | ||
672 | ; | ||
673 | if (i == priv->multi_num) | ||
674 | drop = 1; | ||
675 | } else if (priv->rx_mode != RX_MODE_ALL_MULTI) | ||
676 | drop = 1; /* no broadcast; */ | ||
677 | /* else: all multicast mode: accept all multicast packets */ | ||
678 | } | ||
679 | /* else: broadcast */ | ||
680 | } | ||
681 | else if (memcmp(priv->ule_skb->data, dev->dev_addr, ETH_ALEN)) | ||
682 | drop = 1; | ||
683 | /* else: destination address matches the MAC address of our receiver device */ | ||
684 | } | ||
685 | /* else: promiscious mode; pass everything up the stack */ | ||
686 | |||
687 | if (drop) { | ||
688 | #ifdef ULE_DEBUG | ||
689 | dprintk("Dropping SNDU: MAC destination address does not match: dest addr: "MAC_ADDR_PRINTFMT", dev addr: "MAC_ADDR_PRINTFMT"\n", | ||
690 | MAX_ADDR_PRINTFMT_ARGS(priv->ule_skb->data), MAX_ADDR_PRINTFMT_ARGS(dev->dev_addr)); | ||
691 | #endif | ||
692 | dev_kfree_skb(priv->ule_skb); | ||
693 | goto sndu_done; | ||
694 | } | ||
695 | else | ||
696 | { | ||
697 | memcpy(dest_addr, priv->ule_skb->data, ETH_ALEN); | ||
698 | skb_pull(priv->ule_skb, ETH_ALEN); | ||
699 | } | ||
700 | } | ||
701 | |||
616 | /* Handle ULE Extension Headers. */ | 702 | /* Handle ULE Extension Headers. */ |
617 | if (priv->ule_sndu_type < 1536) { | 703 | if (priv->ule_sndu_type < 1536) { |
618 | /* There is an extension header. Handle it accordingly. */ | 704 | /* There is an extension header. Handle it accordingly. */ |
619 | int l = handle_ule_extensions( priv ); | 705 | int l = handle_ule_extensions(priv); |
620 | if (l < 0) { | 706 | if (l < 0) { |
621 | /* Mandatory extension header unknown or TEST SNDU. Drop it. */ | 707 | /* Mandatory extension header unknown or TEST SNDU. Drop it. */ |
622 | // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" ); | 708 | // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" ); |
623 | dev_kfree_skb( priv->ule_skb ); | 709 | dev_kfree_skb(priv->ule_skb); |
624 | goto sndu_done; | 710 | goto sndu_done; |
625 | } | 711 | } |
626 | skb_pull( priv->ule_skb, l ); | 712 | skb_pull(priv->ule_skb, l); |
627 | } | 713 | } |
628 | 714 | ||
629 | /* CRC32 was OK. Remove it from skb. */ | 715 | /* |
630 | priv->ule_skb->tail -= 4; | 716 | * Construct/assure correct ethernet header. |
631 | priv->ule_skb->len -= 4; | 717 | * Note: in bridged mode (priv->ule_bridged != |
632 | 718 | * 0) we already have the (original) ethernet | |
633 | /* Filter on receiver's destination MAC address, if present. */ | 719 | * header at the start of the payload (after |
634 | if (!priv->ule_dbit) { | 720 | * optional dest. address and any extension |
635 | /* The destination MAC address is the next data in the skb. */ | 721 | * headers). |
636 | if (memcmp( priv->ule_skb->data, dev->dev_addr, ETH_ALEN )) { | 722 | */ |
637 | /* MAC addresses don't match. Drop SNDU. */ | 723 | |
638 | // printk( KERN_WARNING "Dropping SNDU, MAC address.\n" ); | 724 | if (!priv->ule_bridged) { |
639 | dev_kfree_skb( priv->ule_skb ); | 725 | skb_push(priv->ule_skb, ETH_HLEN); |
640 | goto sndu_done; | 726 | ethh = (struct ethhdr *)priv->ule_skb->data; |
641 | } | 727 | if (!priv->ule_dbit) { |
642 | if (! priv->ule_bridged) { | 728 | /* dest_addr buffer is only valid if priv->ule_dbit == 0 */ |
643 | skb_push( priv->ule_skb, ETH_ALEN + 2 ); | 729 | memcpy(ethh->h_dest, dest_addr, ETH_ALEN); |
644 | ethh = (struct ethhdr *)priv->ule_skb->data; | 730 | memset(ethh->h_source, 0, ETH_ALEN); |
645 | memcpy( ethh->h_dest, ethh->h_source, ETH_ALEN ); | ||
646 | memset( ethh->h_source, 0, ETH_ALEN ); | ||
647 | ethh->h_proto = htons( priv->ule_sndu_type ); | ||
648 | } else { | ||
649 | /* Skip the Receiver destination MAC address. */ | ||
650 | skb_pull( priv->ule_skb, ETH_ALEN ); | ||
651 | } | ||
652 | } else { | ||
653 | if (! priv->ule_bridged) { | ||
654 | skb_push( priv->ule_skb, ETH_HLEN ); | ||
655 | ethh = (struct ethhdr *)priv->ule_skb->data; | ||
656 | memcpy( ethh->h_dest, dev->dev_addr, ETH_ALEN ); | ||
657 | memset( ethh->h_source, 0, ETH_ALEN ); | ||
658 | ethh->h_proto = htons( priv->ule_sndu_type ); | ||
659 | } else { | ||
660 | /* skb is in correct state; nothing to do. */ | ||
661 | } | 731 | } |
732 | else /* zeroize source and dest */ | ||
733 | memset( ethh, 0, ETH_ALEN*2 ); | ||
734 | |||
735 | ethh->h_proto = htons(priv->ule_sndu_type); | ||
662 | } | 736 | } |
737 | /* else: skb is in correct state; nothing to do. */ | ||
663 | priv->ule_bridged = 0; | 738 | priv->ule_bridged = 0; |
664 | 739 | ||
665 | /* Stuff into kernel's protocol stack. */ | 740 | /* Stuff into kernel's protocol stack. */ |
@@ -668,8 +743,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
668 | * receive the packet anyhow. */ | 743 | * receive the packet anyhow. */ |
669 | /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) | 744 | /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) |
670 | priv->ule_skb->pkt_type = PACKET_HOST; */ | 745 | priv->ule_skb->pkt_type = PACKET_HOST; */ |
671 | ((struct dvb_net_priv *) dev->priv)->stats.rx_packets++; | 746 | priv->stats.rx_packets++; |
672 | ((struct dvb_net_priv *) dev->priv)->stats.rx_bytes += priv->ule_skb->len; | 747 | priv->stats.rx_bytes += priv->ule_skb->len; |
673 | netif_rx(priv->ule_skb); | 748 | netif_rx(priv->ule_skb); |
674 | } | 749 | } |
675 | sndu_done: | 750 | sndu_done: |
@@ -944,7 +1019,7 @@ static int dvb_net_feed_start(struct net_device *dev) | |||
944 | dprintk("%s: start filtering\n", __FUNCTION__); | 1019 | dprintk("%s: start filtering\n", __FUNCTION__); |
945 | priv->secfeed->start_filtering(priv->secfeed); | 1020 | priv->secfeed->start_filtering(priv->secfeed); |
946 | } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { | 1021 | } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { |
947 | struct timespec timeout = { 0, 30000000 }; // 30 msec | 1022 | struct timespec timeout = { 0, 10000000 }; // 10 msec |
948 | 1023 | ||
949 | /* we have payloads encapsulated in TS */ | 1024 | /* we have payloads encapsulated in TS */ |
950 | dprintk("%s: alloc tsfeed\n", __FUNCTION__); | 1025 | dprintk("%s: alloc tsfeed\n", __FUNCTION__); |
@@ -956,10 +1031,13 @@ static int dvb_net_feed_start(struct net_device *dev) | |||
956 | 1031 | ||
957 | /* Set netdevice pointer for ts decaps callback. */ | 1032 | /* Set netdevice pointer for ts decaps callback. */ |
958 | priv->tsfeed->priv = (void *)dev; | 1033 | priv->tsfeed->priv = (void *)dev; |
959 | ret = priv->tsfeed->set(priv->tsfeed, priv->pid, | 1034 | ret = priv->tsfeed->set(priv->tsfeed, |
960 | TS_PACKET, DMX_TS_PES_OTHER, | 1035 | priv->pid, /* pid */ |
1036 | TS_PACKET, /* type */ | ||
1037 | DMX_TS_PES_OTHER, /* pes type */ | ||
961 | 32768, /* circular buffer size */ | 1038 | 32768, /* circular buffer size */ |
962 | timeout); | 1039 | timeout /* timeout */ |
1040 | ); | ||
963 | 1041 | ||
964 | if (ret < 0) { | 1042 | if (ret < 0) { |
965 | printk("%s: could not set ts feed\n", dev->name); | 1043 | printk("%s: could not set ts feed\n", dev->name); |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 3852430d0260..134c2bbbeeb5 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -236,7 +236,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | |||
236 | "dvb/adapter%d/%s%d", adap->num, dnames[type], id); | 236 | "dvb/adapter%d/%s%d", adap->num, dnames[type], id); |
237 | 237 | ||
238 | class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), | 238 | class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), |
239 | NULL, "dvb%d.%s%d", adap->num, dnames[type], id); | 239 | adap->device, "dvb%d.%s%d", adap->num, dnames[type], id); |
240 | 240 | ||
241 | dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", | 241 | dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", |
242 | adap->num, dnames[type], id, nums2minor(adap->num, type, id), | 242 | adap->num, dnames[type], id, nums2minor(adap->num, type, id), |
@@ -285,7 +285,7 @@ skip: | |||
285 | } | 285 | } |
286 | 286 | ||
287 | 287 | ||
288 | int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module) | 288 | int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module, struct device *device) |
289 | { | 289 | { |
290 | int num; | 290 | int num; |
291 | 291 | ||
@@ -306,6 +306,7 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu | |||
306 | adap->num = num; | 306 | adap->num = num; |
307 | adap->name = name; | 307 | adap->name = name; |
308 | adap->module = module; | 308 | adap->module = module; |
309 | adap->device = device; | ||
309 | 310 | ||
310 | list_add_tail (&adap->list_head, &dvb_adapter_list); | 311 | list_add_tail (&adap->list_head, &dvb_adapter_list); |
311 | 312 | ||
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 74ed5853f0fb..d7a976d040d7 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -51,6 +51,8 @@ struct dvb_adapter { | |||
51 | u8 proposed_mac [6]; | 51 | u8 proposed_mac [6]; |
52 | void* priv; | 52 | void* priv; |
53 | 53 | ||
54 | struct device *device; | ||
55 | |||
54 | struct module *module; | 56 | struct module *module; |
55 | }; | 57 | }; |
56 | 58 | ||
@@ -76,7 +78,7 @@ struct dvb_device { | |||
76 | }; | 78 | }; |
77 | 79 | ||
78 | 80 | ||
79 | extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module); | 81 | extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module, struct device *device); |
80 | extern int dvb_unregister_adapter (struct dvb_adapter *adap); | 82 | extern int dvb_unregister_adapter (struct dvb_adapter *adap); |
81 | 83 | ||
82 | extern int dvb_register_device (struct dvb_adapter *adap, | 84 | extern int dvb_register_device (struct dvb_adapter *adap, |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index e388fb1567d6..3bc6722a6443 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -88,6 +88,7 @@ config DVB_USB_CXUSB | |||
88 | select DVB_CX22702 | 88 | select DVB_CX22702 |
89 | select DVB_LGDT330X | 89 | select DVB_LGDT330X |
90 | select DVB_MT352 | 90 | select DVB_MT352 |
91 | select DVB_ZL10353 | ||
91 | help | 92 | help |
92 | Say Y here to support the Conexant USB2.0 hybrid reference design. | 93 | Say Y here to support the Conexant USB2.0 hybrid reference design. |
93 | Currently, only DVB and ATSC modes are supported, analog mode | 94 | Currently, only DVB and ATSC modes are supported, analog mode |
@@ -130,6 +131,15 @@ config DVB_USB_VP702X | |||
130 | 131 | ||
131 | DVB-S USB2.0 receivers. | 132 | DVB-S USB2.0 receivers. |
132 | 133 | ||
134 | config DVB_USB_GP8PSK | ||
135 | tristate "GENPIX 8PSK->USB module support" | ||
136 | depends on DVB_USB | ||
137 | help | ||
138 | Say Y here to support the | ||
139 | GENPIX 8psk module | ||
140 | |||
141 | DVB-S USB2.0 receivers. | ||
142 | |||
133 | config DVB_USB_NOVA_T_USB2 | 143 | config DVB_USB_NOVA_T_USB2 |
134 | tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" | 144 | tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" |
135 | depends on DVB_USB | 145 | depends on DVB_USB |
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 2dc9aad9681e..9643f56c7fe9 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile | |||
@@ -7,6 +7,9 @@ obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o | |||
7 | dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o | 7 | dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o |
8 | obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o | 8 | obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o |
9 | 9 | ||
10 | dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o | ||
11 | obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o | ||
12 | |||
10 | dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o | 13 | dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o |
11 | obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o | 14 | obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o |
12 | 15 | ||
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 1f0d3e995c8d..ae23bdde42a8 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -27,8 +27,10 @@ | |||
27 | 27 | ||
28 | #include "cx22702.h" | 28 | #include "cx22702.h" |
29 | #include "lgdt330x.h" | 29 | #include "lgdt330x.h" |
30 | #include "lg_h06xf.h" | ||
30 | #include "mt352.h" | 31 | #include "mt352.h" |
31 | #include "mt352_priv.h" | 32 | #include "mt352_priv.h" |
33 | #include "zl10353.h" | ||
32 | 34 | ||
33 | /* debug */ | 35 | /* debug */ |
34 | int dvb_usb_cxusb_debug; | 36 | int dvb_usb_cxusb_debug; |
@@ -322,32 +324,37 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe) | |||
322 | return 0; | 324 | return 0; |
323 | } | 325 | } |
324 | 326 | ||
327 | static int cxusb_lgh064f_tuner_set_params(struct dvb_frontend *fe, | ||
328 | struct dvb_frontend_parameters *fep) | ||
329 | { | ||
330 | struct dvb_usb_device *d = fe->dvb->priv; | ||
331 | return lg_h06xf_pll_set(fe, &d->i2c_adap, fep); | ||
332 | } | ||
333 | |||
325 | static struct cx22702_config cxusb_cx22702_config = { | 334 | static struct cx22702_config cxusb_cx22702_config = { |
326 | .demod_address = 0x63, | 335 | .demod_address = 0x63, |
327 | 336 | ||
328 | .output_mode = CX22702_PARALLEL_OUTPUT, | 337 | .output_mode = CX22702_PARALLEL_OUTPUT, |
329 | |||
330 | .pll_init = dvb_usb_pll_init_i2c, | ||
331 | .pll_set = dvb_usb_pll_set_i2c, | ||
332 | }; | 338 | }; |
333 | 339 | ||
334 | static struct lgdt330x_config cxusb_lgdt3303_config = { | 340 | static struct lgdt330x_config cxusb_lgdt3303_config = { |
335 | .demod_address = 0x0e, | 341 | .demod_address = 0x0e, |
336 | .demod_chip = LGDT3303, | 342 | .demod_chip = LGDT3303, |
337 | .pll_set = dvb_usb_pll_set_i2c, | ||
338 | }; | 343 | }; |
339 | 344 | ||
340 | static struct mt352_config cxusb_dee1601_config = { | 345 | static struct mt352_config cxusb_dee1601_config = { |
341 | .demod_address = 0x0f, | 346 | .demod_address = 0x0f, |
342 | .demod_init = cxusb_dee1601_demod_init, | 347 | .demod_init = cxusb_dee1601_demod_init, |
343 | .pll_set = dvb_usb_pll_set, | ||
344 | }; | 348 | }; |
345 | 349 | ||
346 | struct mt352_config cxusb_mt352_config = { | 350 | static struct zl10353_config cxusb_zl10353_dee1601_config = { |
351 | .demod_address = 0x0f, | ||
352 | }; | ||
353 | |||
354 | static struct mt352_config cxusb_mt352_config = { | ||
347 | /* used in both lgz201 and th7579 */ | 355 | /* used in both lgz201 and th7579 */ |
348 | .demod_address = 0x0f, | 356 | .demod_address = 0x0f, |
349 | .demod_init = cxusb_mt352_demod_init, | 357 | .demod_init = cxusb_mt352_demod_init, |
350 | .pll_set = dvb_usb_pll_set, | ||
351 | }; | 358 | }; |
352 | 359 | ||
353 | /* Callbacks for DVB USB */ | 360 | /* Callbacks for DVB USB */ |
@@ -357,17 +364,10 @@ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d) | |||
357 | d->pll_addr = 0x61; | 364 | d->pll_addr = 0x61; |
358 | memcpy(d->pll_init, bpll, 4); | 365 | memcpy(d->pll_init, bpll, 4); |
359 | d->pll_desc = &dvb_pll_fmd1216me; | 366 | d->pll_desc = &dvb_pll_fmd1216me; |
360 | return 0; | ||
361 | } | ||
362 | 367 | ||
363 | static int cxusb_lgh064f_tuner_attach(struct dvb_usb_device *d) | 368 | d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; |
364 | { | 369 | d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; |
365 | u8 bpll[4] = { 0x00, 0x00, 0x18, 0x50 }; | 370 | |
366 | /* bpll[2] : unset bit 3, set bits 4&5 | ||
367 | bpll[3] : 0x50 - digital, 0x20 - analog */ | ||
368 | d->pll_addr = 0x61; | ||
369 | memcpy(d->pll_init, bpll, 4); | ||
370 | d->pll_desc = &dvb_pll_tdvs_tua6034; | ||
371 | return 0; | 371 | return 0; |
372 | } | 372 | } |
373 | 373 | ||
@@ -375,6 +375,7 @@ static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d) | |||
375 | { | 375 | { |
376 | d->pll_addr = 0x61; | 376 | d->pll_addr = 0x61; |
377 | d->pll_desc = &dvb_pll_thomson_dtt7579; | 377 | d->pll_desc = &dvb_pll_thomson_dtt7579; |
378 | d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; | ||
378 | return 0; | 379 | return 0; |
379 | } | 380 | } |
380 | 381 | ||
@@ -382,6 +383,7 @@ static int cxusb_lgz201_tuner_attach(struct dvb_usb_device *d) | |||
382 | { | 383 | { |
383 | d->pll_addr = 0x61; | 384 | d->pll_addr = 0x61; |
384 | d->pll_desc = &dvb_pll_lg_z201; | 385 | d->pll_desc = &dvb_pll_lg_z201; |
386 | d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; | ||
385 | return 0; | 387 | return 0; |
386 | } | 388 | } |
387 | 389 | ||
@@ -389,6 +391,13 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_device *d) | |||
389 | { | 391 | { |
390 | d->pll_addr = 0x60; | 392 | d->pll_addr = 0x60; |
391 | d->pll_desc = &dvb_pll_thomson_dtt7579; | 393 | d->pll_desc = &dvb_pll_thomson_dtt7579; |
394 | d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int cxusb_lgdt3303_tuner_attach(struct dvb_usb_device *d) | ||
399 | { | ||
400 | d->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params; | ||
392 | return 0; | 401 | return 0; |
393 | } | 402 | } |
394 | 403 | ||
@@ -439,7 +448,8 @@ static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d) | |||
439 | 448 | ||
440 | cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); | 449 | cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); |
441 | 450 | ||
442 | if ((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) | 451 | if (((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) || |
452 | ((d->fe = zl10353_attach(&cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL)) | ||
443 | return 0; | 453 | return 0; |
444 | 454 | ||
445 | return -EIO; | 455 | return -EIO; |
@@ -555,7 +565,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = { | |||
555 | .streaming_ctrl = cxusb_streaming_ctrl, | 565 | .streaming_ctrl = cxusb_streaming_ctrl, |
556 | .power_ctrl = cxusb_bluebird_power_ctrl, | 566 | .power_ctrl = cxusb_bluebird_power_ctrl, |
557 | .frontend_attach = cxusb_lgdt3303_frontend_attach, | 567 | .frontend_attach = cxusb_lgdt3303_frontend_attach, |
558 | .tuner_attach = cxusb_lgh064f_tuner_attach, | 568 | .tuner_attach = cxusb_lgdt3303_tuner_attach, |
559 | 569 | ||
560 | .i2c_algo = &cxusb_i2c_algo, | 570 | .i2c_algo = &cxusb_i2c_algo, |
561 | 571 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 2d52b76671d3..abd75b4a350d 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c | |||
@@ -173,11 +173,10 @@ int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) | |||
173 | struct dib3000_config demod_cfg; | 173 | struct dib3000_config demod_cfg; |
174 | struct dibusb_state *st = d->priv; | 174 | struct dibusb_state *st = d->priv; |
175 | 175 | ||
176 | demod_cfg.pll_set = dvb_usb_pll_set_i2c; | ||
177 | demod_cfg.pll_init = dvb_usb_pll_init_i2c; | ||
178 | |||
179 | for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) | 176 | for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) |
180 | if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { | 177 | if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { |
178 | d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; | ||
179 | d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; | ||
181 | d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; | 180 | d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; |
182 | return 0; | 181 | return 0; |
183 | } | 182 | } |
@@ -190,6 +189,10 @@ int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d) | |||
190 | { | 189 | { |
191 | d->pll_addr = 0x60; | 190 | d->pll_addr = 0x60; |
192 | d->pll_desc = &dvb_pll_env57h1xd5; | 191 | d->pll_desc = &dvb_pll_env57h1xd5; |
192 | |||
193 | d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; | ||
194 | d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; | ||
195 | |||
193 | return 0; | 196 | return 0; |
194 | } | 197 | } |
195 | EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); | 198 | EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); |
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index dd5a13195886..f4c45f386ebc 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c | |||
@@ -20,11 +20,12 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) | |||
20 | struct dibusb_state *st = d->priv; | 20 | struct dibusb_state *st = d->priv; |
21 | 21 | ||
22 | demod_cfg.demod_address = 0x8; | 22 | demod_cfg.demod_address = 0x8; |
23 | demod_cfg.pll_set = dvb_usb_pll_set_i2c; | ||
24 | demod_cfg.pll_init = dvb_usb_pll_init_i2c; | ||
25 | 23 | ||
26 | if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) | 24 | if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) { |
25 | d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; | ||
26 | d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; | ||
27 | return -ENODEV; | 27 | return -ENODEV; |
28 | } | ||
28 | 29 | ||
29 | d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; | 30 | d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; |
30 | 31 | ||
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 91136c00ce9d..c14d9efb48fd 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
@@ -112,27 +112,30 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe) | |||
112 | 112 | ||
113 | static struct mt352_config digitv_mt352_config = { | 113 | static struct mt352_config digitv_mt352_config = { |
114 | .demod_init = digitv_mt352_demod_init, | 114 | .demod_init = digitv_mt352_demod_init, |
115 | .pll_set = dvb_usb_pll_set, | ||
116 | }; | 115 | }; |
117 | 116 | ||
118 | static int digitv_nxt6000_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | 117 | static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) |
119 | { | 118 | { |
120 | struct dvb_usb_device *d = fe->dvb->priv; | 119 | struct dvb_usb_device *d = fe->dvb->priv; |
121 | u8 b[5]; | 120 | u8 b[5]; |
122 | dvb_usb_pll_set(fe,fep,b); | 121 | dvb_usb_tuner_calc_regs(fe,fep,b, 5); |
123 | return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0); | 122 | return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0); |
124 | } | 123 | } |
125 | 124 | ||
126 | static struct nxt6000_config digitv_nxt6000_config = { | 125 | static struct nxt6000_config digitv_nxt6000_config = { |
127 | .clock_inversion = 1, | 126 | .clock_inversion = 1, |
128 | .pll_set = digitv_nxt6000_pll_set, | ||
129 | }; | 127 | }; |
130 | 128 | ||
131 | static int digitv_frontend_attach(struct dvb_usb_device *d) | 129 | static int digitv_frontend_attach(struct dvb_usb_device *d) |
132 | { | 130 | { |
133 | if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL || | 131 | if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL) { |
134 | (d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) | 132 | d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; |
135 | return 0; | 133 | return 0; |
134 | } | ||
135 | if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) { | ||
136 | d->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params; | ||
137 | return 0; | ||
138 | } | ||
136 | return -EIO; | 139 | return -EIO; |
137 | } | 140 | } |
138 | 141 | ||
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c index cd21ddbfd054..17413adec7a1 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c | |||
@@ -18,7 +18,6 @@ struct dtt200u_fe_state { | |||
18 | 18 | ||
19 | struct dvb_frontend_parameters fep; | 19 | struct dvb_frontend_parameters fep; |
20 | struct dvb_frontend frontend; | 20 | struct dvb_frontend frontend; |
21 | struct dvb_frontend_ops ops; | ||
22 | }; | 21 | }; |
23 | 22 | ||
24 | static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) | 23 | static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) |
@@ -163,16 +162,13 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d) | |||
163 | deb_info("attaching frontend dtt200u\n"); | 162 | deb_info("attaching frontend dtt200u\n"); |
164 | 163 | ||
165 | state->d = d; | 164 | state->d = d; |
166 | memcpy(&state->ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops)); | ||
167 | 165 | ||
168 | state->frontend.ops = &state->ops; | 166 | memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops)); |
169 | state->frontend.demodulator_priv = state; | 167 | state->frontend.demodulator_priv = state; |
170 | 168 | ||
171 | goto success; | 169 | return &state->frontend; |
172 | error: | 170 | error: |
173 | return NULL; | 171 | return NULL; |
174 | success: | ||
175 | return &state->frontend; | ||
176 | } | 172 | } |
177 | 173 | ||
178 | static struct dvb_frontend_ops dtt200u_fe_ops = { | 174 | static struct dvb_frontend_ops dtt200u_fe_ops = { |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index 6fa92100248b..ec631708c394 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c | |||
@@ -82,7 +82,7 @@ int dvb_usb_dvb_init(struct dvb_usb_device *d) | |||
82 | int ret; | 82 | int ret; |
83 | 83 | ||
84 | if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name, | 84 | if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name, |
85 | d->owner)) < 0) { | 85 | d->owner, &d->udev->dev)) < 0) { |
86 | deb_info("dvb_register_adapter failed: error %d", ret); | 86 | deb_info("dvb_register_adapter failed: error %d", ret); |
87 | goto err; | 87 | goto err; |
88 | } | 88 | } |
@@ -121,16 +121,15 @@ int dvb_usb_dvb_init(struct dvb_usb_device *d) | |||
121 | 121 | ||
122 | dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx); | 122 | dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx); |
123 | 123 | ||
124 | goto success; | 124 | d->state |= DVB_USB_STATE_DVB; |
125 | return 0; | ||
126 | |||
125 | err_dmx_dev: | 127 | err_dmx_dev: |
126 | dvb_dmx_release(&d->demux); | 128 | dvb_dmx_release(&d->demux); |
127 | err_dmx: | 129 | err_dmx: |
128 | dvb_unregister_adapter(&d->dvb_adap); | 130 | dvb_unregister_adapter(&d->dvb_adap); |
129 | err: | 131 | err: |
130 | return ret; | 132 | return ret; |
131 | success: | ||
132 | d->state |= DVB_USB_STATE_DVB; | ||
133 | return 0; | ||
134 | } | 133 | } |
135 | 134 | ||
136 | int dvb_usb_dvb_exit(struct dvb_usb_device *d) | 135 | int dvb_usb_dvb_exit(struct dvb_usb_device *d) |
@@ -184,13 +183,13 @@ int dvb_usb_fe_init(struct dvb_usb_device* d) | |||
184 | 183 | ||
185 | /* re-assign sleep and wakeup functions */ | 184 | /* re-assign sleep and wakeup functions */ |
186 | if (d->fe != NULL) { | 185 | if (d->fe != NULL) { |
187 | d->fe_init = d->fe->ops->init; d->fe->ops->init = dvb_usb_fe_wakeup; | 186 | d->fe_init = d->fe->ops.init; d->fe->ops.init = dvb_usb_fe_wakeup; |
188 | d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep; | 187 | d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep; |
189 | 188 | ||
190 | if (dvb_register_frontend(&d->dvb_adap, d->fe)) { | 189 | if (dvb_register_frontend(&d->dvb_adap, d->fe)) { |
191 | err("Frontend registration failed."); | 190 | err("Frontend registration failed."); |
192 | if (d->fe->ops->release) | 191 | if (d->fe->ops.release) |
193 | d->fe->ops->release(d->fe); | 192 | d->fe->ops.release(d->fe); |
194 | d->fe = NULL; | 193 | d->fe = NULL; |
195 | return -ENODEV; | 194 | return -ENODEV; |
196 | } | 195 | } |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index 9b254532af4d..6b611a725093 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | |||
@@ -46,7 +46,7 @@ int dvb_usb_i2c_exit(struct dvb_usb_device *d) | |||
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
48 | 48 | ||
49 | int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) | 49 | int dvb_usb_tuner_init_i2c(struct dvb_frontend *fe) |
50 | { | 50 | { |
51 | struct dvb_usb_device *d = fe->dvb->priv; | 51 | struct dvb_usb_device *d = fe->dvb->priv; |
52 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; | 52 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; |
@@ -63,6 +63,8 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) | |||
63 | deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1], | 63 | deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1], |
64 | d->pll_init[2],d->pll_init[3]); | 64 | d->pll_init[2],d->pll_init[3]); |
65 | 65 | ||
66 | if (fe->ops.i2c_gate_ctrl) | ||
67 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
66 | if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { | 68 | if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { |
67 | err("tuner i2c write failed for pll_init."); | 69 | err("tuner i2c write failed for pll_init."); |
68 | ret = -EREMOTEIO; | 70 | ret = -EREMOTEIO; |
@@ -73,38 +75,42 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) | |||
73 | d->tuner_pass_ctrl(fe,0,d->pll_addr); | 75 | d->tuner_pass_ctrl(fe,0,d->pll_addr); |
74 | return ret; | 76 | return ret; |
75 | } | 77 | } |
76 | EXPORT_SYMBOL(dvb_usb_pll_init_i2c); | 78 | EXPORT_SYMBOL(dvb_usb_tuner_init_i2c); |
77 | 79 | ||
78 | int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5]) | 80 | int dvb_usb_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 *b, int buf_len) |
79 | { | 81 | { |
80 | struct dvb_usb_device *d = fe->dvb->priv; | 82 | struct dvb_usb_device *d = fe->dvb->priv; |
81 | 83 | ||
84 | if (buf_len != 5) | ||
85 | return -EINVAL; | ||
82 | if (d->pll_desc == NULL) | 86 | if (d->pll_desc == NULL) |
83 | return 0; | 87 | return 0; |
84 | 88 | ||
85 | deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); | 89 | deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); |
86 | 90 | ||
87 | b[0] = d->pll_addr << 1; | 91 | b[0] = d->pll_addr; |
88 | dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth); | 92 | dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth); |
89 | 93 | ||
90 | deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]); | 94 | deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]); |
91 | 95 | ||
92 | return 0; | 96 | return 5; |
93 | } | 97 | } |
94 | EXPORT_SYMBOL(dvb_usb_pll_set); | 98 | EXPORT_SYMBOL(dvb_usb_tuner_calc_regs); |
95 | 99 | ||
96 | int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | 100 | int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) |
97 | { | 101 | { |
98 | struct dvb_usb_device *d = fe->dvb->priv; | 102 | struct dvb_usb_device *d = fe->dvb->priv; |
99 | int ret = 0; | 103 | int ret = 0; |
100 | u8 b[5]; | 104 | u8 b[5]; |
101 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 }; | 105 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 }; |
102 | 106 | ||
103 | dvb_usb_pll_set(fe,fep,b); | 107 | dvb_usb_tuner_calc_regs(fe,fep,b,5); |
104 | 108 | ||
105 | if (d->tuner_pass_ctrl) | 109 | if (d->tuner_pass_ctrl) |
106 | d->tuner_pass_ctrl(fe,1,d->pll_addr); | 110 | d->tuner_pass_ctrl(fe,1,d->pll_addr); |
107 | 111 | ||
112 | if (fe->ops.i2c_gate_ctrl) | ||
113 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
108 | if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { | 114 | if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { |
109 | err("tuner i2c write failed for pll_set."); | 115 | err("tuner i2c write failed for pll_set."); |
110 | ret = -EREMOTEIO; | 116 | ret = -EREMOTEIO; |
@@ -116,4 +122,4 @@ int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters | |||
116 | 122 | ||
117 | return ret; | 123 | return ret; |
118 | } | 124 | } |
119 | EXPORT_SYMBOL(dvb_usb_pll_set_i2c); | 125 | EXPORT_SYMBOL(dvb_usb_tuner_set_params_i2c); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index cb239049b098..95698918bc11 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #define USB_VID_VISIONPLUS 0x13d3 | 31 | #define USB_VID_VISIONPLUS 0x13d3 |
32 | #define USB_VID_TWINHAN 0x1822 | 32 | #define USB_VID_TWINHAN 0x1822 |
33 | #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 | 33 | #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 |
34 | #define USB_VID_GENPIX 0x09c0 | ||
34 | 35 | ||
35 | /* Product IDs */ | 36 | /* Product IDs */ |
36 | #define USB_PID_ADSTECH_USB2_COLD 0xa333 | 37 | #define USB_PID_ADSTECH_USB2_COLD 0xa333 |
@@ -104,5 +105,6 @@ | |||
104 | #define USB_PID_KYE_DVB_T_WARM 0x701f | 105 | #define USB_PID_KYE_DVB_T_WARM 0x701f |
105 | #define USB_PID_PCTV_200E 0x020e | 106 | #define USB_PID_PCTV_200E 0x020e |
106 | #define USB_PID_PCTV_400E 0x020f | 107 | #define USB_PID_PCTV_400E 0x020f |
107 | 108 | #define USB_PID_GENPIX_8PSK_COLD 0x0200 | |
109 | #define USB_PID_GENPIX_8PSK_WARM 0x0201 | ||
108 | #endif | 110 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index fead958a57e3..4cf9f89c51bf 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
@@ -330,9 +330,9 @@ extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); | |||
330 | extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); | 330 | extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); |
331 | 331 | ||
332 | /* commonly used pll init and set functions */ | 332 | /* commonly used pll init and set functions */ |
333 | extern int dvb_usb_pll_init_i2c(struct dvb_frontend *); | 333 | extern int dvb_usb_tuner_init_i2c(struct dvb_frontend *); |
334 | extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); | 334 | extern int dvb_usb_tuner_calc_regs(struct dvb_frontend *, struct dvb_frontend_parameters *, u8 *buf, int buf_len); |
335 | extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); | 335 | extern int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); |
336 | 336 | ||
337 | /* commonly used firmware download types and function */ | 337 | /* commonly used firmware download types and function */ |
338 | struct hexline { | 338 | struct hexline { |
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c new file mode 100644 index 000000000000..6ccbdc9cd772 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* DVB USB compliant Linux driver for the | ||
2 | * - GENPIX 8pks/qpsk USB2.0 DVB-S module | ||
3 | * | ||
4 | * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com) | ||
5 | * | ||
6 | * Thanks to GENPIX for the sample code used to implement this module. | ||
7 | * | ||
8 | * This module is based off the vp7045 and vp702x modules | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the Free | ||
12 | * Software Foundation, version 2. | ||
13 | * | ||
14 | * see Documentation/dvb/README.dvb-usb for more information | ||
15 | */ | ||
16 | #include "gp8psk.h" | ||
17 | |||
18 | struct gp8psk_fe_state { | ||
19 | struct dvb_frontend fe; | ||
20 | |||
21 | struct dvb_usb_device *d; | ||
22 | |||
23 | u16 snr; | ||
24 | |||
25 | unsigned long next_snr_check; | ||
26 | }; | ||
27 | |||
28 | static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) | ||
29 | { | ||
30 | struct gp8psk_fe_state *st = fe->demodulator_priv; | ||
31 | u8 lock; | ||
32 | |||
33 | if (gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0, 0, &lock,1)) | ||
34 | return -EINVAL; | ||
35 | |||
36 | if (lock) | ||
37 | *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER; | ||
38 | else | ||
39 | *status = 0; | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | /* not supported by this Frontend */ | ||
45 | static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber) | ||
46 | { | ||
47 | (void) fe; | ||
48 | *ber = 0; | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | /* not supported by this Frontend */ | ||
53 | static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) | ||
54 | { | ||
55 | (void) fe; | ||
56 | *unc = 0; | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr) | ||
61 | { | ||
62 | struct gp8psk_fe_state *st = fe->demodulator_priv; | ||
63 | u8 buf[2]; | ||
64 | |||
65 | if (time_after(jiffies,st->next_snr_check)) { | ||
66 | gp8psk_usb_in_op(st->d,GET_SIGNAL_STRENGTH,0,0,buf,2); | ||
67 | *snr = (int)(buf[1]) << 8 | buf[0]; | ||
68 | /* snr is reported in dBu*256 */ | ||
69 | /* snr / 38.4 ~= 100% strength */ | ||
70 | /* snr * 17 returns 100% strength as 65535 */ | ||
71 | if (*snr <= 3855) | ||
72 | *snr = (*snr<<4) + *snr; // snr * 17 | ||
73 | else | ||
74 | *snr = 65535; | ||
75 | st->next_snr_check = jiffies + (10*HZ)/1000; | ||
76 | } else { | ||
77 | *snr = st->snr; | ||
78 | } | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) | ||
83 | { | ||
84 | return gp8psk_fe_read_snr(fe, strength); | ||
85 | } | ||
86 | |||
87 | static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) | ||
88 | { | ||
89 | tune->min_delay_ms = 800; | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, | ||
94 | struct dvb_frontend_parameters *fep) | ||
95 | { | ||
96 | struct gp8psk_fe_state *state = fe->demodulator_priv; | ||
97 | u8 cmd[10]; | ||
98 | u32 freq = fep->frequency * 1000; | ||
99 | |||
100 | cmd[4] = freq & 0xff; | ||
101 | cmd[5] = (freq >> 8) & 0xff; | ||
102 | cmd[6] = (freq >> 16) & 0xff; | ||
103 | cmd[7] = (freq >> 24) & 0xff; | ||
104 | |||
105 | switch(fe->ops.info.type) { | ||
106 | case FE_QPSK: | ||
107 | cmd[0] = fep->u.qpsk.symbol_rate & 0xff; | ||
108 | cmd[1] = (fep->u.qpsk.symbol_rate >> 8) & 0xff; | ||
109 | cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff; | ||
110 | cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff; | ||
111 | cmd[8] = ADV_MOD_DVB_QPSK; | ||
112 | cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/ | ||
113 | break; | ||
114 | default: | ||
115 | // other modes are unsuported right now | ||
116 | cmd[0] = 0; | ||
117 | cmd[1] = 0; | ||
118 | cmd[2] = 0; | ||
119 | cmd[3] = 0; | ||
120 | cmd[8] = 0; | ||
121 | cmd[9] = 0; | ||
122 | break; | ||
123 | } | ||
124 | |||
125 | gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10); | ||
126 | |||
127 | state->next_snr_check = jiffies; | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int gp8psk_fe_get_frontend(struct dvb_frontend* fe, | ||
133 | struct dvb_frontend_parameters *fep) | ||
134 | { | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | |||
139 | static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe, | ||
140 | struct dvb_diseqc_master_cmd *m) | ||
141 | { | ||
142 | struct gp8psk_fe_state *st = fe->demodulator_priv; | ||
143 | |||
144 | deb_fe("%s\n",__FUNCTION__); | ||
145 | |||
146 | if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0, | ||
147 | m->msg, m->msg_len)) { | ||
148 | return -EINVAL; | ||
149 | } | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe, | ||
154 | fe_sec_mini_cmd_t burst) | ||
155 | { | ||
156 | struct gp8psk_fe_state *st = fe->demodulator_priv; | ||
157 | u8 cmd; | ||
158 | |||
159 | deb_fe("%s\n",__FUNCTION__); | ||
160 | |||
161 | /* These commands are certainly wrong */ | ||
162 | cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01; | ||
163 | |||
164 | if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0, | ||
165 | &cmd, 0)) { | ||
166 | return -EINVAL; | ||
167 | } | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
172 | { | ||
173 | struct gp8psk_fe_state* state = fe->demodulator_priv; | ||
174 | |||
175 | if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE, | ||
176 | (tone == SEC_TONE_ON), 0, NULL, 0)) { | ||
177 | return -EINVAL; | ||
178 | } | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
183 | { | ||
184 | struct gp8psk_fe_state* state = fe->demodulator_priv; | ||
185 | |||
186 | if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, | ||
187 | voltage == SEC_VOLTAGE_18, 0, NULL, 0)) { | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd) | ||
194 | { | ||
195 | struct gp8psk_fe_state* state = fe->demodulator_priv; | ||
196 | u8 cmd = sw_cmd & 0x7f; | ||
197 | |||
198 | if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0, | ||
199 | NULL, 0)) { | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80), | ||
203 | 0, NULL, 0)) { | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static void gp8psk_fe_release(struct dvb_frontend* fe) | ||
211 | { | ||
212 | struct gp8psk_fe_state *state = fe->demodulator_priv; | ||
213 | kfree(state); | ||
214 | } | ||
215 | |||
216 | static struct dvb_frontend_ops gp8psk_fe_ops; | ||
217 | |||
218 | struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d) | ||
219 | { | ||
220 | struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL); | ||
221 | if (s == NULL) | ||
222 | goto error; | ||
223 | |||
224 | s->d = d; | ||
225 | memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops)); | ||
226 | s->fe.demodulator_priv = s; | ||
227 | |||
228 | goto success; | ||
229 | error: | ||
230 | return NULL; | ||
231 | success: | ||
232 | return &s->fe; | ||
233 | } | ||
234 | |||
235 | |||
236 | static struct dvb_frontend_ops gp8psk_fe_ops = { | ||
237 | .info = { | ||
238 | .name = "Genpix 8psk-USB DVB-S", | ||
239 | .type = FE_QPSK, | ||
240 | .frequency_min = 950000, | ||
241 | .frequency_max = 2150000, | ||
242 | .frequency_stepsize = 100, | ||
243 | .symbol_rate_min = 1000000, | ||
244 | .symbol_rate_max = 45000000, | ||
245 | .symbol_rate_tolerance = 500, /* ppm */ | ||
246 | .caps = FE_CAN_INVERSION_AUTO | | ||
247 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
248 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
249 | FE_CAN_QPSK | ||
250 | }, | ||
251 | |||
252 | .release = gp8psk_fe_release, | ||
253 | |||
254 | .init = NULL, | ||
255 | .sleep = NULL, | ||
256 | |||
257 | .set_frontend = gp8psk_fe_set_frontend, | ||
258 | .get_frontend = gp8psk_fe_get_frontend, | ||
259 | .get_tune_settings = gp8psk_fe_get_tune_settings, | ||
260 | |||
261 | .read_status = gp8psk_fe_read_status, | ||
262 | .read_ber = gp8psk_fe_read_ber, | ||
263 | .read_signal_strength = gp8psk_fe_read_signal_strength, | ||
264 | .read_snr = gp8psk_fe_read_snr, | ||
265 | .read_ucblocks = gp8psk_fe_read_unc_blocks, | ||
266 | |||
267 | .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg, | ||
268 | .diseqc_send_burst = gp8psk_fe_send_diseqc_burst, | ||
269 | .set_tone = gp8psk_fe_set_tone, | ||
270 | .set_voltage = gp8psk_fe_set_voltage, | ||
271 | .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd, | ||
272 | }; | ||
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c new file mode 100644 index 000000000000..9a98f3fdae31 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/gp8psk.c | |||
@@ -0,0 +1,256 @@ | |||
1 | /* DVB USB compliant Linux driver for the | ||
2 | * - GENPIX 8pks/qpsk USB2.0 DVB-S module | ||
3 | * | ||
4 | * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com) | ||
5 | * | ||
6 | * Thanks to GENPIX for the sample code used to implement this module. | ||
7 | * | ||
8 | * This module is based off the vp7045 and vp702x modules | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the Free | ||
12 | * Software Foundation, version 2. | ||
13 | * | ||
14 | * see Documentation/dvb/README.dvb-usb for more information | ||
15 | */ | ||
16 | #include "gp8psk.h" | ||
17 | |||
18 | /* debug */ | ||
19 | static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw"; | ||
20 | int dvb_usb_gp8psk_debug; | ||
21 | module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644); | ||
22 | MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); | ||
23 | |||
24 | int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) | ||
25 | { | ||
26 | int ret = 0,try = 0; | ||
27 | |||
28 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) | ||
29 | return ret; | ||
30 | |||
31 | while (ret >= 0 && ret != blen && try < 3) { | ||
32 | ret = usb_control_msg(d->udev, | ||
33 | usb_rcvctrlpipe(d->udev,0), | ||
34 | req, | ||
35 | USB_TYPE_VENDOR | USB_DIR_IN, | ||
36 | value,index,b,blen, | ||
37 | 2000); | ||
38 | deb_info("reading number %d (ret: %d)\n",try,ret); | ||
39 | try++; | ||
40 | } | ||
41 | |||
42 | if (ret < 0 || ret != blen) { | ||
43 | warn("usb in operation failed."); | ||
44 | ret = -EIO; | ||
45 | } else | ||
46 | ret = 0; | ||
47 | |||
48 | deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index); | ||
49 | debug_dump(b,blen,deb_xfer); | ||
50 | |||
51 | mutex_unlock(&d->usb_mutex); | ||
52 | |||
53 | return ret; | ||
54 | } | ||
55 | |||
56 | int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, | ||
57 | u16 index, u8 *b, int blen) | ||
58 | { | ||
59 | int ret; | ||
60 | |||
61 | deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index); | ||
62 | debug_dump(b,blen,deb_xfer); | ||
63 | |||
64 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) | ||
65 | return ret; | ||
66 | |||
67 | if (usb_control_msg(d->udev, | ||
68 | usb_sndctrlpipe(d->udev,0), | ||
69 | req, | ||
70 | USB_TYPE_VENDOR | USB_DIR_OUT, | ||
71 | value,index,b,blen, | ||
72 | 2000) != blen) { | ||
73 | warn("usb out operation failed."); | ||
74 | ret = -EIO; | ||
75 | } else | ||
76 | ret = 0; | ||
77 | mutex_unlock(&d->usb_mutex); | ||
78 | |||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d) | ||
83 | { | ||
84 | int ret; | ||
85 | const struct firmware *fw = NULL; | ||
86 | u8 *ptr, *buf; | ||
87 | if ((ret = request_firmware(&fw, bcm4500_firmware, | ||
88 | &d->udev->dev)) != 0) { | ||
89 | err("did not find the bcm4500 firmware file. (%s) " | ||
90 | "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", | ||
91 | bcm4500_firmware,ret); | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | ret = -EINVAL; | ||
96 | |||
97 | if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0)) | ||
98 | goto out_rel_fw; | ||
99 | |||
100 | info("downloaidng bcm4500 firmware from file '%s'",bcm4500_firmware); | ||
101 | |||
102 | ptr = fw->data; | ||
103 | buf = kmalloc(512, GFP_KERNEL | GFP_DMA); | ||
104 | |||
105 | while (ptr[0] != 0xff) { | ||
106 | u16 buflen = ptr[0] + 4; | ||
107 | if (ptr + buflen >= fw->data + fw->size) { | ||
108 | err("failed to load bcm4500 firmware."); | ||
109 | goto out_free; | ||
110 | } | ||
111 | memcpy(buf, ptr, buflen); | ||
112 | if (dvb_usb_generic_write(d, buf, buflen)) { | ||
113 | err("failed to load bcm4500 firmware."); | ||
114 | goto out_free; | ||
115 | } | ||
116 | ptr += buflen; | ||
117 | } | ||
118 | |||
119 | ret = 0; | ||
120 | |||
121 | out_free: | ||
122 | kfree(buf); | ||
123 | out_rel_fw: | ||
124 | release_firmware(fw); | ||
125 | |||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff) | ||
130 | { | ||
131 | u8 status, buf; | ||
132 | if (onoff) { | ||
133 | gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1); | ||
134 | if (! (status & 0x01)) /* started */ | ||
135 | if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1)) | ||
136 | return -EINVAL; | ||
137 | |||
138 | if (! (status & 0x02)) /* BCM4500 firmware loaded */ | ||
139 | if(gp8psk_load_bcm4500fw(d)) | ||
140 | return EINVAL; | ||
141 | |||
142 | if (! (status & 0x04)) /* LNB Power */ | ||
143 | if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0, | ||
144 | &buf, 1)) | ||
145 | return EINVAL; | ||
146 | |||
147 | /* Set DVB mode */ | ||
148 | if(gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0)) | ||
149 | return -EINVAL; | ||
150 | gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1); | ||
151 | } else { | ||
152 | /* Turn off LNB power */ | ||
153 | if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1)) | ||
154 | return EINVAL; | ||
155 | /* Turn off 8psk power */ | ||
156 | if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1)) | ||
157 | return -EINVAL; | ||
158 | |||
159 | } | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | |||
164 | static int gp8psk_streaming_ctrl(struct dvb_usb_device *d, int onoff) | ||
165 | { | ||
166 | return gp8psk_usb_out_op(d, ARM_TRANSFER, onoff, 0 , NULL, 0); | ||
167 | } | ||
168 | |||
169 | static int gp8psk_frontend_attach(struct dvb_usb_device *d) | ||
170 | { | ||
171 | d->fe = gp8psk_fe_attach(d); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static struct dvb_usb_properties gp8psk_properties; | ||
177 | |||
178 | static int gp8psk_usb_probe(struct usb_interface *intf, | ||
179 | const struct usb_device_id *id) | ||
180 | { | ||
181 | return dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL); | ||
182 | } | ||
183 | |||
184 | static struct usb_device_id gp8psk_usb_table [] = { | ||
185 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_COLD) }, | ||
186 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_WARM) }, | ||
187 | { 0 }, | ||
188 | }; | ||
189 | MODULE_DEVICE_TABLE(usb, gp8psk_usb_table); | ||
190 | |||
191 | static struct dvb_usb_properties gp8psk_properties = { | ||
192 | .caps = 0, | ||
193 | |||
194 | .usb_ctrl = CYPRESS_FX2, | ||
195 | .firmware = "dvb-usb-gp8psk-01.fw", | ||
196 | |||
197 | .streaming_ctrl = gp8psk_streaming_ctrl, | ||
198 | .power_ctrl = gp8psk_power_ctrl, | ||
199 | .frontend_attach = gp8psk_frontend_attach, | ||
200 | |||
201 | .generic_bulk_ctrl_endpoint = 0x01, | ||
202 | /* parameter for the MPEG2-data transfer */ | ||
203 | .urb = { | ||
204 | .type = DVB_USB_BULK, | ||
205 | .count = 7, | ||
206 | .endpoint = 0x82, | ||
207 | .u = { | ||
208 | .bulk = { | ||
209 | .buffersize = 8192, | ||
210 | } | ||
211 | } | ||
212 | }, | ||
213 | |||
214 | .num_device_descs = 1, | ||
215 | .devices = { | ||
216 | { .name = "Genpix 8PSK-USB DVB-S USB2.0 receiver", | ||
217 | .cold_ids = { &gp8psk_usb_table[0], NULL }, | ||
218 | .warm_ids = { &gp8psk_usb_table[1], NULL }, | ||
219 | }, | ||
220 | { 0 }, | ||
221 | } | ||
222 | }; | ||
223 | |||
224 | /* usb specific object needed to register this driver with the usb subsystem */ | ||
225 | static struct usb_driver gp8psk_usb_driver = { | ||
226 | .name = "dvb_usb_gp8psk", | ||
227 | .probe = gp8psk_usb_probe, | ||
228 | .disconnect = dvb_usb_device_exit, | ||
229 | .id_table = gp8psk_usb_table, | ||
230 | }; | ||
231 | |||
232 | /* module stuff */ | ||
233 | static int __init gp8psk_usb_module_init(void) | ||
234 | { | ||
235 | int result; | ||
236 | if ((result = usb_register(&gp8psk_usb_driver))) { | ||
237 | err("usb_register failed. (%d)",result); | ||
238 | return result; | ||
239 | } | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static void __exit gp8psk_usb_module_exit(void) | ||
245 | { | ||
246 | /* deregister this driver from the USB subsystem */ | ||
247 | usb_deregister(&gp8psk_usb_driver); | ||
248 | } | ||
249 | |||
250 | module_init(gp8psk_usb_module_init); | ||
251 | module_exit(gp8psk_usb_module_exit); | ||
252 | |||
253 | MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>"); | ||
254 | MODULE_DESCRIPTION("Driver for Genpix 8psk-USB DVB-S USB2.0"); | ||
255 | MODULE_VERSION("1.0"); | ||
256 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h new file mode 100644 index 000000000000..3eba7061011c --- /dev/null +++ b/drivers/media/dvb/dvb-usb/gp8psk.h | |||
@@ -0,0 +1,79 @@ | |||
1 | /* DVB USB compliant Linux driver for the | ||
2 | * - GENPIX 8pks/qpsk USB2.0 DVB-S module | ||
3 | * | ||
4 | * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com) | ||
5 | * | ||
6 | * Thanks to GENPIX for the sample code used to implement this module. | ||
7 | * | ||
8 | * This module is based off the vp7045 and vp702x modules | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the Free | ||
12 | * Software Foundation, version 2. | ||
13 | * | ||
14 | * see Documentation/dvb/README.dvb-usb for more information | ||
15 | */ | ||
16 | #ifndef _DVB_USB_GP8PSK_H_ | ||
17 | #define _DVB_USB_GP8PSK_H_ | ||
18 | |||
19 | #define DVB_USB_LOG_PREFIX "gp8psk" | ||
20 | #include "dvb-usb.h" | ||
21 | |||
22 | extern int dvb_usb_gp8psk_debug; | ||
23 | #define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args) | ||
24 | #define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args) | ||
25 | #define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args) | ||
26 | #define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args) | ||
27 | /* gp8psk commands */ | ||
28 | |||
29 | /* Twinhan Vendor requests */ | ||
30 | #define TH_COMMAND_IN 0xC0 | ||
31 | #define TH_COMMAND_OUT 0xC1 | ||
32 | |||
33 | /* command bytes */ | ||
34 | #define GET_8PSK_CONFIG 0x80 | ||
35 | #define SET_8PSK_CONFIG 0x81 | ||
36 | #define ARM_TRANSFER 0x85 | ||
37 | #define TUNE_8PSK 0x86 | ||
38 | #define GET_SIGNAL_STRENGTH 0x87 | ||
39 | #define LOAD_BCM4500 0x88 | ||
40 | #define BOOT_8PSK 0x89 | ||
41 | #define START_INTERSIL 0x8A | ||
42 | #define SET_LNB_VOLTAGE 0x8B | ||
43 | #define SET_22KHZ_TONE 0x8C | ||
44 | #define SEND_DISEQC_COMMAND 0x8D | ||
45 | #define SET_DVB_MODE 0x8E | ||
46 | #define SET_DN_SWITCH 0x8F | ||
47 | #define GET_SIGNAL_LOCK 0x90 | ||
48 | |||
49 | /* Satellite modulation modes */ | ||
50 | #define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */ | ||
51 | #define ADV_MOD_TURBO_QPSK 1 /* Turbo QPSK */ | ||
52 | #define ADV_MOD_TURBO_8PSK 2 /* Turbo 8PSK (also used for Trellis 8PSK) */ | ||
53 | #define ADV_MOD_TURBO_16QAM 3 /* Turbo 16QAM (also used for Trellis 8PSK) */ | ||
54 | |||
55 | #define ADV_MOD_DCII_C_QPSK 4 /* Digicipher II Combo */ | ||
56 | #define ADV_MOD_DCII_I_QPSK 5 /* Digicipher II I-stream */ | ||
57 | #define ADV_MOD_DCII_Q_QPSK 6 /* Digicipher II Q-stream */ | ||
58 | #define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */ | ||
59 | #define ADV_MOD_DSS_QPSK 8 /* DSS (DIRECTV) QPSK */ | ||
60 | #define ADV_MOD_DVB_BPSK 9 /* DVB-S BPSK */ | ||
61 | |||
62 | #define GET_USB_SPEED 0x07 | ||
63 | #define USB_SPEED_LOW 0 | ||
64 | #define USB_SPEED_FULL 1 | ||
65 | #define USB_SPEED_HIGH 2 | ||
66 | |||
67 | #define RESET_FX2 0x13 | ||
68 | |||
69 | #define FW_VERSION_READ 0x0B | ||
70 | #define VENDOR_STRING_READ 0x0C | ||
71 | #define PRODUCT_STRING_READ 0x0D | ||
72 | #define FW_BCD_VERSION_READ 0x14 | ||
73 | |||
74 | extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d); | ||
75 | extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); | ||
76 | extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, | ||
77 | u16 index, u8 *b, int blen); | ||
78 | |||
79 | #endif | ||
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c index 14f1911c79bb..97d74da0dad8 100644 --- a/drivers/media/dvb/dvb-usb/umt-010.c +++ b/drivers/media/dvb/dvb-usb/umt-010.c | |||
@@ -57,7 +57,6 @@ static int umt_mt352_frontend_attach(struct dvb_usb_device *d) | |||
57 | memset(&umt_config,0,sizeof(struct mt352_config)); | 57 | memset(&umt_config,0,sizeof(struct mt352_config)); |
58 | umt_config.demod_init = umt_mt352_demod_init; | 58 | umt_config.demod_init = umt_mt352_demod_init; |
59 | umt_config.demod_address = 0xf; | 59 | umt_config.demod_address = 0xf; |
60 | umt_config.pll_set = dvb_usb_pll_set; | ||
61 | 60 | ||
62 | d->fe = mt352_attach(&umt_config, &d->i2c_adap); | 61 | d->fe = mt352_attach(&umt_config, &d->i2c_adap); |
63 | 62 | ||
@@ -68,6 +67,7 @@ static int umt_tuner_attach (struct dvb_usb_device *d) | |||
68 | { | 67 | { |
69 | d->pll_addr = 0x61; | 68 | d->pll_addr = 0x61; |
70 | d->pll_desc = &dvb_pll_tua6034; | 69 | d->pll_desc = &dvb_pll_tua6034; |
70 | d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; | ||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c index 2a89f8c5da99..d4da494132ec 100644 --- a/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c | |||
@@ -287,17 +287,16 @@ struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d) | |||
287 | goto error; | 287 | goto error; |
288 | 288 | ||
289 | s->d = d; | 289 | s->d = d; |
290 | s->fe.ops = &vp702x_fe_ops; | 290 | |
291 | memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_ops)); | ||
291 | s->fe.demodulator_priv = s; | 292 | s->fe.demodulator_priv = s; |
292 | 293 | ||
293 | s->lnb_buf[1] = SET_LNB_POWER; | 294 | s->lnb_buf[1] = SET_LNB_POWER; |
294 | s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */ | 295 | s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */ |
295 | 296 | ||
296 | goto success; | 297 | return &s->fe; |
297 | error: | 298 | error: |
298 | return NULL; | 299 | return NULL; |
299 | success: | ||
300 | return &s->fe; | ||
301 | } | 300 | } |
302 | 301 | ||
303 | 302 | ||
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c index 9999336aeeb6..8452eef90322 100644 --- a/drivers/media/dvb/dvb-usb/vp7045-fe.c +++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c | |||
@@ -23,8 +23,6 @@ | |||
23 | 23 | ||
24 | struct vp7045_fe_state { | 24 | struct vp7045_fe_state { |
25 | struct dvb_frontend fe; | 25 | struct dvb_frontend fe; |
26 | struct dvb_frontend_ops ops; | ||
27 | |||
28 | struct dvb_usb_device *d; | 26 | struct dvb_usb_device *d; |
29 | }; | 27 | }; |
30 | 28 | ||
@@ -151,15 +149,12 @@ struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d) | |||
151 | goto error; | 149 | goto error; |
152 | 150 | ||
153 | s->d = d; | 151 | s->d = d; |
154 | memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops)); | 152 | memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops)); |
155 | s->fe.ops = &s->ops; | ||
156 | s->fe.demodulator_priv = s; | 153 | s->fe.demodulator_priv = s; |
157 | 154 | ||
158 | goto success; | 155 | return &s->fe; |
159 | error: | 156 | error: |
160 | return NULL; | 157 | return NULL; |
161 | success: | ||
162 | return &s->fe; | ||
163 | } | 158 | } |
164 | 159 | ||
165 | 160 | ||
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 37d5e0af1683..0ef361f0309b 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -157,7 +157,7 @@ config DVB_STV0297 | |||
157 | help | 157 | help |
158 | A DVB-C tuner module. Say Y when you want to support this frontend. | 158 | A DVB-C tuner module. Say Y when you want to support this frontend. |
159 | 159 | ||
160 | comment "ATSC (North American/Korean Terresterial DTV) frontends" | 160 | comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" |
161 | depends on DVB_CORE | 161 | depends on DVB_CORE |
162 | 162 | ||
163 | config DVB_NXT200X | 163 | config DVB_NXT200X |
@@ -216,4 +216,20 @@ config DVB_LGDT330X | |||
216 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 216 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want |
217 | to support this frontend. | 217 | to support this frontend. |
218 | 218 | ||
219 | |||
220 | comment "Miscellaneous devices" | ||
221 | depends on DVB_CORE | ||
222 | |||
223 | config DVB_LNBP21 | ||
224 | tristate "LNBP21 SEC controller" | ||
225 | depends on DVB_CORE | ||
226 | help | ||
227 | An SEC control chip. | ||
228 | |||
229 | config DVB_ISL6421 | ||
230 | tristate "ISL6421 SEC controller" | ||
231 | depends on DVB_CORE | ||
232 | help | ||
233 | An SEC control chip. | ||
234 | |||
219 | endmenu | 235 | endmenu |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index d09b6071fbaf..5222245c7f59 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -31,3 +31,5 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o | |||
31 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o | 31 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o |
32 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o | 32 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o |
33 | obj-$(CONFIG_DVB_CX24123) += cx24123.o | 33 | obj-$(CONFIG_DVB_CX24123) += cx24123.o |
34 | obj-$(CONFIG_DVB_LNBP21) += lnbp21.o | ||
35 | obj-$(CONFIG_DVB_ISL6421) += isl6421.o | ||
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index 1708a1d4893e..baeb311de893 100644 --- a/drivers/media/dvb/frontends/bcm3510.c +++ b/drivers/media/dvb/frontends/bcm3510.c | |||
@@ -48,7 +48,6 @@ | |||
48 | struct bcm3510_state { | 48 | struct bcm3510_state { |
49 | 49 | ||
50 | struct i2c_adapter* i2c; | 50 | struct i2c_adapter* i2c; |
51 | struct dvb_frontend_ops ops; | ||
52 | const struct bcm3510_config* config; | 51 | const struct bcm3510_config* config; |
53 | struct dvb_frontend frontend; | 52 | struct dvb_frontend frontend; |
54 | 53 | ||
@@ -791,10 +790,9 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, | |||
791 | 790 | ||
792 | state->config = config; | 791 | state->config = config; |
793 | state->i2c = i2c; | 792 | state->i2c = i2c; |
794 | memcpy(&state->ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops)); | ||
795 | 793 | ||
796 | /* create dvb_frontend */ | 794 | /* create dvb_frontend */ |
797 | state->frontend.ops = &state->ops; | 795 | memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops)); |
798 | state->frontend.demodulator_priv = state; | 796 | state->frontend.demodulator_priv = state; |
799 | 797 | ||
800 | mutex_init(&state->hab_mutex); | 798 | mutex_init(&state->hab_mutex); |
diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h index 78573b22ada9..d8f65738e5d2 100644 --- a/drivers/media/dvb/frontends/bsbe1.h +++ b/drivers/media/dvb/frontends/bsbe1.h | |||
@@ -89,12 +89,13 @@ static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra | |||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | 91 | ||
92 | static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | 92 | static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
93 | { | 93 | { |
94 | int ret; | 94 | int ret; |
95 | u8 data[4]; | 95 | u8 data[4]; |
96 | u32 div; | 96 | u32 div; |
97 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | 97 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; |
98 | struct i2c_adapter *i2c = fe->tuner_priv; | ||
98 | 99 | ||
99 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | 100 | if ((params->frequency < 950000) || (params->frequency > 2150000)) |
100 | return -EINVAL; | 101 | return -EINVAL; |
@@ -105,6 +106,8 @@ static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, | |||
105 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | 106 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; |
106 | data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; | 107 | data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; |
107 | 108 | ||
109 | if (fe->ops.i2c_gate_ctrl) | ||
110 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
108 | ret = i2c_transfer(i2c, &msg, 1); | 111 | ret = i2c_transfer(i2c, &msg, 1); |
109 | return (ret != 1) ? -EIO : 0; | 112 | return (ret != 1) ? -EIO : 0; |
110 | } | 113 | } |
@@ -117,7 +120,6 @@ static struct stv0299_config alps_bsbe1_config = { | |||
117 | .skip_reinit = 0, | 120 | .skip_reinit = 0, |
118 | .min_delay_ms = 100, | 121 | .min_delay_ms = 100, |
119 | .set_symbol_rate = alps_bsbe1_set_symbol_rate, | 122 | .set_symbol_rate = alps_bsbe1_set_symbol_rate, |
120 | .pll_set = alps_bsbe1_pll_set, | ||
121 | }; | 123 | }; |
122 | 124 | ||
123 | #endif | 125 | #endif |
diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h index 2a5366ce79cc..e231cd84b3a1 100644 --- a/drivers/media/dvb/frontends/bsru6.h +++ b/drivers/media/dvb/frontends/bsru6.h | |||
@@ -101,11 +101,12 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ra | |||
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | 103 | ||
104 | static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) | 104 | static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
105 | { | 105 | { |
106 | u8 buf[4]; | 106 | u8 buf[4]; |
107 | u32 div; | 107 | u32 div; |
108 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | 108 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; |
109 | struct i2c_adapter *i2c = fe->tuner_priv; | ||
109 | 110 | ||
110 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | 111 | if ((params->frequency < 950000) || (params->frequency > 2150000)) |
111 | return -EINVAL; | 112 | return -EINVAL; |
@@ -119,6 +120,8 @@ static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, | |||
119 | if (params->frequency > 1530000) | 120 | if (params->frequency > 1530000) |
120 | buf[3] = 0xc0; | 121 | buf[3] = 0xc0; |
121 | 122 | ||
123 | if (fe->ops.i2c_gate_ctrl) | ||
124 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
122 | if (i2c_transfer(i2c, &msg, 1) != 1) | 125 | if (i2c_transfer(i2c, &msg, 1) != 1) |
123 | return -EIO; | 126 | return -EIO; |
124 | return 0; | 127 | return 0; |
@@ -134,7 +137,6 @@ static struct stv0299_config alps_bsru6_config = { | |||
134 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 137 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
135 | .min_delay_ms = 100, | 138 | .min_delay_ms = 100, |
136 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | 139 | .set_symbol_rate = alps_bsru6_set_symbol_rate, |
137 | .pll_set = alps_bsru6_pll_set, | ||
138 | }; | 140 | }; |
139 | 141 | ||
140 | #endif | 142 | #endif |
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c index 755f774f6b7d..3c7c09a362b2 100644 --- a/drivers/media/dvb/frontends/cx22700.c +++ b/drivers/media/dvb/frontends/cx22700.c | |||
@@ -34,8 +34,6 @@ struct cx22700_state { | |||
34 | 34 | ||
35 | struct i2c_adapter* i2c; | 35 | struct i2c_adapter* i2c; |
36 | 36 | ||
37 | struct dvb_frontend_ops ops; | ||
38 | |||
39 | const struct cx22700_config* config; | 37 | const struct cx22700_config* config; |
40 | 38 | ||
41 | struct dvb_frontend frontend; | 39 | struct dvb_frontend frontend; |
@@ -247,12 +245,6 @@ static int cx22700_init (struct dvb_frontend* fe) | |||
247 | 245 | ||
248 | cx22700_writereg (state, 0x00, 0x01); | 246 | cx22700_writereg (state, 0x00, 0x01); |
249 | 247 | ||
250 | if (state->config->pll_init) { | ||
251 | cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */ | ||
252 | state->config->pll_init(fe); | ||
253 | cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */ | ||
254 | } | ||
255 | |||
256 | return 0; | 248 | return 0; |
257 | } | 249 | } |
258 | 250 | ||
@@ -333,9 +325,11 @@ static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
333 | cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ | 325 | cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ |
334 | cx22700_writereg (state, 0x00, 0x00); | 326 | cx22700_writereg (state, 0x00, 0x00); |
335 | 327 | ||
336 | cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */ | 328 | if (fe->ops.tuner_ops.set_params) { |
337 | state->config->pll_set(fe, p); | 329 | fe->ops.tuner_ops.set_params(fe, p); |
338 | cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */ | 330 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
331 | } | ||
332 | |||
339 | cx22700_set_inversion (state, p->inversion); | 333 | cx22700_set_inversion (state, p->inversion); |
340 | cx22700_set_tps (state, &p->u.ofdm); | 334 | cx22700_set_tps (state, &p->u.ofdm); |
341 | cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */ | 335 | cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */ |
@@ -353,6 +347,17 @@ static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
353 | return cx22700_get_tps (state, &p->u.ofdm); | 347 | return cx22700_get_tps (state, &p->u.ofdm); |
354 | } | 348 | } |
355 | 349 | ||
350 | static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
351 | { | ||
352 | struct cx22700_state* state = fe->demodulator_priv; | ||
353 | |||
354 | if (enable) { | ||
355 | return cx22700_writereg(state, 0x0a, 0x00); | ||
356 | } else { | ||
357 | return cx22700_writereg(state, 0x0a, 0x01); | ||
358 | } | ||
359 | } | ||
360 | |||
356 | static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | 361 | static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) |
357 | { | 362 | { |
358 | fesettings->min_delay_ms = 150; | 363 | fesettings->min_delay_ms = 150; |
@@ -381,13 +386,12 @@ struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, | |||
381 | /* setup the state */ | 386 | /* setup the state */ |
382 | state->config = config; | 387 | state->config = config; |
383 | state->i2c = i2c; | 388 | state->i2c = i2c; |
384 | memcpy(&state->ops, &cx22700_ops, sizeof(struct dvb_frontend_ops)); | ||
385 | 389 | ||
386 | /* check if the demod is there */ | 390 | /* check if the demod is there */ |
387 | if (cx22700_readreg(state, 0x07) < 0) goto error; | 391 | if (cx22700_readreg(state, 0x07) < 0) goto error; |
388 | 392 | ||
389 | /* create dvb_frontend */ | 393 | /* create dvb_frontend */ |
390 | state->frontend.ops = &state->ops; | 394 | memcpy(&state->frontend.ops, &cx22700_ops, sizeof(struct dvb_frontend_ops)); |
391 | state->frontend.demodulator_priv = state; | 395 | state->frontend.demodulator_priv = state; |
392 | return &state->frontend; | 396 | return &state->frontend; |
393 | 397 | ||
@@ -413,6 +417,7 @@ static struct dvb_frontend_ops cx22700_ops = { | |||
413 | .release = cx22700_release, | 417 | .release = cx22700_release, |
414 | 418 | ||
415 | .init = cx22700_init, | 419 | .init = cx22700_init, |
420 | .i2c_gate_ctrl = cx22700_i2c_gate_ctrl, | ||
416 | 421 | ||
417 | .set_frontend = cx22700_set_frontend, | 422 | .set_frontend = cx22700_set_frontend, |
418 | .get_frontend = cx22700_get_frontend, | 423 | .get_frontend = cx22700_get_frontend, |
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h index c9145b45874b..dcd8979c1a15 100644 --- a/drivers/media/dvb/frontends/cx22700.h +++ b/drivers/media/dvb/frontends/cx22700.h | |||
@@ -29,10 +29,6 @@ struct cx22700_config | |||
29 | { | 29 | { |
30 | /* the demodulator's i2c address */ | 30 | /* the demodulator's i2c address */ |
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | |||
33 | /* PLL maintenance */ | ||
34 | int (*pll_init)(struct dvb_frontend* fe); | ||
35 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
36 | }; | 32 | }; |
37 | 33 | ||
38 | extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, | 34 | extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, |
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 0fc899f81c5e..4106d46c957f 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -40,8 +40,6 @@ struct cx22702_state { | |||
40 | 40 | ||
41 | struct i2c_adapter* i2c; | 41 | struct i2c_adapter* i2c; |
42 | 42 | ||
43 | struct dvb_frontend_ops ops; | ||
44 | |||
45 | /* configuration settings */ | 43 | /* configuration settings */ |
46 | const struct cx22702_config* config; | 44 | const struct cx22702_config* config; |
47 | 45 | ||
@@ -211,22 +209,10 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
211 | u8 val; | 209 | u8 val; |
212 | struct cx22702_state* state = fe->demodulator_priv; | 210 | struct cx22702_state* state = fe->demodulator_priv; |
213 | 211 | ||
214 | /* set PLL */ | 212 | if (fe->ops.tuner_ops.set_params) { |
215 | cx22702_i2c_gate_ctrl(fe, 1); | 213 | fe->ops.tuner_ops.set_params(fe, p); |
216 | if (state->config->pll_set) { | 214 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
217 | state->config->pll_set(fe, p); | ||
218 | } else if (state->config->pll_desc) { | ||
219 | u8 pllbuf[4]; | ||
220 | struct i2c_msg msg = { .addr = state->config->pll_address, | ||
221 | .buf = pllbuf, .len = 4 }; | ||
222 | dvb_pll_configure(state->config->pll_desc, pllbuf, | ||
223 | p->frequency, | ||
224 | p->u.ofdm.bandwidth); | ||
225 | i2c_transfer(state->i2c, &msg, 1); | ||
226 | } else { | ||
227 | BUG(); | ||
228 | } | 215 | } |
229 | cx22702_i2c_gate_ctrl(fe, 0); | ||
230 | 216 | ||
231 | /* set inversion */ | 217 | /* set inversion */ |
232 | cx22702_set_inversion (state, p->inversion); | 218 | cx22702_set_inversion (state, p->inversion); |
@@ -358,10 +344,6 @@ static int cx22702_init (struct dvb_frontend* fe) | |||
358 | 344 | ||
359 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); | 345 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); |
360 | 346 | ||
361 | /* init PLL */ | ||
362 | if (state->config->pll_init) | ||
363 | state->config->pll_init(fe); | ||
364 | |||
365 | cx22702_i2c_gate_ctrl(fe, 0); | 347 | cx22702_i2c_gate_ctrl(fe, 0); |
366 | 348 | ||
367 | return 0; | 349 | return 0; |
@@ -495,7 +477,6 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | |||
495 | /* setup the state */ | 477 | /* setup the state */ |
496 | state->config = config; | 478 | state->config = config; |
497 | state->i2c = i2c; | 479 | state->i2c = i2c; |
498 | memcpy(&state->ops, &cx22702_ops, sizeof(struct dvb_frontend_ops)); | ||
499 | state->prevUCBlocks = 0; | 480 | state->prevUCBlocks = 0; |
500 | 481 | ||
501 | /* check if the demod is there */ | 482 | /* check if the demod is there */ |
@@ -503,7 +484,7 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | |||
503 | goto error; | 484 | goto error; |
504 | 485 | ||
505 | /* create dvb_frontend */ | 486 | /* create dvb_frontend */ |
506 | state->frontend.ops = &state->ops; | 487 | memcpy(&state->frontend.ops, &cx22702_ops, sizeof(struct dvb_frontend_ops)); |
507 | state->frontend.demodulator_priv = state; | 488 | state->frontend.demodulator_priv = state; |
508 | return &state->frontend; | 489 | return &state->frontend; |
509 | 490 | ||
@@ -530,6 +511,7 @@ static struct dvb_frontend_ops cx22702_ops = { | |||
530 | .release = cx22702_release, | 511 | .release = cx22702_release, |
531 | 512 | ||
532 | .init = cx22702_init, | 513 | .init = cx22702_init, |
514 | .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, | ||
533 | 515 | ||
534 | .set_frontend = cx22702_set_tps, | 516 | .set_frontend = cx22702_set_tps, |
535 | .get_frontend = cx22702_get_frontend, | 517 | .get_frontend = cx22702_get_frontend, |
@@ -540,7 +522,6 @@ static struct dvb_frontend_ops cx22702_ops = { | |||
540 | .read_signal_strength = cx22702_read_signal_strength, | 522 | .read_signal_strength = cx22702_read_signal_strength, |
541 | .read_snr = cx22702_read_snr, | 523 | .read_snr = cx22702_read_snr, |
542 | .read_ucblocks = cx22702_read_ucblocks, | 524 | .read_ucblocks = cx22702_read_ucblocks, |
543 | .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, | ||
544 | }; | 525 | }; |
545 | 526 | ||
546 | module_param(debug, int, 0644); | 527 | module_param(debug, int, 0644); |
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h index 5633976a58f1..7f2f241e5d44 100644 --- a/drivers/media/dvb/frontends/cx22702.h +++ b/drivers/media/dvb/frontends/cx22702.h | |||
@@ -39,13 +39,6 @@ struct cx22702_config | |||
39 | #define CX22702_PARALLEL_OUTPUT 0 | 39 | #define CX22702_PARALLEL_OUTPUT 0 |
40 | #define CX22702_SERIAL_OUTPUT 1 | 40 | #define CX22702_SERIAL_OUTPUT 1 |
41 | u8 output_mode; | 41 | u8 output_mode; |
42 | |||
43 | /* PLL maintenance */ | ||
44 | u8 pll_address; | ||
45 | struct dvb_pll_desc *pll_desc; | ||
46 | |||
47 | int (*pll_init)(struct dvb_frontend* fe); | ||
48 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
49 | }; | 42 | }; |
50 | 43 | ||
51 | extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | 44 | extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, |
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index f3edf8b517dd..ce3c7398bac9 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c | |||
@@ -36,8 +36,6 @@ struct cx24110_state { | |||
36 | 36 | ||
37 | struct i2c_adapter* i2c; | 37 | struct i2c_adapter* i2c; |
38 | 38 | ||
39 | struct dvb_frontend_ops ops; | ||
40 | |||
41 | const struct cx24110_config* config; | 39 | const struct cx24110_config* config; |
42 | 40 | ||
43 | struct dvb_frontend frontend; | 41 | struct dvb_frontend frontend; |
@@ -250,7 +248,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) | |||
250 | static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; | 248 | static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; |
251 | int i; | 249 | int i; |
252 | 250 | ||
253 | dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); | 251 | dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); |
254 | if (srate>90999000UL/2) | 252 | if (srate>90999000UL/2) |
255 | srate=90999000UL/2; | 253 | srate=90999000UL/2; |
256 | if (srate<500000) | 254 | if (srate<500000) |
@@ -366,17 +364,6 @@ static int cx24110_initfe(struct dvb_frontend* fe) | |||
366 | cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); | 364 | cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); |
367 | }; | 365 | }; |
368 | 366 | ||
369 | if (state->config->pll_init) state->config->pll_init(fe); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static int cx24110_sleep(struct dvb_frontend *fe) | ||
375 | { | ||
376 | struct cx24110_state *state = fe->demodulator_priv; | ||
377 | |||
378 | if (state->config->pll_sleep) | ||
379 | return state->config->pll_sleep(fe); | ||
380 | return 0; | 367 | return 0; |
381 | } | 368 | } |
382 | 369 | ||
@@ -548,7 +535,12 @@ static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
548 | { | 535 | { |
549 | struct cx24110_state *state = fe->demodulator_priv; | 536 | struct cx24110_state *state = fe->demodulator_priv; |
550 | 537 | ||
551 | state->config->pll_set(fe, p); | 538 | |
539 | if (fe->ops.tuner_ops.set_params) { | ||
540 | fe->ops.tuner_ops.set_params(fe, p); | ||
541 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
542 | } | ||
543 | |||
552 | cx24110_set_inversion (state, p->inversion); | 544 | cx24110_set_inversion (state, p->inversion); |
553 | cx24110_set_fec (state, p->u.qpsk.fec_inner); | 545 | cx24110_set_fec (state, p->u.qpsk.fec_inner); |
554 | cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate); | 546 | cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate); |
@@ -612,7 +604,6 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | |||
612 | /* setup the state */ | 604 | /* setup the state */ |
613 | state->config = config; | 605 | state->config = config; |
614 | state->i2c = i2c; | 606 | state->i2c = i2c; |
615 | memcpy(&state->ops, &cx24110_ops, sizeof(struct dvb_frontend_ops)); | ||
616 | state->lastber = 0; | 607 | state->lastber = 0; |
617 | state->lastbler = 0; | 608 | state->lastbler = 0; |
618 | state->lastesn0 = 0; | 609 | state->lastesn0 = 0; |
@@ -622,7 +613,7 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | |||
622 | if ((ret != 0x5a) && (ret != 0x69)) goto error; | 613 | if ((ret != 0x5a) && (ret != 0x69)) goto error; |
623 | 614 | ||
624 | /* create dvb_frontend */ | 615 | /* create dvb_frontend */ |
625 | state->frontend.ops = &state->ops; | 616 | memcpy(&state->frontend.ops, &cx24110_ops, sizeof(struct dvb_frontend_ops)); |
626 | state->frontend.demodulator_priv = state; | 617 | state->frontend.demodulator_priv = state; |
627 | return &state->frontend; | 618 | return &state->frontend; |
628 | 619 | ||
@@ -651,7 +642,6 @@ static struct dvb_frontend_ops cx24110_ops = { | |||
651 | .release = cx24110_release, | 642 | .release = cx24110_release, |
652 | 643 | ||
653 | .init = cx24110_initfe, | 644 | .init = cx24110_initfe, |
654 | .sleep = cx24110_sleep, | ||
655 | .set_frontend = cx24110_set_frontend, | 645 | .set_frontend = cx24110_set_frontend, |
656 | .get_frontend = cx24110_get_frontend, | 646 | .get_frontend = cx24110_get_frontend, |
657 | .read_status = cx24110_read_status, | 647 | .read_status = cx24110_read_status, |
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h index 609ac642b406..b354a64e0e74 100644 --- a/drivers/media/dvb/frontends/cx24110.h +++ b/drivers/media/dvb/frontends/cx24110.h | |||
@@ -31,11 +31,6 @@ struct cx24110_config | |||
31 | { | 31 | { |
32 | /* the demodulator's i2c address */ | 32 | /* the demodulator's i2c address */ |
33 | u8 demod_address; | 33 | u8 demod_address; |
34 | |||
35 | /* PLL maintenance */ | ||
36 | int (*pll_init)(struct dvb_frontend* fe); | ||
37 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
38 | int (*pll_sleep)(struct dvb_frontend* fe); | ||
39 | }; | 34 | }; |
40 | 35 | ||
41 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | 36 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, |
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index 691dc840dcc0..f2f795cba56a 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/drivers/media/dvb/frontends/cx24123.c | |||
@@ -41,14 +41,12 @@ static int debug; | |||
41 | struct cx24123_state | 41 | struct cx24123_state |
42 | { | 42 | { |
43 | struct i2c_adapter* i2c; | 43 | struct i2c_adapter* i2c; |
44 | struct dvb_frontend_ops ops; | ||
45 | const struct cx24123_config* config; | 44 | const struct cx24123_config* config; |
46 | 45 | ||
47 | struct dvb_frontend frontend; | 46 | struct dvb_frontend frontend; |
48 | 47 | ||
49 | u32 lastber; | 48 | u32 lastber; |
50 | u16 snr; | 49 | u16 snr; |
51 | u8 lnbreg; | ||
52 | 50 | ||
53 | /* Some PLL specifics for tuning */ | 51 | /* Some PLL specifics for tuning */ |
54 | u32 VCAarg; | 52 | u32 VCAarg; |
@@ -249,29 +247,6 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data) | |||
249 | return 0; | 247 | return 0; |
250 | } | 248 | } |
251 | 249 | ||
252 | static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data) | ||
253 | { | ||
254 | u8 buf[] = { reg, data }; | ||
255 | /* fixme: put the intersil addr int the config */ | ||
256 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 }; | ||
257 | int err; | ||
258 | |||
259 | if (debug>1) | ||
260 | printk("cx24123: %s: writeln addr=0x08, reg 0x%02x, value 0x%02x\n", | ||
261 | __FUNCTION__,reg, data); | ||
262 | |||
263 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | ||
264 | printk("%s: writelnbreg error (err == %i, reg == 0x%02x," | ||
265 | " data == 0x%02x)\n", __FUNCTION__, err, reg, data); | ||
266 | return -EREMOTEIO; | ||
267 | } | ||
268 | |||
269 | /* cache the write, no way to read back */ | ||
270 | state->lnbreg = data; | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static int cx24123_readreg(struct cx24123_state* state, u8 reg) | 250 | static int cx24123_readreg(struct cx24123_state* state, u8 reg) |
276 | { | 251 | { |
277 | int ret; | 252 | int ret; |
@@ -295,11 +270,6 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg) | |||
295 | return b1[0]; | 270 | return b1[0]; |
296 | } | 271 | } |
297 | 272 | ||
298 | static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg) | ||
299 | { | ||
300 | return state->lnbreg; | ||
301 | } | ||
302 | |||
303 | static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) | 273 | static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) |
304 | { | 274 | { |
305 | u8 nom_reg = cx24123_readreg(state, 0x0e); | 275 | u8 nom_reg = cx24123_readreg(state, 0x0e); |
@@ -458,8 +428,8 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) | |||
458 | u8 pll_mult; | 428 | u8 pll_mult; |
459 | 429 | ||
460 | /* check if symbol rate is within limits */ | 430 | /* check if symbol rate is within limits */ |
461 | if ((srate > state->ops.info.symbol_rate_max) || | 431 | if ((srate > state->frontend.ops.info.symbol_rate_max) || |
462 | (srate < state->ops.info.symbol_rate_min)) | 432 | (srate < state->frontend.ops.info.symbol_rate_min)) |
463 | return -EOPNOTSUPP;; | 433 | return -EOPNOTSUPP;; |
464 | 434 | ||
465 | /* choose the sampling rate high enough for the required operation, | 435 | /* choose the sampling rate high enough for the required operation, |
@@ -687,13 +657,6 @@ static int cx24123_initfe(struct dvb_frontend* fe) | |||
687 | for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) | 657 | for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) |
688 | cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); | 658 | cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); |
689 | 659 | ||
690 | if (state->config->pll_init) | ||
691 | state->config->pll_init(fe); | ||
692 | |||
693 | /* Configure the LNB for 14V */ | ||
694 | if (state->config->use_isl6421) | ||
695 | cx24123_writelnbreg(state, 0x0, 0x2a); | ||
696 | |||
697 | return 0; | 660 | return 0; |
698 | } | 661 | } |
699 | 662 | ||
@@ -702,50 +665,18 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage | |||
702 | struct cx24123_state *state = fe->demodulator_priv; | 665 | struct cx24123_state *state = fe->demodulator_priv; |
703 | u8 val; | 666 | u8 val; |
704 | 667 | ||
705 | switch (state->config->use_isl6421) { | 668 | val = cx24123_readreg(state, 0x29) & ~0x40; |
706 | |||
707 | case 1: | ||
708 | 669 | ||
709 | val = cx24123_readlnbreg(state, 0x0); | 670 | switch (voltage) { |
710 | 671 | case SEC_VOLTAGE_13: | |
711 | switch (voltage) { | 672 | dprintk("%s: setting voltage 13V\n", __FUNCTION__); |
712 | case SEC_VOLTAGE_13: | 673 | return cx24123_writereg(state, 0x29, val | 0x80); |
713 | dprintk("%s: isl6421 voltage = 13V\n",__FUNCTION__); | 674 | case SEC_VOLTAGE_18: |
714 | return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ | 675 | dprintk("%s: setting voltage 18V\n", __FUNCTION__); |
715 | case SEC_VOLTAGE_18: | 676 | return cx24123_writereg(state, 0x29, val & 0x7f); |
716 | dprintk("%s: isl6421 voltage = 18V\n",__FUNCTION__); | 677 | default: |
717 | return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ | 678 | return -EINVAL; |
718 | case SEC_VOLTAGE_OFF: | 679 | }; |
719 | dprintk("%s: isl5421 voltage off\n",__FUNCTION__); | ||
720 | return cx24123_writelnbreg(state, 0x0, val & 0x30); | ||
721 | default: | ||
722 | return -EINVAL; | ||
723 | }; | ||
724 | |||
725 | case 0: | ||
726 | |||
727 | val = cx24123_readreg(state, 0x29); | ||
728 | |||
729 | switch (voltage) { | ||
730 | case SEC_VOLTAGE_13: | ||
731 | dprintk("%s: setting voltage 13V\n", __FUNCTION__); | ||
732 | if (state->config->enable_lnb_voltage) | ||
733 | state->config->enable_lnb_voltage(fe, 1); | ||
734 | return cx24123_writereg(state, 0x29, val | 0x80); | ||
735 | case SEC_VOLTAGE_18: | ||
736 | dprintk("%s: setting voltage 18V\n", __FUNCTION__); | ||
737 | if (state->config->enable_lnb_voltage) | ||
738 | state->config->enable_lnb_voltage(fe, 1); | ||
739 | return cx24123_writereg(state, 0x29, val & 0x7f); | ||
740 | case SEC_VOLTAGE_OFF: | ||
741 | dprintk("%s: setting voltage off\n", __FUNCTION__); | ||
742 | if (state->config->enable_lnb_voltage) | ||
743 | state->config->enable_lnb_voltage(fe, 0); | ||
744 | return 0; | ||
745 | default: | ||
746 | return -EINVAL; | ||
747 | }; | ||
748 | } | ||
749 | 680 | ||
750 | return 0; | 681 | return 0; |
751 | } | 682 | } |
@@ -766,27 +697,20 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state) | |||
766 | static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) | 697 | static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) |
767 | { | 698 | { |
768 | struct cx24123_state *state = fe->demodulator_priv; | 699 | struct cx24123_state *state = fe->demodulator_priv; |
769 | int i, val; | 700 | int i, val, tone; |
770 | 701 | ||
771 | dprintk("%s:\n",__FUNCTION__); | 702 | dprintk("%s:\n",__FUNCTION__); |
772 | 703 | ||
773 | /* check if continuous tone has been stopped */ | 704 | /* stop continuous tone if enabled */ |
774 | if (state->config->use_isl6421) | 705 | tone = cx24123_readreg(state, 0x29); |
775 | val = cx24123_readlnbreg(state, 0x00) & 0x10; | 706 | if (tone & 0x10) |
776 | else | 707 | cx24123_writereg(state, 0x29, tone & ~0x50); |
777 | val = cx24123_readreg(state, 0x29) & 0x10; | ||
778 | |||
779 | |||
780 | if (val) { | ||
781 | printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__); | ||
782 | return -ENOTSUPP; | ||
783 | } | ||
784 | 708 | ||
785 | /* wait for diseqc queue ready */ | 709 | /* wait for diseqc queue ready */ |
786 | cx24123_wait_for_diseqc(state); | 710 | cx24123_wait_for_diseqc(state); |
787 | 711 | ||
788 | /* select tone mode */ | 712 | /* select tone mode */ |
789 | cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8); | 713 | cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); |
790 | 714 | ||
791 | for (i = 0; i < cmd->msg_len; i++) | 715 | for (i = 0; i < cmd->msg_len; i++) |
792 | cx24123_writereg(state, 0x2C + i, cmd->msg[i]); | 716 | cx24123_writereg(state, 0x2C + i, cmd->msg[i]); |
@@ -797,36 +721,33 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma | |||
797 | /* wait for diseqc message to finish sending */ | 721 | /* wait for diseqc message to finish sending */ |
798 | cx24123_wait_for_diseqc(state); | 722 | cx24123_wait_for_diseqc(state); |
799 | 723 | ||
724 | /* restart continuous tone if enabled */ | ||
725 | if (tone & 0x10) { | ||
726 | cx24123_writereg(state, 0x29, tone & ~0x40); | ||
727 | } | ||
728 | |||
800 | return 0; | 729 | return 0; |
801 | } | 730 | } |
802 | 731 | ||
803 | static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) | 732 | static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) |
804 | { | 733 | { |
805 | struct cx24123_state *state = fe->demodulator_priv; | 734 | struct cx24123_state *state = fe->demodulator_priv; |
806 | int val; | 735 | int val, tone; |
807 | 736 | ||
808 | dprintk("%s:\n", __FUNCTION__); | 737 | dprintk("%s:\n", __FUNCTION__); |
809 | 738 | ||
810 | /* check if continuous tone has been stoped */ | 739 | /* stop continuous tone if enabled */ |
811 | if (state->config->use_isl6421) | 740 | tone = cx24123_readreg(state, 0x29); |
812 | val = cx24123_readlnbreg(state, 0x00) & 0x10; | 741 | if (tone & 0x10) |
813 | else | 742 | cx24123_writereg(state, 0x29, tone & ~0x50); |
814 | val = cx24123_readreg(state, 0x29) & 0x10; | ||
815 | |||
816 | |||
817 | if (val) { | ||
818 | printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__); | ||
819 | return -ENOTSUPP; | ||
820 | } | ||
821 | 743 | ||
744 | /* wait for diseqc queue ready */ | ||
822 | cx24123_wait_for_diseqc(state); | 745 | cx24123_wait_for_diseqc(state); |
823 | 746 | ||
824 | /* select tone mode */ | 747 | /* select tone mode */ |
825 | val = cx24123_readreg(state, 0x2a) & 0xf8; | 748 | cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4); |
826 | cx24123_writereg(state, 0x2a, val | 0x04); | 749 | msleep(30); |
827 | |||
828 | val = cx24123_readreg(state, 0x29); | 750 | val = cx24123_readreg(state, 0x29); |
829 | |||
830 | if (burst == SEC_MINI_A) | 751 | if (burst == SEC_MINI_A) |
831 | cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); | 752 | cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); |
832 | else if (burst == SEC_MINI_B) | 753 | else if (burst == SEC_MINI_B) |
@@ -835,7 +756,12 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t | |||
835 | return -EINVAL; | 756 | return -EINVAL; |
836 | 757 | ||
837 | cx24123_wait_for_diseqc(state); | 758 | cx24123_wait_for_diseqc(state); |
759 | cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); | ||
838 | 760 | ||
761 | /* restart continuous tone if enabled */ | ||
762 | if (tone & 0x10) { | ||
763 | cx24123_writereg(state, 0x29, tone & ~0x40); | ||
764 | } | ||
839 | return 0; | 765 | return 0; |
840 | } | 766 | } |
841 | 767 | ||
@@ -976,38 +902,21 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
976 | struct cx24123_state *state = fe->demodulator_priv; | 902 | struct cx24123_state *state = fe->demodulator_priv; |
977 | u8 val; | 903 | u8 val; |
978 | 904 | ||
979 | switch (state->config->use_isl6421) { | 905 | /* wait for diseqc queue ready */ |
980 | case 1: | 906 | cx24123_wait_for_diseqc(state); |
981 | |||
982 | val = cx24123_readlnbreg(state, 0x0); | ||
983 | |||
984 | switch (tone) { | ||
985 | case SEC_TONE_ON: | ||
986 | dprintk("%s: isl6421 sec tone on\n",__FUNCTION__); | ||
987 | return cx24123_writelnbreg(state, 0x0, val | 0x10); | ||
988 | case SEC_TONE_OFF: | ||
989 | dprintk("%s: isl6421 sec tone off\n",__FUNCTION__); | ||
990 | return cx24123_writelnbreg(state, 0x0, val & 0x2f); | ||
991 | default: | ||
992 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); | ||
993 | return -EINVAL; | ||
994 | } | ||
995 | |||
996 | case 0: | ||
997 | 907 | ||
998 | val = cx24123_readreg(state, 0x29); | 908 | val = cx24123_readreg(state, 0x29) & ~0x40; |
999 | 909 | ||
1000 | switch (tone) { | 910 | switch (tone) { |
1001 | case SEC_TONE_ON: | 911 | case SEC_TONE_ON: |
1002 | dprintk("%s: setting tone on\n", __FUNCTION__); | 912 | dprintk("%s: setting tone on\n", __FUNCTION__); |
1003 | return cx24123_writereg(state, 0x29, val | 0x10); | 913 | return cx24123_writereg(state, 0x29, val | 0x10); |
1004 | case SEC_TONE_OFF: | 914 | case SEC_TONE_OFF: |
1005 | dprintk("%s: setting tone off\n",__FUNCTION__); | 915 | dprintk("%s: setting tone off\n",__FUNCTION__); |
1006 | return cx24123_writereg(state, 0x29, val & 0xef); | 916 | return cx24123_writereg(state, 0x29, val & 0xef); |
1007 | default: | 917 | default: |
1008 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); | 918 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); |
1009 | return -EINVAL; | 919 | return -EINVAL; |
1010 | } | ||
1011 | } | 920 | } |
1012 | 921 | ||
1013 | return 0; | 922 | return 0; |
@@ -1040,10 +949,8 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | |||
1040 | /* setup the state */ | 949 | /* setup the state */ |
1041 | state->config = config; | 950 | state->config = config; |
1042 | state->i2c = i2c; | 951 | state->i2c = i2c; |
1043 | memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); | ||
1044 | state->lastber = 0; | 952 | state->lastber = 0; |
1045 | state->snr = 0; | 953 | state->snr = 0; |
1046 | state->lnbreg = 0; | ||
1047 | state->VCAarg = 0; | 954 | state->VCAarg = 0; |
1048 | state->VGAarg = 0; | 955 | state->VGAarg = 0; |
1049 | state->bandselectarg = 0; | 956 | state->bandselectarg = 0; |
@@ -1059,7 +966,7 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | |||
1059 | } | 966 | } |
1060 | 967 | ||
1061 | /* create dvb_frontend */ | 968 | /* create dvb_frontend */ |
1062 | state->frontend.ops = &state->ops; | 969 | memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); |
1063 | state->frontend.demodulator_priv = state; | 970 | state->frontend.demodulator_priv = state; |
1064 | return &state->frontend; | 971 | return &state->frontend; |
1065 | 972 | ||
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h index 0c922b5e9263..9606f825935c 100644 --- a/drivers/media/dvb/frontends/cx24123.h +++ b/drivers/media/dvb/frontends/cx24123.h | |||
@@ -28,21 +28,8 @@ struct cx24123_config | |||
28 | /* the demodulator's i2c address */ | 28 | /* the demodulator's i2c address */ |
29 | u8 demod_address; | 29 | u8 demod_address; |
30 | 30 | ||
31 | /* | ||
32 | cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip | ||
33 | for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits | ||
34 | from register 0x29 of the CX24123 demodulator | ||
35 | */ | ||
36 | int use_isl6421; | ||
37 | |||
38 | /* PLL maintenance */ | ||
39 | int (*pll_init)(struct dvb_frontend* fe); | ||
40 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
41 | |||
42 | /* Need to set device param for start_dma */ | 31 | /* Need to set device param for start_dma */ |
43 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 32 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
44 | |||
45 | void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on); | ||
46 | }; | 33 | }; |
47 | 34 | ||
48 | extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | 35 | extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, |
diff --git a/drivers/media/dvb/frontends/dib3000-common.h b/drivers/media/dvb/frontends/dib3000-common.h index c31d6df15472..be1c0d3e1389 100644 --- a/drivers/media/dvb/frontends/dib3000-common.h +++ b/drivers/media/dvb/frontends/dib3000-common.h | |||
@@ -38,8 +38,6 @@ | |||
38 | struct dib3000_state { | 38 | struct dib3000_state { |
39 | struct i2c_adapter* i2c; | 39 | struct i2c_adapter* i2c; |
40 | 40 | ||
41 | struct dvb_frontend_ops ops; | ||
42 | |||
43 | /* configuration settings */ | 41 | /* configuration settings */ |
44 | struct dib3000_config config; | 42 | struct dib3000_config config; |
45 | 43 | ||
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h index 2d5475b5c063..ec927628d273 100644 --- a/drivers/media/dvb/frontends/dib3000.h +++ b/drivers/media/dvb/frontends/dib3000.h | |||
@@ -30,10 +30,6 @@ struct dib3000_config | |||
30 | { | 30 | { |
31 | /* the demodulator's i2c address */ | 31 | /* the demodulator's i2c address */ |
32 | u8 demod_address; | 32 | u8 demod_address; |
33 | |||
34 | /* PLL maintenance and the i2c address of the PLL */ | ||
35 | int (*pll_init)(struct dvb_frontend *fe); | ||
36 | int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params); | ||
37 | }; | 33 | }; |
38 | 34 | ||
39 | struct dib_fe_xfer_ops | 35 | struct dib_fe_xfer_ops |
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c index ae589adb1c0a..7c6dc7e30900 100644 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ b/drivers/media/dvb/frontends/dib3000mb.c | |||
@@ -60,8 +60,9 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, | |||
60 | fe_code_rate_t fe_cr = FEC_NONE; | 60 | fe_code_rate_t fe_cr = FEC_NONE; |
61 | int search_state, seq; | 61 | int search_state, seq; |
62 | 62 | ||
63 | if (tuner && state->config.pll_set) { | 63 | if (tuner && fe->ops.tuner_ops.set_params) { |
64 | state->config.pll_set(fe, fep); | 64 | fe->ops.tuner_ops.set_params(fe, fep); |
65 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
65 | 66 | ||
66 | deb_setf("bandwidth: "); | 67 | deb_setf("bandwidth: "); |
67 | switch (ofdm->bandwidth) { | 68 | switch (ofdm->bandwidth) { |
@@ -386,9 +387,6 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) | |||
386 | 387 | ||
387 | wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); | 388 | wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); |
388 | 389 | ||
389 | if (state->config.pll_init) | ||
390 | state->config.pll_init(fe); | ||
391 | |||
392 | return 0; | 390 | return 0; |
393 | } | 391 | } |
394 | 392 | ||
@@ -707,7 +705,6 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, | |||
707 | /* setup the state */ | 705 | /* setup the state */ |
708 | state->i2c = i2c; | 706 | state->i2c = i2c; |
709 | memcpy(&state->config,config,sizeof(struct dib3000_config)); | 707 | memcpy(&state->config,config,sizeof(struct dib3000_config)); |
710 | memcpy(&state->ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops)); | ||
711 | 708 | ||
712 | /* check for the correct demod */ | 709 | /* check for the correct demod */ |
713 | if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) | 710 | if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) |
@@ -717,7 +714,7 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, | |||
717 | goto error; | 714 | goto error; |
718 | 715 | ||
719 | /* create dvb_frontend */ | 716 | /* create dvb_frontend */ |
720 | state->frontend.ops = &state->ops; | 717 | memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops)); |
721 | state->frontend.demodulator_priv = state; | 718 | state->frontend.demodulator_priv = state; |
722 | 719 | ||
723 | /* set the xfer operations */ | 720 | /* set the xfer operations */ |
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index 3b303dbb6156..6c3be2529980 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c | |||
@@ -462,8 +462,9 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, | |||
462 | int search_state,auto_val; | 462 | int search_state,auto_val; |
463 | u16 val; | 463 | u16 val; |
464 | 464 | ||
465 | if (tuner && state->config.pll_set) { /* initial call from dvb */ | 465 | if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */ |
466 | state->config.pll_set(fe,fep); | 466 | fe->ops.tuner_ops.set_params(fe, fep); |
467 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
467 | 468 | ||
468 | state->last_tuned_freq = fep->frequency; | 469 | state->last_tuned_freq = fep->frequency; |
469 | // if (!scanboost) { | 470 | // if (!scanboost) { |
@@ -642,9 +643,6 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) | |||
642 | 643 | ||
643 | set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); | 644 | set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); |
644 | 645 | ||
645 | if (state->config.pll_init) | ||
646 | state->config.pll_init(fe); | ||
647 | |||
648 | deb_info("init end\n"); | 646 | deb_info("init end\n"); |
649 | return 0; | 647 | return 0; |
650 | } | 648 | } |
@@ -839,7 +837,6 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, | |||
839 | /* setup the state */ | 837 | /* setup the state */ |
840 | state->i2c = i2c; | 838 | state->i2c = i2c; |
841 | memcpy(&state->config,config,sizeof(struct dib3000_config)); | 839 | memcpy(&state->config,config,sizeof(struct dib3000_config)); |
842 | memcpy(&state->ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); | ||
843 | 840 | ||
844 | /* check for the correct demod */ | 841 | /* check for the correct demod */ |
845 | if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) | 842 | if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) |
@@ -859,7 +856,7 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, | |||
859 | } | 856 | } |
860 | 857 | ||
861 | /* create dvb_frontend */ | 858 | /* create dvb_frontend */ |
862 | state->frontend.ops = &state->ops; | 859 | memcpy(&state->frontend.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); |
863 | state->frontend.demodulator_priv = state; | 860 | state->frontend.demodulator_priv = state; |
864 | 861 | ||
865 | /* set the xfer operations */ | 862 | /* set the xfer operations */ |
@@ -876,6 +873,7 @@ error: | |||
876 | kfree(state); | 873 | kfree(state); |
877 | return NULL; | 874 | return NULL; |
878 | } | 875 | } |
876 | EXPORT_SYMBOL(dib3000mc_attach); | ||
879 | 877 | ||
880 | static struct dvb_frontend_ops dib3000mc_ops = { | 878 | static struct dvb_frontend_ops dib3000mc_ops = { |
881 | 879 | ||
@@ -914,5 +912,3 @@ static struct dvb_frontend_ops dib3000mc_ops = { | |||
914 | MODULE_AUTHOR(DRIVER_AUTHOR); | 912 | MODULE_AUTHOR(DRIVER_AUTHOR); |
915 | MODULE_DESCRIPTION(DRIVER_DESC); | 913 | MODULE_DESCRIPTION(DRIVER_DESC); |
916 | MODULE_LICENSE("GPL"); | 914 | MODULE_LICENSE("GPL"); |
917 | |||
918 | EXPORT_SYMBOL(dib3000mc_attach); | ||
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 791706ec1da3..a189683454b7 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -227,10 +227,10 @@ struct dvb_pll_desc dvb_pll_tua6034 = { | |||
227 | EXPORT_SYMBOL(dvb_pll_tua6034); | 227 | EXPORT_SYMBOL(dvb_pll_tua6034); |
228 | 228 | ||
229 | /* Infineon TUA6034 | 229 | /* Infineon TUA6034 |
230 | * used in LG TDVS H061F and LG TDVS H062F | 230 | * used in LG TDVS-H061F, LG TDVS-H062F and LG TDVS-H064F |
231 | */ | 231 | */ |
232 | struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { | 232 | struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { |
233 | .name = "LG/Infineon TUA6034", | 233 | .name = "LG TDVS-H06xF", |
234 | .min = 54000000, | 234 | .min = 54000000, |
235 | .max = 863000000, | 235 | .max = 863000000, |
236 | .count = 3, | 236 | .count = 3, |
@@ -240,7 +240,7 @@ struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { | |||
240 | { 999999999, 44000000, 62500, 0xce, 0x04 }, | 240 | { 999999999, 44000000, 62500, 0xce, 0x04 }, |
241 | }, | 241 | }, |
242 | }; | 242 | }; |
243 | EXPORT_SYMBOL(dvb_pll_tdvs_tua6034); | 243 | EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf); |
244 | 244 | ||
245 | /* Philips FMD1216ME | 245 | /* Philips FMD1216ME |
246 | * used in Medion Hybrid PCMCIA card and USB Box | 246 | * used in Medion Hybrid PCMCIA card and USB Box |
@@ -419,6 +419,19 @@ struct dvb_pll_desc dvb_pll_thomson_fe6600 = { | |||
419 | }; | 419 | }; |
420 | EXPORT_SYMBOL(dvb_pll_thomson_fe6600); | 420 | EXPORT_SYMBOL(dvb_pll_thomson_fe6600); |
421 | 421 | ||
422 | struct dvb_pll_priv { | ||
423 | /* i2c details */ | ||
424 | int pll_i2c_address; | ||
425 | struct i2c_adapter *i2c; | ||
426 | |||
427 | /* the PLL descriptor */ | ||
428 | struct dvb_pll_desc *pll_desc; | ||
429 | |||
430 | /* cached frequency/bandwidth */ | ||
431 | u32 frequency; | ||
432 | u32 bandwidth; | ||
433 | }; | ||
434 | |||
422 | /* ----------------------------------------------------------- */ | 435 | /* ----------------------------------------------------------- */ |
423 | /* code */ | 436 | /* code */ |
424 | 437 | ||
@@ -443,7 +456,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
443 | if (debug) | 456 | if (debug) |
444 | printk("pll: %s: freq=%d bw=%d | i=%d/%d\n", | 457 | printk("pll: %s: freq=%d bw=%d | i=%d/%d\n", |
445 | desc->name, freq, bandwidth, i, desc->count); | 458 | desc->name, freq, bandwidth, i, desc->count); |
446 | BUG_ON(i == desc->count); | 459 | if (i == desc->count) |
460 | return -EINVAL; | ||
447 | 461 | ||
448 | div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; | 462 | div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; |
449 | buf[0] = div >> 8; | 463 | buf[0] = div >> 8; |
@@ -462,6 +476,163 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
462 | } | 476 | } |
463 | EXPORT_SYMBOL(dvb_pll_configure); | 477 | EXPORT_SYMBOL(dvb_pll_configure); |
464 | 478 | ||
479 | static int dvb_pll_release(struct dvb_frontend *fe) | ||
480 | { | ||
481 | if (fe->tuner_priv) | ||
482 | kfree(fe->tuner_priv); | ||
483 | fe->tuner_priv = NULL; | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static int dvb_pll_sleep(struct dvb_frontend *fe) | ||
488 | { | ||
489 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
490 | u8 buf[4]; | ||
491 | struct i2c_msg msg = | ||
492 | { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
493 | int i; | ||
494 | int result; | ||
495 | |||
496 | for (i = 0; i < priv->pll_desc->count; i++) { | ||
497 | if (priv->pll_desc->entries[i].limit == 0) | ||
498 | break; | ||
499 | } | ||
500 | if (i == priv->pll_desc->count) | ||
501 | return 0; | ||
502 | |||
503 | buf[0] = 0; | ||
504 | buf[1] = 0; | ||
505 | buf[2] = priv->pll_desc->entries[i].config; | ||
506 | buf[3] = priv->pll_desc->entries[i].cb; | ||
507 | |||
508 | if (fe->ops.i2c_gate_ctrl) | ||
509 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
510 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | ||
511 | return result; | ||
512 | } | ||
513 | |||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static int dvb_pll_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
518 | { | ||
519 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
520 | u8 buf[4]; | ||
521 | struct i2c_msg msg = | ||
522 | { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
523 | int result; | ||
524 | u32 div; | ||
525 | int i; | ||
526 | u32 bandwidth = 0; | ||
527 | |||
528 | if (priv->i2c == NULL) | ||
529 | return -EINVAL; | ||
530 | |||
531 | // DVBT bandwidth only just now | ||
532 | if (fe->ops.info.type == FE_OFDM) { | ||
533 | bandwidth = params->u.ofdm.bandwidth; | ||
534 | } | ||
535 | |||
536 | if ((result = dvb_pll_configure(priv->pll_desc, buf, params->frequency, bandwidth)) != 0) | ||
537 | return result; | ||
538 | |||
539 | if (fe->ops.i2c_gate_ctrl) | ||
540 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
541 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | ||
542 | return result; | ||
543 | } | ||
544 | |||
545 | // calculate the frequency we set it to | ||
546 | for (i = 0; i < priv->pll_desc->count; i++) { | ||
547 | if (params->frequency > priv->pll_desc->entries[i].limit) | ||
548 | continue; | ||
549 | break; | ||
550 | } | ||
551 | div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize; | ||
552 | priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset; | ||
553 | priv->bandwidth = bandwidth; | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static int dvb_pll_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) | ||
559 | { | ||
560 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
561 | int result; | ||
562 | u32 div; | ||
563 | int i; | ||
564 | u32 bandwidth = 0; | ||
565 | |||
566 | if (buf_len < 5) | ||
567 | return -EINVAL; | ||
568 | |||
569 | // DVBT bandwidth only just now | ||
570 | if (fe->ops.info.type == FE_OFDM) { | ||
571 | bandwidth = params->u.ofdm.bandwidth; | ||
572 | } | ||
573 | |||
574 | if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params->frequency, bandwidth)) != 0) | ||
575 | return result; | ||
576 | buf[0] = priv->pll_i2c_address; | ||
577 | |||
578 | // calculate the frequency we set it to | ||
579 | for (i = 0; i < priv->pll_desc->count; i++) { | ||
580 | if (params->frequency > priv->pll_desc->entries[i].limit) | ||
581 | continue; | ||
582 | break; | ||
583 | } | ||
584 | div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize; | ||
585 | priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset; | ||
586 | priv->bandwidth = bandwidth; | ||
587 | |||
588 | return 5; | ||
589 | } | ||
590 | |||
591 | static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
592 | { | ||
593 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
594 | *frequency = priv->frequency; | ||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | ||
599 | { | ||
600 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
601 | *bandwidth = priv->bandwidth; | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static struct dvb_tuner_ops dvb_pll_tuner_ops = { | ||
606 | .release = dvb_pll_release, | ||
607 | .sleep = dvb_pll_sleep, | ||
608 | .set_params = dvb_pll_set_params, | ||
609 | .calc_regs = dvb_pll_calc_regs, | ||
610 | .get_frequency = dvb_pll_get_frequency, | ||
611 | .get_bandwidth = dvb_pll_get_bandwidth, | ||
612 | }; | ||
613 | |||
614 | int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc) | ||
615 | { | ||
616 | struct dvb_pll_priv *priv = NULL; | ||
617 | |||
618 | priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); | ||
619 | if (priv == NULL) | ||
620 | return -ENOMEM; | ||
621 | |||
622 | priv->pll_i2c_address = pll_addr; | ||
623 | priv->i2c = i2c; | ||
624 | priv->pll_desc = desc; | ||
625 | |||
626 | memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, sizeof(struct dvb_tuner_ops)); | ||
627 | strncpy(fe->ops.tuner_ops.info.name, desc->name, 128); | ||
628 | fe->ops.tuner_ops.info.frequency_min = desc->min; | ||
629 | fe->ops.tuner_ops.info.frequency_min = desc->max; | ||
630 | |||
631 | fe->tuner_priv = priv; | ||
632 | return 0; | ||
633 | } | ||
634 | EXPORT_SYMBOL(dvb_pll_attach); | ||
635 | |||
465 | MODULE_DESCRIPTION("dvb pll library"); | 636 | MODULE_DESCRIPTION("dvb pll library"); |
466 | MODULE_AUTHOR("Gerd Knorr"); | 637 | MODULE_AUTHOR("Gerd Knorr"); |
467 | MODULE_LICENSE("GPL"); | 638 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 2b8461784989..66361cd18807 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
@@ -5,6 +5,9 @@ | |||
5 | #ifndef __DVB_PLL_H__ | 5 | #ifndef __DVB_PLL_H__ |
6 | #define __DVB_PLL_H__ | 6 | #define __DVB_PLL_H__ |
7 | 7 | ||
8 | #include <linux/i2c.h> | ||
9 | #include "dvb_frontend.h" | ||
10 | |||
8 | struct dvb_pll_desc { | 11 | struct dvb_pll_desc { |
9 | char *name; | 12 | char *name; |
10 | u32 min; | 13 | u32 min; |
@@ -31,7 +34,7 @@ extern struct dvb_pll_desc dvb_pll_unknown_1; | |||
31 | extern struct dvb_pll_desc dvb_pll_tua6010xs; | 34 | extern struct dvb_pll_desc dvb_pll_tua6010xs; |
32 | extern struct dvb_pll_desc dvb_pll_env57h1xd5; | 35 | extern struct dvb_pll_desc dvb_pll_env57h1xd5; |
33 | extern struct dvb_pll_desc dvb_pll_tua6034; | 36 | extern struct dvb_pll_desc dvb_pll_tua6034; |
34 | extern struct dvb_pll_desc dvb_pll_tdvs_tua6034; | 37 | extern struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf; |
35 | extern struct dvb_pll_desc dvb_pll_tda665x; | 38 | extern struct dvb_pll_desc dvb_pll_tda665x; |
36 | extern struct dvb_pll_desc dvb_pll_fmd1216me; | 39 | extern struct dvb_pll_desc dvb_pll_fmd1216me; |
37 | extern struct dvb_pll_desc dvb_pll_tded4; | 40 | extern struct dvb_pll_desc dvb_pll_tded4; |
@@ -44,7 +47,18 @@ extern struct dvb_pll_desc dvb_pll_philips_td1316; | |||
44 | 47 | ||
45 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; | 48 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; |
46 | 49 | ||
47 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 50 | extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, |
48 | u32 freq, int bandwidth); | 51 | u32 freq, int bandwidth); |
49 | 52 | ||
53 | /** | ||
54 | * Attach a dvb-pll to the supplied frontend structure. | ||
55 | * | ||
56 | * @param fe Frontend to attach to. | ||
57 | * @param pll_addr i2c address of the PLL (if used). | ||
58 | * @param i2c i2c adapter to use (set to NULL if not used). | ||
59 | * @param desc dvb_pll_desc to use. | ||
60 | * @return 0 on success, nonzero on failure. | ||
61 | */ | ||
62 | extern int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc); | ||
63 | |||
50 | #endif | 64 | #endif |
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c index 645946a992d9..6271b1e7f6ab 100644 --- a/drivers/media/dvb/frontends/dvb_dummy_fe.c +++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c | |||
@@ -30,7 +30,6 @@ | |||
30 | 30 | ||
31 | 31 | ||
32 | struct dvb_dummy_fe_state { | 32 | struct dvb_dummy_fe_state { |
33 | struct dvb_frontend_ops ops; | ||
34 | struct dvb_frontend frontend; | 33 | struct dvb_frontend frontend; |
35 | }; | 34 | }; |
36 | 35 | ||
@@ -77,6 +76,11 @@ static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_fronten | |||
77 | 76 | ||
78 | static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 77 | static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
79 | { | 78 | { |
79 | if (fe->ops->tuner_ops->set_params) { | ||
80 | fe->ops->tuner_ops->set_params(fe, p); | ||
81 | if (fe->ops->i2c_gate_ctrl) fe->ops->i2c_gate_ctrl(fe, 0); | ||
82 | } | ||
83 | |||
80 | return 0; | 84 | return 0; |
81 | } | 85 | } |
82 | 86 | ||
@@ -116,11 +120,8 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void) | |||
116 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); | 120 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); |
117 | if (state == NULL) goto error; | 121 | if (state == NULL) goto error; |
118 | 122 | ||
119 | /* setup the state */ | ||
120 | memcpy(&state->ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops)); | ||
121 | |||
122 | /* create dvb_frontend */ | 123 | /* create dvb_frontend */ |
123 | state->frontend.ops = &state->ops; | 124 | memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops)); |
124 | state->frontend.demodulator_priv = state; | 125 | state->frontend.demodulator_priv = state; |
125 | return &state->frontend; | 126 | return &state->frontend; |
126 | 127 | ||
@@ -139,11 +140,8 @@ struct dvb_frontend* dvb_dummy_fe_qpsk_attach() | |||
139 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); | 140 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); |
140 | if (state == NULL) goto error; | 141 | if (state == NULL) goto error; |
141 | 142 | ||
142 | /* setup the state */ | ||
143 | memcpy(&state->ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops)); | ||
144 | |||
145 | /* create dvb_frontend */ | 143 | /* create dvb_frontend */ |
146 | state->frontend.ops = &state->ops; | 144 | memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops)); |
147 | state->frontend.demodulator_priv = state; | 145 | state->frontend.demodulator_priv = state; |
148 | return &state->frontend; | 146 | return &state->frontend; |
149 | 147 | ||
@@ -162,11 +160,8 @@ struct dvb_frontend* dvb_dummy_fe_qam_attach() | |||
162 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); | 160 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); |
163 | if (state == NULL) goto error; | 161 | if (state == NULL) goto error; |
164 | 162 | ||
165 | /* setup the state */ | ||
166 | memcpy(&state->ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops)); | ||
167 | |||
168 | /* create dvb_frontend */ | 163 | /* create dvb_frontend */ |
169 | state->frontend.ops = &state->ops; | 164 | memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops)); |
170 | state->frontend.demodulator_priv = state; | 165 | state->frontend.demodulator_priv = state; |
171 | return &state->frontend; | 166 | return &state->frontend; |
172 | 167 | ||
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c new file mode 100644 index 000000000000..58c34db31071 --- /dev/null +++ b/drivers/media/dvb/frontends/isl6421.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * isl6421.h - driver for lnb supply and control ic ISL6421 | ||
3 | * | ||
4 | * Copyright (C) 2006 Andrew de Quincey | ||
5 | * Copyright (C) 2006 Oliver Endriss | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
23 | * | ||
24 | * | ||
25 | * the project's page is at http://www.linuxtv.org | ||
26 | */ | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/moduleparam.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/slab.h> | ||
35 | |||
36 | #include "dvb_frontend.h" | ||
37 | #include "isl6421.h" | ||
38 | |||
39 | struct isl6421 { | ||
40 | u8 config; | ||
41 | u8 override_or; | ||
42 | u8 override_and; | ||
43 | struct i2c_adapter *i2c; | ||
44 | u8 i2c_addr; | ||
45 | void (*release_chain)(struct dvb_frontend* fe); | ||
46 | }; | ||
47 | |||
48 | static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
49 | { | ||
50 | struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; | ||
51 | struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, | ||
52 | .buf = &isl6421->config, | ||
53 | .len = sizeof(isl6421->config) }; | ||
54 | |||
55 | isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1); | ||
56 | |||
57 | switch(voltage) { | ||
58 | case SEC_VOLTAGE_OFF: | ||
59 | break; | ||
60 | case SEC_VOLTAGE_13: | ||
61 | isl6421->config |= ISL6421_EN1; | ||
62 | break; | ||
63 | case SEC_VOLTAGE_18: | ||
64 | isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1); | ||
65 | break; | ||
66 | default: | ||
67 | return -EINVAL; | ||
68 | }; | ||
69 | |||
70 | isl6421->config |= isl6421->override_or; | ||
71 | isl6421->config &= isl6421->override_and; | ||
72 | |||
73 | return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
74 | } | ||
75 | |||
76 | static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) | ||
77 | { | ||
78 | struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; | ||
79 | struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, | ||
80 | .buf = &isl6421->config, | ||
81 | .len = sizeof(isl6421->config) }; | ||
82 | |||
83 | if (arg) | ||
84 | isl6421->config |= ISL6421_LLC1; | ||
85 | else | ||
86 | isl6421->config &= ~ISL6421_LLC1; | ||
87 | |||
88 | isl6421->config |= isl6421->override_or; | ||
89 | isl6421->config &= isl6421->override_and; | ||
90 | |||
91 | return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
92 | } | ||
93 | |||
94 | static void isl6421_release(struct dvb_frontend *fe) | ||
95 | { | ||
96 | struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; | ||
97 | |||
98 | /* power off */ | ||
99 | isl6421_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
100 | |||
101 | /* free data & call next release routine */ | ||
102 | fe->ops.release = isl6421->release_chain; | ||
103 | kfree(fe->misc_priv); | ||
104 | fe->misc_priv = NULL; | ||
105 | if (fe->ops.release) | ||
106 | fe->ops.release(fe); | ||
107 | } | ||
108 | |||
109 | int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, | ||
110 | u8 override_set, u8 override_clear) | ||
111 | { | ||
112 | struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL); | ||
113 | if (!isl6421) | ||
114 | return -ENOMEM; | ||
115 | |||
116 | /* default configuration */ | ||
117 | isl6421->config = ISL6421_ISEL1; | ||
118 | isl6421->i2c = i2c; | ||
119 | isl6421->i2c_addr = i2c_addr; | ||
120 | fe->misc_priv = isl6421; | ||
121 | |||
122 | /* bits which should be forced to '1' */ | ||
123 | isl6421->override_or = override_set; | ||
124 | |||
125 | /* bits which should be forced to '0' */ | ||
126 | isl6421->override_and = ~override_clear; | ||
127 | |||
128 | /* detect if it is present or not */ | ||
129 | if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) { | ||
130 | kfree(isl6421); | ||
131 | fe->misc_priv = NULL; | ||
132 | return -EIO; | ||
133 | } | ||
134 | |||
135 | /* install release callback */ | ||
136 | isl6421->release_chain = fe->ops.release; | ||
137 | fe->ops.release = isl6421_release; | ||
138 | |||
139 | /* override frontend ops */ | ||
140 | fe->ops.set_voltage = isl6421_set_voltage; | ||
141 | fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage; | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | EXPORT_SYMBOL(isl6421_attach); | ||
146 | |||
147 | MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421"); | ||
148 | MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss"); | ||
149 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h new file mode 100644 index 000000000000..675f80a19b99 --- /dev/null +++ b/drivers/media/dvb/frontends/isl6421.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * isl6421.h - driver for lnb supply and control ic ISL6421 | ||
3 | * | ||
4 | * Copyright (C) 2006 Andrew de Quincey | ||
5 | * Copyright (C) 2006 Oliver Endriss | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
23 | * | ||
24 | * | ||
25 | * the project's page is at http://www.linuxtv.org | ||
26 | */ | ||
27 | |||
28 | #ifndef _ISL6421_H | ||
29 | #define _ISL6421_H | ||
30 | |||
31 | #include <linux/dvb/frontend.h> | ||
32 | |||
33 | /* system register bits */ | ||
34 | #define ISL6421_OLF1 0x01 | ||
35 | #define ISL6421_EN1 0x02 | ||
36 | #define ISL6421_VSEL1 0x04 | ||
37 | #define ISL6421_LLC1 0x08 | ||
38 | #define ISL6421_ENT1 0x10 | ||
39 | #define ISL6421_ISEL1 0x20 | ||
40 | #define ISL6421_DCL 0x40 | ||
41 | |||
42 | /* override_set and override_clear control which system register bits (above) to always set & clear */ | ||
43 | extern int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, | ||
44 | u8 override_set, u8 override_clear); | ||
45 | |||
46 | #endif | ||
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c index 1c7c91224472..f3bc82e44a28 100644 --- a/drivers/media/dvb/frontends/l64781.c +++ b/drivers/media/dvb/frontends/l64781.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | struct l64781_state { | 33 | struct l64781_state { |
34 | struct i2c_adapter* i2c; | 34 | struct i2c_adapter* i2c; |
35 | struct dvb_frontend_ops ops; | ||
36 | const struct l64781_config* config; | 35 | const struct l64781_config* config; |
37 | struct dvb_frontend frontend; | 36 | struct dvb_frontend frontend; |
38 | 37 | ||
@@ -141,7 +140,10 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa | |||
141 | u8 val0x06; | 140 | u8 val0x06; |
142 | int bw = p->bandwidth - BANDWIDTH_8_MHZ; | 141 | int bw = p->bandwidth - BANDWIDTH_8_MHZ; |
143 | 142 | ||
144 | state->config->pll_set(fe, param); | 143 | if (fe->ops.tuner_ops.set_params) { |
144 | fe->ops.tuner_ops.set_params(fe, param); | ||
145 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
146 | } | ||
145 | 147 | ||
146 | if (param->inversion != INVERSION_ON && | 148 | if (param->inversion != INVERSION_ON && |
147 | param->inversion != INVERSION_OFF) | 149 | param->inversion != INVERSION_OFF) |
@@ -463,8 +465,6 @@ static int l64781_init(struct dvb_frontend* fe) | |||
463 | /* Everything is two's complement, soft bit and CSI_OUT too */ | 465 | /* Everything is two's complement, soft bit and CSI_OUT too */ |
464 | l64781_writereg (state, 0x1e, 0x09); | 466 | l64781_writereg (state, 0x1e, 0x09); |
465 | 467 | ||
466 | if (state->config->pll_init) state->config->pll_init(fe); | ||
467 | |||
468 | /* delay a bit after first init attempt */ | 468 | /* delay a bit after first init attempt */ |
469 | if (state->first) { | 469 | if (state->first) { |
470 | state->first = 0; | 470 | state->first = 0; |
@@ -508,7 +508,6 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config, | |||
508 | /* setup the state */ | 508 | /* setup the state */ |
509 | state->config = config; | 509 | state->config = config; |
510 | state->i2c = i2c; | 510 | state->i2c = i2c; |
511 | memcpy(&state->ops, &l64781_ops, sizeof(struct dvb_frontend_ops)); | ||
512 | state->first = 1; | 511 | state->first = 1; |
513 | 512 | ||
514 | /** | 513 | /** |
@@ -554,7 +553,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config, | |||
554 | } | 553 | } |
555 | 554 | ||
556 | /* create dvb_frontend */ | 555 | /* create dvb_frontend */ |
557 | state->frontend.ops = &state->ops; | 556 | memcpy(&state->frontend.ops, &l64781_ops, sizeof(struct dvb_frontend_ops)); |
558 | state->frontend.demodulator_priv = state; | 557 | state->frontend.demodulator_priv = state; |
559 | return &state->frontend; | 558 | return &state->frontend; |
560 | 559 | ||
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h index 947f65f87465..83b8bc210274 100644 --- a/drivers/media/dvb/frontends/l64781.h +++ b/drivers/media/dvb/frontends/l64781.h | |||
@@ -29,10 +29,6 @@ struct l64781_config | |||
29 | { | 29 | { |
30 | /* the demodulator's i2c address */ | 30 | /* the demodulator's i2c address */ |
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | |||
33 | /* PLL maintenance */ | ||
34 | int (*pll_init)(struct dvb_frontend* fe); | ||
35 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
36 | }; | 32 | }; |
37 | 33 | ||
38 | 34 | ||
diff --git a/drivers/media/dvb/frontends/lg_h06xf.h b/drivers/media/dvb/frontends/lg_h06xf.h new file mode 100644 index 000000000000..754d51d11120 --- /dev/null +++ b/drivers/media/dvb/frontends/lg_h06xf.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * lg_h06xf.h - ATSC Tuner support for LG TDVS-H06xF | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | #ifndef _LG_H06XF_H_ | ||
20 | #define _LG_H06XF_H_ | ||
21 | #include "dvb-pll.h" | ||
22 | |||
23 | static int lg_h06xf_pll_set(struct dvb_frontend* fe, struct i2c_adapter* i2c_adap, | ||
24 | struct dvb_frontend_parameters* params) | ||
25 | { | ||
26 | u8 buf[4]; | ||
27 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, | ||
28 | .buf = buf, .len = sizeof(buf) }; | ||
29 | int err; | ||
30 | |||
31 | dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, params->frequency, 0); | ||
32 | if (fe->ops.i2c_gate_ctrl) | ||
33 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
34 | if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) { | ||
35 | printk(KERN_WARNING "lg_h06xf: %s error " | ||
36 | "(addr %02x <- %02x, err = %i)\n", | ||
37 | __FUNCTION__, buf[0], buf[1], err); | ||
38 | if (err < 0) | ||
39 | return err; | ||
40 | else | ||
41 | return -EREMOTEIO; | ||
42 | } | ||
43 | |||
44 | /* Set the Auxiliary Byte. */ | ||
45 | buf[0] = buf[2]; | ||
46 | buf[0] &= ~0x20; | ||
47 | buf[0] |= 0x18; | ||
48 | buf[1] = 0x50; | ||
49 | msg.len = 2; | ||
50 | if (fe->ops.i2c_gate_ctrl) | ||
51 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
52 | if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) { | ||
53 | printk(KERN_WARNING "lg_h06xf: %s error " | ||
54 | "(addr %02x <- %02x, err = %i)\n", | ||
55 | __FUNCTION__, buf[0], buf[1], err); | ||
56 | if (err < 0) | ||
57 | return err; | ||
58 | else | ||
59 | return -EREMOTEIO; | ||
60 | } | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | #endif | ||
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index 4691ac54bc1d..6e8ad176e1a1 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c | |||
@@ -29,6 +29,7 @@ | |||
29 | * DViCO FusionHDTV 5 Lite | 29 | * DViCO FusionHDTV 5 Lite |
30 | * DViCO FusionHDTV 5 USB Gold | 30 | * DViCO FusionHDTV 5 USB Gold |
31 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) | 31 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) |
32 | * pcHDTV HD5500 | ||
32 | * | 33 | * |
33 | * TODO: | 34 | * TODO: |
34 | * signal strength always returns 0. | 35 | * signal strength always returns 0. |
@@ -59,7 +60,6 @@ if (debug) printk(KERN_DEBUG "lgdt330x: " args); \ | |||
59 | struct lgdt330x_state | 60 | struct lgdt330x_state |
60 | { | 61 | { |
61 | struct i2c_adapter* i2c; | 62 | struct i2c_adapter* i2c; |
62 | struct dvb_frontend_ops ops; | ||
63 | 63 | ||
64 | /* Configuration settings */ | 64 | /* Configuration settings */ |
65 | const struct lgdt330x_config* config; | 65 | const struct lgdt330x_config* config; |
@@ -399,8 +399,10 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, | |||
399 | } | 399 | } |
400 | 400 | ||
401 | /* Tune to the specified frequency */ | 401 | /* Tune to the specified frequency */ |
402 | if (state->config->pll_set) | 402 | if (fe->ops.tuner_ops.set_params) { |
403 | state->config->pll_set(fe, param); | 403 | fe->ops.tuner_ops.set_params(fe, param); |
404 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
405 | } | ||
404 | 406 | ||
405 | /* Keep track of the new frequency */ | 407 | /* Keep track of the new frequency */ |
406 | /* FIXME this is the wrong way to do this... */ | 408 | /* FIXME this is the wrong way to do this... */ |
@@ -672,6 +674,7 @@ static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr) | |||
672 | 674 | ||
673 | if (state->current_modulation == VSB_8) { | 675 | if (state->current_modulation == VSB_8) { |
674 | 676 | ||
677 | i2c_read_demod_bytes(state, 0x6e, buf, 5); | ||
675 | /* Phase Tracker Mean-Square Error Register for VSB */ | 678 | /* Phase Tracker Mean-Square Error Register for VSB */ |
676 | noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; | 679 | noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; |
677 | } else { | 680 | } else { |
@@ -721,16 +724,19 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, | |||
721 | /* Setup the state */ | 724 | /* Setup the state */ |
722 | state->config = config; | 725 | state->config = config; |
723 | state->i2c = i2c; | 726 | state->i2c = i2c; |
727 | |||
728 | /* Create dvb_frontend */ | ||
724 | switch (config->demod_chip) { | 729 | switch (config->demod_chip) { |
725 | case LGDT3302: | 730 | case LGDT3302: |
726 | memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops)); | 731 | memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops)); |
727 | break; | 732 | break; |
728 | case LGDT3303: | 733 | case LGDT3303: |
729 | memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops)); | 734 | memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops)); |
730 | break; | 735 | break; |
731 | default: | 736 | default: |
732 | goto error; | 737 | goto error; |
733 | } | 738 | } |
739 | state->frontend.demodulator_priv = state; | ||
734 | 740 | ||
735 | /* Verify communication with demod chip */ | 741 | /* Verify communication with demod chip */ |
736 | if (i2c_read_demod_bytes(state, 2, buf, 1)) | 742 | if (i2c_read_demod_bytes(state, 2, buf, 1)) |
@@ -739,9 +745,6 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, | |||
739 | state->current_frequency = -1; | 745 | state->current_frequency = -1; |
740 | state->current_modulation = -1; | 746 | state->current_modulation = -1; |
741 | 747 | ||
742 | /* Create dvb_frontend */ | ||
743 | state->frontend.ops = &state->ops; | ||
744 | state->frontend.demodulator_priv = state; | ||
745 | return &state->frontend; | 748 | return &state->frontend; |
746 | 749 | ||
747 | error: | 750 | error: |
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h index 2a6529cccf1a..bad903c6f0f8 100644 --- a/drivers/media/dvb/frontends/lgdt330x.h +++ b/drivers/media/dvb/frontends/lgdt330x.h | |||
@@ -43,7 +43,6 @@ struct lgdt330x_config | |||
43 | 43 | ||
44 | /* PLL interface */ | 44 | /* PLL interface */ |
45 | int (*pll_rf_set) (struct dvb_frontend* fe, int index); | 45 | int (*pll_rf_set) (struct dvb_frontend* fe, int index); |
46 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
47 | 46 | ||
48 | /* Need to set device param for start_dma */ | 47 | /* Need to set device param for start_dma */ |
49 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 48 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c new file mode 100644 index 000000000000..e933edc8dd29 --- /dev/null +++ b/drivers/media/dvb/frontends/lnbp21.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * lnbp21.h - driver for lnb supply and control ic lnbp21 | ||
3 | * | ||
4 | * Copyright (C) 2006 Oliver Endriss | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version 2 | ||
9 | * of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
22 | * | ||
23 | * | ||
24 | * the project's page is at http://www.linuxtv.org | ||
25 | */ | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/moduleparam.h> | ||
32 | #include <linux/string.h> | ||
33 | #include <linux/slab.h> | ||
34 | |||
35 | #include "dvb_frontend.h" | ||
36 | #include "lnbp21.h" | ||
37 | |||
38 | struct lnbp21 { | ||
39 | u8 config; | ||
40 | u8 override_or; | ||
41 | u8 override_and; | ||
42 | struct i2c_adapter *i2c; | ||
43 | void (*release_chain)(struct dvb_frontend* fe); | ||
44 | }; | ||
45 | |||
46 | static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
47 | { | ||
48 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
49 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, | ||
50 | .buf = &lnbp21->config, | ||
51 | .len = sizeof(lnbp21->config) }; | ||
52 | |||
53 | lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); | ||
54 | |||
55 | switch(voltage) { | ||
56 | case SEC_VOLTAGE_OFF: | ||
57 | break; | ||
58 | case SEC_VOLTAGE_13: | ||
59 | lnbp21->config |= LNBP21_EN; | ||
60 | break; | ||
61 | case SEC_VOLTAGE_18: | ||
62 | lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); | ||
63 | break; | ||
64 | default: | ||
65 | return -EINVAL; | ||
66 | }; | ||
67 | |||
68 | lnbp21->config |= lnbp21->override_or; | ||
69 | lnbp21->config &= lnbp21->override_and; | ||
70 | |||
71 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
72 | } | ||
73 | |||
74 | static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) | ||
75 | { | ||
76 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
77 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, | ||
78 | .buf = &lnbp21->config, | ||
79 | .len = sizeof(lnbp21->config) }; | ||
80 | |||
81 | if (arg) | ||
82 | lnbp21->config |= LNBP21_LLC; | ||
83 | else | ||
84 | lnbp21->config &= ~LNBP21_LLC; | ||
85 | |||
86 | lnbp21->config |= lnbp21->override_or; | ||
87 | lnbp21->config &= lnbp21->override_and; | ||
88 | |||
89 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
90 | } | ||
91 | |||
92 | static void lnbp21_release(struct dvb_frontend *fe) | ||
93 | { | ||
94 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
95 | |||
96 | /* LNBP power off */ | ||
97 | lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
98 | |||
99 | /* free data & call next release routine */ | ||
100 | fe->ops.release = lnbp21->release_chain; | ||
101 | kfree(fe->misc_priv); | ||
102 | fe->misc_priv = NULL; | ||
103 | if (fe->ops.release) | ||
104 | fe->ops.release(fe); | ||
105 | } | ||
106 | |||
107 | int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) | ||
108 | { | ||
109 | struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); | ||
110 | if (!lnbp21) | ||
111 | return -ENOMEM; | ||
112 | |||
113 | /* default configuration */ | ||
114 | lnbp21->config = LNBP21_ISEL; | ||
115 | lnbp21->i2c = i2c; | ||
116 | fe->misc_priv = lnbp21; | ||
117 | |||
118 | /* bits which should be forced to '1' */ | ||
119 | lnbp21->override_or = override_set; | ||
120 | |||
121 | /* bits which should be forced to '0' */ | ||
122 | lnbp21->override_and = ~override_clear; | ||
123 | |||
124 | /* detect if it is present or not */ | ||
125 | if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) { | ||
126 | kfree(lnbp21); | ||
127 | fe->misc_priv = NULL; | ||
128 | return -EIO; | ||
129 | } | ||
130 | |||
131 | /* install release callback */ | ||
132 | lnbp21->release_chain = fe->ops.release; | ||
133 | fe->ops.release = lnbp21_release; | ||
134 | |||
135 | /* override frontend ops */ | ||
136 | fe->ops.set_voltage = lnbp21_set_voltage; | ||
137 | fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | EXPORT_SYMBOL(lnbp21_attach); | ||
142 | |||
143 | MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21"); | ||
144 | MODULE_AUTHOR("Oliver Endriss"); | ||
145 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h index 0dcbe61b61b1..047a4ab68c01 100644 --- a/drivers/media/dvb/frontends/lnbp21.h +++ b/drivers/media/dvb/frontends/lnbp21.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #ifndef _LNBP21_H | 27 | #ifndef _LNBP21_H |
28 | #define _LNBP21_H | 28 | #define _LNBP21_H |
29 | 29 | ||
30 | /* system register */ | 30 | /* system register bits */ |
31 | #define LNBP21_OLF 0x01 | 31 | #define LNBP21_OLF 0x01 |
32 | #define LNBP21_OTF 0x02 | 32 | #define LNBP21_OTF 0x02 |
33 | #define LNBP21_EN 0x04 | 33 | #define LNBP21_EN 0x04 |
@@ -37,103 +37,9 @@ | |||
37 | #define LNBP21_ISEL 0x40 | 37 | #define LNBP21_ISEL 0x40 |
38 | #define LNBP21_PCL 0x80 | 38 | #define LNBP21_PCL 0x80 |
39 | 39 | ||
40 | struct lnbp21 { | 40 | #include <linux/dvb/frontend.h> |
41 | u8 config; | ||
42 | u8 override_or; | ||
43 | u8 override_and; | ||
44 | struct i2c_adapter *i2c; | ||
45 | void (*release_chain)(struct dvb_frontend* fe); | ||
46 | }; | ||
47 | 41 | ||
48 | static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 42 | /* override_set and override_clear control which system register bits (above) to always set & clear */ |
49 | { | 43 | extern int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); |
50 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
51 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, | ||
52 | .buf = &lnbp21->config, | ||
53 | .len = sizeof(lnbp21->config) }; | ||
54 | |||
55 | lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); | ||
56 | |||
57 | switch(voltage) { | ||
58 | case SEC_VOLTAGE_OFF: | ||
59 | break; | ||
60 | case SEC_VOLTAGE_13: | ||
61 | lnbp21->config |= LNBP21_EN; | ||
62 | break; | ||
63 | case SEC_VOLTAGE_18: | ||
64 | lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); | ||
65 | break; | ||
66 | default: | ||
67 | return -EINVAL; | ||
68 | }; | ||
69 | |||
70 | lnbp21->config |= lnbp21->override_or; | ||
71 | lnbp21->config &= lnbp21->override_and; | ||
72 | |||
73 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
74 | } | ||
75 | |||
76 | static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) | ||
77 | { | ||
78 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
79 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, | ||
80 | .buf = &lnbp21->config, | ||
81 | .len = sizeof(lnbp21->config) }; | ||
82 | |||
83 | if (arg) | ||
84 | lnbp21->config |= LNBP21_LLC; | ||
85 | else | ||
86 | lnbp21->config &= ~LNBP21_LLC; | ||
87 | |||
88 | lnbp21->config |= lnbp21->override_or; | ||
89 | lnbp21->config &= lnbp21->override_and; | ||
90 | |||
91 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
92 | } | ||
93 | |||
94 | static void lnbp21_exit(struct dvb_frontend *fe) | ||
95 | { | ||
96 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
97 | |||
98 | /* LNBP power off */ | ||
99 | lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
100 | |||
101 | /* free data & call next release routine */ | ||
102 | fe->ops->release = lnbp21->release_chain; | ||
103 | kfree(fe->misc_priv); | ||
104 | fe->misc_priv = NULL; | ||
105 | if (fe->ops->release) | ||
106 | fe->ops->release(fe); | ||
107 | } | ||
108 | |||
109 | static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) | ||
110 | { | ||
111 | struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); | ||
112 | |||
113 | if (!lnbp21) | ||
114 | return -ENOMEM; | ||
115 | |||
116 | /* default configuration */ | ||
117 | lnbp21->config = LNBP21_ISEL; | ||
118 | |||
119 | /* bits which should be forced to '1' */ | ||
120 | lnbp21->override_or = override_set; | ||
121 | |||
122 | /* bits which should be forced to '0' */ | ||
123 | lnbp21->override_and = ~override_clear; | ||
124 | |||
125 | /* install release callback */ | ||
126 | lnbp21->release_chain = fe->ops->release; | ||
127 | fe->ops->release = lnbp21_exit; | ||
128 | |||
129 | /* override frontend ops */ | ||
130 | fe->ops->set_voltage = lnbp21_set_voltage; | ||
131 | fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | ||
132 | |||
133 | lnbp21->i2c = i2c; | ||
134 | fe->misc_priv = lnbp21; | ||
135 | |||
136 | return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
137 | } | ||
138 | 44 | ||
139 | #endif | 45 | #endif |
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c index d3aea83cf218..1ef821825641 100644 --- a/drivers/media/dvb/frontends/mt312.c +++ b/drivers/media/dvb/frontends/mt312.c | |||
@@ -39,7 +39,6 @@ | |||
39 | 39 | ||
40 | struct mt312_state { | 40 | struct mt312_state { |
41 | struct i2c_adapter* i2c; | 41 | struct i2c_adapter* i2c; |
42 | struct dvb_frontend_ops ops; | ||
43 | /* configuration settings */ | 42 | /* configuration settings */ |
44 | const struct mt312_config* config; | 43 | const struct mt312_config* config; |
45 | struct dvb_frontend frontend; | 44 | struct dvb_frontend frontend; |
@@ -277,12 +276,6 @@ static int mt312_initfe(struct dvb_frontend* fe) | |||
277 | if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0) | 276 | if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0) |
278 | return ret; | 277 | return ret; |
279 | 278 | ||
280 | if (state->config->pll_init) { | ||
281 | mt312_writereg(state, GPP_CTRL, 0x40); | ||
282 | state->config->pll_init(fe); | ||
283 | mt312_writereg(state, GPP_CTRL, 0x00); | ||
284 | } | ||
285 | |||
286 | return 0; | 279 | return 0; |
287 | } | 280 | } |
288 | 281 | ||
@@ -477,16 +470,16 @@ static int mt312_set_frontend(struct dvb_frontend* fe, | |||
477 | 470 | ||
478 | dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency); | 471 | dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency); |
479 | 472 | ||
480 | if ((p->frequency < fe->ops->info.frequency_min) | 473 | if ((p->frequency < fe->ops.info.frequency_min) |
481 | || (p->frequency > fe->ops->info.frequency_max)) | 474 | || (p->frequency > fe->ops.info.frequency_max)) |
482 | return -EINVAL; | 475 | return -EINVAL; |
483 | 476 | ||
484 | if ((p->inversion < INVERSION_OFF) | 477 | if ((p->inversion < INVERSION_OFF) |
485 | || (p->inversion > INVERSION_ON)) | 478 | || (p->inversion > INVERSION_ON)) |
486 | return -EINVAL; | 479 | return -EINVAL; |
487 | 480 | ||
488 | if ((p->u.qpsk.symbol_rate < fe->ops->info.symbol_rate_min) | 481 | if ((p->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) |
489 | || (p->u.qpsk.symbol_rate > fe->ops->info.symbol_rate_max)) | 482 | || (p->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) |
490 | return -EINVAL; | 483 | return -EINVAL; |
491 | 484 | ||
492 | if ((p->u.qpsk.fec_inner < FEC_NONE) | 485 | if ((p->u.qpsk.fec_inner < FEC_NONE) |
@@ -529,9 +522,10 @@ static int mt312_set_frontend(struct dvb_frontend* fe, | |||
529 | return -EINVAL; | 522 | return -EINVAL; |
530 | } | 523 | } |
531 | 524 | ||
532 | mt312_writereg(state, GPP_CTRL, 0x40); | 525 | if (fe->ops.tuner_ops.set_params) { |
533 | state->config->pll_set(fe, p); | 526 | fe->ops.tuner_ops.set_params(fe, p); |
534 | mt312_writereg(state, GPP_CTRL, 0x00); | 527 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
528 | } | ||
535 | 529 | ||
536 | /* sr = (u16)(sr * 256.0 / 1000000.0) */ | 530 | /* sr = (u16)(sr * 256.0 / 1000000.0) */ |
537 | sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625); | 531 | sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625); |
@@ -578,6 +572,17 @@ static int mt312_get_frontend(struct dvb_frontend* fe, | |||
578 | return 0; | 572 | return 0; |
579 | } | 573 | } |
580 | 574 | ||
575 | static int mt312_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
576 | { | ||
577 | struct mt312_state* state = fe->demodulator_priv; | ||
578 | |||
579 | if (enable) { | ||
580 | return mt312_writereg(state, GPP_CTRL, 0x40); | ||
581 | } else { | ||
582 | return mt312_writereg(state, GPP_CTRL, 0x00); | ||
583 | } | ||
584 | } | ||
585 | |||
581 | static int mt312_sleep(struct dvb_frontend* fe) | 586 | static int mt312_sleep(struct dvb_frontend* fe) |
582 | { | 587 | { |
583 | struct mt312_state *state = fe->demodulator_priv; | 588 | struct mt312_state *state = fe->demodulator_priv; |
@@ -633,6 +638,7 @@ static struct dvb_frontend_ops vp310_mt312_ops = { | |||
633 | 638 | ||
634 | .init = mt312_initfe, | 639 | .init = mt312_initfe, |
635 | .sleep = mt312_sleep, | 640 | .sleep = mt312_sleep, |
641 | .i2c_gate_ctrl = mt312_i2c_gate_ctrl, | ||
636 | 642 | ||
637 | .set_frontend = mt312_set_frontend, | 643 | .set_frontend = mt312_set_frontend, |
638 | .get_frontend = mt312_get_frontend, | 644 | .get_frontend = mt312_get_frontend, |
@@ -663,19 +669,22 @@ struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, | |||
663 | /* setup the state */ | 669 | /* setup the state */ |
664 | state->config = config; | 670 | state->config = config; |
665 | state->i2c = i2c; | 671 | state->i2c = i2c; |
666 | memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); | ||
667 | 672 | ||
668 | /* check if the demod is there */ | 673 | /* check if the demod is there */ |
669 | if (mt312_readreg(state, ID, &state->id) < 0) | 674 | if (mt312_readreg(state, ID, &state->id) < 0) |
670 | goto error; | 675 | goto error; |
671 | 676 | ||
677 | /* create dvb_frontend */ | ||
678 | memcpy(&state->frontend.ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); | ||
679 | state->frontend.demodulator_priv = state; | ||
680 | |||
672 | switch (state->id) { | 681 | switch (state->id) { |
673 | case ID_VP310: | 682 | case ID_VP310: |
674 | strcpy(state->ops.info.name, "Zarlink VP310 DVB-S"); | 683 | strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S"); |
675 | state->frequency = 90; | 684 | state->frequency = 90; |
676 | break; | 685 | break; |
677 | case ID_MT312: | 686 | case ID_MT312: |
678 | strcpy(state->ops.info.name, "Zarlink MT312 DVB-S"); | 687 | strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S"); |
679 | state->frequency = 60; | 688 | state->frequency = 60; |
680 | break; | 689 | break; |
681 | default: | 690 | default: |
@@ -683,9 +692,6 @@ struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, | |||
683 | goto error; | 692 | goto error; |
684 | } | 693 | } |
685 | 694 | ||
686 | /* create dvb_frontend */ | ||
687 | state->frontend.ops = &state->ops; | ||
688 | state->frontend.demodulator_priv = state; | ||
689 | return &state->frontend; | 695 | return &state->frontend; |
690 | 696 | ||
691 | error: | 697 | error: |
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h index 074d844f0139..666a1bd1c244 100644 --- a/drivers/media/dvb/frontends/mt312.h +++ b/drivers/media/dvb/frontends/mt312.h | |||
@@ -32,10 +32,6 @@ struct mt312_config | |||
32 | { | 32 | { |
33 | /* the demodulator's i2c address */ | 33 | /* the demodulator's i2c address */ |
34 | u8 demod_address; | 34 | u8 demod_address; |
35 | |||
36 | /* PLL maintenance */ | ||
37 | int (*pll_init)(struct dvb_frontend* fe); | ||
38 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
39 | }; | 35 | }; |
40 | 36 | ||
41 | struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, | 37 | struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, |
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c index aaaec909ddf8..5de7376c94ce 100644 --- a/drivers/media/dvb/frontends/mt352.c +++ b/drivers/media/dvb/frontends/mt352.c | |||
@@ -45,7 +45,6 @@ | |||
45 | struct mt352_state { | 45 | struct mt352_state { |
46 | struct i2c_adapter* i2c; | 46 | struct i2c_adapter* i2c; |
47 | struct dvb_frontend frontend; | 47 | struct dvb_frontend frontend; |
48 | struct dvb_frontend_ops ops; | ||
49 | 48 | ||
50 | /* configuration settings */ | 49 | /* configuration settings */ |
51 | struct mt352_config config; | 50 | struct mt352_config config; |
@@ -286,16 +285,25 @@ static int mt352_set_parameters(struct dvb_frontend* fe, | |||
286 | 285 | ||
287 | mt352_calc_nominal_rate(state, op->bandwidth, buf+4); | 286 | mt352_calc_nominal_rate(state, op->bandwidth, buf+4); |
288 | mt352_calc_input_freq(state, buf+6); | 287 | mt352_calc_input_freq(state, buf+6); |
289 | state->config.pll_set(fe, param, buf+8); | ||
290 | 288 | ||
291 | mt352_write(fe, buf, sizeof(buf)); | ||
292 | if (state->config.no_tuner) { | 289 | if (state->config.no_tuner) { |
293 | /* start decoding */ | 290 | if (fe->ops.tuner_ops.set_params) { |
291 | fe->ops.tuner_ops.set_params(fe, param); | ||
292 | if (fe->ops.i2c_gate_ctrl) | ||
293 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
294 | } | ||
295 | |||
296 | mt352_write(fe, buf, 8); | ||
294 | mt352_write(fe, fsm_go, 2); | 297 | mt352_write(fe, fsm_go, 2); |
295 | } else { | 298 | } else { |
296 | /* start tuning */ | 299 | if (fe->ops.tuner_ops.calc_regs) { |
297 | mt352_write(fe, tuner_go, 2); | 300 | fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5); |
301 | buf[8] <<= 1; | ||
302 | mt352_write(fe, buf, sizeof(buf)); | ||
303 | mt352_write(fe, tuner_go, 2); | ||
304 | } | ||
298 | } | 305 | } |
306 | |||
299 | return 0; | 307 | return 0; |
300 | } | 308 | } |
301 | 309 | ||
@@ -541,13 +549,12 @@ struct dvb_frontend* mt352_attach(const struct mt352_config* config, | |||
541 | /* setup the state */ | 549 | /* setup the state */ |
542 | state->i2c = i2c; | 550 | state->i2c = i2c; |
543 | memcpy(&state->config,config,sizeof(struct mt352_config)); | 551 | memcpy(&state->config,config,sizeof(struct mt352_config)); |
544 | memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops)); | ||
545 | 552 | ||
546 | /* check if the demod is there */ | 553 | /* check if the demod is there */ |
547 | if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error; | 554 | if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error; |
548 | 555 | ||
549 | /* create dvb_frontend */ | 556 | /* create dvb_frontend */ |
550 | state->frontend.ops = &state->ops; | 557 | memcpy(&state->frontend.ops, &mt352_ops, sizeof(struct dvb_frontend_ops)); |
551 | state->frontend.demodulator_priv = state; | 558 | state->frontend.demodulator_priv = state; |
552 | return &state->frontend; | 559 | return &state->frontend; |
553 | 560 | ||
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h index 03040cd595bb..9e7ff4b8fe5f 100644 --- a/drivers/media/dvb/frontends/mt352.h +++ b/drivers/media/dvb/frontends/mt352.h | |||
@@ -49,12 +49,6 @@ struct mt352_config | |||
49 | 49 | ||
50 | /* Initialise the demodulator and PLL. Cannot be NULL */ | 50 | /* Initialise the demodulator and PLL. Cannot be NULL */ |
51 | int (*demod_init)(struct dvb_frontend* fe); | 51 | int (*demod_init)(struct dvb_frontend* fe); |
52 | |||
53 | /* PLL setup - fill out the supplied 5 byte buffer with your PLL settings. | ||
54 | * byte0: Set to pll i2c address (nonlinux; left shifted by 1) | ||
55 | * byte1-4: PLL configuration. | ||
56 | */ | ||
57 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf); | ||
58 | }; | 52 | }; |
59 | 53 | ||
60 | extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, | 54 | extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, |
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c index 9e3535394509..55671cb5255e 100644 --- a/drivers/media/dvb/frontends/nxt200x.c +++ b/drivers/media/dvb/frontends/nxt200x.c | |||
@@ -55,7 +55,6 @@ | |||
55 | struct nxt200x_state { | 55 | struct nxt200x_state { |
56 | 56 | ||
57 | struct i2c_adapter* i2c; | 57 | struct i2c_adapter* i2c; |
58 | struct dvb_frontend_ops ops; | ||
59 | const struct nxt200x_config* config; | 58 | const struct nxt200x_config* config; |
60 | struct dvb_frontend frontend; | 59 | struct dvb_frontend frontend; |
61 | 60 | ||
@@ -333,17 +332,17 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) | |||
333 | 332 | ||
334 | dprintk("%s\n", __FUNCTION__); | 333 | dprintk("%s\n", __FUNCTION__); |
335 | 334 | ||
336 | dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]); | 335 | dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]); |
337 | 336 | ||
338 | /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip. | 337 | /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip. |
339 | * direct write is required for Philips TUV1236D and ALPS TDHU2 */ | 338 | * direct write is required for Philips TUV1236D and ALPS TDHU2 */ |
340 | switch (state->demod_chip) { | 339 | switch (state->demod_chip) { |
341 | case NXT2004: | 340 | case NXT2004: |
342 | if (i2c_writebytes(state, state->config->pll_address, data, 4)) | 341 | if (i2c_writebytes(state, data[0], data+1, 4)) |
343 | printk(KERN_WARNING "nxt200x: error writing to tuner\n"); | 342 | printk(KERN_WARNING "nxt200x: error writing to tuner\n"); |
344 | /* wait until we have a lock */ | 343 | /* wait until we have a lock */ |
345 | while (count < 20) { | 344 | while (count < 20) { |
346 | i2c_readbytes(state, state->config->pll_address, &buf, 1); | 345 | i2c_readbytes(state, data[0], &buf, 1); |
347 | if (buf & 0x40) | 346 | if (buf & 0x40) |
348 | return 0; | 347 | return 0; |
349 | msleep(100); | 348 | msleep(100); |
@@ -361,10 +360,10 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) | |||
361 | nxt200x_writebytes(state, 0x34, &buf, 1); | 360 | nxt200x_writebytes(state, 0x34, &buf, 1); |
362 | 361 | ||
363 | /* write actual tuner bytes */ | 362 | /* write actual tuner bytes */ |
364 | nxt200x_writebytes(state, 0x36, data, 4); | 363 | nxt200x_writebytes(state, 0x36, data+1, 4); |
365 | 364 | ||
366 | /* set tuner i2c address */ | 365 | /* set tuner i2c address */ |
367 | buf = state->config->pll_address; | 366 | buf = data[0] << 1; |
368 | nxt200x_writebytes(state, 0x35, &buf, 1); | 367 | nxt200x_writebytes(state, 0x35, &buf, 1); |
369 | 368 | ||
370 | /* write UC Opmode to begin transfer */ | 369 | /* write UC Opmode to begin transfer */ |
@@ -534,7 +533,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
534 | struct dvb_frontend_parameters *p) | 533 | struct dvb_frontend_parameters *p) |
535 | { | 534 | { |
536 | struct nxt200x_state* state = fe->demodulator_priv; | 535 | struct nxt200x_state* state = fe->demodulator_priv; |
537 | u8 buf[4]; | 536 | u8 buf[5]; |
538 | 537 | ||
539 | /* stop the micro first */ | 538 | /* stop the micro first */ |
540 | nxt200x_microcontroller_stop(state); | 539 | nxt200x_microcontroller_stop(state); |
@@ -548,7 +547,9 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
548 | } | 547 | } |
549 | 548 | ||
550 | /* get tuning information */ | 549 | /* get tuning information */ |
551 | dvb_pll_configure(state->config->pll_desc, buf, p->frequency, 0); | 550 | if (fe->ops.tuner_ops.calc_regs) { |
551 | fe->ops.tuner_ops.calc_regs(fe, p, buf, 5); | ||
552 | } | ||
552 | 553 | ||
553 | /* set additional params */ | 554 | /* set additional params */ |
554 | switch (p->u.vsb.modulation) { | 555 | switch (p->u.vsb.modulation) { |
@@ -1159,7 +1160,6 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, | |||
1159 | /* setup the state */ | 1160 | /* setup the state */ |
1160 | state->config = config; | 1161 | state->config = config; |
1161 | state->i2c = i2c; | 1162 | state->i2c = i2c; |
1162 | memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops)); | ||
1163 | state->initialised = 0; | 1163 | state->initialised = 0; |
1164 | 1164 | ||
1165 | /* read card id */ | 1165 | /* read card id */ |
@@ -1198,7 +1198,7 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, | |||
1198 | } | 1198 | } |
1199 | 1199 | ||
1200 | /* create dvb_frontend */ | 1200 | /* create dvb_frontend */ |
1201 | state->frontend.ops = &state->ops; | 1201 | memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops)); |
1202 | state->frontend.demodulator_priv = state; | 1202 | state->frontend.demodulator_priv = state; |
1203 | return &state->frontend; | 1203 | return &state->frontend; |
1204 | 1204 | ||
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h index 1d9d70bc37ef..34d61735845b 100644 --- a/drivers/media/dvb/frontends/nxt200x.h +++ b/drivers/media/dvb/frontends/nxt200x.h | |||
@@ -38,10 +38,6 @@ struct nxt200x_config | |||
38 | /* the demodulator's i2c address */ | 38 | /* the demodulator's i2c address */ |
39 | u8 demod_address; | 39 | u8 demod_address; |
40 | 40 | ||
41 | /* tuner information */ | ||
42 | u8 pll_address; | ||
43 | struct dvb_pll_desc *pll_desc; | ||
44 | |||
45 | /* used to set pll input */ | 41 | /* used to set pll input */ |
46 | int (*set_pll_input)(u8* buf, int input); | 42 | int (*set_pll_input)(u8* buf, int input); |
47 | 43 | ||
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c index a16eeba0020d..d313d7dcf386 100644 --- a/drivers/media/dvb/frontends/nxt6000.c +++ b/drivers/media/dvb/frontends/nxt6000.c | |||
@@ -33,7 +33,6 @@ | |||
33 | 33 | ||
34 | struct nxt6000_state { | 34 | struct nxt6000_state { |
35 | struct i2c_adapter* i2c; | 35 | struct i2c_adapter* i2c; |
36 | struct dvb_frontend_ops ops; | ||
37 | /* configuration settings */ | 36 | /* configuration settings */ |
38 | const struct nxt6000_config* config; | 37 | const struct nxt6000_config* config; |
39 | struct dvb_frontend frontend; | 38 | struct dvb_frontend frontend; |
@@ -207,12 +206,6 @@ static void nxt6000_setup(struct dvb_frontend* fe) | |||
207 | nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0); | 206 | nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0); |
208 | 207 | ||
209 | nxt6000_writereg(state, TS_FORMAT, 0); | 208 | nxt6000_writereg(state, TS_FORMAT, 0); |
210 | |||
211 | if (state->config->pll_init) { | ||
212 | nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */ | ||
213 | state->config->pll_init(fe); | ||
214 | nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */ | ||
215 | } | ||
216 | } | 209 | } |
217 | 210 | ||
218 | static void nxt6000_dump_status(struct nxt6000_state *state) | 211 | static void nxt6000_dump_status(struct nxt6000_state *state) |
@@ -469,9 +462,10 @@ static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
469 | struct nxt6000_state* state = fe->demodulator_priv; | 462 | struct nxt6000_state* state = fe->demodulator_priv; |
470 | int result; | 463 | int result; |
471 | 464 | ||
472 | nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */ | 465 | if (fe->ops.tuner_ops.set_params) { |
473 | state->config->pll_set(fe, param); | 466 | fe->ops.tuner_ops.set_params(fe, param); |
474 | nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */ | 467 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
468 | } | ||
475 | 469 | ||
476 | if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0) | 470 | if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0) |
477 | return result; | 471 | return result; |
@@ -532,6 +526,17 @@ static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_fron | |||
532 | return 0; | 526 | return 0; |
533 | } | 527 | } |
534 | 528 | ||
529 | static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
530 | { | ||
531 | struct nxt6000_state* state = fe->demodulator_priv; | ||
532 | |||
533 | if (enable) { | ||
534 | return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); | ||
535 | } else { | ||
536 | return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); | ||
537 | } | ||
538 | } | ||
539 | |||
535 | static struct dvb_frontend_ops nxt6000_ops; | 540 | static struct dvb_frontend_ops nxt6000_ops; |
536 | 541 | ||
537 | struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, | 542 | struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, |
@@ -546,13 +551,12 @@ struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, | |||
546 | /* setup the state */ | 551 | /* setup the state */ |
547 | state->config = config; | 552 | state->config = config; |
548 | state->i2c = i2c; | 553 | state->i2c = i2c; |
549 | memcpy(&state->ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops)); | ||
550 | 554 | ||
551 | /* check if the demod is there */ | 555 | /* check if the demod is there */ |
552 | if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error; | 556 | if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error; |
553 | 557 | ||
554 | /* create dvb_frontend */ | 558 | /* create dvb_frontend */ |
555 | state->frontend.ops = &state->ops; | 559 | memcpy(&state->frontend.ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops)); |
556 | state->frontend.demodulator_priv = state; | 560 | state->frontend.demodulator_priv = state; |
557 | return &state->frontend; | 561 | return &state->frontend; |
558 | 562 | ||
@@ -584,6 +588,7 @@ static struct dvb_frontend_ops nxt6000_ops = { | |||
584 | .release = nxt6000_release, | 588 | .release = nxt6000_release, |
585 | 589 | ||
586 | .init = nxt6000_init, | 590 | .init = nxt6000_init, |
591 | .i2c_gate_ctrl = nxt6000_i2c_gate_ctrl, | ||
587 | 592 | ||
588 | .get_tune_settings = nxt6000_fe_get_tune_settings, | 593 | .get_tune_settings = nxt6000_fe_get_tune_settings, |
589 | 594 | ||
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h index b7d9bead3002..117031d11708 100644 --- a/drivers/media/dvb/frontends/nxt6000.h +++ b/drivers/media/dvb/frontends/nxt6000.h | |||
@@ -31,10 +31,6 @@ struct nxt6000_config | |||
31 | 31 | ||
32 | /* should clock inversion be used? */ | 32 | /* should clock inversion be used? */ |
33 | u8 clock_inversion:1; | 33 | u8 clock_inversion:1; |
34 | |||
35 | /* PLL maintenance */ | ||
36 | int (*pll_init)(struct dvb_frontend* fe); | ||
37 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
38 | }; | 34 | }; |
39 | 35 | ||
40 | extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, | 36 | extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, |
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index 80e0f28127b7..d20ab30c1e83 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c | |||
@@ -54,7 +54,6 @@ static int debug; | |||
54 | struct or51132_state | 54 | struct or51132_state |
55 | { | 55 | { |
56 | struct i2c_adapter* i2c; | 56 | struct i2c_adapter* i2c; |
57 | struct dvb_frontend_ops ops; | ||
58 | 57 | ||
59 | /* Configuration settings */ | 58 | /* Configuration settings */ |
60 | const struct or51132_config* config; | 59 | const struct or51132_config* config; |
@@ -106,9 +105,8 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
106 | { | 105 | { |
107 | struct or51132_state* state = fe->demodulator_priv; | 106 | struct or51132_state* state = fe->demodulator_priv; |
108 | static u8 run_buf[] = {0x7F,0x01}; | 107 | static u8 run_buf[] = {0x7F,0x01}; |
109 | static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; | 108 | u8 rec_buf[8]; |
110 | u8 rec_buf[14]; | 109 | u8 cmd_buf[3]; |
111 | u8 cmd_buf[14]; | ||
112 | u32 firmwareAsize, firmwareBsize; | 110 | u32 firmwareAsize, firmwareBsize; |
113 | int i,ret; | 111 | int i,ret; |
114 | 112 | ||
@@ -157,7 +155,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
157 | cmd_buf[0] = 0x10; | 155 | cmd_buf[0] = 0x10; |
158 | cmd_buf[1] = 0x10; | 156 | cmd_buf[1] = 0x10; |
159 | cmd_buf[2] = 0x00; | 157 | cmd_buf[2] = 0x00; |
160 | cmd_buf[3] = 0x00; | ||
161 | msleep(20); /* 20ms */ | 158 | msleep(20); /* 20ms */ |
162 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 159 | if ((ret = i2c_writebytes(state,state->config->demod_address, |
163 | cmd_buf,3))) { | 160 | cmd_buf,3))) { |
@@ -167,8 +164,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
167 | 164 | ||
168 | cmd_buf[0] = 0x04; | 165 | cmd_buf[0] = 0x04; |
169 | cmd_buf[1] = 0x17; | 166 | cmd_buf[1] = 0x17; |
170 | cmd_buf[2] = 0x00; | ||
171 | cmd_buf[3] = 0x00; | ||
172 | msleep(20); /* 20ms */ | 167 | msleep(20); /* 20ms */ |
173 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 168 | if ((ret = i2c_writebytes(state,state->config->demod_address, |
174 | cmd_buf,2))) { | 169 | cmd_buf,2))) { |
@@ -178,8 +173,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
178 | 173 | ||
179 | cmd_buf[0] = 0x00; | 174 | cmd_buf[0] = 0x00; |
180 | cmd_buf[1] = 0x00; | 175 | cmd_buf[1] = 0x00; |
181 | cmd_buf[2] = 0x00; | ||
182 | cmd_buf[3] = 0x00; | ||
183 | msleep(20); /* 20ms */ | 176 | msleep(20); /* 20ms */ |
184 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 177 | if ((ret = i2c_writebytes(state,state->config->demod_address, |
185 | cmd_buf,2))) { | 178 | cmd_buf,2))) { |
@@ -189,7 +182,11 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
189 | 182 | ||
190 | for(i=0;i<4;i++) { | 183 | for(i=0;i<4;i++) { |
191 | msleep(20); /* 20ms */ | 184 | msleep(20); /* 20ms */ |
192 | get_ver_buf[4] = i+1; | 185 | /* Once upon a time, this command might have had something |
186 | to do with getting the firmware version, but it's | ||
187 | not used anymore: | ||
188 | {0x04,0x00,0x30,0x00,i+1} */ | ||
189 | /* Read 8 bytes, two bytes at a time */ | ||
193 | if ((ret = i2c_readbytes(state,state->config->demod_address, | 190 | if ((ret = i2c_readbytes(state,state->config->demod_address, |
194 | &rec_buf[i*2],2))) { | 191 | &rec_buf[i*2],2))) { |
195 | printk(KERN_WARNING | 192 | printk(KERN_WARNING |
@@ -208,7 +205,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
208 | cmd_buf[0] = 0x10; | 205 | cmd_buf[0] = 0x10; |
209 | cmd_buf[1] = 0x00; | 206 | cmd_buf[1] = 0x00; |
210 | cmd_buf[2] = 0x00; | 207 | cmd_buf[2] = 0x00; |
211 | cmd_buf[3] = 0x00; | ||
212 | msleep(20); /* 20ms */ | 208 | msleep(20); /* 20ms */ |
213 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 209 | if ((ret = i2c_writebytes(state,state->config->demod_address, |
214 | cmd_buf,3))) { | 210 | cmd_buf,3))) { |
@@ -243,7 +239,7 @@ static int or51132_sleep(struct dvb_frontend* fe) | |||
243 | static int or51132_setmode(struct dvb_frontend* fe) | 239 | static int or51132_setmode(struct dvb_frontend* fe) |
244 | { | 240 | { |
245 | struct or51132_state* state = fe->demodulator_priv; | 241 | struct or51132_state* state = fe->demodulator_priv; |
246 | unsigned char cmd_buf[4]; | 242 | unsigned char cmd_buf[3]; |
247 | 243 | ||
248 | dprintk("setmode %d\n",(int)state->current_modulation); | 244 | dprintk("setmode %d\n",(int)state->current_modulation); |
249 | /* set operation mode in Receiver 1 register; */ | 245 | /* set operation mode in Receiver 1 register; */ |
@@ -263,7 +259,6 @@ static int or51132_setmode(struct dvb_frontend* fe) | |||
263 | default: | 259 | default: |
264 | printk("setmode:Modulation set to unsupported value\n"); | 260 | printk("setmode:Modulation set to unsupported value\n"); |
265 | }; | 261 | }; |
266 | cmd_buf[3] = 0x00; | ||
267 | if (i2c_writebytes(state,state->config->demod_address, | 262 | if (i2c_writebytes(state,state->config->demod_address, |
268 | cmd_buf,3)) { | 263 | cmd_buf,3)) { |
269 | printk(KERN_WARNING "or51132: set_mode error 1\n"); | 264 | printk(KERN_WARNING "or51132: set_mode error 1\n"); |
@@ -301,7 +296,6 @@ static int or51132_setmode(struct dvb_frontend* fe) | |||
301 | default: | 296 | default: |
302 | printk("setmode: Modulation set to unsupported value\n"); | 297 | printk("setmode: Modulation set to unsupported value\n"); |
303 | }; | 298 | }; |
304 | cmd_buf[3] = 0x00; | ||
305 | msleep(20); /* 20ms */ | 299 | msleep(20); /* 20ms */ |
306 | if (i2c_writebytes(state,state->config->demod_address, | 300 | if (i2c_writebytes(state,state->config->demod_address, |
307 | cmd_buf,3)) { | 301 | cmd_buf,3)) { |
@@ -313,52 +307,65 @@ static int or51132_setmode(struct dvb_frontend* fe) | |||
313 | return 0; | 307 | return 0; |
314 | } | 308 | } |
315 | 309 | ||
310 | /* Some modulations use the same firmware. This classifies modulations | ||
311 | by the firmware they use. */ | ||
312 | #define MOD_FWCLASS_UNKNOWN 0 | ||
313 | #define MOD_FWCLASS_VSB 1 | ||
314 | #define MOD_FWCLASS_QAM 2 | ||
315 | static int modulation_fw_class(fe_modulation_t modulation) | ||
316 | { | ||
317 | switch(modulation) { | ||
318 | case VSB_8: | ||
319 | return MOD_FWCLASS_VSB; | ||
320 | case QAM_AUTO: | ||
321 | case QAM_64: | ||
322 | case QAM_256: | ||
323 | return MOD_FWCLASS_QAM; | ||
324 | default: | ||
325 | return MOD_FWCLASS_UNKNOWN; | ||
326 | } | ||
327 | } | ||
328 | |||
316 | static int or51132_set_parameters(struct dvb_frontend* fe, | 329 | static int or51132_set_parameters(struct dvb_frontend* fe, |
317 | struct dvb_frontend_parameters *param) | 330 | struct dvb_frontend_parameters *param) |
318 | { | 331 | { |
319 | int ret; | 332 | int ret; |
320 | u8 buf[4]; | ||
321 | struct or51132_state* state = fe->demodulator_priv; | 333 | struct or51132_state* state = fe->demodulator_priv; |
322 | const struct firmware *fw; | 334 | const struct firmware *fw; |
323 | 335 | const char *fwname; | |
324 | /* Change only if we are actually changing the modulation */ | 336 | int clock_mode; |
325 | if (state->current_modulation != param->u.vsb.modulation) { | 337 | |
326 | switch(param->u.vsb.modulation) { | 338 | /* Upload new firmware only if we need a different one */ |
327 | case VSB_8: | 339 | if (modulation_fw_class(state->current_modulation) != |
340 | modulation_fw_class(param->u.vsb.modulation)) { | ||
341 | switch(modulation_fw_class(param->u.vsb.modulation)) { | ||
342 | case MOD_FWCLASS_VSB: | ||
328 | dprintk("set_parameters VSB MODE\n"); | 343 | dprintk("set_parameters VSB MODE\n"); |
329 | printk("or51132: Waiting for firmware upload(%s)...\n", | 344 | fwname = OR51132_VSB_FIRMWARE; |
330 | OR51132_VSB_FIRMWARE); | 345 | |
331 | ret = request_firmware(&fw, OR51132_VSB_FIRMWARE, | ||
332 | &state->i2c->dev); | ||
333 | if (ret){ | ||
334 | printk(KERN_WARNING "or51132: No firmware up" | ||
335 | "loaded(timeout or file not found?)\n"); | ||
336 | return ret; | ||
337 | } | ||
338 | /* Set non-punctured clock for VSB */ | 346 | /* Set non-punctured clock for VSB */ |
339 | state->config->set_ts_params(fe, 0); | 347 | clock_mode = 0; |
340 | break; | 348 | break; |
341 | case QAM_AUTO: | 349 | case MOD_FWCLASS_QAM: |
342 | case QAM_64: | ||
343 | case QAM_256: | ||
344 | dprintk("set_parameters QAM MODE\n"); | 350 | dprintk("set_parameters QAM MODE\n"); |
345 | printk("or51132: Waiting for firmware upload(%s)...\n", | 351 | fwname = OR51132_QAM_FIRMWARE; |
346 | OR51132_QAM_FIRMWARE); | 352 | |
347 | ret = request_firmware(&fw, OR51132_QAM_FIRMWARE, | ||
348 | &state->i2c->dev); | ||
349 | if (ret){ | ||
350 | printk(KERN_WARNING "or51132: No firmware up" | ||
351 | "loaded(timeout or file not found?)\n"); | ||
352 | return ret; | ||
353 | } | ||
354 | /* Set punctured clock for QAM */ | 353 | /* Set punctured clock for QAM */ |
355 | state->config->set_ts_params(fe, 1); | 354 | clock_mode = 1; |
356 | break; | 355 | break; |
357 | default: | 356 | default: |
358 | printk("or51132:Modulation type(%d) UNSUPPORTED\n", | 357 | printk("or51132: Modulation type(%d) UNSUPPORTED\n", |
359 | param->u.vsb.modulation); | 358 | param->u.vsb.modulation); |
360 | return -1; | 359 | return -1; |
361 | }; | 360 | } |
361 | printk("or51132: Waiting for firmware upload(%s)...\n", | ||
362 | fwname); | ||
363 | ret = request_firmware(&fw, fwname, &state->i2c->dev); | ||
364 | if (ret) { | ||
365 | printk(KERN_WARNING "or51132: No firmware up" | ||
366 | "loaded(timeout or file not found?)\n"); | ||
367 | return ret; | ||
368 | } | ||
362 | ret = or51132_load_firmware(fe, fw); | 369 | ret = or51132_load_firmware(fe, fw); |
363 | release_firmware(fw); | 370 | release_firmware(fw); |
364 | if (ret) { | 371 | if (ret) { |
@@ -367,18 +374,18 @@ static int or51132_set_parameters(struct dvb_frontend* fe, | |||
367 | return ret; | 374 | return ret; |
368 | } | 375 | } |
369 | printk("or51132: Firmware upload complete.\n"); | 376 | printk("or51132: Firmware upload complete.\n"); |
370 | 377 | state->config->set_ts_params(fe, clock_mode); | |
378 | } | ||
379 | /* Change only if we are actually changing the modulation */ | ||
380 | if (state->current_modulation != param->u.vsb.modulation) { | ||
371 | state->current_modulation = param->u.vsb.modulation; | 381 | state->current_modulation = param->u.vsb.modulation; |
372 | or51132_setmode(fe); | 382 | or51132_setmode(fe); |
373 | } | 383 | } |
374 | 384 | ||
375 | dvb_pll_configure(state->config->pll_desc, buf, | 385 | if (fe->ops.tuner_ops.set_params) { |
376 | param->frequency, 0); | 386 | fe->ops.tuner_ops.set_params(fe, param); |
377 | dprintk("set_parameters tuner bytes: 0x%02x 0x%02x " | 387 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
378 | "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]); | 388 | } |
379 | if (i2c_writebytes(state, state->config->pll_address ,buf, 4)) | ||
380 | printk(KERN_WARNING "or51132: set_parameters error " | ||
381 | "writing to tuner\n"); | ||
382 | 389 | ||
383 | /* Set to current mode */ | 390 | /* Set to current mode */ |
384 | or51132_setmode(fe); | 391 | or51132_setmode(fe); |
@@ -388,6 +395,44 @@ static int or51132_set_parameters(struct dvb_frontend* fe, | |||
388 | return 0; | 395 | return 0; |
389 | } | 396 | } |
390 | 397 | ||
398 | static int or51132_get_parameters(struct dvb_frontend* fe, | ||
399 | struct dvb_frontend_parameters *param) | ||
400 | { | ||
401 | struct or51132_state* state = fe->demodulator_priv; | ||
402 | u8 buf[2]; | ||
403 | |||
404 | /* Receiver Status */ | ||
405 | buf[0]=0x04; | ||
406 | buf[1]=0x00; | ||
407 | msleep(30); /* 30ms */ | ||
408 | if (i2c_writebytes(state,state->config->demod_address,buf,2)) { | ||
409 | printk(KERN_WARNING "or51132: get_parameters write error\n"); | ||
410 | return -EREMOTEIO; | ||
411 | } | ||
412 | msleep(30); /* 30ms */ | ||
413 | if (i2c_readbytes(state,state->config->demod_address,buf,2)) { | ||
414 | printk(KERN_WARNING "or51132: get_parameters read error\n"); | ||
415 | return -EREMOTEIO; | ||
416 | } | ||
417 | switch(buf[0]) { | ||
418 | case 0x06: param->u.vsb.modulation = VSB_8; break; | ||
419 | case 0x43: param->u.vsb.modulation = QAM_64; break; | ||
420 | case 0x45: param->u.vsb.modulation = QAM_256; break; | ||
421 | default: | ||
422 | printk(KERN_WARNING "or51132: unknown status 0x%02x\n", | ||
423 | buf[0]); | ||
424 | return -EREMOTEIO; | ||
425 | } | ||
426 | |||
427 | /* FIXME: Read frequency from frontend, take AFC into account */ | ||
428 | param->frequency = state->current_frequency; | ||
429 | |||
430 | /* FIXME: How to read inversion setting? Receiver 6 register? */ | ||
431 | param->inversion = INVERSION_AUTO; | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
391 | static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) | 436 | static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) |
392 | { | 437 | { |
393 | struct or51132_state* state = fe->demodulator_priv; | 438 | struct or51132_state* state = fe->demodulator_priv; |
@@ -572,12 +617,11 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config, | |||
572 | /* Setup the state */ | 617 | /* Setup the state */ |
573 | state->config = config; | 618 | state->config = config; |
574 | state->i2c = i2c; | 619 | state->i2c = i2c; |
575 | memcpy(&state->ops, &or51132_ops, sizeof(struct dvb_frontend_ops)); | ||
576 | state->current_frequency = -1; | 620 | state->current_frequency = -1; |
577 | state->current_modulation = -1; | 621 | state->current_modulation = -1; |
578 | 622 | ||
579 | /* Create dvb_frontend */ | 623 | /* Create dvb_frontend */ |
580 | state->frontend.ops = &state->ops; | 624 | memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops)); |
581 | state->frontend.demodulator_priv = state; | 625 | state->frontend.demodulator_priv = state; |
582 | return &state->frontend; | 626 | return &state->frontend; |
583 | 627 | ||
@@ -590,7 +634,7 @@ static struct dvb_frontend_ops or51132_ops = { | |||
590 | 634 | ||
591 | .info = { | 635 | .info = { |
592 | .name = "Oren OR51132 VSB/QAM Frontend", | 636 | .name = "Oren OR51132 VSB/QAM Frontend", |
593 | .type = FE_ATSC, | 637 | .type = FE_ATSC, |
594 | .frequency_min = 44000000, | 638 | .frequency_min = 44000000, |
595 | .frequency_max = 958000000, | 639 | .frequency_max = 958000000, |
596 | .frequency_stepsize = 166666, | 640 | .frequency_stepsize = 166666, |
@@ -606,6 +650,7 @@ static struct dvb_frontend_ops or51132_ops = { | |||
606 | .sleep = or51132_sleep, | 650 | .sleep = or51132_sleep, |
607 | 651 | ||
608 | .set_frontend = or51132_set_parameters, | 652 | .set_frontend = or51132_set_parameters, |
653 | .get_frontend = or51132_get_parameters, | ||
609 | .get_tune_settings = or51132_get_tune_settings, | 654 | .get_tune_settings = or51132_get_tune_settings, |
610 | 655 | ||
611 | .read_status = or51132_read_status, | 656 | .read_status = or51132_read_status, |
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h index 622cdd18381b..89658883abf5 100644 --- a/drivers/media/dvb/frontends/or51132.h +++ b/drivers/media/dvb/frontends/or51132.h | |||
@@ -29,8 +29,6 @@ struct or51132_config | |||
29 | { | 29 | { |
30 | /* The demodulator's i2c address */ | 30 | /* The demodulator's i2c address */ |
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | u8 pll_address; | ||
33 | struct dvb_pll_desc *pll_desc; | ||
34 | 32 | ||
35 | /* Need to set device param for start_dma */ | 33 | /* Need to set device param for start_dma */ |
36 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 34 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c index 7c3aed1f546b..26bed616fabe 100644 --- a/drivers/media/dvb/frontends/or51211.c +++ b/drivers/media/dvb/frontends/or51211.c | |||
@@ -54,7 +54,6 @@ static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC | |||
54 | struct or51211_state { | 54 | struct or51211_state { |
55 | 55 | ||
56 | struct i2c_adapter* i2c; | 56 | struct i2c_adapter* i2c; |
57 | struct dvb_frontend_ops ops; | ||
58 | 57 | ||
59 | /* Configuration settings */ | 58 | /* Configuration settings */ |
60 | const struct or51211_config* config; | 59 | const struct or51211_config* config; |
@@ -585,12 +584,11 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config, | |||
585 | /* Setup the state */ | 584 | /* Setup the state */ |
586 | state->config = config; | 585 | state->config = config; |
587 | state->i2c = i2c; | 586 | state->i2c = i2c; |
588 | memcpy(&state->ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); | ||
589 | state->initialized = 0; | 587 | state->initialized = 0; |
590 | state->current_frequency = 0; | 588 | state->current_frequency = 0; |
591 | 589 | ||
592 | /* Create dvb_frontend */ | 590 | /* Create dvb_frontend */ |
593 | state->frontend.ops = &state->ops; | 591 | memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); |
594 | state->frontend.demodulator_priv = state; | 592 | state->frontend.demodulator_priv = state; |
595 | return &state->frontend; | 593 | return &state->frontend; |
596 | 594 | ||
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c index d69477596921..2c2c344c4c64 100644 --- a/drivers/media/dvb/frontends/s5h1420.c +++ b/drivers/media/dvb/frontends/s5h1420.c | |||
@@ -38,7 +38,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
38 | 38 | ||
39 | struct s5h1420_state { | 39 | struct s5h1420_state { |
40 | struct i2c_adapter* i2c; | 40 | struct i2c_adapter* i2c; |
41 | struct dvb_frontend_ops ops; | ||
42 | const struct s5h1420_config* config; | 41 | const struct s5h1420_config* config; |
43 | struct dvb_frontend frontend; | 42 | struct dvb_frontend frontend; |
44 | 43 | ||
@@ -584,7 +583,6 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, | |||
584 | struct s5h1420_state* state = fe->demodulator_priv; | 583 | struct s5h1420_state* state = fe->demodulator_priv; |
585 | int frequency_delta; | 584 | int frequency_delta; |
586 | struct dvb_frontend_tune_settings fesettings; | 585 | struct dvb_frontend_tune_settings fesettings; |
587 | u32 tmp; | ||
588 | 586 | ||
589 | /* check if we should do a fast-tune */ | 587 | /* check if we should do a fast-tune */ |
590 | memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); | 588 | memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); |
@@ -596,10 +594,17 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, | |||
596 | (state->fec_inner == p->u.qpsk.fec_inner) && | 594 | (state->fec_inner == p->u.qpsk.fec_inner) && |
597 | (state->symbol_rate == p->u.qpsk.symbol_rate)) { | 595 | (state->symbol_rate == p->u.qpsk.symbol_rate)) { |
598 | 596 | ||
599 | if (state->config->pll_set) { | 597 | if (fe->ops.tuner_ops.set_params) { |
600 | s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); | 598 | fe->ops.tuner_ops.set_params(fe, p); |
601 | state->config->pll_set(fe, p, &tmp); | 599 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
600 | } | ||
601 | if (fe->ops.tuner_ops.get_frequency) { | ||
602 | u32 tmp; | ||
603 | fe->ops.tuner_ops.get_frequency(fe, &tmp); | ||
604 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
602 | s5h1420_setfreqoffset(state, p->frequency - tmp); | 605 | s5h1420_setfreqoffset(state, p->frequency - tmp); |
606 | } else { | ||
607 | s5h1420_setfreqoffset(state, 0); | ||
603 | } | 608 | } |
604 | return 0; | 609 | return 0; |
605 | } | 610 | } |
@@ -646,9 +651,9 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, | |||
646 | s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1); | 651 | s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1); |
647 | 652 | ||
648 | /* set tuner PLL */ | 653 | /* set tuner PLL */ |
649 | if (state->config->pll_set) { | 654 | if (fe->ops.tuner_ops.set_params) { |
650 | s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); | 655 | fe->ops.tuner_ops.set_params(fe, p); |
651 | state->config->pll_set(fe, p, &tmp); | 656 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
652 | s5h1420_setfreqoffset(state, 0); | 657 | s5h1420_setfreqoffset(state, 0); |
653 | } | 658 | } |
654 | 659 | ||
@@ -708,6 +713,17 @@ static int s5h1420_get_tune_settings(struct dvb_frontend* fe, | |||
708 | return 0; | 713 | return 0; |
709 | } | 714 | } |
710 | 715 | ||
716 | static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
717 | { | ||
718 | struct s5h1420_state* state = fe->demodulator_priv; | ||
719 | |||
720 | if (enable) { | ||
721 | return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); | ||
722 | } else { | ||
723 | return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe); | ||
724 | } | ||
725 | } | ||
726 | |||
711 | static int s5h1420_init (struct dvb_frontend* fe) | 727 | static int s5h1420_init (struct dvb_frontend* fe) |
712 | { | 728 | { |
713 | struct s5h1420_state* state = fe->demodulator_priv; | 729 | struct s5h1420_state* state = fe->demodulator_priv; |
@@ -717,13 +733,6 @@ static int s5h1420_init (struct dvb_frontend* fe) | |||
717 | msleep(10); | 733 | msleep(10); |
718 | s5h1420_reset(state); | 734 | s5h1420_reset(state); |
719 | 735 | ||
720 | /* init PLL */ | ||
721 | if (state->config->pll_init) { | ||
722 | s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); | ||
723 | state->config->pll_init(fe); | ||
724 | s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe); | ||
725 | } | ||
726 | |||
727 | return 0; | 736 | return 0; |
728 | } | 737 | } |
729 | 738 | ||
@@ -756,7 +765,6 @@ struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, | |||
756 | /* setup the state */ | 765 | /* setup the state */ |
757 | state->config = config; | 766 | state->config = config; |
758 | state->i2c = i2c; | 767 | state->i2c = i2c; |
759 | memcpy(&state->ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops)); | ||
760 | state->postlocked = 0; | 768 | state->postlocked = 0; |
761 | state->fclk = 88000000; | 769 | state->fclk = 88000000; |
762 | state->tunedfreq = 0; | 770 | state->tunedfreq = 0; |
@@ -769,7 +777,7 @@ struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, | |||
769 | goto error; | 777 | goto error; |
770 | 778 | ||
771 | /* create dvb_frontend */ | 779 | /* create dvb_frontend */ |
772 | state->frontend.ops = &state->ops; | 780 | memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops)); |
773 | state->frontend.demodulator_priv = state; | 781 | state->frontend.demodulator_priv = state; |
774 | return &state->frontend; | 782 | return &state->frontend; |
775 | 783 | ||
@@ -800,6 +808,7 @@ static struct dvb_frontend_ops s5h1420_ops = { | |||
800 | 808 | ||
801 | .init = s5h1420_init, | 809 | .init = s5h1420_init, |
802 | .sleep = s5h1420_sleep, | 810 | .sleep = s5h1420_sleep, |
811 | .i2c_gate_ctrl = s5h1420_i2c_gate_ctrl, | ||
803 | 812 | ||
804 | .set_frontend = s5h1420_set_frontend, | 813 | .set_frontend = s5h1420_set_frontend, |
805 | .get_frontend = s5h1420_get_frontend, | 814 | .get_frontend = s5h1420_get_frontend, |
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h index 73296f13c324..4e39015fa67e 100644 --- a/drivers/media/dvb/frontends/s5h1420.h +++ b/drivers/media/dvb/frontends/s5h1420.h | |||
@@ -32,10 +32,6 @@ struct s5h1420_config | |||
32 | 32 | ||
33 | /* does the inversion require inversion? */ | 33 | /* does the inversion require inversion? */ |
34 | u8 invert:1; | 34 | u8 invert:1; |
35 | |||
36 | /* PLL maintenance */ | ||
37 | int (*pll_init)(struct dvb_frontend* fe); | ||
38 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout); | ||
39 | }; | 35 | }; |
40 | 36 | ||
41 | extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, | 37 | extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, |
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c index 73829e647e50..44ec5b9a4695 100644 --- a/drivers/media/dvb/frontends/sp8870.c +++ b/drivers/media/dvb/frontends/sp8870.c | |||
@@ -44,8 +44,6 @@ struct sp8870_state { | |||
44 | 44 | ||
45 | struct i2c_adapter* i2c; | 45 | struct i2c_adapter* i2c; |
46 | 46 | ||
47 | struct dvb_frontend_ops ops; | ||
48 | |||
49 | const struct sp8870_config* config; | 47 | const struct sp8870_config* config; |
50 | 48 | ||
51 | struct dvb_frontend frontend; | 49 | struct dvb_frontend frontend; |
@@ -262,9 +260,10 @@ static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, | |||
262 | sp8870_microcontroller_stop(state); | 260 | sp8870_microcontroller_stop(state); |
263 | 261 | ||
264 | // set tuner parameters | 262 | // set tuner parameters |
265 | sp8870_writereg(state, 0x206, 0x001); | 263 | if (fe->ops.tuner_ops.set_params) { |
266 | state->config->pll_set(fe, p); | 264 | fe->ops.tuner_ops.set_params(fe, p); |
267 | sp8870_writereg(state, 0x206, 0x000); | 265 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
266 | } | ||
268 | 267 | ||
269 | // sample rate correction bit [23..17] | 268 | // sample rate correction bit [23..17] |
270 | sp8870_writereg(state, 0x0319, 0x000A); | 269 | sp8870_writereg(state, 0x0319, 0x000A); |
@@ -349,13 +348,6 @@ static int sp8870_init (struct dvb_frontend* fe) | |||
349 | sp8870_writereg(state, 0x0D00, 0x010); | 348 | sp8870_writereg(state, 0x0D00, 0x010); |
350 | sp8870_writereg(state, 0x0D01, 0x000); | 349 | sp8870_writereg(state, 0x0D01, 0x000); |
351 | 350 | ||
352 | /* setup PLL */ | ||
353 | if (state->config->pll_init) { | ||
354 | sp8870_writereg(state, 0x206, 0x001); | ||
355 | state->config->pll_init(fe); | ||
356 | sp8870_writereg(state, 0x206, 0x000); | ||
357 | } | ||
358 | |||
359 | return 0; | 351 | return 0; |
360 | } | 352 | } |
361 | 353 | ||
@@ -541,6 +533,17 @@ static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend | |||
541 | return 0; | 533 | return 0; |
542 | } | 534 | } |
543 | 535 | ||
536 | static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
537 | { | ||
538 | struct sp8870_state* state = fe->demodulator_priv; | ||
539 | |||
540 | if (enable) { | ||
541 | return sp8870_writereg(state, 0x206, 0x001); | ||
542 | } else { | ||
543 | return sp8870_writereg(state, 0x206, 0x000); | ||
544 | } | ||
545 | } | ||
546 | |||
544 | static void sp8870_release(struct dvb_frontend* fe) | 547 | static void sp8870_release(struct dvb_frontend* fe) |
545 | { | 548 | { |
546 | struct sp8870_state* state = fe->demodulator_priv; | 549 | struct sp8870_state* state = fe->demodulator_priv; |
@@ -561,14 +564,13 @@ struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, | |||
561 | /* setup the state */ | 564 | /* setup the state */ |
562 | state->config = config; | 565 | state->config = config; |
563 | state->i2c = i2c; | 566 | state->i2c = i2c; |
564 | memcpy(&state->ops, &sp8870_ops, sizeof(struct dvb_frontend_ops)); | ||
565 | state->initialised = 0; | 567 | state->initialised = 0; |
566 | 568 | ||
567 | /* check if the demod is there */ | 569 | /* check if the demod is there */ |
568 | if (sp8870_readreg(state, 0x0200) < 0) goto error; | 570 | if (sp8870_readreg(state, 0x0200) < 0) goto error; |
569 | 571 | ||
570 | /* create dvb_frontend */ | 572 | /* create dvb_frontend */ |
571 | state->frontend.ops = &state->ops; | 573 | memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops)); |
572 | state->frontend.demodulator_priv = state; | 574 | state->frontend.demodulator_priv = state; |
573 | return &state->frontend; | 575 | return &state->frontend; |
574 | 576 | ||
@@ -597,6 +599,7 @@ static struct dvb_frontend_ops sp8870_ops = { | |||
597 | 599 | ||
598 | .init = sp8870_init, | 600 | .init = sp8870_init, |
599 | .sleep = sp8870_sleep, | 601 | .sleep = sp8870_sleep, |
602 | .i2c_gate_ctrl = sp8870_i2c_gate_ctrl, | ||
600 | 603 | ||
601 | .set_frontend = sp8870_set_frontend, | 604 | .set_frontend = sp8870_set_frontend, |
602 | .get_tune_settings = sp8870_get_tune_settings, | 605 | .get_tune_settings = sp8870_get_tune_settings, |
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h index f3b555dbc960..93afbb969d6b 100644 --- a/drivers/media/dvb/frontends/sp8870.h +++ b/drivers/media/dvb/frontends/sp8870.h | |||
@@ -31,10 +31,6 @@ struct sp8870_config | |||
31 | /* the demodulator's i2c address */ | 31 | /* the demodulator's i2c address */ |
32 | u8 demod_address; | 32 | u8 demod_address; |
33 | 33 | ||
34 | /* PLL maintenance */ | ||
35 | int (*pll_init)(struct dvb_frontend* fe); | ||
36 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
37 | |||
38 | /* request firmware for device */ | 34 | /* request firmware for device */ |
39 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 35 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
40 | }; | 36 | }; |
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c index eb8a602198ca..b0a2b02f6608 100644 --- a/drivers/media/dvb/frontends/sp887x.c +++ b/drivers/media/dvb/frontends/sp887x.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | struct sp887x_state { | 25 | struct sp887x_state { |
26 | struct i2c_adapter* i2c; | 26 | struct i2c_adapter* i2c; |
27 | struct dvb_frontend_ops ops; | ||
28 | const struct sp887x_config* config; | 27 | const struct sp887x_config* config; |
29 | struct dvb_frontend frontend; | 28 | struct dvb_frontend frontend; |
30 | 29 | ||
@@ -208,15 +207,6 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware | |||
208 | /* bit 0x010: enable data valid signal */ | 207 | /* bit 0x010: enable data valid signal */ |
209 | sp887x_writereg(state, 0xd00, 0x010); | 208 | sp887x_writereg(state, 0xd00, 0x010); |
210 | sp887x_writereg(state, 0x0d1, 0x000); | 209 | sp887x_writereg(state, 0x0d1, 0x000); |
211 | |||
212 | /* setup the PLL */ | ||
213 | if (state->config->pll_init) { | ||
214 | sp887x_writereg(state, 0x206, 0x001); | ||
215 | state->config->pll_init(fe); | ||
216 | sp887x_writereg(state, 0x206, 0x000); | ||
217 | } | ||
218 | |||
219 | printk ("done.\n"); | ||
220 | return 0; | 210 | return 0; |
221 | }; | 211 | }; |
222 | 212 | ||
@@ -362,9 +352,16 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
362 | sp887x_microcontroller_stop(state); | 352 | sp887x_microcontroller_stop(state); |
363 | 353 | ||
364 | /* setup the PLL */ | 354 | /* setup the PLL */ |
365 | sp887x_writereg(state, 0x206, 0x001); | 355 | if (fe->ops.tuner_ops.set_params) { |
366 | actual_freq = state->config->pll_set(fe, p); | 356 | fe->ops.tuner_ops.set_params(fe, p); |
367 | sp887x_writereg(state, 0x206, 0x000); | 357 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
358 | } | ||
359 | if (fe->ops.tuner_ops.get_frequency) { | ||
360 | fe->ops.tuner_ops.get_frequency(fe, &actual_freq); | ||
361 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
362 | } else { | ||
363 | actual_freq = p->frequency; | ||
364 | } | ||
368 | 365 | ||
369 | /* read status reg in order to clear <pending irqs */ | 366 | /* read status reg in order to clear <pending irqs */ |
370 | sp887x_readreg(state, 0x200); | 367 | sp887x_readreg(state, 0x200); |
@@ -486,6 +483,17 @@ static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
486 | return 0; | 483 | return 0; |
487 | } | 484 | } |
488 | 485 | ||
486 | static int sp887x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
487 | { | ||
488 | struct sp887x_state* state = fe->demodulator_priv; | ||
489 | |||
490 | if (enable) { | ||
491 | return sp887x_writereg(state, 0x206, 0x001); | ||
492 | } else { | ||
493 | return sp887x_writereg(state, 0x206, 0x000); | ||
494 | } | ||
495 | } | ||
496 | |||
489 | static int sp887x_sleep(struct dvb_frontend* fe) | 497 | static int sp887x_sleep(struct dvb_frontend* fe) |
490 | { | 498 | { |
491 | struct sp887x_state* state = fe->demodulator_priv; | 499 | struct sp887x_state* state = fe->demodulator_priv; |
@@ -555,14 +563,13 @@ struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, | |||
555 | /* setup the state */ | 563 | /* setup the state */ |
556 | state->config = config; | 564 | state->config = config; |
557 | state->i2c = i2c; | 565 | state->i2c = i2c; |
558 | memcpy(&state->ops, &sp887x_ops, sizeof(struct dvb_frontend_ops)); | ||
559 | state->initialised = 0; | 566 | state->initialised = 0; |
560 | 567 | ||
561 | /* check if the demod is there */ | 568 | /* check if the demod is there */ |
562 | if (sp887x_readreg(state, 0x0200) < 0) goto error; | 569 | if (sp887x_readreg(state, 0x0200) < 0) goto error; |
563 | 570 | ||
564 | /* create dvb_frontend */ | 571 | /* create dvb_frontend */ |
565 | state->frontend.ops = &state->ops; | 572 | memcpy(&state->frontend.ops, &sp887x_ops, sizeof(struct dvb_frontend_ops)); |
566 | state->frontend.demodulator_priv = state; | 573 | state->frontend.demodulator_priv = state; |
567 | return &state->frontend; | 574 | return &state->frontend; |
568 | 575 | ||
@@ -589,6 +596,7 @@ static struct dvb_frontend_ops sp887x_ops = { | |||
589 | 596 | ||
590 | .init = sp887x_init, | 597 | .init = sp887x_init, |
591 | .sleep = sp887x_sleep, | 598 | .sleep = sp887x_sleep, |
599 | .i2c_gate_ctrl = sp887x_i2c_gate_ctrl, | ||
592 | 600 | ||
593 | .set_frontend = sp887x_setup_frontend_parameters, | 601 | .set_frontend = sp887x_setup_frontend_parameters, |
594 | .get_tune_settings = sp887x_get_tune_settings, | 602 | .get_tune_settings = sp887x_get_tune_settings, |
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h index 6a05d8f8e8cc..c44b0ebdf1e2 100644 --- a/drivers/media/dvb/frontends/sp887x.h +++ b/drivers/media/dvb/frontends/sp887x.h | |||
@@ -13,12 +13,6 @@ struct sp887x_config | |||
13 | /* the demodulator's i2c address */ | 13 | /* the demodulator's i2c address */ |
14 | u8 demod_address; | 14 | u8 demod_address; |
15 | 15 | ||
16 | /* PLL maintenance */ | ||
17 | int (*pll_init)(struct dvb_frontend* fe); | ||
18 | |||
19 | /* this should return the actual frequency tuned to */ | ||
20 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
21 | |||
22 | /* request firmware for device */ | 16 | /* request firmware for device */ |
23 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 17 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
24 | }; | 18 | }; |
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c index eb15676d374f..1ca64249010c 100644 --- a/drivers/media/dvb/frontends/stv0297.c +++ b/drivers/media/dvb/frontends/stv0297.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | struct stv0297_state { | 33 | struct stv0297_state { |
34 | struct i2c_adapter *i2c; | 34 | struct i2c_adapter *i2c; |
35 | struct dvb_frontend_ops ops; | ||
36 | const struct stv0297_config *config; | 35 | const struct stv0297_config *config; |
37 | struct dvb_frontend frontend; | 36 | struct dvb_frontend frontend; |
38 | 37 | ||
@@ -68,19 +67,25 @@ static int stv0297_readreg(struct stv0297_state *state, u8 reg) | |||
68 | int ret; | 67 | int ret; |
69 | u8 b0[] = { reg }; | 68 | u8 b0[] = { reg }; |
70 | u8 b1[] = { 0 }; | 69 | u8 b1[] = { 0 }; |
71 | struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = | 70 | struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1}, |
72 | 1}, | 71 | {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} |
73 | {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} | 72 | }; |
74 | }; | ||
75 | 73 | ||
76 | // this device needs a STOP between the register and data | 74 | // this device needs a STOP between the register and data |
77 | if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { | 75 | if (state->config->stop_during_read) { |
78 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); | 76 | if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { |
79 | return -1; | 77 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); |
80 | } | 78 | return -1; |
81 | if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { | 79 | } |
82 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); | 80 | if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { |
83 | return -1; | 81 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); |
82 | return -1; | ||
83 | } | ||
84 | } else { | ||
85 | if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { | ||
86 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); | ||
87 | return -1; | ||
88 | } | ||
84 | } | 89 | } |
85 | 90 | ||
86 | return b1[0]; | 91 | return b1[0]; |
@@ -107,13 +112,20 @@ static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len | |||
107 | }; | 112 | }; |
108 | 113 | ||
109 | // this device needs a STOP between the register and data | 114 | // this device needs a STOP between the register and data |
110 | if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { | 115 | if (state->config->stop_during_read) { |
111 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); | 116 | if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { |
112 | return -1; | 117 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); |
113 | } | 118 | return -1; |
114 | if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { | 119 | } |
115 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); | 120 | if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { |
116 | return -1; | 121 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); |
122 | return -1; | ||
123 | } | ||
124 | } else { | ||
125 | if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { | ||
126 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); | ||
127 | return -1; | ||
128 | } | ||
117 | } | 129 | } |
118 | 130 | ||
119 | return 0; | 131 | return 0; |
@@ -276,12 +288,14 @@ static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_invers | |||
276 | return 0; | 288 | return 0; |
277 | } | 289 | } |
278 | 290 | ||
279 | int stv0297_enable_plli2c(struct dvb_frontend *fe) | 291 | static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
280 | { | 292 | { |
281 | struct stv0297_state *state = fe->demodulator_priv; | 293 | struct stv0297_state *state = fe->demodulator_priv; |
282 | 294 | ||
283 | stv0297_writereg(state, 0x87, 0x78); | 295 | if (enable) { |
284 | stv0297_writereg(state, 0x86, 0xc8); | 296 | stv0297_writereg(state, 0x87, 0x78); |
297 | stv0297_writereg(state, 0x86, 0xc8); | ||
298 | } | ||
285 | 299 | ||
286 | return 0; | 300 | return 0; |
287 | } | 301 | } |
@@ -296,9 +310,6 @@ static int stv0297_init(struct dvb_frontend *fe) | |||
296 | stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); | 310 | stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); |
297 | msleep(200); | 311 | msleep(200); |
298 | 312 | ||
299 | if (state->config->pll_init) | ||
300 | state->config->pll_init(fe); | ||
301 | |||
302 | return 0; | 313 | return 0; |
303 | } | 314 | } |
304 | 315 | ||
@@ -389,7 +400,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
389 | case QAM_32: | 400 | case QAM_32: |
390 | case QAM_64: | 401 | case QAM_64: |
391 | delay = 100; | 402 | delay = 100; |
392 | sweeprate = 1500; | 403 | sweeprate = 1000; |
393 | break; | 404 | break; |
394 | 405 | ||
395 | case QAM_128: | 406 | case QAM_128: |
@@ -421,7 +432,10 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
421 | } | 432 | } |
422 | 433 | ||
423 | stv0297_init(fe); | 434 | stv0297_init(fe); |
424 | state->config->pll_set(fe, p); | 435 | if (fe->ops.tuner_ops.set_params) { |
436 | fe->ops.tuner_ops.set_params(fe, p); | ||
437 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
438 | } | ||
425 | 439 | ||
426 | /* clear software interrupts */ | 440 | /* clear software interrupts */ |
427 | stv0297_writereg(state, 0x82, 0x0); | 441 | stv0297_writereg(state, 0x82, 0x0); |
@@ -634,7 +648,6 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, | |||
634 | /* setup the state */ | 648 | /* setup the state */ |
635 | state->config = config; | 649 | state->config = config; |
636 | state->i2c = i2c; | 650 | state->i2c = i2c; |
637 | memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); | ||
638 | state->base_freq = 0; | 651 | state->base_freq = 0; |
639 | 652 | ||
640 | /* check if the demod is there */ | 653 | /* check if the demod is there */ |
@@ -642,7 +655,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, | |||
642 | goto error; | 655 | goto error; |
643 | 656 | ||
644 | /* create dvb_frontend */ | 657 | /* create dvb_frontend */ |
645 | state->frontend.ops = &state->ops; | 658 | memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); |
646 | state->frontend.demodulator_priv = state; | 659 | state->frontend.demodulator_priv = state; |
647 | return &state->frontend; | 660 | return &state->frontend; |
648 | 661 | ||
@@ -668,6 +681,7 @@ static struct dvb_frontend_ops stv0297_ops = { | |||
668 | 681 | ||
669 | .init = stv0297_init, | 682 | .init = stv0297_init, |
670 | .sleep = stv0297_sleep, | 683 | .sleep = stv0297_sleep, |
684 | .i2c_gate_ctrl = stv0297_i2c_gate_ctrl, | ||
671 | 685 | ||
672 | .set_frontend = stv0297_set_frontend, | 686 | .set_frontend = stv0297_set_frontend, |
673 | .get_frontend = stv0297_get_frontend, | 687 | .get_frontend = stv0297_get_frontend, |
@@ -684,4 +698,3 @@ MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey"); | |||
684 | MODULE_LICENSE("GPL"); | 698 | MODULE_LICENSE("GPL"); |
685 | 699 | ||
686 | EXPORT_SYMBOL(stv0297_attach); | 700 | EXPORT_SYMBOL(stv0297_attach); |
687 | EXPORT_SYMBOL(stv0297_enable_plli2c); | ||
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h index 9e53f019db71..1da5384fb985 100644 --- a/drivers/media/dvb/frontends/stv0297.h +++ b/drivers/media/dvb/frontends/stv0297.h | |||
@@ -38,13 +38,11 @@ struct stv0297_config | |||
38 | /* does the "inversion" need inverted? */ | 38 | /* does the "inversion" need inverted? */ |
39 | u8 invert:1; | 39 | u8 invert:1; |
40 | 40 | ||
41 | /* PLL maintenance */ | 41 | /* set to 1 if the device requires an i2c STOP during reading */ |
42 | int (*pll_init)(struct dvb_frontend* fe); | 42 | u8 stop_during_read:1; |
43 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
44 | }; | 43 | }; |
45 | 44 | ||
46 | extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, | 45 | extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, |
47 | struct i2c_adapter* i2c); | 46 | struct i2c_adapter* i2c); |
48 | extern int stv0297_enable_plli2c(struct dvb_frontend* fe); | ||
49 | 47 | ||
50 | #endif // STV0297_H | 48 | #endif // STV0297_H |
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 5bcd00f792e6..96648a75440d 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c | |||
@@ -56,7 +56,6 @@ | |||
56 | 56 | ||
57 | struct stv0299_state { | 57 | struct stv0299_state { |
58 | struct i2c_adapter* i2c; | 58 | struct i2c_adapter* i2c; |
59 | struct dvb_frontend_ops ops; | ||
60 | const struct stv0299_config* config; | 59 | const struct stv0299_config* config; |
61 | struct dvb_frontend frontend; | 60 | struct dvb_frontend frontend; |
62 | 61 | ||
@@ -131,13 +130,6 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len | |||
131 | return ret == 2 ? 0 : ret; | 130 | return ret == 2 ? 0 : ret; |
132 | } | 131 | } |
133 | 132 | ||
134 | int stv0299_enable_plli2c (struct dvb_frontend* fe) | ||
135 | { | ||
136 | struct stv0299_state* state = fe->demodulator_priv; | ||
137 | |||
138 | return stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | ||
139 | } | ||
140 | |||
141 | static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) | 133 | static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) |
142 | { | 134 | { |
143 | dprintk ("%s\n", __FUNCTION__); | 135 | dprintk ("%s\n", __FUNCTION__); |
@@ -457,12 +449,6 @@ static int stv0299_init (struct dvb_frontend* fe) | |||
457 | for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) | 449 | for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) |
458 | stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]); | 450 | stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]); |
459 | 451 | ||
460 | if (state->config->pll_init) { | ||
461 | stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | ||
462 | state->config->pll_init(fe, state->i2c); | ||
463 | stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ | ||
464 | } | ||
465 | |||
466 | return 0; | 452 | return 0; |
467 | } | 453 | } |
468 | 454 | ||
@@ -560,9 +546,10 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
560 | if (state->config->invert) invval = (~invval) & 1; | 546 | if (state->config->invert) invval = (~invval) & 1; |
561 | stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); | 547 | stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); |
562 | 548 | ||
563 | stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | 549 | if (fe->ops.tuner_ops.set_params) { |
564 | state->config->pll_set(fe, state->i2c, p); | 550 | fe->ops.tuner_ops.set_params(fe, p); |
565 | stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ | 551 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
552 | } | ||
566 | 553 | ||
567 | stv0299_set_FEC (state, p->u.qpsk.fec_inner); | 554 | stv0299_set_FEC (state, p->u.qpsk.fec_inner); |
568 | stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); | 555 | stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); |
@@ -611,6 +598,19 @@ static int stv0299_sleep(struct dvb_frontend* fe) | |||
611 | return 0; | 598 | return 0; |
612 | } | 599 | } |
613 | 600 | ||
601 | static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
602 | { | ||
603 | struct stv0299_state* state = fe->demodulator_priv; | ||
604 | |||
605 | if (enable) { | ||
606 | stv0299_writeregI(state, 0x05, 0xb5); | ||
607 | } else { | ||
608 | stv0299_writeregI(state, 0x05, 0x35); | ||
609 | } | ||
610 | udelay(1); | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | 614 | static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) |
615 | { | 615 | { |
616 | struct stv0299_state* state = fe->demodulator_priv; | 616 | struct stv0299_state* state = fe->demodulator_priv; |
@@ -647,7 +647,6 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | |||
647 | /* setup the state */ | 647 | /* setup the state */ |
648 | state->config = config; | 648 | state->config = config; |
649 | state->i2c = i2c; | 649 | state->i2c = i2c; |
650 | memcpy(&state->ops, &stv0299_ops, sizeof(struct dvb_frontend_ops)); | ||
651 | state->initialised = 0; | 650 | state->initialised = 0; |
652 | state->tuner_frequency = 0; | 651 | state->tuner_frequency = 0; |
653 | state->symbol_rate = 0; | 652 | state->symbol_rate = 0; |
@@ -664,7 +663,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | |||
664 | if (id != 0xa1 && id != 0x80) goto error; | 663 | if (id != 0xa1 && id != 0x80) goto error; |
665 | 664 | ||
666 | /* create dvb_frontend */ | 665 | /* create dvb_frontend */ |
667 | state->frontend.ops = &state->ops; | 666 | memcpy(&state->frontend.ops, &stv0299_ops, sizeof(struct dvb_frontend_ops)); |
668 | state->frontend.demodulator_priv = state; | 667 | state->frontend.demodulator_priv = state; |
669 | return &state->frontend; | 668 | return &state->frontend; |
670 | 669 | ||
@@ -695,6 +694,7 @@ static struct dvb_frontend_ops stv0299_ops = { | |||
695 | 694 | ||
696 | .init = stv0299_init, | 695 | .init = stv0299_init, |
697 | .sleep = stv0299_sleep, | 696 | .sleep = stv0299_sleep, |
697 | .i2c_gate_ctrl = stv0299_i2c_gate_ctrl, | ||
698 | 698 | ||
699 | .set_frontend = stv0299_set_frontend, | 699 | .set_frontend = stv0299_set_frontend, |
700 | .get_frontend = stv0299_get_frontend, | 700 | .get_frontend = stv0299_get_frontend, |
@@ -721,9 +721,8 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | |||
721 | 721 | ||
722 | MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver"); | 722 | MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver"); |
723 | MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " | 723 | MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " |
724 | "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); | 724 | "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); |
725 | MODULE_LICENSE("GPL"); | 725 | MODULE_LICENSE("GPL"); |
726 | 726 | ||
727 | EXPORT_SYMBOL(stv0299_enable_plli2c); | ||
728 | EXPORT_SYMBOL(stv0299_writereg); | 727 | EXPORT_SYMBOL(stv0299_writereg); |
729 | EXPORT_SYMBOL(stv0299_attach); | 728 | EXPORT_SYMBOL(stv0299_attach); |
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h index 32c87b4c2f13..1504828e4232 100644 --- a/drivers/media/dvb/frontends/stv0299.h +++ b/drivers/media/dvb/frontends/stv0299.h | |||
@@ -87,14 +87,9 @@ struct stv0299_config | |||
87 | 87 | ||
88 | /* Set the symbol rate */ | 88 | /* Set the symbol rate */ |
89 | int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); | 89 | int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); |
90 | |||
91 | /* PLL maintenance */ | ||
92 | int (*pll_init)(struct dvb_frontend *fe, struct i2c_adapter *i2c); | ||
93 | int (*pll_set)(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params); | ||
94 | }; | 90 | }; |
95 | 91 | ||
96 | extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); | 92 | extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); |
97 | extern int stv0299_enable_plli2c (struct dvb_frontend* fe); | ||
98 | 93 | ||
99 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | 94 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, |
100 | struct i2c_adapter* i2c); | 95 | struct i2c_adapter* i2c); |
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 21255cac9793..e83ff2104c9b 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
@@ -36,7 +36,6 @@ | |||
36 | 36 | ||
37 | struct tda10021_state { | 37 | struct tda10021_state { |
38 | struct i2c_adapter* i2c; | 38 | struct i2c_adapter* i2c; |
39 | struct dvb_frontend_ops ops; | ||
40 | /* configuration settings */ | 39 | /* configuration settings */ |
41 | const struct tda10021_config* config; | 40 | const struct tda10021_config* config; |
42 | struct dvb_frontend frontend; | 41 | struct dvb_frontend frontend; |
@@ -90,6 +89,14 @@ static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data) | |||
90 | return (ret != 1) ? -EREMOTEIO : 0; | 89 | return (ret != 1) ? -EREMOTEIO : 0; |
91 | } | 90 | } |
92 | 91 | ||
92 | int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data) | ||
93 | { | ||
94 | struct tda10021_state* state = fe->demodulator_priv; | ||
95 | |||
96 | return tda10021_writereg(state, reg, data); | ||
97 | } | ||
98 | EXPORT_SYMBOL(tda10021_write_byte); | ||
99 | |||
93 | static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) | 100 | static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) |
94 | { | 101 | { |
95 | u8 b0 [] = { reg }; | 102 | u8 b0 [] = { reg }; |
@@ -225,13 +232,6 @@ static int tda10021_init (struct dvb_frontend *fe) | |||
225 | 232 | ||
226 | //Activate PLL | 233 | //Activate PLL |
227 | tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef); | 234 | tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef); |
228 | |||
229 | if (state->config->pll_init) { | ||
230 | lock_tuner(state); | ||
231 | state->config->pll_init(fe); | ||
232 | unlock_tuner(state); | ||
233 | } | ||
234 | |||
235 | return 0; | 235 | return 0; |
236 | } | 236 | } |
237 | 237 | ||
@@ -259,9 +259,10 @@ static int tda10021_set_parameters (struct dvb_frontend *fe, | |||
259 | 259 | ||
260 | //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); | 260 | //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); |
261 | 261 | ||
262 | lock_tuner(state); | 262 | if (fe->ops.tuner_ops.set_params) { |
263 | state->config->pll_set(fe, p); | 263 | fe->ops.tuner_ops.set_params(fe, p); |
264 | unlock_tuner(state); | 264 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
265 | } | ||
265 | 266 | ||
266 | tda10021_set_symbolrate (state, p->u.qam.symbol_rate); | 267 | tda10021_set_symbolrate (state, p->u.qam.symbol_rate); |
267 | tda10021_writereg (state, 0x34, state->pwm); | 268 | tda10021_writereg (state, 0x34, state->pwm); |
@@ -376,6 +377,18 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa | |||
376 | return 0; | 377 | return 0; |
377 | } | 378 | } |
378 | 379 | ||
380 | static int tda10021_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
381 | { | ||
382 | struct tda10021_state* state = fe->demodulator_priv; | ||
383 | |||
384 | if (enable) { | ||
385 | lock_tuner(state); | ||
386 | } else { | ||
387 | unlock_tuner(state); | ||
388 | } | ||
389 | return 0; | ||
390 | } | ||
391 | |||
379 | static int tda10021_sleep(struct dvb_frontend* fe) | 392 | static int tda10021_sleep(struct dvb_frontend* fe) |
380 | { | 393 | { |
381 | struct tda10021_state* state = fe->demodulator_priv; | 394 | struct tda10021_state* state = fe->demodulator_priv; |
@@ -407,7 +420,6 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | |||
407 | /* setup the state */ | 420 | /* setup the state */ |
408 | state->config = config; | 421 | state->config = config; |
409 | state->i2c = i2c; | 422 | state->i2c = i2c; |
410 | memcpy(&state->ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); | ||
411 | state->pwm = pwm; | 423 | state->pwm = pwm; |
412 | state->reg0 = tda10021_inittab[0]; | 424 | state->reg0 = tda10021_inittab[0]; |
413 | 425 | ||
@@ -415,7 +427,7 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | |||
415 | if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; | 427 | if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; |
416 | 428 | ||
417 | /* create dvb_frontend */ | 429 | /* create dvb_frontend */ |
418 | state->frontend.ops = &state->ops; | 430 | memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); |
419 | state->frontend.demodulator_priv = state; | 431 | state->frontend.demodulator_priv = state; |
420 | return &state->frontend; | 432 | return &state->frontend; |
421 | 433 | ||
@@ -448,6 +460,7 @@ static struct dvb_frontend_ops tda10021_ops = { | |||
448 | 460 | ||
449 | .init = tda10021_init, | 461 | .init = tda10021_init, |
450 | .sleep = tda10021_sleep, | 462 | .sleep = tda10021_sleep, |
463 | .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, | ||
451 | 464 | ||
452 | .set_frontend = tda10021_set_parameters, | 465 | .set_frontend = tda10021_set_parameters, |
453 | .get_frontend = tda10021_get_frontend, | 466 | .get_frontend = tda10021_get_frontend, |
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h index 53be939e8c55..b1df4259bee9 100644 --- a/drivers/media/dvb/frontends/tda10021.h +++ b/drivers/media/dvb/frontends/tda10021.h | |||
@@ -30,13 +30,11 @@ struct tda10021_config | |||
30 | { | 30 | { |
31 | /* the demodulator's i2c address */ | 31 | /* the demodulator's i2c address */ |
32 | u8 demod_address; | 32 | u8 demod_address; |
33 | |||
34 | /* PLL maintenance */ | ||
35 | int (*pll_init)(struct dvb_frontend* fe); | ||
36 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
37 | }; | 33 | }; |
38 | 34 | ||
39 | extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | 35 | extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, |
40 | struct i2c_adapter* i2c, u8 pwm); | 36 | struct i2c_adapter* i2c, u8 pwm); |
41 | 37 | ||
38 | extern int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data); | ||
39 | |||
42 | #endif // TDA10021_H | 40 | #endif // TDA10021_H |
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index b83dafa4e12c..59a2ed614fca 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
@@ -47,7 +47,6 @@ enum tda1004x_demod { | |||
47 | 47 | ||
48 | struct tda1004x_state { | 48 | struct tda1004x_state { |
49 | struct i2c_adapter* i2c; | 49 | struct i2c_adapter* i2c; |
50 | struct dvb_frontend_ops ops; | ||
51 | const struct tda1004x_config* config; | 50 | const struct tda1004x_config* config; |
52 | struct dvb_frontend frontend; | 51 | struct dvb_frontend frontend; |
53 | 52 | ||
@@ -600,13 +599,6 @@ static int tda10045_init(struct dvb_frontend* fe) | |||
600 | 599 | ||
601 | tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC | 600 | tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC |
602 | 601 | ||
603 | // Init the PLL | ||
604 | if (state->config->pll_init) { | ||
605 | tda1004x_enable_tuner_i2c(state); | ||
606 | state->config->pll_init(fe); | ||
607 | tda1004x_disable_tuner_i2c(state); | ||
608 | } | ||
609 | |||
610 | // tda setup | 602 | // tda setup |
611 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer | 603 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer |
612 | tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream | 604 | tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream |
@@ -635,16 +627,6 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
635 | return -EIO; | 627 | return -EIO; |
636 | } | 628 | } |
637 | 629 | ||
638 | // Init the tuner PLL | ||
639 | if (state->config->pll_init) { | ||
640 | tda1004x_enable_tuner_i2c(state); | ||
641 | if (state->config->pll_init(fe)) { | ||
642 | printk(KERN_ERR "tda1004x: pll init failed\n"); | ||
643 | return -EIO; | ||
644 | } | ||
645 | tda1004x_disable_tuner_i2c(state); | ||
646 | } | ||
647 | |||
648 | // tda setup | 630 | // tda setup |
649 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer | 631 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer |
650 | tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream | 632 | tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream |
@@ -712,12 +694,10 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
712 | } | 694 | } |
713 | 695 | ||
714 | // set frequency | 696 | // set frequency |
715 | tda1004x_enable_tuner_i2c(state); | 697 | if (fe->ops.tuner_ops.set_params) { |
716 | if (state->config->pll_set(fe, fe_params)) { | 698 | fe->ops.tuner_ops.set_params(fe, fe_params); |
717 | printk(KERN_ERR "tda1004x: pll set failed\n"); | 699 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
718 | return -EIO; | ||
719 | } | 700 | } |
720 | tda1004x_disable_tuner_i2c(state); | ||
721 | 701 | ||
722 | // Hardcoded to use auto as much as possible on the TDA10045 as it | 702 | // Hardcoded to use auto as much as possible on the TDA10045 as it |
723 | // is very unreliable if AUTO mode is _not_ used. | 703 | // is very unreliable if AUTO mode is _not_ used. |
@@ -1183,16 +1163,6 @@ static int tda1004x_sleep(struct dvb_frontend* fe) | |||
1183 | break; | 1163 | break; |
1184 | 1164 | ||
1185 | case TDA1004X_DEMOD_TDA10046: | 1165 | case TDA1004X_DEMOD_TDA10046: |
1186 | if (state->config->pll_sleep != NULL) { | ||
1187 | tda1004x_enable_tuner_i2c(state); | ||
1188 | state->config->pll_sleep(fe); | ||
1189 | if (state->config->if_freq != TDA10046_FREQ_052) { | ||
1190 | /* special hack for Philips EUROPA Based boards: | ||
1191 | * keep the I2c bridge open for tuner access in analog mode | ||
1192 | */ | ||
1193 | tda1004x_disable_tuner_i2c(state); | ||
1194 | } | ||
1195 | } | ||
1196 | /* set outputs to tristate */ | 1166 | /* set outputs to tristate */ |
1197 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); | 1167 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); |
1198 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); | 1168 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); |
@@ -1202,6 +1172,17 @@ static int tda1004x_sleep(struct dvb_frontend* fe) | |||
1202 | return 0; | 1172 | return 0; |
1203 | } | 1173 | } |
1204 | 1174 | ||
1175 | static int tda1004x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
1176 | { | ||
1177 | struct tda1004x_state* state = fe->demodulator_priv; | ||
1178 | |||
1179 | if (enable) { | ||
1180 | return tda1004x_enable_tuner_i2c(state); | ||
1181 | } else { | ||
1182 | return tda1004x_disable_tuner_i2c(state); | ||
1183 | } | ||
1184 | } | ||
1185 | |||
1205 | static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | 1186 | static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) |
1206 | { | 1187 | { |
1207 | fesettings->min_delay_ms = 800; | 1188 | fesettings->min_delay_ms = 800; |
@@ -1235,6 +1216,7 @@ static struct dvb_frontend_ops tda10045_ops = { | |||
1235 | 1216 | ||
1236 | .init = tda10045_init, | 1217 | .init = tda10045_init, |
1237 | .sleep = tda1004x_sleep, | 1218 | .sleep = tda1004x_sleep, |
1219 | .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, | ||
1238 | 1220 | ||
1239 | .set_frontend = tda1004x_set_fe, | 1221 | .set_frontend = tda1004x_set_fe, |
1240 | .get_frontend = tda1004x_get_fe, | 1222 | .get_frontend = tda1004x_get_fe, |
@@ -1260,7 +1242,6 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | |||
1260 | /* setup the state */ | 1242 | /* setup the state */ |
1261 | state->config = config; | 1243 | state->config = config; |
1262 | state->i2c = i2c; | 1244 | state->i2c = i2c; |
1263 | memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); | ||
1264 | state->demod_type = TDA1004X_DEMOD_TDA10045; | 1245 | state->demod_type = TDA1004X_DEMOD_TDA10045; |
1265 | 1246 | ||
1266 | /* check if the demod is there */ | 1247 | /* check if the demod is there */ |
@@ -1270,7 +1251,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | |||
1270 | } | 1251 | } |
1271 | 1252 | ||
1272 | /* create dvb_frontend */ | 1253 | /* create dvb_frontend */ |
1273 | state->frontend.ops = &state->ops; | 1254 | memcpy(&state->frontend.ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); |
1274 | state->frontend.demodulator_priv = state; | 1255 | state->frontend.demodulator_priv = state; |
1275 | return &state->frontend; | 1256 | return &state->frontend; |
1276 | } | 1257 | } |
@@ -1293,6 +1274,7 @@ static struct dvb_frontend_ops tda10046_ops = { | |||
1293 | 1274 | ||
1294 | .init = tda10046_init, | 1275 | .init = tda10046_init, |
1295 | .sleep = tda1004x_sleep, | 1276 | .sleep = tda1004x_sleep, |
1277 | .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, | ||
1296 | 1278 | ||
1297 | .set_frontend = tda1004x_set_fe, | 1279 | .set_frontend = tda1004x_set_fe, |
1298 | .get_frontend = tda1004x_get_fe, | 1280 | .get_frontend = tda1004x_get_fe, |
@@ -1318,7 +1300,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, | |||
1318 | /* setup the state */ | 1300 | /* setup the state */ |
1319 | state->config = config; | 1301 | state->config = config; |
1320 | state->i2c = i2c; | 1302 | state->i2c = i2c; |
1321 | memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); | ||
1322 | state->demod_type = TDA1004X_DEMOD_TDA10046; | 1303 | state->demod_type = TDA1004X_DEMOD_TDA10046; |
1323 | 1304 | ||
1324 | /* check if the demod is there */ | 1305 | /* check if the demod is there */ |
@@ -1328,7 +1309,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, | |||
1328 | } | 1309 | } |
1329 | 1310 | ||
1330 | /* create dvb_frontend */ | 1311 | /* create dvb_frontend */ |
1331 | state->frontend.ops = &state->ops; | 1312 | memcpy(&state->frontend.ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); |
1332 | state->frontend.demodulator_priv = state; | 1313 | state->frontend.demodulator_priv = state; |
1333 | return &state->frontend; | 1314 | return &state->frontend; |
1334 | } | 1315 | } |
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h index cc0c4af64067..b877b23ed734 100644 --- a/drivers/media/dvb/frontends/tda1004x.h +++ b/drivers/media/dvb/frontends/tda1004x.h | |||
@@ -66,11 +66,6 @@ struct tda1004x_config | |||
66 | /* AGC configuration */ | 66 | /* AGC configuration */ |
67 | enum tda10046_agc agc_config; | 67 | enum tda10046_agc agc_config; |
68 | 68 | ||
69 | /* PLL maintenance */ | ||
70 | int (*pll_init)(struct dvb_frontend* fe); | ||
71 | void (*pll_sleep)(struct dvb_frontend* fe); | ||
72 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
73 | |||
74 | /* request firmware for device */ | 69 | /* request firmware for device */ |
75 | /* set this to NULL if the card has a firmware EEPROM */ | 70 | /* set this to NULL if the card has a firmware EEPROM */ |
76 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 71 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c index 91baa9cedd79..3aa45ebbac3d 100644 --- a/drivers/media/dvb/frontends/tda8083.c +++ b/drivers/media/dvb/frontends/tda8083.c | |||
@@ -37,7 +37,6 @@ | |||
37 | 37 | ||
38 | struct tda8083_state { | 38 | struct tda8083_state { |
39 | struct i2c_adapter* i2c; | 39 | struct i2c_adapter* i2c; |
40 | struct dvb_frontend_ops ops; | ||
41 | /* configuration settings */ | 40 | /* configuration settings */ |
42 | const struct tda8083_config* config; | 41 | const struct tda8083_config* config; |
43 | struct dvb_frontend frontend; | 42 | struct dvb_frontend frontend; |
@@ -293,7 +292,11 @@ static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
293 | { | 292 | { |
294 | struct tda8083_state* state = fe->demodulator_priv; | 293 | struct tda8083_state* state = fe->demodulator_priv; |
295 | 294 | ||
296 | state->config->pll_set(fe, p); | 295 | if (fe->ops.tuner_ops.set_params) { |
296 | fe->ops.tuner_ops.set_params(fe, p); | ||
297 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
298 | } | ||
299 | |||
297 | tda8083_set_inversion (state, p->inversion); | 300 | tda8083_set_inversion (state, p->inversion); |
298 | tda8083_set_fec (state, p->u.qpsk.fec_inner); | 301 | tda8083_set_fec (state, p->u.qpsk.fec_inner); |
299 | tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate); | 302 | tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate); |
@@ -334,8 +337,6 @@ static int tda8083_init(struct dvb_frontend* fe) | |||
334 | for (i=0; i<44; i++) | 337 | for (i=0; i<44; i++) |
335 | tda8083_writereg (state, i, tda8083_init_tab[i]); | 338 | tda8083_writereg (state, i, tda8083_init_tab[i]); |
336 | 339 | ||
337 | if (state->config->pll_init) state->config->pll_init(fe); | ||
338 | |||
339 | tda8083_writereg (state, 0x00, 0x3c); | 340 | tda8083_writereg (state, 0x00, 0x3c); |
340 | tda8083_writereg (state, 0x00, 0x04); | 341 | tda8083_writereg (state, 0x00, 0x04); |
341 | 342 | ||
@@ -395,13 +396,12 @@ struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, | |||
395 | /* setup the state */ | 396 | /* setup the state */ |
396 | state->config = config; | 397 | state->config = config; |
397 | state->i2c = i2c; | 398 | state->i2c = i2c; |
398 | memcpy(&state->ops, &tda8083_ops, sizeof(struct dvb_frontend_ops)); | ||
399 | 399 | ||
400 | /* check if the demod is there */ | 400 | /* check if the demod is there */ |
401 | if ((tda8083_readreg(state, 0x00)) != 0x05) goto error; | 401 | if ((tda8083_readreg(state, 0x00)) != 0x05) goto error; |
402 | 402 | ||
403 | /* create dvb_frontend */ | 403 | /* create dvb_frontend */ |
404 | state->frontend.ops = &state->ops; | 404 | memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops)); |
405 | state->frontend.demodulator_priv = state; | 405 | state->frontend.demodulator_priv = state; |
406 | return &state->frontend; | 406 | return &state->frontend; |
407 | 407 | ||
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h index 466663307bf1..e7a48f61ea2c 100644 --- a/drivers/media/dvb/frontends/tda8083.h +++ b/drivers/media/dvb/frontends/tda8083.h | |||
@@ -33,10 +33,6 @@ struct tda8083_config | |||
33 | { | 33 | { |
34 | /* the demodulator's i2c address */ | 34 | /* the demodulator's i2c address */ |
35 | u8 demod_address; | 35 | u8 demod_address; |
36 | |||
37 | /* PLL maintenance */ | ||
38 | int (*pll_init)(struct dvb_frontend* fe); | ||
39 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
40 | }; | 36 | }; |
41 | 37 | ||
42 | extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, | 38 | extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, |
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c index ad8647a3c85e..6bffe85c161c 100644 --- a/drivers/media/dvb/frontends/ves1820.c +++ b/drivers/media/dvb/frontends/ves1820.c | |||
@@ -35,7 +35,6 @@ | |||
35 | 35 | ||
36 | struct ves1820_state { | 36 | struct ves1820_state { |
37 | struct i2c_adapter* i2c; | 37 | struct i2c_adapter* i2c; |
38 | struct dvb_frontend_ops ops; | ||
39 | /* configuration settings */ | 38 | /* configuration settings */ |
40 | const struct ves1820_config* config; | 39 | const struct ves1820_config* config; |
41 | struct dvb_frontend frontend; | 40 | struct dvb_frontend frontend; |
@@ -204,9 +203,6 @@ static int ves1820_init(struct dvb_frontend* fe) | |||
204 | 203 | ||
205 | ves1820_writereg(state, 0x34, state->pwm); | 204 | ves1820_writereg(state, 0x34, state->pwm); |
206 | 205 | ||
207 | if (state->config->pll_init) | ||
208 | state->config->pll_init(fe); | ||
209 | |||
210 | return 0; | 206 | return 0; |
211 | } | 207 | } |
212 | 208 | ||
@@ -223,7 +219,11 @@ static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_p | |||
223 | if (real_qam < 0 || real_qam > 4) | 219 | if (real_qam < 0 || real_qam > 4) |
224 | return -EINVAL; | 220 | return -EINVAL; |
225 | 221 | ||
226 | state->config->pll_set(fe, p); | 222 | if (fe->ops.tuner_ops.set_params) { |
223 | fe->ops.tuner_ops.set_params(fe, p); | ||
224 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
225 | } | ||
226 | |||
227 | ves1820_set_symbolrate(state, p->u.qam.symbol_rate); | 227 | ves1820_set_symbolrate(state, p->u.qam.symbol_rate); |
228 | ves1820_writereg(state, 0x34, state->pwm); | 228 | ves1820_writereg(state, 0x34, state->pwm); |
229 | 229 | ||
@@ -380,7 +380,6 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, | |||
380 | goto error; | 380 | goto error; |
381 | 381 | ||
382 | /* setup the state */ | 382 | /* setup the state */ |
383 | memcpy(&state->ops, &ves1820_ops, sizeof(struct dvb_frontend_ops)); | ||
384 | state->reg0 = ves1820_inittab[0]; | 383 | state->reg0 = ves1820_inittab[0]; |
385 | state->config = config; | 384 | state->config = config; |
386 | state->i2c = i2c; | 385 | state->i2c = i2c; |
@@ -393,12 +392,12 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, | |||
393 | if (verbose) | 392 | if (verbose) |
394 | printk("ves1820: pwm=0x%02x\n", state->pwm); | 393 | printk("ves1820: pwm=0x%02x\n", state->pwm); |
395 | 394 | ||
396 | state->ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */ | ||
397 | state->ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */ | ||
398 | |||
399 | /* create dvb_frontend */ | 395 | /* create dvb_frontend */ |
400 | state->frontend.ops = &state->ops; | 396 | memcpy(&state->frontend.ops, &ves1820_ops, sizeof(struct dvb_frontend_ops)); |
397 | state->frontend.ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */ | ||
398 | state->frontend.ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */ | ||
401 | state->frontend.demodulator_priv = state; | 399 | state->frontend.demodulator_priv = state; |
400 | |||
402 | return &state->frontend; | 401 | return &state->frontend; |
403 | 402 | ||
404 | error: | 403 | error: |
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h index 355f130b1be8..520f09522fbb 100644 --- a/drivers/media/dvb/frontends/ves1820.h +++ b/drivers/media/dvb/frontends/ves1820.h | |||
@@ -39,10 +39,6 @@ struct ves1820_config | |||
39 | 39 | ||
40 | /* SELAGC control */ | 40 | /* SELAGC control */ |
41 | u8 selagc:1; | 41 | u8 selagc:1; |
42 | |||
43 | /* PLL maintenance */ | ||
44 | int (*pll_init)(struct dvb_frontend* fe); | ||
45 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
46 | }; | 42 | }; |
47 | 43 | ||
48 | extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, | 44 | extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, |
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c index 821df8e839d0..54d7b07571b8 100644 --- a/drivers/media/dvb/frontends/ves1x93.c +++ b/drivers/media/dvb/frontends/ves1x93.c | |||
@@ -36,7 +36,6 @@ | |||
36 | 36 | ||
37 | struct ves1x93_state { | 37 | struct ves1x93_state { |
38 | struct i2c_adapter* i2c; | 38 | struct i2c_adapter* i2c; |
39 | struct dvb_frontend_ops ops; | ||
40 | /* configuration settings */ | 39 | /* configuration settings */ |
41 | const struct ves1x93_config* config; | 40 | const struct ves1x93_config* config; |
42 | struct dvb_frontend frontend; | 41 | struct dvb_frontend frontend; |
@@ -278,12 +277,6 @@ static int ves1x93_init (struct dvb_frontend* fe) | |||
278 | } | 277 | } |
279 | } | 278 | } |
280 | 279 | ||
281 | if (state->config->pll_init) { | ||
282 | ves1x93_writereg(state, 0x00, 0x11); | ||
283 | state->config->pll_init(fe); | ||
284 | ves1x93_writereg(state, 0x00, 0x01); | ||
285 | } | ||
286 | |||
287 | return 0; | 280 | return 0; |
288 | } | 281 | } |
289 | 282 | ||
@@ -395,9 +388,10 @@ static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
395 | { | 388 | { |
396 | struct ves1x93_state* state = fe->demodulator_priv; | 389 | struct ves1x93_state* state = fe->demodulator_priv; |
397 | 390 | ||
398 | ves1x93_writereg(state, 0x00, 0x11); | 391 | if (fe->ops.tuner_ops.set_params) { |
399 | state->config->pll_set(fe, p); | 392 | fe->ops.tuner_ops.set_params(fe, p); |
400 | ves1x93_writereg(state, 0x00, 0x01); | 393 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
394 | } | ||
401 | ves1x93_set_inversion (state, p->inversion); | 395 | ves1x93_set_inversion (state, p->inversion); |
402 | ves1x93_set_fec (state, p->u.qpsk.fec_inner); | 396 | ves1x93_set_fec (state, p->u.qpsk.fec_inner); |
403 | ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate); | 397 | ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate); |
@@ -442,6 +436,17 @@ static void ves1x93_release(struct dvb_frontend* fe) | |||
442 | kfree(state); | 436 | kfree(state); |
443 | } | 437 | } |
444 | 438 | ||
439 | static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
440 | { | ||
441 | struct ves1x93_state* state = fe->demodulator_priv; | ||
442 | |||
443 | if (enable) { | ||
444 | return ves1x93_writereg(state, 0x00, 0x11); | ||
445 | } else { | ||
446 | return ves1x93_writereg(state, 0x00, 0x01); | ||
447 | } | ||
448 | } | ||
449 | |||
445 | static struct dvb_frontend_ops ves1x93_ops; | 450 | static struct dvb_frontend_ops ves1x93_ops; |
446 | 451 | ||
447 | struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | 452 | struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, |
@@ -457,7 +462,6 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | |||
457 | /* setup the state */ | 462 | /* setup the state */ |
458 | state->config = config; | 463 | state->config = config; |
459 | state->i2c = i2c; | 464 | state->i2c = i2c; |
460 | memcpy(&state->ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops)); | ||
461 | state->inversion = INVERSION_OFF; | 465 | state->inversion = INVERSION_OFF; |
462 | 466 | ||
463 | /* check if the demod is there + identify it */ | 467 | /* check if the demod is there + identify it */ |
@@ -492,7 +496,7 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | |||
492 | } | 496 | } |
493 | 497 | ||
494 | /* create dvb_frontend */ | 498 | /* create dvb_frontend */ |
495 | state->frontend.ops = &state->ops; | 499 | memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops)); |
496 | state->frontend.demodulator_priv = state; | 500 | state->frontend.demodulator_priv = state; |
497 | return &state->frontend; | 501 | return &state->frontend; |
498 | 502 | ||
@@ -523,6 +527,7 @@ static struct dvb_frontend_ops ves1x93_ops = { | |||
523 | 527 | ||
524 | .init = ves1x93_init, | 528 | .init = ves1x93_init, |
525 | .sleep = ves1x93_sleep, | 529 | .sleep = ves1x93_sleep, |
530 | .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl, | ||
526 | 531 | ||
527 | .set_frontend = ves1x93_set_frontend, | 532 | .set_frontend = ves1x93_set_frontend, |
528 | .get_frontend = ves1x93_get_frontend, | 533 | .get_frontend = ves1x93_get_frontend, |
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h index 1627e37c57a4..ba88ae0855c9 100644 --- a/drivers/media/dvb/frontends/ves1x93.h +++ b/drivers/media/dvb/frontends/ves1x93.h | |||
@@ -38,10 +38,6 @@ struct ves1x93_config | |||
38 | 38 | ||
39 | /* should PWM be inverted? */ | 39 | /* should PWM be inverted? */ |
40 | u8 invert_pwm:1; | 40 | u8 invert_pwm:1; |
41 | |||
42 | /* PLL maintenance */ | ||
43 | int (*pll_init)(struct dvb_frontend* fe); | ||
44 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
45 | }; | 41 | }; |
46 | 42 | ||
47 | extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | 43 | extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, |
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index d7d9f59d76d2..2b95e8b6cd39 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c | |||
@@ -34,7 +34,6 @@ | |||
34 | struct zl10353_state { | 34 | struct zl10353_state { |
35 | struct i2c_adapter *i2c; | 35 | struct i2c_adapter *i2c; |
36 | struct dvb_frontend frontend; | 36 | struct dvb_frontend frontend; |
37 | struct dvb_frontend_ops ops; | ||
38 | 37 | ||
39 | struct zl10353_config config; | 38 | struct zl10353_config config; |
40 | }; | 39 | }; |
@@ -126,6 +125,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, | |||
126 | struct dvb_frontend_parameters *param) | 125 | struct dvb_frontend_parameters *param) |
127 | { | 126 | { |
128 | struct zl10353_state *state = fe->demodulator_priv; | 127 | struct zl10353_state *state = fe->demodulator_priv; |
128 | |||
129 | u8 pllbuf[6] = { 0x67 }; | 129 | u8 pllbuf[6] = { 0x67 }; |
130 | 130 | ||
131 | /* These settings set "auto-everything" and start the FSM. */ | 131 | /* These settings set "auto-everything" and start the FSM. */ |
@@ -142,7 +142,30 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, | |||
142 | zl10353_single_write(fe, 0x66, 0xE9); | 142 | zl10353_single_write(fe, 0x66, 0xE9); |
143 | zl10353_single_write(fe, 0x62, 0x0A); | 143 | zl10353_single_write(fe, 0x62, 0x0A); |
144 | 144 | ||
145 | state->config.pll_set(fe, param, pllbuf + 1); | 145 | // if there is no attached secondary tuner, we call set_params to program |
146 | // a potential tuner attached somewhere else | ||
147 | if (state->config.no_tuner) { | ||
148 | if (fe->ops.tuner_ops.set_params) { | ||
149 | fe->ops.tuner_ops.set_params(fe, param); | ||
150 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | // if pllbuf is defined, retrieve the settings | ||
155 | if (fe->ops.tuner_ops.calc_regs) { | ||
156 | fe->ops.tuner_ops.calc_regs(fe, param, pllbuf+1, 5); | ||
157 | pllbuf[1] <<= 1; | ||
158 | } else { | ||
159 | // fake pllbuf settings | ||
160 | pllbuf[1] = 0x61 << 1; | ||
161 | pllbuf[2] = 0; | ||
162 | pllbuf[3] = 0; | ||
163 | pllbuf[3] = 0; | ||
164 | pllbuf[4] = 0; | ||
165 | } | ||
166 | |||
167 | // there is no call to _just_ start decoding, so we send the pllbuf anyway | ||
168 | // even if there isn't a PLL attached to the secondary bus | ||
146 | zl10353_write(fe, pllbuf, sizeof(pllbuf)); | 169 | zl10353_write(fe, pllbuf, sizeof(pllbuf)); |
147 | 170 | ||
148 | zl10353_single_write(fe, 0x70, 0x01); | 171 | zl10353_single_write(fe, 0x70, 0x01); |
@@ -254,14 +277,13 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, | |||
254 | /* setup the state */ | 277 | /* setup the state */ |
255 | state->i2c = i2c; | 278 | state->i2c = i2c; |
256 | memcpy(&state->config, config, sizeof(struct zl10353_config)); | 279 | memcpy(&state->config, config, sizeof(struct zl10353_config)); |
257 | memcpy(&state->ops, &zl10353_ops, sizeof(struct dvb_frontend_ops)); | ||
258 | 280 | ||
259 | /* check if the demod is there */ | 281 | /* check if the demod is there */ |
260 | if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) | 282 | if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) |
261 | goto error; | 283 | goto error; |
262 | 284 | ||
263 | /* create dvb_frontend */ | 285 | /* create dvb_frontend */ |
264 | state->frontend.ops = &state->ops; | 286 | memcpy(&state->frontend.ops, &zl10353_ops, sizeof(struct dvb_frontend_ops)); |
265 | state->frontend.demodulator_priv = state; | 287 | state->frontend.demodulator_priv = state; |
266 | 288 | ||
267 | return &state->frontend; | 289 | return &state->frontend; |
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h index 5cc4ae718d8c..9770cb840cfc 100644 --- a/drivers/media/dvb/frontends/zl10353.h +++ b/drivers/media/dvb/frontends/zl10353.h | |||
@@ -29,10 +29,8 @@ struct zl10353_config | |||
29 | /* demodulator's I2C address */ | 29 | /* demodulator's I2C address */ |
30 | u8 demod_address; | 30 | u8 demod_address; |
31 | 31 | ||
32 | /* function which configures the PLL buffer (for secondary I2C | 32 | /* set if no pll is connected to the secondary i2c bus */ |
33 | * connected tuner) or tunes the PLL (for direct connected tuner) */ | 33 | int no_tuner; |
34 | int (*pll_set)(struct dvb_frontend *fe, | ||
35 | struct dvb_frontend_parameters *params, u8 *pllbuf); | ||
36 | }; | 34 | }; |
37 | 35 | ||
38 | extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, | 36 | extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, |
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 1c5316e209ef..acabea0793b6 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c | |||
@@ -424,8 +424,8 @@ static inline u32 divide(u32 numerator, u32 denominator) | |||
424 | } | 424 | } |
425 | 425 | ||
426 | /* LG Innotek TDTE-E001P (Infineon TUA6034) */ | 426 | /* LG Innotek TDTE-E001P (Infineon TUA6034) */ |
427 | static int lg_tdtpe001p_pll_set(struct dvb_frontend *fe, | 427 | static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe, |
428 | struct dvb_frontend_parameters *p) | 428 | struct dvb_frontend_parameters *p) |
429 | { | 429 | { |
430 | struct pluto *pluto = frontend_to_pluto(fe); | 430 | struct pluto *pluto = frontend_to_pluto(fe); |
431 | struct i2c_msg msg; | 431 | struct i2c_msg msg; |
@@ -473,6 +473,8 @@ static int lg_tdtpe001p_pll_set(struct dvb_frontend *fe, | |||
473 | msg.buf = buf; | 473 | msg.buf = buf; |
474 | msg.len = sizeof(buf); | 474 | msg.len = sizeof(buf); |
475 | 475 | ||
476 | if (fe->ops.i2c_gate_ctrl) | ||
477 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
476 | ret = i2c_transfer(&pluto->i2c_adap, &msg, 1); | 478 | ret = i2c_transfer(&pluto->i2c_adap, &msg, 1); |
477 | if (ret < 0) | 479 | if (ret < 0) |
478 | return ret; | 480 | return ret; |
@@ -497,8 +499,6 @@ static struct tda1004x_config pluto2_fe_config __devinitdata = { | |||
497 | .xtal_freq = TDA10046_XTAL_16M, | 499 | .xtal_freq = TDA10046_XTAL_16M, |
498 | .agc_config = TDA10046_AGC_DEFAULT, | 500 | .agc_config = TDA10046_AGC_DEFAULT, |
499 | .if_freq = TDA10046_FREQ_3617, | 501 | .if_freq = TDA10046_FREQ_3617, |
500 | .pll_set = lg_tdtpe001p_pll_set, | ||
501 | .pll_sleep = NULL, | ||
502 | .request_firmware = pluto2_request_firmware, | 502 | .request_firmware = pluto2_request_firmware, |
503 | }; | 503 | }; |
504 | 504 | ||
@@ -511,11 +511,12 @@ static int __devinit frontend_init(struct pluto *pluto) | |||
511 | dev_err(&pluto->pdev->dev, "could not attach frontend\n"); | 511 | dev_err(&pluto->pdev->dev, "could not attach frontend\n"); |
512 | return -ENODEV; | 512 | return -ENODEV; |
513 | } | 513 | } |
514 | pluto->fe->ops.tuner_ops.set_params = lg_tdtpe001p_tuner_set_params; | ||
514 | 515 | ||
515 | ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe); | 516 | ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe); |
516 | if (ret < 0) { | 517 | if (ret < 0) { |
517 | if (pluto->fe->ops->release) | 518 | if (pluto->fe->ops.release) |
518 | pluto->fe->ops->release(pluto->fe); | 519 | pluto->fe->ops.release(pluto->fe); |
519 | return ret; | 520 | return ret; |
520 | } | 521 | } |
521 | 522 | ||
@@ -647,7 +648,7 @@ static int __devinit pluto2_probe(struct pci_dev *pdev, | |||
647 | goto err_pluto_hw_exit; | 648 | goto err_pluto_hw_exit; |
648 | 649 | ||
649 | /* dvb */ | 650 | /* dvb */ |
650 | ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE); | 651 | ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE, &pdev->dev); |
651 | if (ret < 0) | 652 | if (ret < 0) |
652 | goto err_i2c_bit_del_bus; | 653 | goto err_i2c_bit_del_bus; |
653 | 654 | ||
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index b5ac7dfde52f..987881fa988c 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig | |||
@@ -10,6 +10,7 @@ config DVB_AV7110 | |||
10 | select DVB_SP8870 | 10 | select DVB_SP8870 |
11 | select DVB_STV0297 | 11 | select DVB_STV0297 |
12 | select DVB_L64781 | 12 | select DVB_L64781 |
13 | select DVB_LNBP21 | ||
13 | help | 14 | help |
14 | Support for SAA7146 and AV7110 based DVB cards as produced | 15 | Support for SAA7146 and AV7110 based DVB cards as produced |
15 | by Fujitsu-Siemens, Technotrend, Hauppauge and others. | 16 | by Fujitsu-Siemens, Technotrend, Hauppauge and others. |
@@ -67,6 +68,7 @@ config DVB_BUDGET | |||
67 | select DVB_TDA8083 | 68 | select DVB_TDA8083 |
68 | select DVB_TDA10021 | 69 | select DVB_TDA10021 |
69 | select DVB_S5H1420 | 70 | select DVB_S5H1420 |
71 | select DVB_LNBP21 | ||
70 | help | 72 | help |
71 | Support for simple SAA7146 based DVB cards | 73 | Support for simple SAA7146 based DVB cards |
72 | (so called Budget- or Nova-PCI cards) without onboard | 74 | (so called Budget- or Nova-PCI cards) without onboard |
@@ -84,6 +86,7 @@ config DVB_BUDGET_CI | |||
84 | select DVB_STV0297 | 86 | select DVB_STV0297 |
85 | select DVB_STV0299 | 87 | select DVB_STV0299 |
86 | select DVB_TDA1004X | 88 | select DVB_TDA1004X |
89 | select DVB_LNBP21 | ||
87 | help | 90 | help |
88 | Support for simple SAA7146 based DVB cards | 91 | Support for simple SAA7146 based DVB cards |
89 | (so called Budget- or Nova-PCI cards) without onboard | 92 | (so called Budget- or Nova-PCI cards) without onboard |
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile index a690730ac39d..aa85ecdc6c80 100644 --- a/drivers/media/dvb/ttpci/Makefile +++ b/drivers/media/dvb/ttpci/Makefile | |||
@@ -15,9 +15,9 @@ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | |||
15 | 15 | ||
16 | hostprogs-y := fdump | 16 | hostprogs-y := fdump |
17 | 17 | ||
18 | ifdef CONFIG_DVB_AV7110_FIRMWARE | 18 | ifeq ($(CONFIG_DVB_AV7110_FIRMWARE),y) |
19 | $(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h | 19 | $(obj)/av7110.o: $(obj)/av7110_firm.h |
20 | 20 | ||
21 | $(obj)/av7110_firm.h: | 21 | $(obj)/av7110_firm.h: $(obj)/fdump |
22 | $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ | 22 | $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ |
23 | endif | 23 | endif |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index d028245c8eed..8832f80c05f7 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -1552,7 +1552,7 @@ static int get_firmware(struct av7110* av7110) | |||
1552 | #endif | 1552 | #endif |
1553 | 1553 | ||
1554 | 1554 | ||
1555 | static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1555 | static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1556 | { | 1556 | { |
1557 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; | 1557 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; |
1558 | u8 pwr = 0; | 1558 | u8 pwr = 0; |
@@ -1575,6 +1575,8 @@ static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1575 | // NOTE: since we're using a prescaler of 2, we set the | 1575 | // NOTE: since we're using a prescaler of 2, we set the |
1576 | // divisor frequency to 62.5kHz and divide by 125 above | 1576 | // divisor frequency to 62.5kHz and divide by 125 above |
1577 | 1577 | ||
1578 | if (fe->ops.i2c_gate_ctrl) | ||
1579 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1578 | if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) | 1580 | if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) |
1579 | return -EIO; | 1581 | return -EIO; |
1580 | return 0; | 1582 | return 0; |
@@ -1584,10 +1586,9 @@ static struct ves1x93_config alps_bsrv2_config = { | |||
1584 | .demod_address = 0x08, | 1586 | .demod_address = 0x08, |
1585 | .xin = 90100000UL, | 1587 | .xin = 90100000UL, |
1586 | .invert_pwm = 0, | 1588 | .invert_pwm = 0, |
1587 | .pll_set = alps_bsrv2_pll_set, | ||
1588 | }; | 1589 | }; |
1589 | 1590 | ||
1590 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1591 | static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1591 | { | 1592 | { |
1592 | struct av7110* av7110 = fe->dvb->priv; | 1593 | struct av7110* av7110 = fe->dvb->priv; |
1593 | u32 div; | 1594 | u32 div; |
@@ -1601,6 +1602,8 @@ static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1601 | data[2] = 0x85 | ((div >> 10) & 0x60); | 1602 | data[2] = 0x85 | ((div >> 10) & 0x60); |
1602 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); | 1603 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); |
1603 | 1604 | ||
1605 | if (fe->ops.i2c_gate_ctrl) | ||
1606 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1604 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | 1607 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) |
1605 | return -EIO; | 1608 | return -EIO; |
1606 | return 0; | 1609 | return 0; |
@@ -1611,14 +1614,12 @@ static struct ves1820_config alps_tdbe2_config = { | |||
1611 | .xin = 57840000UL, | 1614 | .xin = 57840000UL, |
1612 | .invert = 1, | 1615 | .invert = 1, |
1613 | .selagc = VES1820_SELAGC_SIGNAMPERR, | 1616 | .selagc = VES1820_SELAGC_SIGNAMPERR, |
1614 | .pll_set = alps_tdbe2_pll_set, | ||
1615 | }; | 1617 | }; |
1616 | 1618 | ||
1617 | 1619 | ||
1618 | 1620 | ||
1619 | 1621 | ||
1620 | static int grundig_29504_451_pll_set(struct dvb_frontend* fe, | 1622 | static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1621 | struct dvb_frontend_parameters* params) | ||
1622 | { | 1623 | { |
1623 | struct av7110* av7110 = fe->dvb->priv; | 1624 | struct av7110* av7110 = fe->dvb->priv; |
1624 | u32 div; | 1625 | u32 div; |
@@ -1631,6 +1632,8 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe, | |||
1631 | data[2] = 0x8e; | 1632 | data[2] = 0x8e; |
1632 | data[3] = 0x00; | 1633 | data[3] = 0x00; |
1633 | 1634 | ||
1635 | if (fe->ops.i2c_gate_ctrl) | ||
1636 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1634 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | 1637 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) |
1635 | return -EIO; | 1638 | return -EIO; |
1636 | return 0; | 1639 | return 0; |
@@ -1638,13 +1641,11 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe, | |||
1638 | 1641 | ||
1639 | static struct tda8083_config grundig_29504_451_config = { | 1642 | static struct tda8083_config grundig_29504_451_config = { |
1640 | .demod_address = 0x68, | 1643 | .demod_address = 0x68, |
1641 | .pll_set = grundig_29504_451_pll_set, | ||
1642 | }; | 1644 | }; |
1643 | 1645 | ||
1644 | 1646 | ||
1645 | 1647 | ||
1646 | static int philips_cd1516_pll_set(struct dvb_frontend* fe, | 1648 | static int philips_cd1516_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1647 | struct dvb_frontend_parameters* params) | ||
1648 | { | 1649 | { |
1649 | struct av7110* av7110 = fe->dvb->priv; | 1650 | struct av7110* av7110 = fe->dvb->priv; |
1650 | u32 div; | 1651 | u32 div; |
@@ -1659,6 +1660,8 @@ static int philips_cd1516_pll_set(struct dvb_frontend* fe, | |||
1659 | data[2] = 0x8e; | 1660 | data[2] = 0x8e; |
1660 | data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34); | 1661 | data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34); |
1661 | 1662 | ||
1663 | if (fe->ops.i2c_gate_ctrl) | ||
1664 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1662 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | 1665 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) |
1663 | return -EIO; | 1666 | return -EIO; |
1664 | return 0; | 1667 | return 0; |
@@ -1669,12 +1672,11 @@ static struct ves1820_config philips_cd1516_config = { | |||
1669 | .xin = 57840000UL, | 1672 | .xin = 57840000UL, |
1670 | .invert = 1, | 1673 | .invert = 1, |
1671 | .selagc = VES1820_SELAGC_SIGNAMPERR, | 1674 | .selagc = VES1820_SELAGC_SIGNAMPERR, |
1672 | .pll_set = philips_cd1516_pll_set, | ||
1673 | }; | 1675 | }; |
1674 | 1676 | ||
1675 | 1677 | ||
1676 | 1678 | ||
1677 | static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1679 | static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1678 | { | 1680 | { |
1679 | struct av7110* av7110 = fe->dvb->priv; | 1681 | struct av7110* av7110 = fe->dvb->priv; |
1680 | u32 div, pwr; | 1682 | u32 div, pwr; |
@@ -1693,6 +1695,8 @@ static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1693 | data[2] = 0x85; | 1695 | data[2] = 0x85; |
1694 | data[3] = pwr << 6; | 1696 | data[3] = pwr << 6; |
1695 | 1697 | ||
1698 | if (fe->ops.i2c_gate_ctrl) | ||
1699 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1696 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | 1700 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) |
1697 | return -EIO; | 1701 | return -EIO; |
1698 | return 0; | 1702 | return 0; |
@@ -1708,7 +1712,6 @@ static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct fir | |||
1708 | static struct sp8870_config alps_tdlb7_config = { | 1712 | static struct sp8870_config alps_tdlb7_config = { |
1709 | 1713 | ||
1710 | .demod_address = 0x71, | 1714 | .demod_address = 0x71, |
1711 | .pll_set = alps_tdlb7_pll_set, | ||
1712 | .request_firmware = alps_tdlb7_request_firmware, | 1715 | .request_firmware = alps_tdlb7_request_firmware, |
1713 | }; | 1716 | }; |
1714 | 1717 | ||
@@ -1806,7 +1809,7 @@ static u8 nexusca_stv0297_inittab[] = { | |||
1806 | 0xff, 0xff, | 1809 | 0xff, 0xff, |
1807 | }; | 1810 | }; |
1808 | 1811 | ||
1809 | static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1812 | static int nexusca_stv0297_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1810 | { | 1813 | { |
1811 | struct av7110* av7110 = fe->dvb->priv; | 1814 | struct av7110* av7110 = fe->dvb->priv; |
1812 | u32 div; | 1815 | u32 div; |
@@ -1832,7 +1835,8 @@ static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_ | |||
1832 | else | 1835 | else |
1833 | return -EINVAL; | 1836 | return -EINVAL; |
1834 | 1837 | ||
1835 | stv0297_enable_plli2c(fe); | 1838 | if (fe->ops.i2c_gate_ctrl) |
1839 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1836 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) { | 1840 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) { |
1837 | printk("nexusca: pll transfer failed!\n"); | 1841 | printk("nexusca: pll transfer failed!\n"); |
1838 | return -EIO; | 1842 | return -EIO; |
@@ -1840,8 +1844,8 @@ static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_ | |||
1840 | 1844 | ||
1841 | // wait for PLL lock | 1845 | // wait for PLL lock |
1842 | for(i = 0; i < 20; i++) { | 1846 | for(i = 0; i < 20; i++) { |
1843 | 1847 | if (fe->ops.i2c_gate_ctrl) | |
1844 | stv0297_enable_plli2c(fe); | 1848 | fe->ops.i2c_gate_ctrl(fe, 1); |
1845 | if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1) | 1849 | if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1) |
1846 | if (data[0] & 0x40) break; | 1850 | if (data[0] & 0x40) break; |
1847 | msleep(10); | 1851 | msleep(10); |
@@ -1855,12 +1859,12 @@ static struct stv0297_config nexusca_stv0297_config = { | |||
1855 | .demod_address = 0x1C, | 1859 | .demod_address = 0x1C, |
1856 | .inittab = nexusca_stv0297_inittab, | 1860 | .inittab = nexusca_stv0297_inittab, |
1857 | .invert = 1, | 1861 | .invert = 1, |
1858 | .pll_set = nexusca_stv0297_pll_set, | 1862 | .stop_during_read = 1, |
1859 | }; | 1863 | }; |
1860 | 1864 | ||
1861 | 1865 | ||
1862 | 1866 | ||
1863 | static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1867 | static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1864 | { | 1868 | { |
1865 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; | 1869 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; |
1866 | u32 div; | 1870 | u32 div; |
@@ -1887,13 +1891,14 @@ static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
1887 | data[2] = ((div >> 10) & 0x60) | cfg; | 1891 | data[2] = ((div >> 10) & 0x60) | cfg; |
1888 | data[3] = (cpump << 6) | band_select; | 1892 | data[3] = (cpump << 6) | band_select; |
1889 | 1893 | ||
1894 | if (fe->ops.i2c_gate_ctrl) | ||
1895 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1890 | if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO; | 1896 | if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO; |
1891 | return 0; | 1897 | return 0; |
1892 | } | 1898 | } |
1893 | 1899 | ||
1894 | static struct l64781_config grundig_29504_401_config = { | 1900 | static struct l64781_config grundig_29504_401_config = { |
1895 | .demod_address = 0x55, | 1901 | .demod_address = 0x55, |
1896 | .pll_set = grundig_29504_401_pll_set, | ||
1897 | }; | 1902 | }; |
1898 | 1903 | ||
1899 | 1904 | ||
@@ -2079,6 +2084,9 @@ static int frontend_init(struct av7110 *av7110) | |||
2079 | case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??)) | 2084 | case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??)) |
2080 | av7110->fe = ves1820_attach(&philips_cd1516_config, | 2085 | av7110->fe = ves1820_attach(&philips_cd1516_config, |
2081 | &av7110->i2c_adap, read_pwm(av7110)); | 2086 | &av7110->i2c_adap, read_pwm(av7110)); |
2087 | if (av7110->fe) { | ||
2088 | av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params; | ||
2089 | } | ||
2082 | break; | 2090 | break; |
2083 | } | 2091 | } |
2084 | 2092 | ||
@@ -2091,9 +2099,10 @@ static int frontend_init(struct av7110 *av7110) | |||
2091 | // try the ALPS BSRV2 first of all | 2099 | // try the ALPS BSRV2 first of all |
2092 | av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); | 2100 | av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); |
2093 | if (av7110->fe) { | 2101 | if (av7110->fe) { |
2094 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2102 | av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; |
2095 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2103 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2096 | av7110->fe->ops->set_tone = av7110_set_tone; | 2104 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; |
2105 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2097 | av7110->recover = dvb_s_recover; | 2106 | av7110->recover = dvb_s_recover; |
2098 | break; | 2107 | break; |
2099 | } | 2108 | } |
@@ -2101,9 +2110,12 @@ static int frontend_init(struct av7110 *av7110) | |||
2101 | // try the ALPS BSRU6 now | 2110 | // try the ALPS BSRU6 now |
2102 | av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap); | 2111 | av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap); |
2103 | if (av7110->fe) { | 2112 | if (av7110->fe) { |
2104 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2113 | av7110->fe->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; |
2105 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2114 | av7110->fe->tuner_priv = &av7110->i2c_adap; |
2106 | av7110->fe->ops->set_tone = av7110_set_tone; | 2115 | |
2116 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | ||
2117 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; | ||
2118 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2107 | av7110->recover = dvb_s_recover; | 2119 | av7110->recover = dvb_s_recover; |
2108 | break; | 2120 | break; |
2109 | } | 2121 | } |
@@ -2111,9 +2123,10 @@ static int frontend_init(struct av7110 *av7110) | |||
2111 | // Try the grundig 29504-451 | 2123 | // Try the grundig 29504-451 |
2112 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); | 2124 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); |
2113 | if (av7110->fe) { | 2125 | if (av7110->fe) { |
2114 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2126 | av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; |
2115 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2127 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2116 | av7110->fe->ops->set_tone = av7110_set_tone; | 2128 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; |
2129 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2117 | av7110->recover = dvb_s_recover; | 2130 | av7110->recover = dvb_s_recover; |
2118 | break; | 2131 | break; |
2119 | } | 2132 | } |
@@ -2124,11 +2137,17 @@ static int frontend_init(struct av7110 *av7110) | |||
2124 | /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */ | 2137 | /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */ |
2125 | av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap, | 2138 | av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap, |
2126 | read_pwm(av7110)); | 2139 | read_pwm(av7110)); |
2140 | if (av7110->fe) { | ||
2141 | av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params; | ||
2142 | } | ||
2127 | break; | 2143 | break; |
2128 | case 0x0003: | 2144 | case 0x0003: |
2129 | /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */ | 2145 | /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */ |
2130 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, | 2146 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, |
2131 | read_pwm(av7110)); | 2147 | read_pwm(av7110)); |
2148 | if (av7110->fe) { | ||
2149 | av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
2150 | } | ||
2132 | break; | 2151 | break; |
2133 | } | 2152 | } |
2134 | break; | 2153 | break; |
@@ -2137,20 +2156,27 @@ static int frontend_init(struct av7110 *av7110) | |||
2137 | 2156 | ||
2138 | // ALPS TDLB7 | 2157 | // ALPS TDLB7 |
2139 | av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); | 2158 | av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); |
2159 | if (av7110->fe) { | ||
2160 | av7110->fe->ops.tuner_ops.set_params = alps_tdlb7_tuner_set_params; | ||
2161 | } | ||
2140 | break; | 2162 | break; |
2141 | 2163 | ||
2142 | case 0x0002: // Hauppauge/TT DVB-C premium rev2.X | 2164 | case 0x0002: // Hauppauge/TT DVB-C premium rev2.X |
2143 | 2165 | ||
2144 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); | 2166 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); |
2167 | if (av7110->fe) { | ||
2168 | av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
2169 | } | ||
2145 | break; | 2170 | break; |
2146 | 2171 | ||
2147 | case 0x0004: // Galaxis DVB-S rev1.3 | 2172 | case 0x0004: // Galaxis DVB-S rev1.3 |
2148 | /* ALPS BSRV2 */ | 2173 | /* ALPS BSRV2 */ |
2149 | av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); | 2174 | av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); |
2150 | if (av7110->fe) { | 2175 | if (av7110->fe) { |
2151 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2176 | av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; |
2152 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2177 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2153 | av7110->fe->ops->set_tone = av7110_set_tone; | 2178 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; |
2179 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2154 | av7110->recover = dvb_s_recover; | 2180 | av7110->recover = dvb_s_recover; |
2155 | } | 2181 | } |
2156 | break; | 2182 | break; |
@@ -2159,9 +2185,10 @@ static int frontend_init(struct av7110 *av7110) | |||
2159 | /* Grundig 29504-451 */ | 2185 | /* Grundig 29504-451 */ |
2160 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); | 2186 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); |
2161 | if (av7110->fe) { | 2187 | if (av7110->fe) { |
2162 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2188 | av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; |
2163 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2189 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2164 | av7110->fe->ops->set_tone = av7110_set_tone; | 2190 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; |
2191 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2165 | av7110->recover = dvb_s_recover; | 2192 | av7110->recover = dvb_s_recover; |
2166 | } | 2193 | } |
2167 | break; | 2194 | break; |
@@ -2169,12 +2196,17 @@ static int frontend_init(struct av7110 *av7110) | |||
2169 | case 0x0008: // Hauppauge/TT DVB-T | 2196 | case 0x0008: // Hauppauge/TT DVB-T |
2170 | 2197 | ||
2171 | av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap); | 2198 | av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap); |
2199 | if (av7110->fe) { | ||
2200 | av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; | ||
2201 | } | ||
2172 | break; | 2202 | break; |
2173 | 2203 | ||
2174 | case 0x000A: // Hauppauge/TT Nexus-CA rev1.X | 2204 | case 0x000A: // Hauppauge/TT Nexus-CA rev1.X |
2175 | 2205 | ||
2176 | av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap); | 2206 | av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap); |
2177 | if (av7110->fe) { | 2207 | if (av7110->fe) { |
2208 | av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params; | ||
2209 | |||
2178 | /* set TDA9819 into DVB mode */ | 2210 | /* set TDA9819 into DVB mode */ |
2179 | saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD) | 2211 | saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD) |
2180 | saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF) | 2212 | saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF) |
@@ -2189,13 +2221,16 @@ static int frontend_init(struct av7110 *av7110) | |||
2189 | /* ALPS BSBE1 */ | 2221 | /* ALPS BSBE1 */ |
2190 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); | 2222 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); |
2191 | if (av7110->fe) { | 2223 | if (av7110->fe) { |
2192 | if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) { | 2224 | av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; |
2225 | av7110->fe->tuner_priv = &av7110->i2c_adap; | ||
2226 | |||
2227 | if (lnbp21_attach(av7110->fe, &av7110->i2c_adap, 0, 0)) { | ||
2193 | printk("dvb-ttpci: LNBP21 not found!\n"); | 2228 | printk("dvb-ttpci: LNBP21 not found!\n"); |
2194 | if (av7110->fe->ops->release) | 2229 | if (av7110->fe->ops.release) |
2195 | av7110->fe->ops->release(av7110->fe); | 2230 | av7110->fe->ops.release(av7110->fe); |
2196 | av7110->fe = NULL; | 2231 | av7110->fe = NULL; |
2197 | } else { | 2232 | } else { |
2198 | av7110->fe->ops->dishnetwork_send_legacy_command = NULL; | 2233 | av7110->fe->ops.dishnetwork_send_legacy_command = NULL; |
2199 | av7110->recover = dvb_s_recover; | 2234 | av7110->recover = dvb_s_recover; |
2200 | } | 2235 | } |
2201 | } | 2236 | } |
@@ -2212,21 +2247,21 @@ static int frontend_init(struct av7110 *av7110) | |||
2212 | av7110->dev->pci->subsystem_vendor, | 2247 | av7110->dev->pci->subsystem_vendor, |
2213 | av7110->dev->pci->subsystem_device); | 2248 | av7110->dev->pci->subsystem_device); |
2214 | } else { | 2249 | } else { |
2215 | FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init); | 2250 | FE_FUNC_OVERRIDE(av7110->fe->ops.init, av7110->fe_init, av7110_fe_init); |
2216 | FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status); | 2251 | FE_FUNC_OVERRIDE(av7110->fe->ops.read_status, av7110->fe_read_status, av7110_fe_read_status); |
2217 | FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload); | 2252 | FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload); |
2218 | FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); | 2253 | FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); |
2219 | FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); | 2254 | FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); |
2220 | FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone); | 2255 | FE_FUNC_OVERRIDE(av7110->fe->ops.set_tone, av7110->fe_set_tone, av7110_fe_set_tone); |
2221 | FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;) | 2256 | FE_FUNC_OVERRIDE(av7110->fe->ops.set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;) |
2222 | FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); | 2257 | FE_FUNC_OVERRIDE(av7110->fe->ops.dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); |
2223 | FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); | 2258 | FE_FUNC_OVERRIDE(av7110->fe->ops.set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); |
2224 | 2259 | ||
2225 | ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe); | 2260 | ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe); |
2226 | if (ret < 0) { | 2261 | if (ret < 0) { |
2227 | printk("av7110: Frontend registration failed!\n"); | 2262 | printk("av7110: Frontend registration failed!\n"); |
2228 | if (av7110->fe->ops->release) | 2263 | if (av7110->fe->ops.release) |
2229 | av7110->fe->ops->release(av7110->fe); | 2264 | av7110->fe->ops.release(av7110->fe); |
2230 | av7110->fe = NULL; | 2265 | av7110->fe = NULL; |
2231 | } | 2266 | } |
2232 | } | 2267 | } |
@@ -2413,7 +2448,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, | |||
2413 | goto err_kfree_0; | 2448 | goto err_kfree_0; |
2414 | 2449 | ||
2415 | ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, | 2450 | ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, |
2416 | THIS_MODULE); | 2451 | THIS_MODULE, &dev->pci->dev); |
2417 | if (ret < 0) | 2452 | if (ret < 0) |
2418 | goto err_put_firmware_1; | 2453 | goto err_put_firmware_1; |
2419 | 2454 | ||
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 8a7cd7d505cf..6163cb03b8f4 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
@@ -50,6 +50,12 @@ | |||
50 | 50 | ||
51 | #define DEBICICAM 0x02420000 | 51 | #define DEBICICAM 0x02420000 |
52 | 52 | ||
53 | #define SLOTSTATUS_NONE 1 | ||
54 | #define SLOTSTATUS_PRESENT 2 | ||
55 | #define SLOTSTATUS_RESET 4 | ||
56 | #define SLOTSTATUS_READY 8 | ||
57 | #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) | ||
58 | |||
53 | struct budget_av { | 59 | struct budget_av { |
54 | struct budget budget; | 60 | struct budget budget; |
55 | struct video_device *vd; | 61 | struct video_device *vd; |
@@ -58,8 +64,15 @@ struct budget_av { | |||
58 | struct tasklet_struct ciintf_irq_tasklet; | 64 | struct tasklet_struct ciintf_irq_tasklet; |
59 | int slot_status; | 65 | int slot_status; |
60 | struct dvb_ca_en50221 ca; | 66 | struct dvb_ca_en50221 ca; |
67 | u8 reinitialise_demod:1; | ||
68 | u8 tda10021_poclkp:1; | ||
69 | u8 tda10021_ts_enabled; | ||
70 | int (*tda10021_set_frontend)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); | ||
61 | }; | 71 | }; |
62 | 72 | ||
73 | static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); | ||
74 | |||
75 | |||
63 | /* GPIO Connections: | 76 | /* GPIO Connections: |
64 | * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! | 77 | * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! |
65 | * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory | 78 | * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory |
@@ -129,9 +142,10 @@ static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int ad | |||
129 | udelay(1); | 142 | udelay(1); |
130 | 143 | ||
131 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); | 144 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); |
132 | 145 | if (result == -ETIMEDOUT) { | |
133 | if (result == -ETIMEDOUT) | 146 | ciintf_slot_shutdown(ca, slot); |
134 | budget_av->slot_status = 0; | 147 | printk(KERN_INFO "budget-av: cam ejected 1\n"); |
148 | } | ||
135 | return result; | 149 | return result; |
136 | } | 150 | } |
137 | 151 | ||
@@ -147,9 +161,10 @@ static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int a | |||
147 | udelay(1); | 161 | udelay(1); |
148 | 162 | ||
149 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); | 163 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); |
150 | 164 | if (result == -ETIMEDOUT) { | |
151 | if (result == -ETIMEDOUT) | 165 | ciintf_slot_shutdown(ca, slot); |
152 | budget_av->slot_status = 0; | 166 | printk(KERN_INFO "budget-av: cam ejected 2\n"); |
167 | } | ||
153 | return result; | 168 | return result; |
154 | } | 169 | } |
155 | 170 | ||
@@ -165,9 +180,11 @@ static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addre | |||
165 | udelay(1); | 180 | udelay(1); |
166 | 181 | ||
167 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); | 182 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); |
168 | 183 | if ((result == -ETIMEDOUT) || ((result == 0xff) && ((address & 3) < 2))) { | |
169 | if (result == -ETIMEDOUT) | 184 | ciintf_slot_shutdown(ca, slot); |
170 | budget_av->slot_status = 0; | 185 | printk(KERN_INFO "budget-av: cam ejected 3\n"); |
186 | return -ETIMEDOUT; | ||
187 | } | ||
171 | return result; | 188 | return result; |
172 | } | 189 | } |
173 | 190 | ||
@@ -183,9 +200,10 @@ static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addr | |||
183 | udelay(1); | 200 | udelay(1); |
184 | 201 | ||
185 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0); | 202 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0); |
186 | 203 | if (result == -ETIMEDOUT) { | |
187 | if (result == -ETIMEDOUT) | 204 | ciintf_slot_shutdown(ca, slot); |
188 | budget_av->slot_status = 0; | 205 | printk(KERN_INFO "budget-av: cam ejected 5\n"); |
206 | } | ||
189 | return result; | 207 | return result; |
190 | } | 208 | } |
191 | 209 | ||
@@ -193,12 +211,12 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | |||
193 | { | 211 | { |
194 | struct budget_av *budget_av = (struct budget_av *) ca->data; | 212 | struct budget_av *budget_av = (struct budget_av *) ca->data; |
195 | struct saa7146_dev *saa = budget_av->budget.dev; | 213 | struct saa7146_dev *saa = budget_av->budget.dev; |
196 | int timeout = 50; // 5 seconds (4.4.6 Ready) | ||
197 | 214 | ||
198 | if (slot != 0) | 215 | if (slot != 0) |
199 | return -EINVAL; | 216 | return -EINVAL; |
200 | 217 | ||
201 | dprintk(1, "ciintf_slot_reset\n"); | 218 | dprintk(1, "ciintf_slot_reset\n"); |
219 | budget_av->slot_status = SLOTSTATUS_RESET; | ||
202 | 220 | ||
203 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ | 221 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ |
204 | 222 | ||
@@ -208,20 +226,17 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | |||
208 | msleep(20); /* 20 ms Vcc settling time */ | 226 | msleep(20); /* 20 ms Vcc settling time */ |
209 | 227 | ||
210 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ | 228 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ |
229 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | ||
230 | msleep(20); | ||
211 | 231 | ||
212 | /* This should have been based on pin 16 READY of the pcmcia port, | 232 | /* reinitialise the frontend if necessary */ |
213 | * but AFAICS it is not routed to the saa7146 */ | 233 | if (budget_av->reinitialise_demod) |
214 | while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) | 234 | dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); |
215 | msleep(100); | ||
216 | |||
217 | /* reinitialise the frontend */ | ||
218 | dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); | ||
219 | 235 | ||
220 | if (timeout <= 0) | 236 | /* set tda10021 back to original clock configuration on reset */ |
221 | { | 237 | if (budget_av->tda10021_poclkp) { |
222 | printk(KERN_ERR "budget-av: cam reset failed (timeout).\n"); | 238 | tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0); |
223 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ | 239 | budget_av->tda10021_ts_enabled = 0; |
224 | return -ETIMEDOUT; | ||
225 | } | 240 | } |
226 | 241 | ||
227 | return 0; | 242 | return 0; |
@@ -238,7 +253,13 @@ static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) | |||
238 | dprintk(1, "ciintf_slot_shutdown\n"); | 253 | dprintk(1, "ciintf_slot_shutdown\n"); |
239 | 254 | ||
240 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | 255 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); |
241 | budget_av->slot_status = 0; | 256 | budget_av->slot_status = SLOTSTATUS_NONE; |
257 | |||
258 | /* set tda10021 back to original clock configuration when cam removed */ | ||
259 | if (budget_av->tda10021_poclkp) { | ||
260 | tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0); | ||
261 | budget_av->tda10021_ts_enabled = 0; | ||
262 | } | ||
242 | return 0; | 263 | return 0; |
243 | } | 264 | } |
244 | 265 | ||
@@ -253,6 +274,13 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) | |||
253 | dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); | 274 | dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); |
254 | 275 | ||
255 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); | 276 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); |
277 | |||
278 | /* tda10021 seems to need a different TS clock config when data is routed to the CAM */ | ||
279 | if (budget_av->tda10021_poclkp) { | ||
280 | tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa1); | ||
281 | budget_av->tda10021_ts_enabled = 1; | ||
282 | } | ||
283 | |||
256 | return 0; | 284 | return 0; |
257 | } | 285 | } |
258 | 286 | ||
@@ -260,50 +288,61 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open | |||
260 | { | 288 | { |
261 | struct budget_av *budget_av = (struct budget_av *) ca->data; | 289 | struct budget_av *budget_av = (struct budget_av *) ca->data; |
262 | struct saa7146_dev *saa = budget_av->budget.dev; | 290 | struct saa7146_dev *saa = budget_av->budget.dev; |
263 | int cam_present = 0; | 291 | int result; |
264 | 292 | ||
265 | if (slot != 0) | 293 | if (slot != 0) |
266 | return -EINVAL; | 294 | return -EINVAL; |
267 | 295 | ||
268 | if (!budget_av->slot_status) | 296 | /* test the card detect line - needs to be done carefully |
269 | { | 297 | * since it never goes high for some CAMs on this interface (e.g. topuptv) */ |
270 | // first of all test the card detect line | 298 | if (budget_av->slot_status == SLOTSTATUS_NONE) { |
271 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | 299 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); |
272 | udelay(1); | 300 | udelay(1); |
273 | if (saa7146_read(saa, PSR) & MASK_06) | 301 | if (saa7146_read(saa, PSR) & MASK_06) { |
274 | { | 302 | if (budget_av->slot_status == SLOTSTATUS_NONE) { |
275 | cam_present = 1; | 303 | budget_av->slot_status = SLOTSTATUS_PRESENT; |
304 | printk(KERN_INFO "budget-av: cam inserted A\n"); | ||
305 | } | ||
276 | } | 306 | } |
277 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | 307 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); |
308 | } | ||
278 | 309 | ||
279 | // that is unreliable however, so try and read from IO memory | 310 | /* We also try and read from IO memory to work round the above detection bug. If |
280 | if (!cam_present) | 311 | * there is no CAM, we will get a timeout. Only done if there is no cam |
281 | { | 312 | * present, since this test actually breaks some cams :( |
282 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | 313 | * |
283 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) != -ETIMEDOUT) | 314 | * if the CI interface is not open, we also do the above test since we |
284 | { | 315 | * don't care if the cam has problems - we'll be resetting it on open() anyway */ |
285 | cam_present = 1; | 316 | if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) { |
317 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | ||
318 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1); | ||
319 | if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) { | ||
320 | budget_av->slot_status = SLOTSTATUS_PRESENT; | ||
321 | printk(KERN_INFO "budget-av: cam inserted B\n"); | ||
322 | } else if (result < 0) { | ||
323 | if (budget_av->slot_status != SLOTSTATUS_NONE) { | ||
324 | ciintf_slot_shutdown(ca, slot); | ||
325 | printk(KERN_INFO "budget-av: cam ejected 5\n"); | ||
326 | return 0; | ||
286 | } | 327 | } |
287 | } | 328 | } |
329 | } | ||
288 | 330 | ||
289 | // did we find something? | 331 | /* read from attribute memory in reset/ready state to know when the CAM is ready */ |
290 | if (cam_present) { | 332 | if (budget_av->slot_status == SLOTSTATUS_RESET) { |
291 | printk(KERN_INFO "budget-av: cam inserted\n"); | 333 | result = ciintf_read_attribute_mem(ca, slot, 0); |
292 | budget_av->slot_status = 1; | 334 | if (result == 0x1d) { |
293 | } | 335 | budget_av->slot_status = SLOTSTATUS_READY; |
294 | } else if (!open) { | ||
295 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | ||
296 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) | ||
297 | { | ||
298 | printk(KERN_INFO "budget-av: cam ejected\n"); | ||
299 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ | ||
300 | budget_av->slot_status = 0; | ||
301 | } | 336 | } |
302 | } | 337 | } |
303 | 338 | ||
304 | if (budget_av->slot_status == 1) | 339 | /* work out correct return code */ |
305 | return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | 340 | if (budget_av->slot_status != SLOTSTATUS_NONE) { |
306 | 341 | if (budget_av->slot_status & SLOTSTATUS_READY) { | |
342 | return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | ||
343 | } | ||
344 | return DVB_CA_EN50221_POLL_CAM_PRESENT; | ||
345 | } | ||
307 | return 0; | 346 | return 0; |
308 | } | 347 | } |
309 | 348 | ||
@@ -333,6 +372,8 @@ static int ciintf_init(struct budget_av *budget_av) | |||
333 | budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; | 372 | budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; |
334 | budget_av->ca.poll_slot_status = ciintf_poll_slot_status; | 373 | budget_av->ca.poll_slot_status = ciintf_poll_slot_status; |
335 | budget_av->ca.data = budget_av; | 374 | budget_av->ca.data = budget_av; |
375 | budget_av->budget.ci_present = 1; | ||
376 | budget_av->slot_status = SLOTSTATUS_NONE; | ||
336 | 377 | ||
337 | if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, | 378 | if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, |
338 | &budget_av->ca, 0, 1)) != 0) { | 379 | &budget_av->ca, 0, 1)) != 0) { |
@@ -341,7 +382,6 @@ static int ciintf_init(struct budget_av *budget_av) | |||
341 | } | 382 | } |
342 | 383 | ||
343 | printk(KERN_INFO "budget-av: ci interface initialised.\n"); | 384 | printk(KERN_INFO "budget-av: ci interface initialised.\n"); |
344 | budget_av->budget.ci_present = 1; | ||
345 | return 0; | 385 | return 0; |
346 | 386 | ||
347 | error: | 387 | error: |
@@ -472,12 +512,12 @@ static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 sra | |||
472 | return 0; | 512 | return 0; |
473 | } | 513 | } |
474 | 514 | ||
475 | static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, | 515 | static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe, |
476 | struct i2c_adapter *i2c, | 516 | struct dvb_frontend_parameters *params) |
477 | struct dvb_frontend_parameters *params) | ||
478 | { | 517 | { |
479 | u32 div; | 518 | u32 div; |
480 | u8 buf[4]; | 519 | u8 buf[4]; |
520 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
481 | struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; | 521 | struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; |
482 | 522 | ||
483 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | 523 | if ((params->frequency < 950000) || (params->frequency > 2150000)) |
@@ -501,7 +541,9 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, | |||
501 | else if (params->frequency < 2150000) | 541 | else if (params->frequency < 2150000) |
502 | buf[3] |= 0xC0; | 542 | buf[3] |= 0xC0; |
503 | 543 | ||
504 | if (i2c_transfer(i2c, &msg, 1) != 1) | 544 | if (fe->ops.i2c_gate_ctrl) |
545 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
546 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | ||
505 | return -EIO; | 547 | return -EIO; |
506 | return 0; | 548 | return 0; |
507 | } | 549 | } |
@@ -509,9 +551,8 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, | |||
509 | #define MIN2(a,b) ((a) < (b) ? (a) : (b)) | 551 | #define MIN2(a,b) ((a) < (b) ? (a) : (b)) |
510 | #define MIN3(a,b,c) MIN2(MIN2(a,b),c) | 552 | #define MIN3(a,b,c) MIN2(MIN2(a,b),c) |
511 | 553 | ||
512 | static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, | 554 | static int philips_su1278sh2_tua6100_tuner_set_params(struct dvb_frontend *fe, |
513 | struct i2c_adapter *i2c, | 555 | struct dvb_frontend_parameters *params) |
514 | struct dvb_frontend_parameters *params) | ||
515 | { | 556 | { |
516 | u8 reg0 [2] = { 0x00, 0x00 }; | 557 | u8 reg0 [2] = { 0x00, 0x00 }; |
517 | u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 }; | 558 | u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 }; |
@@ -521,6 +562,7 @@ static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, | |||
521 | int R, A, N, P, M; | 562 | int R, A, N, P, M; |
522 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 }; | 563 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 }; |
523 | int freq = params->frequency; | 564 | int freq = params->frequency; |
565 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
524 | 566 | ||
525 | first_ZF = (freq) / 1000; | 567 | first_ZF = (freq) / 1000; |
526 | 568 | ||
@@ -620,21 +662,25 @@ static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, | |||
620 | reg0[1] |= 0x03; | 662 | reg0[1] |= 0x03; |
621 | 663 | ||
622 | /* already enabled - do not reenable i2c repeater or TX fails */ | 664 | /* already enabled - do not reenable i2c repeater or TX fails */ |
665 | if (fe->ops.i2c_gate_ctrl) | ||
666 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
623 | msg.buf = reg0; | 667 | msg.buf = reg0; |
624 | msg.len = sizeof(reg0); | 668 | msg.len = sizeof(reg0); |
625 | if (i2c_transfer(i2c, &msg, 1) != 1) | 669 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) |
626 | return -EIO; | 670 | return -EIO; |
627 | 671 | ||
628 | stv0299_enable_plli2c(fe); | 672 | if (fe->ops.i2c_gate_ctrl) |
673 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
629 | msg.buf = reg1; | 674 | msg.buf = reg1; |
630 | msg.len = sizeof(reg1); | 675 | msg.len = sizeof(reg1); |
631 | if (i2c_transfer(i2c, &msg, 1) != 1) | 676 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) |
632 | return -EIO; | 677 | return -EIO; |
633 | 678 | ||
634 | stv0299_enable_plli2c(fe); | 679 | if (fe->ops.i2c_gate_ctrl) |
680 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
635 | msg.buf = reg2; | 681 | msg.buf = reg2; |
636 | msg.len = sizeof(reg2); | 682 | msg.len = sizeof(reg2); |
637 | if (i2c_transfer(i2c, &msg, 1) != 1) | 683 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) |
638 | return -EIO; | 684 | return -EIO; |
639 | 685 | ||
640 | return 0; | 686 | return 0; |
@@ -692,7 +738,6 @@ static struct stv0299_config typhoon_config = { | |||
692 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | 738 | .volt13_op0_op1 = STV0299_VOLT13_OP0, |
693 | .min_delay_ms = 100, | 739 | .min_delay_ms = 100, |
694 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | 740 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, |
695 | .pll_set = philips_su1278_ty_ci_pll_set, | ||
696 | }; | 741 | }; |
697 | 742 | ||
698 | 743 | ||
@@ -706,7 +751,6 @@ static struct stv0299_config cinergy_1200s_config = { | |||
706 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | 751 | .volt13_op0_op1 = STV0299_VOLT13_OP0, |
707 | .min_delay_ms = 100, | 752 | .min_delay_ms = 100, |
708 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | 753 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, |
709 | .pll_set = philips_su1278_ty_ci_pll_set, | ||
710 | }; | 754 | }; |
711 | 755 | ||
712 | static struct stv0299_config cinergy_1200s_1894_0010_config = { | 756 | static struct stv0299_config cinergy_1200s_1894_0010_config = { |
@@ -719,10 +763,9 @@ static struct stv0299_config cinergy_1200s_1894_0010_config = { | |||
719 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | 763 | .volt13_op0_op1 = STV0299_VOLT13_OP0, |
720 | .min_delay_ms = 100, | 764 | .min_delay_ms = 100, |
721 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | 765 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, |
722 | .pll_set = philips_su1278sh2_tua6100_pll_set, | ||
723 | }; | 766 | }; |
724 | 767 | ||
725 | static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 768 | static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
726 | { | 769 | { |
727 | struct budget *budget = (struct budget *) fe->dvb->priv; | 770 | struct budget *budget = (struct budget *) fe->dvb->priv; |
728 | u8 buf[4]; | 771 | u8 buf[4]; |
@@ -738,6 +781,8 @@ static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p | |||
738 | buf[3] = (params->frequency < 150000000 ? 0x01 : | 781 | buf[3] = (params->frequency < 150000000 ? 0x01 : |
739 | params->frequency < 445000000 ? 0x02 : 0x04); | 782 | params->frequency < 445000000 ? 0x02 : 0x04); |
740 | 783 | ||
784 | if (fe->ops.i2c_gate_ctrl) | ||
785 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
741 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | 786 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) |
742 | return -EIO; | 787 | return -EIO; |
743 | return 0; | 788 | return 0; |
@@ -745,19 +790,20 @@ static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p | |||
745 | 790 | ||
746 | static struct tda10021_config philips_cu1216_config = { | 791 | static struct tda10021_config philips_cu1216_config = { |
747 | .demod_address = 0x0c, | 792 | .demod_address = 0x0c, |
748 | .pll_set = philips_cu1216_pll_set, | ||
749 | }; | 793 | }; |
750 | 794 | ||
751 | 795 | ||
752 | 796 | ||
753 | 797 | ||
754 | static int philips_tu1216_pll_init(struct dvb_frontend *fe) | 798 | static int philips_tu1216_tuner_init(struct dvb_frontend *fe) |
755 | { | 799 | { |
756 | struct budget *budget = (struct budget *) fe->dvb->priv; | 800 | struct budget *budget = (struct budget *) fe->dvb->priv; |
757 | static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | 801 | static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; |
758 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; | 802 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; |
759 | 803 | ||
760 | // setup PLL configuration | 804 | // setup PLL configuration |
805 | if (fe->ops.i2c_gate_ctrl) | ||
806 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
761 | if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | 807 | if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) |
762 | return -EIO; | 808 | return -EIO; |
763 | msleep(1); | 809 | msleep(1); |
@@ -765,7 +811,7 @@ static int philips_tu1216_pll_init(struct dvb_frontend *fe) | |||
765 | return 0; | 811 | return 0; |
766 | } | 812 | } |
767 | 813 | ||
768 | static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 814 | static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
769 | { | 815 | { |
770 | struct budget *budget = (struct budget *) fe->dvb->priv; | 816 | struct budget *budget = (struct budget *) fe->dvb->priv; |
771 | u8 tuner_buf[4]; | 817 | u8 tuner_buf[4]; |
@@ -839,6 +885,8 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p | |||
839 | tuner_buf[2] = 0xca; | 885 | tuner_buf[2] = 0xca; |
840 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | 886 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; |
841 | 887 | ||
888 | if (fe->ops.i2c_gate_ctrl) | ||
889 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
842 | if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | 890 | if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) |
843 | return -EIO; | 891 | return -EIO; |
844 | 892 | ||
@@ -862,9 +910,6 @@ static struct tda1004x_config philips_tu1216_config = { | |||
862 | .xtal_freq = TDA10046_XTAL_4M, | 910 | .xtal_freq = TDA10046_XTAL_4M, |
863 | .agc_config = TDA10046_AGC_DEFAULT, | 911 | .agc_config = TDA10046_AGC_DEFAULT, |
864 | .if_freq = TDA10046_FREQ_3617, | 912 | .if_freq = TDA10046_FREQ_3617, |
865 | .pll_init = philips_tu1216_pll_init, | ||
866 | .pll_set = philips_tu1216_pll_set, | ||
867 | .pll_sleep = NULL, | ||
868 | .request_firmware = philips_tu1216_request_firmware, | 913 | .request_firmware = philips_tu1216_request_firmware, |
869 | }; | 914 | }; |
870 | 915 | ||
@@ -911,13 +956,13 @@ static u8 philips_sd1878_inittab[] = { | |||
911 | 0xff, 0xff | 956 | 0xff, 0xff |
912 | }; | 957 | }; |
913 | 958 | ||
914 | static int philips_sd1878_tda8261_pll_set(struct dvb_frontend *fe, | 959 | static int philips_sd1878_tda8261_tuner_set_params(struct dvb_frontend *fe, |
915 | struct i2c_adapter *i2c, | 960 | struct dvb_frontend_parameters *params) |
916 | struct dvb_frontend_parameters *params) | ||
917 | { | 961 | { |
918 | u8 buf[4]; | 962 | u8 buf[4]; |
919 | int rc; | 963 | int rc; |
920 | struct i2c_msg tuner_msg = {.addr=0x60,.flags=0,.buf=buf,.len=sizeof(buf)}; | 964 | struct i2c_msg tuner_msg = {.addr=0x60,.flags=0,.buf=buf,.len=sizeof(buf)}; |
965 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
921 | 966 | ||
922 | if((params->frequency < 950000) || (params->frequency > 2150000)) | 967 | if((params->frequency < 950000) || (params->frequency > 2150000)) |
923 | return -EINVAL; | 968 | return -EINVAL; |
@@ -926,7 +971,9 @@ static int philips_sd1878_tda8261_pll_set(struct dvb_frontend *fe, | |||
926 | params->frequency, 0); | 971 | params->frequency, 0); |
927 | if(rc < 0) return rc; | 972 | if(rc < 0) return rc; |
928 | 973 | ||
929 | if(i2c_transfer(i2c, &tuner_msg, 1) != 1) | 974 | if (fe->ops.i2c_gate_ctrl) |
975 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
976 | if(i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | ||
930 | return -EIO; | 977 | return -EIO; |
931 | 978 | ||
932 | return 0; | 979 | return 0; |
@@ -969,7 +1016,7 @@ static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe, | |||
969 | 1016 | ||
970 | static struct stv0299_config philips_sd1878_config = { | 1017 | static struct stv0299_config philips_sd1878_config = { |
971 | .demod_address = 0x68, | 1018 | .demod_address = 0x68, |
972 | .inittab = philips_sd1878_inittab, | 1019 | .inittab = philips_sd1878_inittab, |
973 | .mclk = 88000000UL, | 1020 | .mclk = 88000000UL, |
974 | .invert = 0, | 1021 | .invert = 0, |
975 | .skip_reinit = 0, | 1022 | .skip_reinit = 0, |
@@ -977,7 +1024,6 @@ static struct stv0299_config philips_sd1878_config = { | |||
977 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | 1024 | .volt13_op0_op1 = STV0299_VOLT13_OP0, |
978 | .min_delay_ms = 100, | 1025 | .min_delay_ms = 100, |
979 | .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, | 1026 | .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, |
980 | .pll_set = philips_sd1878_tda8261_pll_set, | ||
981 | }; | 1027 | }; |
982 | 1028 | ||
983 | static u8 read_pwm(struct budget_av *budget_av) | 1029 | static u8 read_pwm(struct budget_av *budget_av) |
@@ -1003,6 +1049,7 @@ static u8 read_pwm(struct budget_av *budget_av) | |||
1003 | 1049 | ||
1004 | #define SUBID_DVBS_TV_STAR 0x0014 | 1050 | #define SUBID_DVBS_TV_STAR 0x0014 |
1005 | #define SUBID_DVBS_TV_STAR_CI 0x0016 | 1051 | #define SUBID_DVBS_TV_STAR_CI 0x0016 |
1052 | #define SUBID_DVBS_EASYWATCH_1 0x001a | ||
1006 | #define SUBID_DVBS_EASYWATCH 0x001e | 1053 | #define SUBID_DVBS_EASYWATCH 0x001e |
1007 | #define SUBID_DVBC_KNC1 0x0020 | 1054 | #define SUBID_DVBC_KNC1 0x0020 |
1008 | #define SUBID_DVBC_KNC1_PLUS 0x0021 | 1055 | #define SUBID_DVBC_KNC1_PLUS 0x0021 |
@@ -1012,17 +1059,36 @@ static u8 read_pwm(struct budget_av *budget_av) | |||
1012 | #define SUBID_DVBT_KNC1 0x0030 | 1059 | #define SUBID_DVBT_KNC1 0x0030 |
1013 | #define SUBID_DVBT_CINERGY1200 0x1157 | 1060 | #define SUBID_DVBT_CINERGY1200 0x1157 |
1014 | 1061 | ||
1062 | |||
1063 | static int tda10021_set_frontend(struct dvb_frontend *fe, | ||
1064 | struct dvb_frontend_parameters *p) | ||
1065 | { | ||
1066 | struct budget_av* budget_av = fe->dvb->priv; | ||
1067 | int result; | ||
1068 | |||
1069 | result = budget_av->tda10021_set_frontend(fe, p); | ||
1070 | if (budget_av->tda10021_ts_enabled) { | ||
1071 | tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa1); | ||
1072 | } else { | ||
1073 | tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0); | ||
1074 | } | ||
1075 | |||
1076 | return result; | ||
1077 | } | ||
1078 | |||
1015 | static void frontend_init(struct budget_av *budget_av) | 1079 | static void frontend_init(struct budget_av *budget_av) |
1016 | { | 1080 | { |
1017 | struct saa7146_dev * saa = budget_av->budget.dev; | 1081 | struct saa7146_dev * saa = budget_av->budget.dev; |
1018 | struct dvb_frontend * fe = NULL; | 1082 | struct dvb_frontend * fe = NULL; |
1019 | 1083 | ||
1084 | /* Enable / PowerON Frontend */ | ||
1085 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); | ||
1086 | |||
1087 | /* additional setup necessary for the PLUS cards */ | ||
1020 | switch (saa->pci->subsystem_device) { | 1088 | switch (saa->pci->subsystem_device) { |
1021 | case SUBID_DVBS_KNC1_PLUS: | 1089 | case SUBID_DVBS_KNC1_PLUS: |
1022 | case SUBID_DVBC_KNC1_PLUS: | 1090 | case SUBID_DVBC_KNC1_PLUS: |
1023 | case SUBID_DVBT_KNC1_PLUS: | 1091 | case SUBID_DVBT_KNC1_PLUS: |
1024 | // Enable / PowerON Frontend | ||
1025 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); | ||
1026 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); | 1092 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); |
1027 | break; | 1093 | break; |
1028 | } | 1094 | } |
@@ -1030,12 +1096,19 @@ static void frontend_init(struct budget_av *budget_av) | |||
1030 | switch (saa->pci->subsystem_device) { | 1096 | switch (saa->pci->subsystem_device) { |
1031 | 1097 | ||
1032 | case SUBID_DVBS_KNC1: | 1098 | case SUBID_DVBS_KNC1: |
1099 | case SUBID_DVBS_EASYWATCH_1: | ||
1033 | if (saa->pci->subsystem_vendor == 0x1894) { | 1100 | if (saa->pci->subsystem_vendor == 0x1894) { |
1034 | fe = stv0299_attach(&cinergy_1200s_1894_0010_config, | 1101 | fe = stv0299_attach(&cinergy_1200s_1894_0010_config, |
1035 | &budget_av->budget.i2c_adap); | 1102 | &budget_av->budget.i2c_adap); |
1103 | if (fe) { | ||
1104 | fe->ops.tuner_ops.set_params = philips_su1278sh2_tua6100_tuner_set_params; | ||
1105 | } | ||
1036 | } else { | 1106 | } else { |
1037 | fe = stv0299_attach(&typhoon_config, | 1107 | fe = stv0299_attach(&typhoon_config, |
1038 | &budget_av->budget.i2c_adap); | 1108 | &budget_av->budget.i2c_adap); |
1109 | if (fe) { | ||
1110 | fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | ||
1111 | } | ||
1039 | } | 1112 | } |
1040 | break; | 1113 | break; |
1041 | 1114 | ||
@@ -1045,41 +1118,53 @@ static void frontend_init(struct budget_av *budget_av) | |||
1045 | case SUBID_DVBS_EASYWATCH: | 1118 | case SUBID_DVBS_EASYWATCH: |
1046 | fe = stv0299_attach(&philips_sd1878_config, | 1119 | fe = stv0299_attach(&philips_sd1878_config, |
1047 | &budget_av->budget.i2c_adap); | 1120 | &budget_av->budget.i2c_adap); |
1121 | if (fe) { | ||
1122 | fe->ops.tuner_ops.set_params = philips_sd1878_tda8261_tuner_set_params; | ||
1123 | } | ||
1048 | break; | 1124 | break; |
1049 | 1125 | ||
1050 | case SUBID_DVBS_KNC1_PLUS: | 1126 | case SUBID_DVBS_KNC1_PLUS: |
1051 | case SUBID_DVBS_TYPHOON: | 1127 | case SUBID_DVBS_TYPHOON: |
1052 | fe = stv0299_attach(&typhoon_config, | 1128 | fe = stv0299_attach(&typhoon_config, |
1053 | &budget_av->budget.i2c_adap); | 1129 | &budget_av->budget.i2c_adap); |
1130 | if (fe) { | ||
1131 | fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | ||
1132 | } | ||
1054 | break; | 1133 | break; |
1055 | 1134 | ||
1056 | case SUBID_DVBS_CINERGY1200: | 1135 | case SUBID_DVBS_CINERGY1200: |
1057 | fe = stv0299_attach(&cinergy_1200s_config, | 1136 | fe = stv0299_attach(&cinergy_1200s_config, |
1058 | &budget_av->budget.i2c_adap); | 1137 | &budget_av->budget.i2c_adap); |
1138 | if (fe) { | ||
1139 | fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | ||
1140 | } | ||
1059 | break; | 1141 | break; |
1060 | 1142 | ||
1061 | case SUBID_DVBC_KNC1: | 1143 | case SUBID_DVBC_KNC1: |
1062 | case SUBID_DVBC_KNC1_PLUS: | 1144 | case SUBID_DVBC_KNC1_PLUS: |
1145 | case SUBID_DVBC_CINERGY1200: | ||
1146 | budget_av->reinitialise_demod = 1; | ||
1063 | fe = tda10021_attach(&philips_cu1216_config, | 1147 | fe = tda10021_attach(&philips_cu1216_config, |
1064 | &budget_av->budget.i2c_adap, | 1148 | &budget_av->budget.i2c_adap, |
1065 | read_pwm(budget_av)); | 1149 | read_pwm(budget_av)); |
1150 | if (fe) { | ||
1151 | budget_av->tda10021_poclkp = 1; | ||
1152 | budget_av->tda10021_set_frontend = fe->ops.set_frontend; | ||
1153 | fe->ops.set_frontend = tda10021_set_frontend; | ||
1154 | fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; | ||
1155 | } | ||
1066 | break; | 1156 | break; |
1067 | 1157 | ||
1068 | case SUBID_DVBT_KNC1: | 1158 | case SUBID_DVBT_KNC1: |
1069 | case SUBID_DVBT_KNC1_PLUS: | 1159 | case SUBID_DVBT_KNC1_PLUS: |
1070 | fe = tda10046_attach(&philips_tu1216_config, | ||
1071 | &budget_av->budget.i2c_adap); | ||
1072 | break; | ||
1073 | |||
1074 | case SUBID_DVBC_CINERGY1200: | ||
1075 | fe = tda10021_attach(&philips_cu1216_config, | ||
1076 | &budget_av->budget.i2c_adap, | ||
1077 | read_pwm(budget_av)); | ||
1078 | break; | ||
1079 | |||
1080 | case SUBID_DVBT_CINERGY1200: | 1160 | case SUBID_DVBT_CINERGY1200: |
1161 | budget_av->reinitialise_demod = 1; | ||
1081 | fe = tda10046_attach(&philips_tu1216_config, | 1162 | fe = tda10046_attach(&philips_tu1216_config, |
1082 | &budget_av->budget.i2c_adap); | 1163 | &budget_av->budget.i2c_adap); |
1164 | if (fe) { | ||
1165 | fe->ops.tuner_ops.init = philips_tu1216_tuner_init; | ||
1166 | fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params; | ||
1167 | } | ||
1083 | break; | 1168 | break; |
1084 | } | 1169 | } |
1085 | 1170 | ||
@@ -1098,8 +1183,8 @@ static void frontend_init(struct budget_av *budget_av) | |||
1098 | if (dvb_register_frontend(&budget_av->budget.dvb_adapter, | 1183 | if (dvb_register_frontend(&budget_av->budget.dvb_adapter, |
1099 | budget_av->budget.dvb_frontend)) { | 1184 | budget_av->budget.dvb_frontend)) { |
1100 | printk(KERN_ERR "budget-av: Frontend registration failed!\n"); | 1185 | printk(KERN_ERR "budget-av: Frontend registration failed!\n"); |
1101 | if (budget_av->budget.dvb_frontend->ops->release) | 1186 | if (budget_av->budget.dvb_frontend->ops.release) |
1102 | budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend); | 1187 | budget_av->budget.dvb_frontend->ops.release(budget_av->budget.dvb_frontend); |
1103 | budget_av->budget.dvb_frontend = NULL; | 1188 | budget_av->budget.dvb_frontend = NULL; |
1104 | } | 1189 | } |
1105 | } | 1190 | } |
@@ -1293,6 +1378,7 @@ MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); | |||
1293 | MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); | 1378 | MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); |
1294 | MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); | 1379 | MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); |
1295 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); | 1380 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); |
1381 | MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); | ||
1296 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); | 1382 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); |
1297 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); | 1383 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); |
1298 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); | 1384 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); |
@@ -1309,6 +1395,7 @@ static struct pci_device_id pci_tbl[] = { | |||
1309 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), | 1395 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), |
1310 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), | 1396 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), |
1311 | MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), | 1397 | MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), |
1398 | MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), | ||
1312 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), | 1399 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), |
1313 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), | 1400 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), |
1314 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), | 1401 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index e64a609cf4ff..4b966eea3834 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -620,10 +620,10 @@ static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, | |||
620 | return 0; | 620 | return 0; |
621 | } | 621 | } |
622 | 622 | ||
623 | static int philips_su1278_tt_pll_set(struct dvb_frontend *fe, | 623 | static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe, |
624 | struct i2c_adapter *i2c, | 624 | struct dvb_frontend_parameters *params) |
625 | struct dvb_frontend_parameters *params) | ||
626 | { | 625 | { |
626 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | ||
627 | u32 div; | 627 | u32 div; |
628 | u8 buf[4]; | 628 | u8 buf[4]; |
629 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; | 629 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; |
@@ -649,7 +649,9 @@ static int philips_su1278_tt_pll_set(struct dvb_frontend *fe, | |||
649 | else if (params->frequency < 2150000) | 649 | else if (params->frequency < 2150000) |
650 | buf[3] |= 0xC0; | 650 | buf[3] |= 0xC0; |
651 | 651 | ||
652 | if (i2c_transfer(i2c, &msg, 1) != 1) | 652 | if (fe->ops.i2c_gate_ctrl) |
653 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
654 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1) | ||
653 | return -EIO; | 655 | return -EIO; |
654 | return 0; | 656 | return 0; |
655 | } | 657 | } |
@@ -665,12 +667,11 @@ static struct stv0299_config philips_su1278_tt_config = { | |||
665 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 667 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
666 | .min_delay_ms = 50, | 668 | .min_delay_ms = 50, |
667 | .set_symbol_rate = philips_su1278_tt_set_symbol_rate, | 669 | .set_symbol_rate = philips_su1278_tt_set_symbol_rate, |
668 | .pll_set = philips_su1278_tt_pll_set, | ||
669 | }; | 670 | }; |
670 | 671 | ||
671 | 672 | ||
672 | 673 | ||
673 | static int philips_tdm1316l_pll_init(struct dvb_frontend *fe) | 674 | static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe) |
674 | { | 675 | { |
675 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | 676 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; |
676 | static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | 677 | static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; |
@@ -679,6 +680,8 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend *fe) | |||
679 | sizeof(td1316_init) }; | 680 | sizeof(td1316_init) }; |
680 | 681 | ||
681 | // setup PLL configuration | 682 | // setup PLL configuration |
683 | if (fe->ops.i2c_gate_ctrl) | ||
684 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
682 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | 685 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) |
683 | return -EIO; | 686 | return -EIO; |
684 | msleep(1); | 687 | msleep(1); |
@@ -687,14 +690,18 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend *fe) | |||
687 | tuner_msg.addr = 0x65; | 690 | tuner_msg.addr = 0x65; |
688 | tuner_msg.buf = disable_mc44BC374c; | 691 | tuner_msg.buf = disable_mc44BC374c; |
689 | tuner_msg.len = sizeof(disable_mc44BC374c); | 692 | tuner_msg.len = sizeof(disable_mc44BC374c); |
693 | if (fe->ops.i2c_gate_ctrl) | ||
694 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
690 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) { | 695 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) { |
696 | if (fe->ops.i2c_gate_ctrl) | ||
697 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
691 | i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1); | 698 | i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1); |
692 | } | 699 | } |
693 | 700 | ||
694 | return 0; | 701 | return 0; |
695 | } | 702 | } |
696 | 703 | ||
697 | static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 704 | static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
698 | { | 705 | { |
699 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | 706 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; |
700 | u8 tuner_buf[4]; | 707 | u8 tuner_buf[4]; |
@@ -770,6 +777,8 @@ static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend | |||
770 | tuner_buf[2] = 0xca; | 777 | tuner_buf[2] = 0xca; |
771 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | 778 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; |
772 | 779 | ||
780 | if (fe->ops.i2c_gate_ctrl) | ||
781 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
773 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | 782 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) |
774 | return -EIO; | 783 | return -EIO; |
775 | 784 | ||
@@ -793,13 +802,10 @@ static struct tda1004x_config philips_tdm1316l_config = { | |||
793 | .xtal_freq = TDA10046_XTAL_4M, | 802 | .xtal_freq = TDA10046_XTAL_4M, |
794 | .agc_config = TDA10046_AGC_DEFAULT, | 803 | .agc_config = TDA10046_AGC_DEFAULT, |
795 | .if_freq = TDA10046_FREQ_3617, | 804 | .if_freq = TDA10046_FREQ_3617, |
796 | .pll_init = philips_tdm1316l_pll_init, | ||
797 | .pll_set = philips_tdm1316l_pll_set, | ||
798 | .pll_sleep = NULL, | ||
799 | .request_firmware = philips_tdm1316l_request_firmware, | 805 | .request_firmware = philips_tdm1316l_request_firmware, |
800 | }; | 806 | }; |
801 | 807 | ||
802 | static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 808 | static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
803 | { | 809 | { |
804 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | 810 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; |
805 | u8 tuner_buf[5]; | 811 | u8 tuner_buf[5]; |
@@ -857,13 +863,15 @@ static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_fro | |||
857 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | 863 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; |
858 | tuner_buf[4] = 0x80; | 864 | tuner_buf[4] = 0x80; |
859 | 865 | ||
860 | stv0297_enable_plli2c(fe); | 866 | if (fe->ops.i2c_gate_ctrl) |
867 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
861 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | 868 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) |
862 | return -EIO; | 869 | return -EIO; |
863 | 870 | ||
864 | msleep(50); | 871 | msleep(50); |
865 | 872 | ||
866 | stv0297_enable_plli2c(fe); | 873 | if (fe->ops.i2c_gate_ctrl) |
874 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
867 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | 875 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) |
868 | return -EIO; | 876 | return -EIO; |
869 | 877 | ||
@@ -969,7 +977,7 @@ static struct stv0297_config dvbc_philips_tdm1316l_config = { | |||
969 | .demod_address = 0x1c, | 977 | .demod_address = 0x1c, |
970 | .inittab = dvbc_philips_tdm1316l_inittab, | 978 | .inittab = dvbc_philips_tdm1316l_inittab, |
971 | .invert = 0, | 979 | .invert = 0, |
972 | .pll_set = dvbc_philips_tdm1316l_pll_set, | 980 | .stop_during_read = 1, |
973 | }; | 981 | }; |
974 | 982 | ||
975 | 983 | ||
@@ -982,6 +990,8 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
982 | budget_ci->budget.dvb_frontend = | 990 | budget_ci->budget.dvb_frontend = |
983 | stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap); | 991 | stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap); |
984 | if (budget_ci->budget.dvb_frontend) { | 992 | if (budget_ci->budget.dvb_frontend) { |
993 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; | ||
994 | budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; | ||
985 | break; | 995 | break; |
986 | } | 996 | } |
987 | break; | 997 | break; |
@@ -990,6 +1000,7 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
990 | budget_ci->budget.dvb_frontend = | 1000 | budget_ci->budget.dvb_frontend = |
991 | stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap); | 1001 | stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap); |
992 | if (budget_ci->budget.dvb_frontend) { | 1002 | if (budget_ci->budget.dvb_frontend) { |
1003 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params; | ||
993 | break; | 1004 | break; |
994 | } | 1005 | } |
995 | break; | 1006 | break; |
@@ -999,6 +1010,7 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
999 | budget_ci->budget.dvb_frontend = | 1010 | budget_ci->budget.dvb_frontend = |
1000 | stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap); | 1011 | stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap); |
1001 | if (budget_ci->budget.dvb_frontend) { | 1012 | if (budget_ci->budget.dvb_frontend) { |
1013 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params; | ||
1002 | break; | 1014 | break; |
1003 | } | 1015 | } |
1004 | break; | 1016 | break; |
@@ -1008,6 +1020,8 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
1008 | budget_ci->budget.dvb_frontend = | 1020 | budget_ci->budget.dvb_frontend = |
1009 | tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); | 1021 | tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); |
1010 | if (budget_ci->budget.dvb_frontend) { | 1022 | if (budget_ci->budget.dvb_frontend) { |
1023 | budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; | ||
1024 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; | ||
1011 | break; | 1025 | break; |
1012 | } | 1026 | } |
1013 | break; | 1027 | break; |
@@ -1017,6 +1031,8 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
1017 | budget_ci->budget.dvb_frontend = | 1031 | budget_ci->budget.dvb_frontend = |
1018 | tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); | 1032 | tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); |
1019 | if (budget_ci->budget.dvb_frontend) { | 1033 | if (budget_ci->budget.dvb_frontend) { |
1034 | budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; | ||
1035 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; | ||
1020 | break; | 1036 | break; |
1021 | } | 1037 | } |
1022 | break; | 1038 | break; |
@@ -1024,11 +1040,14 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
1024 | case 0x1017: // TT S-1500 PCI | 1040 | case 0x1017: // TT S-1500 PCI |
1025 | budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap); | 1041 | budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap); |
1026 | if (budget_ci->budget.dvb_frontend) { | 1042 | if (budget_ci->budget.dvb_frontend) { |
1027 | budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; | 1043 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; |
1028 | if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) { | 1044 | budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; |
1045 | |||
1046 | budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; | ||
1047 | if (lnbp21_attach(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) { | ||
1029 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | 1048 | printk("%s: No LNBP21 found!\n", __FUNCTION__); |
1030 | if (budget_ci->budget.dvb_frontend->ops->release) | 1049 | if (budget_ci->budget.dvb_frontend->ops.release) |
1031 | budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); | 1050 | budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend); |
1032 | budget_ci->budget.dvb_frontend = NULL; | 1051 | budget_ci->budget.dvb_frontend = NULL; |
1033 | } | 1052 | } |
1034 | } | 1053 | } |
@@ -1046,8 +1065,8 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
1046 | if (dvb_register_frontend | 1065 | if (dvb_register_frontend |
1047 | (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { | 1066 | (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { |
1048 | printk("budget-ci: Frontend registration failed!\n"); | 1067 | printk("budget-ci: Frontend registration failed!\n"); |
1049 | if (budget_ci->budget.dvb_frontend->ops->release) | 1068 | if (budget_ci->budget.dvb_frontend->ops.release) |
1050 | budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); | 1069 | budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend); |
1051 | budget_ci->budget.dvb_frontend = NULL; | 1070 | budget_ci->budget.dvb_frontend = NULL; |
1052 | } | 1071 | } |
1053 | } | 1072 | } |
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index ea2066d461fc..e4cf7775e07f 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c | |||
@@ -400,7 +400,9 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | |||
400 | budget->dev->name, budget->buffer_width, budget->buffer_height); | 400 | budget->dev->name, budget->buffer_width, budget->buffer_height); |
401 | printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); | 401 | printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); |
402 | 402 | ||
403 | dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner); | 403 | if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) { |
404 | return ret; | ||
405 | } | ||
404 | 406 | ||
405 | /* set dd1 stream a & b */ | 407 | /* set dd1 stream a & b */ |
406 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); | 408 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); |
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index 1b3aaac5e763..ee60ce90a400 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c | |||
@@ -258,7 +258,7 @@ static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_c | |||
258 | return 0; | 258 | return 0; |
259 | } | 259 | } |
260 | 260 | ||
261 | static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 261 | static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
262 | { | 262 | { |
263 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; | 263 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; |
264 | u8 pwr = 0; | 264 | u8 pwr = 0; |
@@ -281,7 +281,10 @@ static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
281 | // NOTE: since we're using a prescaler of 2, we set the | 281 | // NOTE: since we're using a prescaler of 2, we set the |
282 | // divisor frequency to 62.5kHz and divide by 125 above | 282 | // divisor frequency to 62.5kHz and divide by 125 above |
283 | 283 | ||
284 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 284 | if (fe->ops.i2c_gate_ctrl) |
285 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
286 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) | ||
287 | return -EIO; | ||
285 | return 0; | 288 | return 0; |
286 | } | 289 | } |
287 | 290 | ||
@@ -289,10 +292,9 @@ static struct ves1x93_config alps_bsrv2_config = { | |||
289 | .demod_address = 0x08, | 292 | .demod_address = 0x08, |
290 | .xin = 90100000UL, | 293 | .xin = 90100000UL, |
291 | .invert_pwm = 0, | 294 | .invert_pwm = 0, |
292 | .pll_set = alps_bsrv2_pll_set, | ||
293 | }; | 295 | }; |
294 | 296 | ||
295 | static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 297 | static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
296 | { | 298 | { |
297 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; | 299 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; |
298 | u32 div; | 300 | u32 div; |
@@ -305,13 +307,15 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
305 | data[2] = 0x8e; | 307 | data[2] = 0x8e; |
306 | data[3] = 0x00; | 308 | data[3] = 0x00; |
307 | 309 | ||
308 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 310 | if (fe->ops.i2c_gate_ctrl) |
311 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
312 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) | ||
313 | return -EIO; | ||
309 | return 0; | 314 | return 0; |
310 | } | 315 | } |
311 | 316 | ||
312 | static struct tda8083_config grundig_29504_451_config = { | 317 | static struct tda8083_config grundig_29504_451_config = { |
313 | .demod_address = 0x68, | 318 | .demod_address = 0x68, |
314 | .pll_set = grundig_29504_451_pll_set, | ||
315 | }; | 319 | }; |
316 | 320 | ||
317 | static void frontend_init(struct budget_patch* budget) | 321 | static void frontend_init(struct budget_patch* budget) |
@@ -323,27 +327,32 @@ static void frontend_init(struct budget_patch* budget) | |||
323 | // try the ALPS BSRV2 first of all | 327 | // try the ALPS BSRV2 first of all |
324 | budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); | 328 | budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); |
325 | if (budget->dvb_frontend) { | 329 | if (budget->dvb_frontend) { |
326 | budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd; | 330 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; |
327 | budget->dvb_frontend->ops->diseqc_send_burst = budget_patch_diseqc_send_burst; | 331 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd; |
328 | budget->dvb_frontend->ops->set_tone = budget_patch_set_tone; | 332 | budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst; |
333 | budget->dvb_frontend->ops.set_tone = budget_patch_set_tone; | ||
329 | break; | 334 | break; |
330 | } | 335 | } |
331 | 336 | ||
332 | // try the ALPS BSRU6 now | 337 | // try the ALPS BSRU6 now |
333 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); | 338 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); |
334 | if (budget->dvb_frontend) { | 339 | if (budget->dvb_frontend) { |
335 | budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | 340 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; |
336 | budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; | 341 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; |
337 | budget->dvb_frontend->ops->set_tone = budget_set_tone; | 342 | |
343 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | ||
344 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; | ||
345 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
338 | break; | 346 | break; |
339 | } | 347 | } |
340 | 348 | ||
341 | // Try the grundig 29504-451 | 349 | // Try the grundig 29504-451 |
342 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); | 350 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); |
343 | if (budget->dvb_frontend) { | 351 | if (budget->dvb_frontend) { |
344 | budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | 352 | budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; |
345 | budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; | 353 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; |
346 | budget->dvb_frontend->ops->set_tone = budget_set_tone; | 354 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; |
355 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
347 | break; | 356 | break; |
348 | } | 357 | } |
349 | break; | 358 | break; |
@@ -358,8 +367,8 @@ static void frontend_init(struct budget_patch* budget) | |||
358 | } else { | 367 | } else { |
359 | if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { | 368 | if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { |
360 | printk("budget-av: Frontend registration failed!\n"); | 369 | printk("budget-av: Frontend registration failed!\n"); |
361 | if (budget->dvb_frontend->ops->release) | 370 | if (budget->dvb_frontend->ops.release) |
362 | budget->dvb_frontend->ops->release(budget->dvb_frontend); | 371 | budget->dvb_frontend->ops.release(budget->dvb_frontend); |
363 | budget->dvb_frontend = NULL; | 372 | budget->dvb_frontend = NULL; |
364 | } | 373 | } |
365 | } | 374 | } |
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index c23c02d95641..35761f13c12b 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
@@ -186,7 +186,7 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m | |||
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
188 | 188 | ||
189 | static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 189 | static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
190 | { | 190 | { |
191 | struct budget* budget = (struct budget*) fe->dvb->priv; | 191 | struct budget* budget = (struct budget*) fe->dvb->priv; |
192 | u8 pwr = 0; | 192 | u8 pwr = 0; |
@@ -209,6 +209,8 @@ static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
209 | // NOTE: since we're using a prescaler of 2, we set the | 209 | // NOTE: since we're using a prescaler of 2, we set the |
210 | // divisor frequency to 62.5kHz and divide by 125 above | 210 | // divisor frequency to 62.5kHz and divide by 125 above |
211 | 211 | ||
212 | if (fe->ops.i2c_gate_ctrl) | ||
213 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
212 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 214 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; |
213 | return 0; | 215 | return 0; |
214 | } | 216 | } |
@@ -218,10 +220,9 @@ static struct ves1x93_config alps_bsrv2_config = | |||
218 | .demod_address = 0x08, | 220 | .demod_address = 0x08, |
219 | .xin = 90100000UL, | 221 | .xin = 90100000UL, |
220 | .invert_pwm = 0, | 222 | .invert_pwm = 0, |
221 | .pll_set = alps_bsrv2_pll_set, | ||
222 | }; | 223 | }; |
223 | 224 | ||
224 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 225 | static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
225 | { | 226 | { |
226 | struct budget* budget = (struct budget*) fe->dvb->priv; | 227 | struct budget* budget = (struct budget*) fe->dvb->priv; |
227 | u32 div; | 228 | u32 div; |
@@ -235,6 +236,8 @@ static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
235 | data[2] = 0x85 | ((div >> 10) & 0x60); | 236 | data[2] = 0x85 | ((div >> 10) & 0x60); |
236 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); | 237 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); |
237 | 238 | ||
239 | if (fe->ops.i2c_gate_ctrl) | ||
240 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
238 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 241 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; |
239 | return 0; | 242 | return 0; |
240 | } | 243 | } |
@@ -244,10 +247,9 @@ static struct ves1820_config alps_tdbe2_config = { | |||
244 | .xin = 57840000UL, | 247 | .xin = 57840000UL, |
245 | .invert = 1, | 248 | .invert = 1, |
246 | .selagc = VES1820_SELAGC_SIGNAMPERR, | 249 | .selagc = VES1820_SELAGC_SIGNAMPERR, |
247 | .pll_set = alps_tdbe2_pll_set, | ||
248 | }; | 250 | }; |
249 | 251 | ||
250 | static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 252 | static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
251 | { | 253 | { |
252 | struct budget* budget = (struct budget*) fe->dvb->priv; | 254 | struct budget* budget = (struct budget*) fe->dvb->priv; |
253 | u32 div; | 255 | u32 div; |
@@ -274,16 +276,17 @@ static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
274 | data[2] = ((div >> 10) & 0x60) | cfg; | 276 | data[2] = ((div >> 10) & 0x60) | cfg; |
275 | data[3] = (cpump << 6) | band_select; | 277 | data[3] = (cpump << 6) | band_select; |
276 | 278 | ||
279 | if (fe->ops.i2c_gate_ctrl) | ||
280 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
277 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 281 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; |
278 | return 0; | 282 | return 0; |
279 | } | 283 | } |
280 | 284 | ||
281 | static struct l64781_config grundig_29504_401_config = { | 285 | static struct l64781_config grundig_29504_401_config = { |
282 | .demod_address = 0x55, | 286 | .demod_address = 0x55, |
283 | .pll_set = grundig_29504_401_pll_set, | ||
284 | }; | 287 | }; |
285 | 288 | ||
286 | static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 289 | static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
287 | { | 290 | { |
288 | struct budget* budget = (struct budget*) fe->dvb->priv; | 291 | struct budget* budget = (struct budget*) fe->dvb->priv; |
289 | u32 div; | 292 | u32 div; |
@@ -296,16 +299,17 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
296 | data[2] = 0x8e; | 299 | data[2] = 0x8e; |
297 | data[3] = 0x00; | 300 | data[3] = 0x00; |
298 | 301 | ||
302 | if (fe->ops.i2c_gate_ctrl) | ||
303 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
299 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 304 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; |
300 | return 0; | 305 | return 0; |
301 | } | 306 | } |
302 | 307 | ||
303 | static struct tda8083_config grundig_29504_451_config = { | 308 | static struct tda8083_config grundig_29504_451_config = { |
304 | .demod_address = 0x68, | 309 | .demod_address = 0x68, |
305 | .pll_set = grundig_29504_451_pll_set, | ||
306 | }; | 310 | }; |
307 | 311 | ||
308 | static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout) | 312 | static int s5h1420_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
309 | { | 313 | { |
310 | struct budget* budget = (struct budget*) fe->dvb->priv; | 314 | struct budget* budget = (struct budget*) fe->dvb->priv; |
311 | u32 div; | 315 | u32 div; |
@@ -326,16 +330,16 @@ static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
326 | else | 330 | else |
327 | data[3] = 0xc0; | 331 | data[3] = 0xc0; |
328 | 332 | ||
333 | if (fe->ops.i2c_gate_ctrl) | ||
334 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
329 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 335 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; |
330 | 336 | ||
331 | *freqout = div * 1000; | ||
332 | return 0; | 337 | return 0; |
333 | } | 338 | } |
334 | 339 | ||
335 | static struct s5h1420_config s5h1420_config = { | 340 | static struct s5h1420_config s5h1420_config = { |
336 | .demod_address = 0x53, | 341 | .demod_address = 0x53, |
337 | .invert = 1, | 342 | .invert = 1, |
338 | .pll_set = s5h1420_pll_set, | ||
339 | }; | 343 | }; |
340 | 344 | ||
341 | static u8 read_pwm(struct budget* budget) | 345 | static u8 read_pwm(struct budget* budget) |
@@ -359,18 +363,21 @@ static void frontend_init(struct budget *budget) | |||
359 | // try the ALPS BSRV2 first of all | 363 | // try the ALPS BSRV2 first of all |
360 | budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); | 364 | budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); |
361 | if (budget->dvb_frontend) { | 365 | if (budget->dvb_frontend) { |
362 | budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | 366 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; |
363 | budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; | 367 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; |
364 | budget->dvb_frontend->ops->set_tone = budget_set_tone; | 368 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; |
369 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
365 | break; | 370 | break; |
366 | } | 371 | } |
367 | 372 | ||
368 | // try the ALPS BSRU6 now | 373 | // try the ALPS BSRU6 now |
369 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); | 374 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); |
370 | if (budget->dvb_frontend) { | 375 | if (budget->dvb_frontend) { |
371 | budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | 376 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; |
372 | budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; | 377 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; |
373 | budget->dvb_frontend->ops->set_tone = budget_set_tone; | 378 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; |
379 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; | ||
380 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
374 | break; | 381 | break; |
375 | } | 382 | } |
376 | break; | 383 | break; |
@@ -378,35 +385,45 @@ static void frontend_init(struct budget *budget) | |||
378 | case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) | 385 | case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) |
379 | 386 | ||
380 | budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); | 387 | budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); |
381 | if (budget->dvb_frontend) break; | 388 | if (budget->dvb_frontend) { |
389 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
390 | break; | ||
391 | } | ||
382 | break; | 392 | break; |
383 | 393 | ||
384 | case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) | 394 | case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) |
385 | 395 | ||
386 | budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap); | 396 | budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap); |
387 | if (budget->dvb_frontend) break; | 397 | if (budget->dvb_frontend) { |
398 | budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; | ||
399 | break; | ||
400 | } | ||
388 | break; | 401 | break; |
389 | 402 | ||
390 | case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059)) | 403 | case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059)) |
391 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); | 404 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); |
392 | if (budget->dvb_frontend) { | 405 | if (budget->dvb_frontend) { |
393 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; | 406 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; |
394 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; | 407 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; |
408 | budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; | ||
409 | budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; | ||
395 | } | 410 | } |
396 | break; | 411 | break; |
397 | 412 | ||
398 | case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) | 413 | case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) |
399 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); | 414 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); |
400 | if (budget->dvb_frontend) { | 415 | if (budget->dvb_frontend) { |
401 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; | 416 | budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; |
402 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; | 417 | budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; |
418 | budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; | ||
403 | } | 419 | } |
404 | break; | 420 | break; |
405 | 421 | ||
406 | case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) | 422 | case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) |
407 | budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); | 423 | budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); |
408 | if (budget->dvb_frontend) { | 424 | if (budget->dvb_frontend) { |
409 | if (lnbp21_init(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { | 425 | budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params; |
426 | if (lnbp21_attach(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { | ||
410 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | 427 | printk("%s: No LNBP21 found!\n", __FUNCTION__); |
411 | goto error_out; | 428 | goto error_out; |
412 | } | 429 | } |
@@ -428,8 +445,8 @@ static void frontend_init(struct budget *budget) | |||
428 | 445 | ||
429 | error_out: | 446 | error_out: |
430 | printk("budget: Frontend registration failed!\n"); | 447 | printk("budget: Frontend registration failed!\n"); |
431 | if (budget->dvb_frontend->ops->release) | 448 | if (budget->dvb_frontend->ops.release) |
432 | budget->dvb_frontend->ops->release(budget->dvb_frontend); | 449 | budget->dvb_frontend->ops.release(budget->dvb_frontend); |
433 | budget->dvb_frontend = NULL; | 450 | budget->dvb_frontend = NULL; |
434 | return; | 451 | return; |
435 | } | 452 | } |
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig index 914587d52b57..92c7cdcf8981 100644 --- a/drivers/media/dvb/ttusb-budget/Kconfig +++ b/drivers/media/dvb/ttusb-budget/Kconfig | |||
@@ -6,6 +6,8 @@ config DVB_TTUSB_BUDGET | |||
6 | select DVB_VES1820 | 6 | select DVB_VES1820 |
7 | select DVB_TDA8083 | 7 | select DVB_TDA8083 |
8 | select DVB_STV0299 | 8 | select DVB_STV0299 |
9 | select DVB_STV0297 | ||
10 | select DVB_LNBP21 | ||
9 | help | 11 | help |
10 | Support for external USB adapters designed by Technotrend and | 12 | Support for external USB adapters designed by Technotrend and |
11 | produced by Hauppauge, shipped under the brand name 'Nova-USB'. | 13 | produced by Hauppauge, shipped under the brand name 'Nova-USB'. |
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 6ceae38125c7..14559ef6153c 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include "tda1004x.h" | 30 | #include "tda1004x.h" |
31 | #include "stv0299.h" | 31 | #include "stv0299.h" |
32 | #include "tda8083.h" | 32 | #include "tda8083.h" |
33 | #include "stv0297.h" | ||
34 | #include "lnbp21.h" | ||
33 | 35 | ||
34 | #include <linux/dvb/frontend.h> | 36 | #include <linux/dvb/frontend.h> |
35 | #include <linux/dvb/dmx.h> | 37 | #include <linux/dvb/dmx.h> |
@@ -486,31 +488,6 @@ static int ttusb_send_diseqc(struct dvb_frontend* fe, | |||
486 | } | 488 | } |
487 | #endif | 489 | #endif |
488 | 490 | ||
489 | static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
490 | { | ||
491 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | ||
492 | int ret; | ||
493 | u8 data[1]; | ||
494 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
495 | |||
496 | switch(voltage) { | ||
497 | case SEC_VOLTAGE_OFF: | ||
498 | data[0] = 0x00; | ||
499 | break; | ||
500 | case SEC_VOLTAGE_13: | ||
501 | data[0] = 0x44; | ||
502 | break; | ||
503 | case SEC_VOLTAGE_18: | ||
504 | data[0] = 0x4c; | ||
505 | break; | ||
506 | default: | ||
507 | return -EINVAL; | ||
508 | }; | ||
509 | |||
510 | ret = i2c_transfer(&ttusb->i2c_adap, &msg, 1); | ||
511 | return (ret != 1) ? -EIO : 0; | ||
512 | } | ||
513 | |||
514 | static int ttusb_update_lnb(struct ttusb *ttusb) | 491 | static int ttusb_update_lnb(struct ttusb *ttusb) |
515 | { | 492 | { |
516 | u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1, | 493 | u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1, |
@@ -1048,7 +1025,7 @@ static u32 functionality(struct i2c_adapter *adapter) | |||
1048 | 1025 | ||
1049 | 1026 | ||
1050 | 1027 | ||
1051 | static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1028 | static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
1052 | { | 1029 | { |
1053 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | 1030 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; |
1054 | u8 data[4]; | 1031 | u8 data[4]; |
@@ -1062,20 +1039,21 @@ static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1062 | data[2] = ((div >> 10) & 0x60) | 0x85; | 1039 | data[2] = ((div >> 10) & 0x60) | 0x85; |
1063 | data[3] = params->frequency < 592000000 ? 0x40 : 0x80; | 1040 | data[3] = params->frequency < 592000000 ? 0x40 : 0x80; |
1064 | 1041 | ||
1042 | if (fe->ops.i2c_gate_ctrl) | ||
1043 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1065 | if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO; | 1044 | if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO; |
1066 | return 0; | 1045 | return 0; |
1067 | } | 1046 | } |
1068 | 1047 | ||
1069 | static struct cx22700_config alps_tdmb7_config = { | 1048 | static struct cx22700_config alps_tdmb7_config = { |
1070 | .demod_address = 0x43, | 1049 | .demod_address = 0x43, |
1071 | .pll_set = alps_tdmb7_pll_set, | ||
1072 | }; | 1050 | }; |
1073 | 1051 | ||
1074 | 1052 | ||
1075 | 1053 | ||
1076 | 1054 | ||
1077 | 1055 | ||
1078 | static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) | 1056 | static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe) |
1079 | { | 1057 | { |
1080 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | 1058 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; |
1081 | static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | 1059 | static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; |
@@ -1083,6 +1061,8 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) | |||
1083 | struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) }; | 1061 | struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) }; |
1084 | 1062 | ||
1085 | // setup PLL configuration | 1063 | // setup PLL configuration |
1064 | if (fe->ops.i2c_gate_ctrl) | ||
1065 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1086 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; | 1066 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; |
1087 | msleep(1); | 1067 | msleep(1); |
1088 | 1068 | ||
@@ -1090,6 +1070,8 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) | |||
1090 | tuner_msg.addr = 0x65; | 1070 | tuner_msg.addr = 0x65; |
1091 | tuner_msg.buf = disable_mc44BC374c; | 1071 | tuner_msg.buf = disable_mc44BC374c; |
1092 | tuner_msg.len = sizeof(disable_mc44BC374c); | 1072 | tuner_msg.len = sizeof(disable_mc44BC374c); |
1073 | if (fe->ops.i2c_gate_ctrl) | ||
1074 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1093 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { | 1075 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { |
1094 | i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1); | 1076 | i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1); |
1095 | } | 1077 | } |
@@ -1097,7 +1079,7 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) | |||
1097 | return 0; | 1079 | return 0; |
1098 | } | 1080 | } |
1099 | 1081 | ||
1100 | static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1082 | static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
1101 | { | 1083 | { |
1102 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | 1084 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; |
1103 | u8 tuner_buf[4]; | 1085 | u8 tuner_buf[4]; |
@@ -1157,6 +1139,8 @@ static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend | |||
1157 | tuner_buf[2] = 0xca; | 1139 | tuner_buf[2] = 0xca; |
1158 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | 1140 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; |
1159 | 1141 | ||
1142 | if (fe->ops.i2c_gate_ctrl) | ||
1143 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1160 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) | 1144 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) |
1161 | return -EIO; | 1145 | return -EIO; |
1162 | 1146 | ||
@@ -1176,8 +1160,6 @@ static struct tda1004x_config philips_tdm1316l_config = { | |||
1176 | .demod_address = 0x8, | 1160 | .demod_address = 0x8, |
1177 | .invert = 1, | 1161 | .invert = 1, |
1178 | .invert_oclk = 0, | 1162 | .invert_oclk = 0, |
1179 | .pll_init = philips_tdm1316l_pll_init, | ||
1180 | .pll_set = philips_tdm1316l_pll_set, | ||
1181 | .request_firmware = philips_tdm1316l_request_firmware, | 1163 | .request_firmware = philips_tdm1316l_request_firmware, |
1182 | }; | 1164 | }; |
1183 | 1165 | ||
@@ -1299,7 +1281,7 @@ static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 | |||
1299 | return 0; | 1281 | return 0; |
1300 | } | 1282 | } |
1301 | 1283 | ||
1302 | static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) | 1284 | static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
1303 | { | 1285 | { |
1304 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | 1286 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; |
1305 | u8 buf[4]; | 1287 | u8 buf[4]; |
@@ -1322,7 +1304,9 @@ static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct i2c_adapter * | |||
1322 | if (ttusb->revision == TTUSB_REV_2_2) | 1304 | if (ttusb->revision == TTUSB_REV_2_2) |
1323 | buf[3] |= 0x20; | 1305 | buf[3] |= 0x20; |
1324 | 1306 | ||
1325 | if (i2c_transfer(i2c, &msg, 1) != 1) | 1307 | if (fe->ops.i2c_gate_ctrl) |
1308 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1309 | if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) | ||
1326 | return -EIO; | 1310 | return -EIO; |
1327 | 1311 | ||
1328 | return 0; | 1312 | return 0; |
@@ -1338,10 +1322,9 @@ static struct stv0299_config alps_stv0299_config = { | |||
1338 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 1322 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
1339 | .min_delay_ms = 100, | 1323 | .min_delay_ms = 100, |
1340 | .set_symbol_rate = alps_stv0299_set_symbol_rate, | 1324 | .set_symbol_rate = alps_stv0299_set_symbol_rate, |
1341 | .pll_set = philips_tsa5059_pll_set, | ||
1342 | }; | 1325 | }; |
1343 | 1326 | ||
1344 | static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 1327 | static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
1345 | { | 1328 | { |
1346 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | 1329 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; |
1347 | u8 buf[4]; | 1330 | u8 buf[4]; |
@@ -1355,6 +1338,8 @@ static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct | |||
1355 | buf[2] = 0x8e; | 1338 | buf[2] = 0x8e; |
1356 | buf[3] = 0x00; | 1339 | buf[3] = 0x00; |
1357 | 1340 | ||
1341 | if (fe->ops.i2c_gate_ctrl) | ||
1342 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1358 | if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) | 1343 | if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) |
1359 | return -EIO; | 1344 | return -EIO; |
1360 | 1345 | ||
@@ -1364,10 +1349,9 @@ static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct | |||
1364 | static struct tda8083_config ttusb_novas_grundig_29504_491_config = { | 1349 | static struct tda8083_config ttusb_novas_grundig_29504_491_config = { |
1365 | 1350 | ||
1366 | .demod_address = 0x68, | 1351 | .demod_address = 0x68, |
1367 | .pll_set = ttusb_novas_grundig_29504_491_pll_set, | ||
1368 | }; | 1352 | }; |
1369 | 1353 | ||
1370 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1354 | static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
1371 | { | 1355 | { |
1372 | struct ttusb* ttusb = fe->dvb->priv; | 1356 | struct ttusb* ttusb = fe->dvb->priv; |
1373 | u32 div; | 1357 | u32 div; |
@@ -1381,6 +1365,8 @@ static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1381 | data[2] = 0x85 | ((div >> 10) & 0x60); | 1365 | data[2] = 0x85 | ((div >> 10) & 0x60); |
1382 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); | 1366 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); |
1383 | 1367 | ||
1368 | if (fe->ops.i2c_gate_ctrl) | ||
1369 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1384 | if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1) | 1370 | if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1) |
1385 | return -EIO; | 1371 | return -EIO; |
1386 | 1372 | ||
@@ -1393,7 +1379,6 @@ static struct ves1820_config alps_tdbe2_config = { | |||
1393 | .xin = 57840000UL, | 1379 | .xin = 57840000UL, |
1394 | .invert = 1, | 1380 | .invert = 1, |
1395 | .selagc = VES1820_SELAGC_SIGNAMPERR, | 1381 | .selagc = VES1820_SELAGC_SIGNAMPERR, |
1396 | .pll_set = alps_tdbe2_pll_set, | ||
1397 | }; | 1382 | }; |
1398 | 1383 | ||
1399 | static u8 read_pwm(struct ttusb* ttusb) | 1384 | static u8 read_pwm(struct ttusb* ttusb) |
@@ -1410,6 +1395,174 @@ static u8 read_pwm(struct ttusb* ttusb) | |||
1410 | } | 1395 | } |
1411 | 1396 | ||
1412 | 1397 | ||
1398 | static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
1399 | { | ||
1400 | struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv; | ||
1401 | u8 tuner_buf[5]; | ||
1402 | struct i2c_msg tuner_msg = {.addr = 0x60, | ||
1403 | .flags = 0, | ||
1404 | .buf = tuner_buf, | ||
1405 | .len = sizeof(tuner_buf) }; | ||
1406 | int tuner_frequency = 0; | ||
1407 | u8 band, cp, filter; | ||
1408 | |||
1409 | // determine charge pump | ||
1410 | tuner_frequency = params->frequency; | ||
1411 | if (tuner_frequency < 87000000) {return -EINVAL;} | ||
1412 | else if (tuner_frequency < 130000000) {cp = 3; band = 1;} | ||
1413 | else if (tuner_frequency < 160000000) {cp = 5; band = 1;} | ||
1414 | else if (tuner_frequency < 200000000) {cp = 6; band = 1;} | ||
1415 | else if (tuner_frequency < 290000000) {cp = 3; band = 2;} | ||
1416 | else if (tuner_frequency < 420000000) {cp = 5; band = 2;} | ||
1417 | else if (tuner_frequency < 480000000) {cp = 6; band = 2;} | ||
1418 | else if (tuner_frequency < 620000000) {cp = 3; band = 4;} | ||
1419 | else if (tuner_frequency < 830000000) {cp = 5; band = 4;} | ||
1420 | else if (tuner_frequency < 895000000) {cp = 7; band = 4;} | ||
1421 | else {return -EINVAL;} | ||
1422 | |||
1423 | // assume PLL filter should always be 8MHz for the moment. | ||
1424 | filter = 1; | ||
1425 | |||
1426 | // calculate divisor | ||
1427 | // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz | ||
1428 | tuner_frequency = ((params->frequency + 36125000) / 62500); | ||
1429 | |||
1430 | // setup tuner buffer | ||
1431 | tuner_buf[0] = tuner_frequency >> 8; | ||
1432 | tuner_buf[1] = tuner_frequency & 0xff; | ||
1433 | tuner_buf[2] = 0xc8; | ||
1434 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | ||
1435 | tuner_buf[4] = 0x80; | ||
1436 | |||
1437 | if (fe->ops.i2c_gate_ctrl) | ||
1438 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1439 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { | ||
1440 | printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n"); | ||
1441 | return -EIO; | ||
1442 | } | ||
1443 | |||
1444 | msleep(50); | ||
1445 | |||
1446 | if (fe->ops.i2c_gate_ctrl) | ||
1447 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1448 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { | ||
1449 | printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n"); | ||
1450 | return -EIO; | ||
1451 | } | ||
1452 | |||
1453 | msleep(1); | ||
1454 | |||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1458 | static u8 dvbc_philips_tdm1316l_inittab[] = { | ||
1459 | 0x80, 0x21, | ||
1460 | 0x80, 0x20, | ||
1461 | 0x81, 0x01, | ||
1462 | 0x81, 0x00, | ||
1463 | 0x00, 0x09, | ||
1464 | 0x01, 0x69, | ||
1465 | 0x03, 0x00, | ||
1466 | 0x04, 0x00, | ||
1467 | 0x07, 0x00, | ||
1468 | 0x08, 0x00, | ||
1469 | 0x20, 0x00, | ||
1470 | 0x21, 0x40, | ||
1471 | 0x22, 0x00, | ||
1472 | 0x23, 0x00, | ||
1473 | 0x24, 0x40, | ||
1474 | 0x25, 0x88, | ||
1475 | 0x30, 0xff, | ||
1476 | 0x31, 0x00, | ||
1477 | 0x32, 0xff, | ||
1478 | 0x33, 0x00, | ||
1479 | 0x34, 0x50, | ||
1480 | 0x35, 0x7f, | ||
1481 | 0x36, 0x00, | ||
1482 | 0x37, 0x20, | ||
1483 | 0x38, 0x00, | ||
1484 | 0x40, 0x1c, | ||
1485 | 0x41, 0xff, | ||
1486 | 0x42, 0x29, | ||
1487 | 0x43, 0x20, | ||
1488 | 0x44, 0xff, | ||
1489 | 0x45, 0x00, | ||
1490 | 0x46, 0x00, | ||
1491 | 0x49, 0x04, | ||
1492 | 0x4a, 0xff, | ||
1493 | 0x4b, 0x7f, | ||
1494 | 0x52, 0x30, | ||
1495 | 0x55, 0xae, | ||
1496 | 0x56, 0x47, | ||
1497 | 0x57, 0xe1, | ||
1498 | 0x58, 0x3a, | ||
1499 | 0x5a, 0x1e, | ||
1500 | 0x5b, 0x34, | ||
1501 | 0x60, 0x00, | ||
1502 | 0x63, 0x00, | ||
1503 | 0x64, 0x00, | ||
1504 | 0x65, 0x00, | ||
1505 | 0x66, 0x00, | ||
1506 | 0x67, 0x00, | ||
1507 | 0x68, 0x00, | ||
1508 | 0x69, 0x00, | ||
1509 | 0x6a, 0x02, | ||
1510 | 0x6b, 0x00, | ||
1511 | 0x70, 0xff, | ||
1512 | 0x71, 0x00, | ||
1513 | 0x72, 0x00, | ||
1514 | 0x73, 0x00, | ||
1515 | 0x74, 0x0c, | ||
1516 | 0x80, 0x00, | ||
1517 | 0x81, 0x00, | ||
1518 | 0x82, 0x00, | ||
1519 | 0x83, 0x00, | ||
1520 | 0x84, 0x04, | ||
1521 | 0x85, 0x80, | ||
1522 | 0x86, 0x24, | ||
1523 | 0x87, 0x78, | ||
1524 | 0x88, 0x00, | ||
1525 | 0x89, 0x00, | ||
1526 | 0x90, 0x01, | ||
1527 | 0x91, 0x01, | ||
1528 | 0xa0, 0x00, | ||
1529 | 0xa1, 0x00, | ||
1530 | 0xa2, 0x00, | ||
1531 | 0xb0, 0x91, | ||
1532 | 0xb1, 0x0b, | ||
1533 | 0xc0, 0x4b, | ||
1534 | 0xc1, 0x00, | ||
1535 | 0xc2, 0x00, | ||
1536 | 0xd0, 0x00, | ||
1537 | 0xd1, 0x00, | ||
1538 | 0xd2, 0x00, | ||
1539 | 0xd3, 0x00, | ||
1540 | 0xd4, 0x00, | ||
1541 | 0xd5, 0x00, | ||
1542 | 0xde, 0x00, | ||
1543 | 0xdf, 0x00, | ||
1544 | 0x61, 0x38, | ||
1545 | 0x62, 0x0a, | ||
1546 | 0x53, 0x13, | ||
1547 | 0x59, 0x08, | ||
1548 | 0x55, 0x00, | ||
1549 | 0x56, 0x40, | ||
1550 | 0x57, 0x08, | ||
1551 | 0x58, 0x3d, | ||
1552 | 0x88, 0x10, | ||
1553 | 0xa0, 0x00, | ||
1554 | 0xa0, 0x00, | ||
1555 | 0xa0, 0x00, | ||
1556 | 0xa0, 0x04, | ||
1557 | 0xff, 0xff, | ||
1558 | }; | ||
1559 | |||
1560 | static struct stv0297_config dvbc_philips_tdm1316l_config = { | ||
1561 | .demod_address = 0x1c, | ||
1562 | .inittab = dvbc_philips_tdm1316l_inittab, | ||
1563 | .invert = 0, | ||
1564 | }; | ||
1565 | |||
1413 | static void frontend_init(struct ttusb* ttusb) | 1566 | static void frontend_init(struct ttusb* ttusb) |
1414 | { | 1567 | { |
1415 | switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) { | 1568 | switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) { |
@@ -1417,11 +1570,13 @@ static void frontend_init(struct ttusb* ttusb) | |||
1417 | // try the stv0299 based first | 1570 | // try the stv0299 based first |
1418 | ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap); | 1571 | ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap); |
1419 | if (ttusb->fe != NULL) { | 1572 | if (ttusb->fe != NULL) { |
1573 | ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params; | ||
1574 | |||
1420 | if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1 | 1575 | if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1 |
1421 | alps_stv0299_config.inittab = alps_bsbe1_inittab; | 1576 | alps_stv0299_config.inittab = alps_bsbe1_inittab; |
1422 | ttusb->fe->ops->set_voltage = lnbp21_set_voltage; | 1577 | lnbp21_attach(ttusb->fe, &ttusb->i2c_adap, 0, 0); |
1423 | } else { // ALPS BSRU6 | 1578 | } else { // ALPS BSRU6 |
1424 | ttusb->fe->ops->set_voltage = ttusb_set_voltage; | 1579 | ttusb->fe->ops.set_voltage = ttusb_set_voltage; |
1425 | } | 1580 | } |
1426 | break; | 1581 | break; |
1427 | } | 1582 | } |
@@ -1429,28 +1584,41 @@ static void frontend_init(struct ttusb* ttusb) | |||
1429 | // Grundig 29504-491 | 1584 | // Grundig 29504-491 |
1430 | ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap); | 1585 | ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap); |
1431 | if (ttusb->fe != NULL) { | 1586 | if (ttusb->fe != NULL) { |
1432 | ttusb->fe->ops->set_voltage = ttusb_set_voltage; | 1587 | ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params; |
1588 | ttusb->fe->ops.set_voltage = ttusb_set_voltage; | ||
1433 | break; | 1589 | break; |
1434 | } | 1590 | } |
1435 | |||
1436 | break; | 1591 | break; |
1437 | 1592 | ||
1438 | case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) | 1593 | case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) |
1439 | ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb)); | 1594 | ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb)); |
1440 | if (ttusb->fe != NULL) | 1595 | if (ttusb->fe != NULL) { |
1596 | ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
1597 | break; | ||
1598 | } | ||
1599 | |||
1600 | ttusb->fe = stv0297_attach(&dvbc_philips_tdm1316l_config, &ttusb->i2c_adap); | ||
1601 | if (ttusb->fe != NULL) { | ||
1602 | ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params; | ||
1441 | break; | 1603 | break; |
1604 | } | ||
1442 | break; | 1605 | break; |
1443 | 1606 | ||
1444 | case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) | 1607 | case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) |
1445 | // try the ALPS TDMB7 first | 1608 | // try the ALPS TDMB7 first |
1446 | ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap); | 1609 | ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap); |
1447 | if (ttusb->fe != NULL) | 1610 | if (ttusb->fe != NULL) { |
1611 | ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params; | ||
1448 | break; | 1612 | break; |
1613 | } | ||
1449 | 1614 | ||
1450 | // Philips td1316 | 1615 | // Philips td1316 |
1451 | ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap); | 1616 | ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap); |
1452 | if (ttusb->fe != NULL) | 1617 | if (ttusb->fe != NULL) { |
1618 | ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init; | ||
1619 | ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; | ||
1453 | break; | 1620 | break; |
1621 | } | ||
1454 | break; | 1622 | break; |
1455 | } | 1623 | } |
1456 | 1624 | ||
@@ -1461,8 +1629,8 @@ static void frontend_init(struct ttusb* ttusb) | |||
1461 | } else { | 1629 | } else { |
1462 | if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) { | 1630 | if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) { |
1463 | printk("dvb-ttusb-budget: Frontend registration failed!\n"); | 1631 | printk("dvb-ttusb-budget: Frontend registration failed!\n"); |
1464 | if (ttusb->fe->ops->release) | 1632 | if (ttusb->fe->ops.release) |
1465 | ttusb->fe->ops->release(ttusb->fe); | 1633 | ttusb->fe->ops.release(ttusb->fe); |
1466 | ttusb->fe = NULL; | 1634 | ttusb->fe = NULL; |
1467 | } | 1635 | } |
1468 | } | 1636 | } |
@@ -1507,7 +1675,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1507 | 1675 | ||
1508 | mutex_unlock(&ttusb->semi2c); | 1676 | mutex_unlock(&ttusb->semi2c); |
1509 | 1677 | ||
1510 | if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE)) < 0) { | 1678 | if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE, &udev->dev)) < 0) { |
1511 | ttusb_free_iso_urbs(ttusb); | 1679 | ttusb_free_iso_urbs(ttusb); |
1512 | kfree(ttusb); | 1680 | kfree(ttusb); |
1513 | return result; | 1681 | return result; |
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 44dea3211848..6c1cb770bcf5 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c | |||
@@ -1432,7 +1432,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) | |||
1432 | dprintk("%s\n", __FUNCTION__); | 1432 | dprintk("%s\n", __FUNCTION__); |
1433 | 1433 | ||
1434 | if ((result = dvb_register_adapter(&dec->adapter, | 1434 | if ((result = dvb_register_adapter(&dec->adapter, |
1435 | dec->model_name, THIS_MODULE)) < 0) { | 1435 | dec->model_name, THIS_MODULE, &dec->udev->dev)) < 0) { |
1436 | printk("%s: dvb_register_adapter failed: error %d\n", | 1436 | printk("%s: dvb_register_adapter failed: error %d\n", |
1437 | __FUNCTION__, result); | 1437 | __FUNCTION__, result); |
1438 | 1438 | ||
@@ -1657,8 +1657,8 @@ static int ttusb_dec_probe(struct usb_interface *intf, | |||
1657 | } else { | 1657 | } else { |
1658 | if (dvb_register_frontend(&dec->adapter, dec->fe)) { | 1658 | if (dvb_register_frontend(&dec->adapter, dec->fe)) { |
1659 | printk("budget-ci: Frontend registration failed!\n"); | 1659 | printk("budget-ci: Frontend registration failed!\n"); |
1660 | if (dec->fe->ops->release) | 1660 | if (dec->fe->ops.release) |
1661 | dec->fe->ops->release(dec->fe); | 1661 | dec->fe->ops.release(dec->fe); |
1662 | dec->fe = NULL; | 1662 | dec->fe = NULL; |
1663 | } | 1663 | } |
1664 | } | 1664 | } |
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index a5a46175fa09..42f39a89bc4d 100644 --- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c | |||
@@ -28,8 +28,6 @@ | |||
28 | 28 | ||
29 | struct ttusbdecfe_state { | 29 | struct ttusbdecfe_state { |
30 | 30 | ||
31 | struct dvb_frontend_ops ops; | ||
32 | |||
33 | /* configuration settings */ | 31 | /* configuration settings */ |
34 | const struct ttusbdecfe_config* config; | 32 | const struct ttusbdecfe_config* config; |
35 | 33 | ||
@@ -203,10 +201,9 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf | |||
203 | 201 | ||
204 | /* setup the state */ | 202 | /* setup the state */ |
205 | state->config = config; | 203 | state->config = config; |
206 | memcpy(&state->ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops)); | ||
207 | 204 | ||
208 | /* create dvb_frontend */ | 205 | /* create dvb_frontend */ |
209 | state->frontend.ops = &state->ops; | 206 | memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops)); |
210 | state->frontend.demodulator_priv = state; | 207 | state->frontend.demodulator_priv = state; |
211 | return &state->frontend; | 208 | return &state->frontend; |
212 | } | 209 | } |
@@ -226,10 +223,9 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf | |||
226 | state->config = config; | 223 | state->config = config; |
227 | state->voltage = 0; | 224 | state->voltage = 0; |
228 | state->hi_band = 0; | 225 | state->hi_band = 0; |
229 | memcpy(&state->ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops)); | ||
230 | 226 | ||
231 | /* create dvb_frontend */ | 227 | /* create dvb_frontend */ |
232 | state->frontend.ops = &state->ops; | 228 | memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops)); |
233 | state->frontend.demodulator_priv = state; | 229 | state->frontend.demodulator_priv = state; |
234 | return &state->frontend; | 230 | return &state->frontend; |
235 | } | 231 | } |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 3fff75763693..de3128a31de8 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -136,7 +136,7 @@ config RADIO_GEMTEK_PCI | |||
136 | Choose Y here if you have this PCI FM radio card. | 136 | Choose Y here if you have this PCI FM radio card. |
137 | 137 | ||
138 | In order to control your radio card, you will need to use programs | 138 | In order to control your radio card, you will need to use programs |
139 | that are compatible with the Video for Linux API. Information on | 139 | that are compatible with the Video for Linux API. Information on |
140 | this API and pointers to "v4l" programs may be found at | 140 | this API and pointers to "v4l" programs may be found at |
141 | <file:Documentation/video4linux/API.html>. | 141 | <file:Documentation/video4linux/API.html>. |
142 | 142 | ||
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index 8b351945d066..e95b6805e002 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile | |||
@@ -20,3 +20,5 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o | |||
20 | obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o | 20 | obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o |
21 | obj-$(CONFIG_RADIO_TRUST) += radio-trust.o | 21 | obj-$(CONFIG_RADIO_TRUST) += radio-trust.o |
22 | obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o | 22 | obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o |
23 | |||
24 | EXTRA_CFLAGS += -Isound | ||
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c index dc292da2605f..c4312fa0e2f5 100644 --- a/drivers/media/radio/miropcm20-radio.c +++ b/drivers/media/radio/miropcm20-radio.c | |||
@@ -16,13 +16,14 @@ | |||
16 | 16 | ||
17 | /* What ever you think about the ACI, version 0x07 is not very well! | 17 | /* What ever you think about the ACI, version 0x07 is not very well! |
18 | * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono | 18 | * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono |
19 | * conditions... Robert | 19 | * conditions... Robert |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/videodev.h> | 24 | #include <linux/videodev.h> |
25 | #include "../../../sound/oss/aci.h" | 25 | #include <media/v4l2-common.h> |
26 | #include "oss/aci.h" | ||
26 | #include "miropcm20-rds-core.h" | 27 | #include "miropcm20-rds-core.h" |
27 | 28 | ||
28 | static int radio_nr = -1; | 29 | static int radio_nr = -1; |
@@ -123,7 +124,7 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file, | |||
123 | struct video_device *dev = video_devdata(file); | 124 | struct video_device *dev = video_devdata(file); |
124 | struct pcm20_device *pcm20 = dev->priv; | 125 | struct pcm20_device *pcm20 = dev->priv; |
125 | int i; | 126 | int i; |
126 | 127 | ||
127 | switch(cmd) | 128 | switch(cmd) |
128 | { | 129 | { |
129 | case VIDIOCGCAP: | 130 | case VIDIOCGCAP: |
@@ -139,7 +140,7 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file, | |||
139 | case VIDIOCGTUNER: | 140 | case VIDIOCGTUNER: |
140 | { | 141 | { |
141 | struct video_tuner *v = arg; | 142 | struct video_tuner *v = arg; |
142 | if(v->tuner) /* Only 1 tuner */ | 143 | if(v->tuner) /* Only 1 tuner */ |
143 | return -EINVAL; | 144 | return -EINVAL; |
144 | v->rangelow=87*16000; | 145 | v->rangelow=87*16000; |
145 | v->rangehigh=108*16000; | 146 | v->rangehigh=108*16000; |
@@ -172,7 +173,7 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file, | |||
172 | return i; | 173 | return i; |
173 | } | 174 | } |
174 | case VIDIOCGAUDIO: | 175 | case VIDIOCGAUDIO: |
175 | { | 176 | { |
176 | struct video_audio *v = arg; | 177 | struct video_audio *v = arg; |
177 | memset(v,0, sizeof(*v)); | 178 | memset(v,0, sizeof(*v)); |
178 | v->flags=VIDEO_AUDIO_MUTABLE; | 179 | v->flags=VIDEO_AUDIO_MUTABLE; |
@@ -183,12 +184,12 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file, | |||
183 | v->mode|=VIDEO_SOUND_MONO; | 184 | v->mode|=VIDEO_SOUND_MONO; |
184 | /* v->step=2048; */ | 185 | /* v->step=2048; */ |
185 | strcpy(v->name, "Radio"); | 186 | strcpy(v->name, "Radio"); |
186 | return 0; | 187 | return 0; |
187 | } | 188 | } |
188 | case VIDIOCSAUDIO: | 189 | case VIDIOCSAUDIO: |
189 | { | 190 | { |
190 | struct video_audio *v = arg; | 191 | struct video_audio *v = arg; |
191 | if(v->audio) | 192 | if(v->audio) |
192 | return -EINVAL; | 193 | return -EINVAL; |
193 | 194 | ||
194 | pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE)); | 195 | pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE)); |
@@ -237,7 +238,7 @@ static int __init pcm20_init(void) | |||
237 | { | 238 | { |
238 | if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1) | 239 | if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1) |
239 | goto video_register_device; | 240 | goto video_register_device; |
240 | 241 | ||
241 | if(attach_aci_rds()<0) | 242 | if(attach_aci_rds()<0) |
242 | goto attach_aci_rds; | 243 | goto attach_aci_rds; |
243 | 244 | ||
diff --git a/drivers/media/radio/miropcm20-rds-core.c b/drivers/media/radio/miropcm20-rds-core.c index b602c73e2309..9428d8b2642c 100644 --- a/drivers/media/radio/miropcm20-rds-core.c +++ b/drivers/media/radio/miropcm20-rds-core.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | 22 | ||
23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
24 | #include "../../../sound/oss/aci.h" | 24 | #include "oss/aci.h" |
25 | #include "miropcm20-rds-core.h" | 25 | #include "miropcm20-rds-core.h" |
26 | 26 | ||
27 | #define DEBUG 0 | 27 | #define DEBUG 0 |
@@ -33,24 +33,24 @@ static struct mutex aci_rds_mutex; | |||
33 | #define RDS_BUSYMASK 0x10 /* Bit 4 */ | 33 | #define RDS_BUSYMASK 0x10 /* Bit 4 */ |
34 | #define RDS_CLOCKMASK 0x08 /* Bit 3 */ | 34 | #define RDS_CLOCKMASK 0x08 /* Bit 3 */ |
35 | 35 | ||
36 | #define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1) | 36 | #define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1) |
37 | 37 | ||
38 | 38 | ||
39 | #if DEBUG | 39 | #if DEBUG |
40 | static void print_matrix(char array[], unsigned int length) | 40 | static void print_matrix(char array[], unsigned int length) |
41 | { | 41 | { |
42 | int i, j; | 42 | int i, j; |
43 | 43 | ||
44 | for (i=0; i<length; i++) { | 44 | for (i=0; i<length; i++) { |
45 | printk(KERN_DEBUG "aci-rds: "); | 45 | printk(KERN_DEBUG "aci-rds: "); |
46 | for (j=7; j>=0; j--) { | 46 | for (j=7; j>=0; j--) { |
47 | printk("%d", (array[i] >> j) & 0x1); | 47 | printk("%d", (array[i] >> j) & 0x1); |
48 | } | 48 | } |
49 | if (i%8 == 0) | 49 | if (i%8 == 0) |
50 | printk(" byte-border\n"); | 50 | printk(" byte-border\n"); |
51 | else | 51 | else |
52 | printk("\n"); | 52 | printk("\n"); |
53 | } | 53 | } |
54 | } | 54 | } |
55 | #endif /* DEBUG */ | 55 | #endif /* DEBUG */ |
56 | 56 | ||
@@ -114,7 +114,7 @@ static int rds_write(unsigned char cmd) | |||
114 | { | 114 | { |
115 | unsigned char sendbuffer[8]; | 115 | unsigned char sendbuffer[8]; |
116 | int i; | 116 | int i; |
117 | 117 | ||
118 | if (byte2trans(cmd, sendbuffer, 8) != 0){ | 118 | if (byte2trans(cmd, sendbuffer, 8) != 0){ |
119 | return -1; | 119 | return -1; |
120 | } else { | 120 | } else { |
@@ -151,7 +151,7 @@ static int rds_read(unsigned char databuffer[], int datasize) | |||
151 | I have to waitread() here */ | 151 | I have to waitread() here */ |
152 | if (rds_waitread() < 0) | 152 | if (rds_waitread() < 0) |
153 | return -1; | 153 | return -1; |
154 | 154 | ||
155 | memset(databuffer, 0, datasize); | 155 | memset(databuffer, 0, datasize); |
156 | 156 | ||
157 | for (i=0; i< READSIZE; i++) | 157 | for (i=0; i< READSIZE; i++) |
@@ -194,7 +194,7 @@ int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize) | |||
194 | ret = 0; | 194 | ret = 0; |
195 | 195 | ||
196 | mutex_unlock(&aci_rds_mutex); | 196 | mutex_unlock(&aci_rds_mutex); |
197 | 197 | ||
198 | return ret; | 198 | return ret; |
199 | } | 199 | } |
200 | EXPORT_SYMBOL(aci_rds_cmd); | 200 | EXPORT_SYMBOL(aci_rds_cmd); |
diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c index e09214082e01..87b37b7691da 100644 --- a/drivers/media/radio/miropcm20-rds.c +++ b/drivers/media/radio/miropcm20-rds.c | |||
@@ -48,7 +48,7 @@ static int rds_f_release(struct inode *in, struct file *fi) | |||
48 | 48 | ||
49 | static void print_matrix(char *ch, char out[]) | 49 | static void print_matrix(char *ch, char out[]) |
50 | { | 50 | { |
51 | int j; | 51 | int j; |
52 | 52 | ||
53 | for (j=7; j>=0; j--) { | 53 | for (j=7; j>=0; j--) { |
54 | out[7-j] = ((*ch >> j) & 0x1) + '0'; | 54 | out[7-j] = ((*ch >> j) & 0x1) + '0'; |
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 557fb5c4af38..df22a582e7a2 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * out(port, start_increasing_volume); | 24 | * out(port, start_increasing_volume); |
25 | * wait(a_wee_while); | 25 | * wait(a_wee_while); |
26 | * out(port, stop_changing_the_volume); | 26 | * out(port, stop_changing_the_volume); |
27 | * | 27 | * |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/module.h> /* Modules */ | 30 | #include <linux/module.h> /* Modules */ |
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/io.h> /* outb, outb_p */ | 34 | #include <asm/io.h> /* outb, outb_p */ |
35 | #include <asm/uaccess.h> /* copy to/from user */ | 35 | #include <asm/uaccess.h> /* copy to/from user */ |
36 | #include <linux/videodev.h> /* kernel radio structs */ | 36 | #include <linux/videodev.h> /* kernel radio structs */ |
37 | #include <media/v4l2-common.h> | ||
37 | #include <linux/config.h> /* CONFIG_RADIO_RTRACK_PORT */ | 38 | #include <linux/config.h> /* CONFIG_RADIO_RTRACK_PORT */ |
38 | #include <asm/semaphore.h> /* Lock for the I/O */ | 39 | #include <asm/semaphore.h> /* Lock for the I/O */ |
39 | 40 | ||
@@ -41,7 +42,7 @@ | |||
41 | #define CONFIG_RADIO_RTRACK_PORT -1 | 42 | #define CONFIG_RADIO_RTRACK_PORT -1 |
42 | #endif | 43 | #endif |
43 | 44 | ||
44 | static int io = CONFIG_RADIO_RTRACK_PORT; | 45 | static int io = CONFIG_RADIO_RTRACK_PORT; |
45 | static int radio_nr = -1; | 46 | static int radio_nr = -1; |
46 | static struct mutex lock; | 47 | static struct mutex lock; |
47 | 48 | ||
@@ -93,12 +94,12 @@ static int rt_setvol(struct rt_device *dev, int vol) | |||
93 | int i; | 94 | int i; |
94 | 95 | ||
95 | mutex_lock(&lock); | 96 | mutex_lock(&lock); |
96 | 97 | ||
97 | if(vol == dev->curvol) { /* requested volume = current */ | 98 | if(vol == dev->curvol) { /* requested volume = current */ |
98 | if (dev->muted) { /* user is unmuting the card */ | 99 | if (dev->muted) { /* user is unmuting the card */ |
99 | dev->muted = 0; | 100 | dev->muted = 0; |
100 | outb (0xd8, io); /* enable card */ | 101 | outb (0xd8, io); /* enable card */ |
101 | } | 102 | } |
102 | mutex_unlock(&lock); | 103 | mutex_unlock(&lock); |
103 | return 0; | 104 | return 0; |
104 | } | 105 | } |
@@ -114,10 +115,10 @@ static int rt_setvol(struct rt_device *dev, int vol) | |||
114 | 115 | ||
115 | dev->muted = 0; | 116 | dev->muted = 0; |
116 | if(vol > dev->curvol) | 117 | if(vol > dev->curvol) |
117 | for(i = dev->curvol; i < vol; i++) | 118 | for(i = dev->curvol; i < vol; i++) |
118 | rt_incvol(); | 119 | rt_incvol(); |
119 | else | 120 | else |
120 | for(i = dev->curvol; i > vol; i--) | 121 | for(i = dev->curvol; i > vol; i--) |
121 | rt_decvol(); | 122 | rt_decvol(); |
122 | 123 | ||
123 | dev->curvol = vol; | 124 | dev->curvol = vol; |
@@ -125,7 +126,7 @@ static int rt_setvol(struct rt_device *dev, int vol) | |||
125 | return 0; | 126 | return 0; |
126 | } | 127 | } |
127 | 128 | ||
128 | /* the 128+64 on these outb's is to keep the volume stable while tuning | 129 | /* the 128+64 on these outb's is to keep the volume stable while tuning |
129 | * without them, the volume _will_ creep up with each frequency change | 130 | * without them, the volume _will_ creep up with each frequency change |
130 | * and bit 4 (+16) is to keep the signal strength meter enabled | 131 | * and bit 4 (+16) is to keep the signal strength meter enabled |
131 | */ | 132 | */ |
@@ -140,7 +141,7 @@ static void send_0_byte(int port, struct rt_device *dev) | |||
140 | outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */ | 141 | outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */ |
141 | outb_p(128+64+16+8+2+1, port); /* clock */ | 142 | outb_p(128+64+16+8+2+1, port); /* clock */ |
142 | } | 143 | } |
143 | sleep_delay(1000); | 144 | sleep_delay(1000); |
144 | } | 145 | } |
145 | 146 | ||
146 | static void send_1_byte(int port, struct rt_device *dev) | 147 | static void send_1_byte(int port, struct rt_device *dev) |
@@ -148,13 +149,13 @@ static void send_1_byte(int port, struct rt_device *dev) | |||
148 | if ((dev->curvol == 0) || (dev->muted)) { | 149 | if ((dev->curvol == 0) || (dev->muted)) { |
149 | outb_p(128+64+16+4 +1, port); /* wr-enable+data high */ | 150 | outb_p(128+64+16+4 +1, port); /* wr-enable+data high */ |
150 | outb_p(128+64+16+4+2+1, port); /* clock */ | 151 | outb_p(128+64+16+4+2+1, port); /* clock */ |
151 | } | 152 | } |
152 | else { | 153 | else { |
153 | outb_p(128+64+16+8+4 +1, port); /* on+wr-enable+data high */ | 154 | outb_p(128+64+16+8+4 +1, port); /* on+wr-enable+data high */ |
154 | outb_p(128+64+16+8+4+2+1, port); /* clock */ | 155 | outb_p(128+64+16+8+4+2+1, port); /* clock */ |
155 | } | 156 | } |
156 | 157 | ||
157 | sleep_delay(1000); | 158 | sleep_delay(1000); |
158 | } | 159 | } |
159 | 160 | ||
160 | static int rt_setfreq(struct rt_device *dev, unsigned long freq) | 161 | static int rt_setfreq(struct rt_device *dev, unsigned long freq) |
@@ -167,9 +168,9 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) | |||
167 | 168 | ||
168 | freq += 171200; /* Add 10.7 MHz IF */ | 169 | freq += 171200; /* Add 10.7 MHz IF */ |
169 | freq /= 800; /* Convert to 50 kHz units */ | 170 | freq /= 800; /* Convert to 50 kHz units */ |
170 | 171 | ||
171 | mutex_lock(&lock); /* Stop other ops interfering */ | 172 | mutex_lock(&lock); /* Stop other ops interfering */ |
172 | 173 | ||
173 | send_0_byte (io, dev); /* 0: LSB of frequency */ | 174 | send_0_byte (io, dev); /* 0: LSB of frequency */ |
174 | 175 | ||
175 | for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ | 176 | for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ |
@@ -195,7 +196,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) | |||
195 | outb (0xd0, io); /* volume steady + sigstr */ | 196 | outb (0xd0, io); /* volume steady + sigstr */ |
196 | else | 197 | else |
197 | outb (0xd8, io); /* volume steady + sigstr + on */ | 198 | outb (0xd8, io); /* volume steady + sigstr + on */ |
198 | 199 | ||
199 | mutex_unlock(&lock); | 200 | mutex_unlock(&lock); |
200 | 201 | ||
201 | return 0; | 202 | return 0; |
@@ -213,7 +214,7 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, | |||
213 | { | 214 | { |
214 | struct video_device *dev = video_devdata(file); | 215 | struct video_device *dev = video_devdata(file); |
215 | struct rt_device *rt=dev->priv; | 216 | struct rt_device *rt=dev->priv; |
216 | 217 | ||
217 | switch(cmd) | 218 | switch(cmd) |
218 | { | 219 | { |
219 | case VIDIOCGCAP: | 220 | case VIDIOCGCAP: |
@@ -229,7 +230,7 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, | |||
229 | case VIDIOCGTUNER: | 230 | case VIDIOCGTUNER: |
230 | { | 231 | { |
231 | struct video_tuner *v = arg; | 232 | struct video_tuner *v = arg; |
232 | if(v->tuner) /* Only 1 tuner */ | 233 | if(v->tuner) /* Only 1 tuner */ |
233 | return -EINVAL; | 234 | return -EINVAL; |
234 | v->rangelow=(87*16000); | 235 | v->rangelow=(87*16000); |
235 | v->rangehigh=(108*16000); | 236 | v->rangehigh=(108*16000); |
@@ -261,21 +262,21 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, | |||
261 | return 0; | 262 | return 0; |
262 | } | 263 | } |
263 | case VIDIOCGAUDIO: | 264 | case VIDIOCGAUDIO: |
264 | { | 265 | { |
265 | struct video_audio *v = arg; | 266 | struct video_audio *v = arg; |
266 | memset(v,0, sizeof(*v)); | 267 | memset(v,0, sizeof(*v)); |
267 | v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; | 268 | v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; |
268 | v->volume=rt->curvol * 6554; | 269 | v->volume=rt->curvol * 6554; |
269 | v->step=6554; | 270 | v->step=6554; |
270 | strcpy(v->name, "Radio"); | 271 | strcpy(v->name, "Radio"); |
271 | return 0; | 272 | return 0; |
272 | } | 273 | } |
273 | case VIDIOCSAUDIO: | 274 | case VIDIOCSAUDIO: |
274 | { | 275 | { |
275 | struct video_audio *v = arg; | 276 | struct video_audio *v = arg; |
276 | if(v->audio) | 277 | if(v->audio) |
277 | return -EINVAL; | 278 | return -EINVAL; |
278 | if(v->flags&VIDEO_AUDIO_MUTE) | 279 | if(v->flags&VIDEO_AUDIO_MUTE) |
279 | rt_mute(rt); | 280 | rt_mute(rt); |
280 | else | 281 | else |
281 | rt_setvol(rt,v->volume/6554); | 282 | rt_setvol(rt,v->volume/6554); |
@@ -298,7 +299,7 @@ static struct file_operations rtrack_fops = { | |||
298 | .owner = THIS_MODULE, | 299 | .owner = THIS_MODULE, |
299 | .open = video_exclusive_open, | 300 | .open = video_exclusive_open, |
300 | .release = video_exclusive_release, | 301 | .release = video_exclusive_release, |
301 | .ioctl = rt_ioctl, | 302 | .ioctl = rt_ioctl, |
302 | .compat_ioctl = v4l_compat_ioctl32, | 303 | .compat_ioctl = v4l_compat_ioctl32, |
303 | .llseek = no_llseek, | 304 | .llseek = no_llseek, |
304 | }; | 305 | }; |
@@ -320,14 +321,14 @@ static int __init rtrack_init(void) | |||
320 | return -EINVAL; | 321 | return -EINVAL; |
321 | } | 322 | } |
322 | 323 | ||
323 | if (!request_region(io, 2, "rtrack")) | 324 | if (!request_region(io, 2, "rtrack")) |
324 | { | 325 | { |
325 | printk(KERN_ERR "rtrack: port 0x%x already in use\n", io); | 326 | printk(KERN_ERR "rtrack: port 0x%x already in use\n", io); |
326 | return -EBUSY; | 327 | return -EBUSY; |
327 | } | 328 | } |
328 | 329 | ||
329 | rtrack_radio.priv=&rtrack_unit; | 330 | rtrack_radio.priv=&rtrack_unit; |
330 | 331 | ||
331 | if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1) | 332 | if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1) |
332 | { | 333 | { |
333 | release_region(io, 2); | 334 | release_region(io, 2); |
@@ -336,10 +337,10 @@ static int __init rtrack_init(void) | |||
336 | printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n"); | 337 | printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n"); |
337 | 338 | ||
338 | /* Set up the I/O locking */ | 339 | /* Set up the I/O locking */ |
339 | 340 | ||
340 | mutex_init(&lock); | 341 | mutex_init(&lock); |
341 | 342 | ||
342 | /* mute card - prevents noisy bootups */ | 343 | /* mute card - prevents noisy bootups */ |
343 | 344 | ||
344 | /* this ensures that the volume is all the way down */ | 345 | /* this ensures that the volume is all the way down */ |
345 | outb(0x48, io); /* volume down but still "on" */ | 346 | outb(0x48, io); /* volume down but still "on" */ |
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 83bdae23417d..95e6322133ee 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
@@ -1,11 +1,11 @@ | |||
1 | /* radio-aztech.c - Aztech radio card driver for Linux 2.2 | 1 | /* radio-aztech.c - Aztech radio card driver for Linux 2.2 |
2 | * | 2 | * |
3 | * Adapted to support the Video for Linux API by | 3 | * Adapted to support the Video for Linux API by |
4 | * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: | 4 | * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: |
5 | * | 5 | * |
6 | * Quay Ly | 6 | * Quay Ly |
7 | * Donald Song | 7 | * Donald Song |
8 | * Jason Lewis (jlewis@twilight.vtc.vsc.edu) | 8 | * Jason Lewis (jlewis@twilight.vtc.vsc.edu) |
9 | * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) | 9 | * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) |
10 | * William McGrath (wmcgrath@twilight.vtc.vsc.edu) | 10 | * William McGrath (wmcgrath@twilight.vtc.vsc.edu) |
11 | * | 11 | * |
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/io.h> /* outb, outb_p */ | 31 | #include <asm/io.h> /* outb, outb_p */ |
32 | #include <asm/uaccess.h> /* copy to/from user */ | 32 | #include <asm/uaccess.h> /* copy to/from user */ |
33 | #include <linux/videodev.h> /* kernel radio structs */ | 33 | #include <linux/videodev.h> /* kernel radio structs */ |
34 | #include <media/v4l2-common.h> | ||
34 | #include <linux/config.h> /* CONFIG_RADIO_AZTECH_PORT */ | 35 | #include <linux/config.h> /* CONFIG_RADIO_AZTECH_PORT */ |
35 | 36 | ||
36 | /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ | 37 | /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ |
@@ -39,7 +40,7 @@ | |||
39 | #define CONFIG_RADIO_AZTECH_PORT -1 | 40 | #define CONFIG_RADIO_AZTECH_PORT -1 |
40 | #endif | 41 | #endif |
41 | 42 | ||
42 | static int io = CONFIG_RADIO_AZTECH_PORT; | 43 | static int io = CONFIG_RADIO_AZTECH_PORT; |
43 | static int radio_nr = -1; | 44 | static int radio_nr = -1; |
44 | static int radio_wait_time = 1000; | 45 | static int radio_wait_time = 1000; |
45 | static struct mutex lock; | 46 | static struct mutex lock; |
@@ -53,15 +54,15 @@ struct az_device | |||
53 | 54 | ||
54 | static int volconvert(int level) | 55 | static int volconvert(int level) |
55 | { | 56 | { |
56 | level>>=14; /* Map 16bits down to 2 bit */ | 57 | level>>=14; /* Map 16bits down to 2 bit */ |
57 | level&=3; | 58 | level&=3; |
58 | 59 | ||
59 | /* convert to card-friendly values */ | 60 | /* convert to card-friendly values */ |
60 | switch (level) | 61 | switch (level) |
61 | { | 62 | { |
62 | case 0: | 63 | case 0: |
63 | return 0; | 64 | return 0; |
64 | case 1: | 65 | case 1: |
65 | return 1; | 66 | return 1; |
66 | case 2: | 67 | case 2: |
67 | return 4; | 68 | return 4; |
@@ -121,9 +122,9 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency) | |||
121 | 122 | ||
122 | frequency += 171200; /* Add 10.7 MHz IF */ | 123 | frequency += 171200; /* Add 10.7 MHz IF */ |
123 | frequency /= 800; /* Convert to 50 kHz units */ | 124 | frequency /= 800; /* Convert to 50 kHz units */ |
124 | 125 | ||
125 | mutex_lock(&lock); | 126 | mutex_lock(&lock); |
126 | 127 | ||
127 | send_0_byte (dev); /* 0: LSB of frequency */ | 128 | send_0_byte (dev); /* 0: LSB of frequency */ |
128 | 129 | ||
129 | for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ | 130 | for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ |
@@ -151,7 +152,7 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency) | |||
151 | 152 | ||
152 | udelay (radio_wait_time); | 153 | udelay (radio_wait_time); |
153 | outb_p(128+64+volconvert(dev->curvol), io); | 154 | outb_p(128+64+volconvert(dev->curvol), io); |
154 | 155 | ||
155 | mutex_unlock(&lock); | 156 | mutex_unlock(&lock); |
156 | 157 | ||
157 | return 0; | 158 | return 0; |
@@ -162,7 +163,7 @@ static int az_do_ioctl(struct inode *inode, struct file *file, | |||
162 | { | 163 | { |
163 | struct video_device *dev = video_devdata(file); | 164 | struct video_device *dev = video_devdata(file); |
164 | struct az_device *az = dev->priv; | 165 | struct az_device *az = dev->priv; |
165 | 166 | ||
166 | switch(cmd) | 167 | switch(cmd) |
167 | { | 168 | { |
168 | case VIDIOCGCAP: | 169 | case VIDIOCGCAP: |
@@ -178,7 +179,7 @@ static int az_do_ioctl(struct inode *inode, struct file *file, | |||
178 | case VIDIOCGTUNER: | 179 | case VIDIOCGTUNER: |
179 | { | 180 | { |
180 | struct video_tuner *v = arg; | 181 | struct video_tuner *v = arg; |
181 | if(v->tuner) /* Only 1 tuner */ | 182 | if(v->tuner) /* Only 1 tuner */ |
182 | return -EINVAL; | 183 | return -EINVAL; |
183 | v->rangelow=(87*16000); | 184 | v->rangelow=(87*16000); |
184 | v->rangehigh=(108*16000); | 185 | v->rangehigh=(108*16000); |
@@ -211,7 +212,7 @@ static int az_do_ioctl(struct inode *inode, struct file *file, | |||
211 | return 0; | 212 | return 0; |
212 | } | 213 | } |
213 | case VIDIOCGAUDIO: | 214 | case VIDIOCGAUDIO: |
214 | { | 215 | { |
215 | struct video_audio *v = arg; | 216 | struct video_audio *v = arg; |
216 | memset(v,0, sizeof(*v)); | 217 | memset(v,0, sizeof(*v)); |
217 | v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; | 218 | v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; |
@@ -222,17 +223,17 @@ static int az_do_ioctl(struct inode *inode, struct file *file, | |||
222 | v->volume=az->curvol; | 223 | v->volume=az->curvol; |
223 | v->step=16384; | 224 | v->step=16384; |
224 | strcpy(v->name, "Radio"); | 225 | strcpy(v->name, "Radio"); |
225 | return 0; | 226 | return 0; |
226 | } | 227 | } |
227 | case VIDIOCSAUDIO: | 228 | case VIDIOCSAUDIO: |
228 | { | 229 | { |
229 | struct video_audio *v = arg; | 230 | struct video_audio *v = arg; |
230 | if(v->audio) | 231 | if(v->audio) |
231 | return -EINVAL; | 232 | return -EINVAL; |
232 | az->curvol=v->volume; | 233 | az->curvol=v->volume; |
233 | 234 | ||
234 | az->stereo=(v->mode&VIDEO_SOUND_STEREO)?1:0; | 235 | az->stereo=(v->mode&VIDEO_SOUND_STEREO)?1:0; |
235 | if(v->flags&VIDEO_AUDIO_MUTE) | 236 | if(v->flags&VIDEO_AUDIO_MUTE) |
236 | az_setvol(az,0); | 237 | az_setvol(az,0); |
237 | else | 238 | else |
238 | az_setvol(az,az->curvol); | 239 | az_setvol(az,az->curvol); |
@@ -277,7 +278,7 @@ static int __init aztech_init(void) | |||
277 | return -EINVAL; | 278 | return -EINVAL; |
278 | } | 279 | } |
279 | 280 | ||
280 | if (!request_region(io, 2, "aztech")) | 281 | if (!request_region(io, 2, "aztech")) |
281 | { | 282 | { |
282 | printk(KERN_ERR "aztech: port 0x%x already in use\n", io); | 283 | printk(KERN_ERR "aztech: port 0x%x already in use\n", io); |
283 | return -EBUSY; | 284 | return -EBUSY; |
@@ -285,13 +286,13 @@ static int __init aztech_init(void) | |||
285 | 286 | ||
286 | mutex_init(&lock); | 287 | mutex_init(&lock); |
287 | aztech_radio.priv=&aztech_unit; | 288 | aztech_radio.priv=&aztech_unit; |
288 | 289 | ||
289 | if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1) | 290 | if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1) |
290 | { | 291 | { |
291 | release_region(io,2); | 292 | release_region(io,2); |
292 | return -EINVAL; | 293 | return -EINVAL; |
293 | } | 294 | } |
294 | 295 | ||
295 | printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); | 296 | printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); |
296 | /* mute card - prevents noisy bootups */ | 297 | /* mute card - prevents noisy bootups */ |
297 | outb (0, io); | 298 | outb (0, io); |
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index f1b5ac81e9d2..8641aec7baf8 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Russell Kroll (rkroll@exploits.org) | 8 | * Russell Kroll (rkroll@exploits.org) |
9 | * Quay Ly | 9 | * Quay Ly |
10 | * Donald Song | 10 | * Donald Song |
11 | * Jason Lewis (jlewis@twilight.vtc.vsc.edu) | 11 | * Jason Lewis (jlewis@twilight.vtc.vsc.edu) |
12 | * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) | 12 | * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) |
13 | * William McGrath (wmcgrath@twilight.vtc.vsc.edu) | 13 | * William McGrath (wmcgrath@twilight.vtc.vsc.edu) |
14 | * | 14 | * |
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/io.h> /* outb, outb_p */ | 34 | #include <asm/io.h> /* outb, outb_p */ |
35 | #include <asm/uaccess.h> /* copy to/from user */ | 35 | #include <asm/uaccess.h> /* copy to/from user */ |
36 | #include <linux/videodev.h> /* kernel radio structs */ | 36 | #include <linux/videodev.h> /* kernel radio structs */ |
37 | #include <media/v4l2-common.h> | ||
37 | #include <linux/param.h> | 38 | #include <linux/param.h> |
38 | #include <linux/pnp.h> | 39 | #include <linux/pnp.h> |
39 | 40 | ||
@@ -55,29 +56,29 @@ static int cadet_probe(void); | |||
55 | 56 | ||
56 | /* | 57 | /* |
57 | * Signal Strength Threshold Values | 58 | * Signal Strength Threshold Values |
58 | * The V4L API spec does not define any particular unit for the signal | 59 | * The V4L API spec does not define any particular unit for the signal |
59 | * strength value. These values are in microvolts of RF at the tuner's input. | 60 | * strength value. These values are in microvolts of RF at the tuner's input. |
60 | */ | 61 | */ |
61 | static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}}; | 62 | static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}}; |
62 | 63 | ||
63 | static int cadet_getrds(void) | 64 | static int cadet_getrds(void) |
64 | { | 65 | { |
65 | int rdsstat=0; | 66 | int rdsstat=0; |
66 | 67 | ||
67 | spin_lock(&cadet_io_lock); | 68 | spin_lock(&cadet_io_lock); |
68 | outb(3,io); /* Select Decoder Control/Status */ | 69 | outb(3,io); /* Select Decoder Control/Status */ |
69 | outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */ | 70 | outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */ |
70 | spin_unlock(&cadet_io_lock); | 71 | spin_unlock(&cadet_io_lock); |
71 | 72 | ||
72 | msleep(100); | 73 | msleep(100); |
73 | 74 | ||
74 | spin_lock(&cadet_io_lock); | 75 | spin_lock(&cadet_io_lock); |
75 | outb(3,io); /* Select Decoder Control/Status */ | 76 | outb(3,io); /* Select Decoder Control/Status */ |
76 | if((inb(io+1)&0x80)!=0) { | 77 | if((inb(io+1)&0x80)!=0) { |
77 | rdsstat|=VIDEO_TUNER_RDS_ON; | 78 | rdsstat|=VIDEO_TUNER_RDS_ON; |
78 | } | 79 | } |
79 | if((inb(io+1)&0x10)!=0) { | 80 | if((inb(io+1)&0x10)!=0) { |
80 | rdsstat|=VIDEO_TUNER_MBS_ON; | 81 | rdsstat|=VIDEO_TUNER_MBS_ON; |
81 | } | 82 | } |
82 | spin_unlock(&cadet_io_lock); | 83 | spin_unlock(&cadet_io_lock); |
83 | return rdsstat; | 84 | return rdsstat; |
@@ -86,49 +87,49 @@ static int cadet_getrds(void) | |||
86 | static int cadet_getstereo(void) | 87 | static int cadet_getstereo(void) |
87 | { | 88 | { |
88 | int ret = 0; | 89 | int ret = 0; |
89 | if(curtuner != 0) /* Only FM has stereo capability! */ | 90 | if(curtuner != 0) /* Only FM has stereo capability! */ |
90 | return 0; | 91 | return 0; |
91 | 92 | ||
92 | spin_lock(&cadet_io_lock); | 93 | spin_lock(&cadet_io_lock); |
93 | outb(7,io); /* Select tuner control */ | 94 | outb(7,io); /* Select tuner control */ |
94 | if( (inb(io+1) & 0x40) == 0) | 95 | if( (inb(io+1) & 0x40) == 0) |
95 | ret = 1; | 96 | ret = 1; |
96 | spin_unlock(&cadet_io_lock); | 97 | spin_unlock(&cadet_io_lock); |
97 | return ret; | 98 | return ret; |
98 | } | 99 | } |
99 | 100 | ||
100 | static unsigned cadet_gettune(void) | 101 | static unsigned cadet_gettune(void) |
101 | { | 102 | { |
102 | int curvol,i; | 103 | int curvol,i; |
103 | unsigned fifo=0; | 104 | unsigned fifo=0; |
104 | 105 | ||
105 | /* | 106 | /* |
106 | * Prepare for read | 107 | * Prepare for read |
107 | */ | 108 | */ |
108 | 109 | ||
109 | spin_lock(&cadet_io_lock); | 110 | spin_lock(&cadet_io_lock); |
110 | 111 | ||
111 | outb(7,io); /* Select tuner control */ | 112 | outb(7,io); /* Select tuner control */ |
112 | curvol=inb(io+1); /* Save current volume/mute setting */ | 113 | curvol=inb(io+1); /* Save current volume/mute setting */ |
113 | outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */ | 114 | outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */ |
114 | tunestat=0xffff; | 115 | tunestat=0xffff; |
115 | 116 | ||
116 | /* | 117 | /* |
117 | * Read the shift register | 118 | * Read the shift register |
118 | */ | 119 | */ |
119 | for(i=0;i<25;i++) { | 120 | for(i=0;i<25;i++) { |
120 | fifo=(fifo<<1)|((inb(io+1)>>7)&0x01); | 121 | fifo=(fifo<<1)|((inb(io+1)>>7)&0x01); |
121 | if(i<24) { | 122 | if(i<24) { |
122 | outb(0x01,io+1); | 123 | outb(0x01,io+1); |
123 | tunestat&=inb(io+1); | 124 | tunestat&=inb(io+1); |
124 | outb(0x00,io+1); | 125 | outb(0x00,io+1); |
125 | } | 126 | } |
126 | } | 127 | } |
127 | 128 | ||
128 | /* | 129 | /* |
129 | * Restore volume/mute setting | 130 | * Restore volume/mute setting |
130 | */ | 131 | */ |
131 | outb(curvol,io+1); | 132 | outb(curvol,io+1); |
132 | spin_unlock(&cadet_io_lock); | 133 | spin_unlock(&cadet_io_lock); |
133 | 134 | ||
134 | return fifo; | 135 | return fifo; |
@@ -136,43 +137,43 @@ static unsigned cadet_gettune(void) | |||
136 | 137 | ||
137 | static unsigned cadet_getfreq(void) | 138 | static unsigned cadet_getfreq(void) |
138 | { | 139 | { |
139 | int i; | 140 | int i; |
140 | unsigned freq=0,test,fifo=0; | 141 | unsigned freq=0,test,fifo=0; |
141 | 142 | ||
142 | /* | 143 | /* |
143 | * Read current tuning | 144 | * Read current tuning |
144 | */ | 145 | */ |
145 | fifo=cadet_gettune(); | 146 | fifo=cadet_gettune(); |
146 | 147 | ||
147 | /* | 148 | /* |
148 | * Convert to actual frequency | 149 | * Convert to actual frequency |
149 | */ | 150 | */ |
150 | if(curtuner==0) { /* FM */ | 151 | if(curtuner==0) { /* FM */ |
151 | test=12500; | 152 | test=12500; |
152 | for(i=0;i<14;i++) { | 153 | for(i=0;i<14;i++) { |
153 | if((fifo&0x01)!=0) { | 154 | if((fifo&0x01)!=0) { |
154 | freq+=test; | 155 | freq+=test; |
155 | } | 156 | } |
156 | test=test<<1; | 157 | test=test<<1; |
157 | fifo=fifo>>1; | 158 | fifo=fifo>>1; |
158 | } | 159 | } |
159 | freq-=10700000; /* IF frequency is 10.7 MHz */ | 160 | freq-=10700000; /* IF frequency is 10.7 MHz */ |
160 | freq=(freq*16)/1000000; /* Make it 1/16 MHz */ | 161 | freq=(freq*16)/1000000; /* Make it 1/16 MHz */ |
161 | } | 162 | } |
162 | if(curtuner==1) { /* AM */ | 163 | if(curtuner==1) { /* AM */ |
163 | freq=((fifo&0x7fff)-2010)*16; | 164 | freq=((fifo&0x7fff)-2010)*16; |
164 | } | 165 | } |
165 | 166 | ||
166 | return freq; | 167 | return freq; |
167 | } | 168 | } |
168 | 169 | ||
169 | static void cadet_settune(unsigned fifo) | 170 | static void cadet_settune(unsigned fifo) |
170 | { | 171 | { |
171 | int i; | 172 | int i; |
172 | unsigned test; | 173 | unsigned test; |
173 | 174 | ||
174 | spin_lock(&cadet_io_lock); | 175 | spin_lock(&cadet_io_lock); |
175 | 176 | ||
176 | outb(7,io); /* Select tuner control */ | 177 | outb(7,io); /* Select tuner control */ |
177 | /* | 178 | /* |
178 | * Write the shift register | 179 | * Write the shift register |
@@ -183,7 +184,7 @@ static void cadet_settune(unsigned fifo) | |||
183 | outb(7,io); /* Select tuner control */ | 184 | outb(7,io); /* Select tuner control */ |
184 | outb(test,io+1); /* Initialize for write */ | 185 | outb(test,io+1); /* Initialize for write */ |
185 | for(i=0;i<25;i++) { | 186 | for(i=0;i<25;i++) { |
186 | test|=0x01; /* Toggle SCK High */ | 187 | test|=0x01; /* Toggle SCK High */ |
187 | outb(test,io+1); | 188 | outb(test,io+1); |
188 | test&=0xfe; /* Toggle SCK Low */ | 189 | test&=0xfe; /* Toggle SCK Low */ |
189 | outb(test,io+1); | 190 | outb(test,io+1); |
@@ -196,57 +197,57 @@ static void cadet_settune(unsigned fifo) | |||
196 | 197 | ||
197 | static void cadet_setfreq(unsigned freq) | 198 | static void cadet_setfreq(unsigned freq) |
198 | { | 199 | { |
199 | unsigned fifo; | 200 | unsigned fifo; |
200 | int i,j,test; | 201 | int i,j,test; |
201 | int curvol; | 202 | int curvol; |
202 | 203 | ||
203 | /* | 204 | /* |
204 | * Formulate a fifo command | 205 | * Formulate a fifo command |
205 | */ | 206 | */ |
206 | fifo=0; | 207 | fifo=0; |
207 | if(curtuner==0) { /* FM */ | 208 | if(curtuner==0) { /* FM */ |
208 | test=102400; | 209 | test=102400; |
209 | freq=(freq*1000)/16; /* Make it kHz */ | 210 | freq=(freq*1000)/16; /* Make it kHz */ |
210 | freq+=10700; /* IF is 10700 kHz */ | 211 | freq+=10700; /* IF is 10700 kHz */ |
211 | for(i=0;i<14;i++) { | 212 | for(i=0;i<14;i++) { |
212 | fifo=fifo<<1; | 213 | fifo=fifo<<1; |
213 | if(freq>=test) { | 214 | if(freq>=test) { |
214 | fifo|=0x01; | 215 | fifo|=0x01; |
215 | freq-=test; | 216 | freq-=test; |
216 | } | 217 | } |
217 | test=test>>1; | 218 | test=test>>1; |
218 | } | 219 | } |
219 | } | 220 | } |
220 | if(curtuner==1) { /* AM */ | 221 | if(curtuner==1) { /* AM */ |
221 | fifo=(freq/16)+2010; /* Make it kHz */ | 222 | fifo=(freq/16)+2010; /* Make it kHz */ |
222 | fifo|=0x100000; /* Select AM Band */ | 223 | fifo|=0x100000; /* Select AM Band */ |
223 | } | 224 | } |
224 | 225 | ||
225 | /* | 226 | /* |
226 | * Save current volume/mute setting | 227 | * Save current volume/mute setting |
227 | */ | 228 | */ |
228 | 229 | ||
229 | spin_lock(&cadet_io_lock); | 230 | spin_lock(&cadet_io_lock); |
230 | outb(7,io); /* Select tuner control */ | 231 | outb(7,io); /* Select tuner control */ |
231 | curvol=inb(io+1); | 232 | curvol=inb(io+1); |
232 | spin_unlock(&cadet_io_lock); | 233 | spin_unlock(&cadet_io_lock); |
233 | 234 | ||
234 | /* | 235 | /* |
235 | * Tune the card | 236 | * Tune the card |
236 | */ | 237 | */ |
237 | for(j=3;j>-1;j--) { | 238 | for(j=3;j>-1;j--) { |
238 | cadet_settune(fifo|(j<<16)); | 239 | cadet_settune(fifo|(j<<16)); |
239 | 240 | ||
240 | spin_lock(&cadet_io_lock); | 241 | spin_lock(&cadet_io_lock); |
241 | outb(7,io); /* Select tuner control */ | 242 | outb(7,io); /* Select tuner control */ |
242 | outb(curvol,io+1); | 243 | outb(curvol,io+1); |
243 | spin_unlock(&cadet_io_lock); | 244 | spin_unlock(&cadet_io_lock); |
244 | 245 | ||
245 | msleep(100); | 246 | msleep(100); |
246 | 247 | ||
247 | cadet_gettune(); | 248 | cadet_gettune(); |
248 | if((tunestat & 0x40) == 0) { /* Tuned */ | 249 | if((tunestat & 0x40) == 0) { /* Tuned */ |
249 | sigstrength=sigtable[curtuner][j]; | 250 | sigstrength=sigtable[curtuner][j]; |
250 | return; | 251 | return; |
251 | } | 252 | } |
252 | } | 253 | } |
@@ -257,28 +258,28 @@ static void cadet_setfreq(unsigned freq) | |||
257 | static int cadet_getvol(void) | 258 | static int cadet_getvol(void) |
258 | { | 259 | { |
259 | int ret = 0; | 260 | int ret = 0; |
260 | 261 | ||
261 | spin_lock(&cadet_io_lock); | 262 | spin_lock(&cadet_io_lock); |
262 | 263 | ||
263 | outb(7,io); /* Select tuner control */ | 264 | outb(7,io); /* Select tuner control */ |
264 | if((inb(io + 1) & 0x20) != 0) | 265 | if((inb(io + 1) & 0x20) != 0) |
265 | ret = 0xffff; | 266 | ret = 0xffff; |
266 | 267 | ||
267 | spin_unlock(&cadet_io_lock); | 268 | spin_unlock(&cadet_io_lock); |
268 | return ret; | 269 | return ret; |
269 | } | 270 | } |
270 | 271 | ||
271 | 272 | ||
272 | static void cadet_setvol(int vol) | 273 | static void cadet_setvol(int vol) |
273 | { | 274 | { |
274 | spin_lock(&cadet_io_lock); | 275 | spin_lock(&cadet_io_lock); |
275 | outb(7,io); /* Select tuner control */ | 276 | outb(7,io); /* Select tuner control */ |
276 | if(vol>0) | 277 | if(vol>0) |
277 | outb(0x20,io+1); | 278 | outb(0x20,io+1); |
278 | else | 279 | else |
279 | outb(0x00,io+1); | 280 | outb(0x00,io+1); |
280 | spin_unlock(&cadet_io_lock); | 281 | spin_unlock(&cadet_io_lock); |
281 | } | 282 | } |
282 | 283 | ||
283 | static void cadet_handler(unsigned long data) | 284 | static void cadet_handler(unsigned long data) |
284 | { | 285 | { |
@@ -288,15 +289,15 @@ static void cadet_handler(unsigned long data) | |||
288 | 289 | ||
289 | if(spin_trylock(&cadet_io_lock)) | 290 | if(spin_trylock(&cadet_io_lock)) |
290 | { | 291 | { |
291 | outb(0x3,io); /* Select RDS Decoder Control */ | 292 | outb(0x3,io); /* Select RDS Decoder Control */ |
292 | if((inb(io+1)&0x20)!=0) { | 293 | if((inb(io+1)&0x20)!=0) { |
293 | printk(KERN_CRIT "cadet: RDS fifo overflow\n"); | 294 | printk(KERN_CRIT "cadet: RDS fifo overflow\n"); |
294 | } | 295 | } |
295 | outb(0x80,io); /* Select RDS fifo */ | 296 | outb(0x80,io); /* Select RDS fifo */ |
296 | while((inb(io)&0x80)!=0) { | 297 | while((inb(io)&0x80)!=0) { |
297 | rdsbuf[rdsin]=inb(io+1); | 298 | rdsbuf[rdsin]=inb(io+1); |
298 | if(rdsin==rdsout) | 299 | if(rdsin==rdsout) |
299 | printk(KERN_WARNING "cadet: RDS buffer overflow\n"); | 300 | printk(KERN_WARNING "cadet: RDS buffer overflow\n"); |
300 | else | 301 | else |
301 | rdsin++; | 302 | rdsin++; |
302 | } | 303 | } |
@@ -307,9 +308,9 @@ static void cadet_handler(unsigned long data) | |||
307 | * Service pending read | 308 | * Service pending read |
308 | */ | 309 | */ |
309 | if( rdsin!=rdsout) | 310 | if( rdsin!=rdsout) |
310 | wake_up_interruptible(&read_queue); | 311 | wake_up_interruptible(&read_queue); |
311 | 312 | ||
312 | /* | 313 | /* |
313 | * Clean up and exit | 314 | * Clean up and exit |
314 | */ | 315 | */ |
315 | init_timer(&readtimer); | 316 | init_timer(&readtimer); |
@@ -324,12 +325,12 @@ static void cadet_handler(unsigned long data) | |||
324 | static ssize_t cadet_read(struct file *file, char __user *data, | 325 | static ssize_t cadet_read(struct file *file, char __user *data, |
325 | size_t count, loff_t *ppos) | 326 | size_t count, loff_t *ppos) |
326 | { | 327 | { |
327 | int i=0; | 328 | int i=0; |
328 | unsigned char readbuf[RDS_BUFFER]; | 329 | unsigned char readbuf[RDS_BUFFER]; |
329 | 330 | ||
330 | if(rdsstat==0) { | 331 | if(rdsstat==0) { |
331 | spin_lock(&cadet_io_lock); | 332 | spin_lock(&cadet_io_lock); |
332 | rdsstat=1; | 333 | rdsstat=1; |
333 | outb(0x80,io); /* Select RDS fifo */ | 334 | outb(0x80,io); /* Select RDS fifo */ |
334 | spin_unlock(&cadet_io_lock); | 335 | spin_unlock(&cadet_io_lock); |
335 | init_timer(&readtimer); | 336 | init_timer(&readtimer); |
@@ -339,15 +340,15 @@ static ssize_t cadet_read(struct file *file, char __user *data, | |||
339 | add_timer(&readtimer); | 340 | add_timer(&readtimer); |
340 | } | 341 | } |
341 | if(rdsin==rdsout) { | 342 | if(rdsin==rdsout) { |
342 | if (file->f_flags & O_NONBLOCK) | 343 | if (file->f_flags & O_NONBLOCK) |
343 | return -EWOULDBLOCK; | 344 | return -EWOULDBLOCK; |
344 | interruptible_sleep_on(&read_queue); | 345 | interruptible_sleep_on(&read_queue); |
345 | } | 346 | } |
346 | while( i<count && rdsin!=rdsout) | 347 | while( i<count && rdsin!=rdsout) |
347 | readbuf[i++]=rdsbuf[rdsout++]; | 348 | readbuf[i++]=rdsbuf[rdsout++]; |
348 | 349 | ||
349 | if (copy_to_user(data,readbuf,i)) | 350 | if (copy_to_user(data,readbuf,i)) |
350 | return -EFAULT; | 351 | return -EFAULT; |
351 | return i; | 352 | return i; |
352 | } | 353 | } |
353 | 354 | ||
@@ -375,29 +376,29 @@ static int cadet_do_ioctl(struct inode *inode, struct file *file, | |||
375 | return -EINVAL; | 376 | return -EINVAL; |
376 | } | 377 | } |
377 | switch(v->tuner) { | 378 | switch(v->tuner) { |
378 | case 0: | 379 | case 0: |
379 | strcpy(v->name,"FM"); | 380 | strcpy(v->name,"FM"); |
380 | v->rangelow=1400; /* 87.5 MHz */ | 381 | v->rangelow=1400; /* 87.5 MHz */ |
381 | v->rangehigh=1728; /* 108.0 MHz */ | 382 | v->rangehigh=1728; /* 108.0 MHz */ |
382 | v->flags=0; | 383 | v->flags=0; |
383 | v->mode=0; | 384 | v->mode=0; |
384 | v->mode|=VIDEO_MODE_AUTO; | 385 | v->mode|=VIDEO_MODE_AUTO; |
385 | v->signal=sigstrength; | 386 | v->signal=sigstrength; |
386 | if(cadet_getstereo()==1) { | 387 | if(cadet_getstereo()==1) { |
387 | v->flags|=VIDEO_TUNER_STEREO_ON; | 388 | v->flags|=VIDEO_TUNER_STEREO_ON; |
388 | } | 389 | } |
389 | v->flags|=cadet_getrds(); | 390 | v->flags|=cadet_getrds(); |
390 | break; | 391 | break; |
391 | case 1: | 392 | case 1: |
392 | strcpy(v->name,"AM"); | 393 | strcpy(v->name,"AM"); |
393 | v->rangelow=8320; /* 520 kHz */ | 394 | v->rangelow=8320; /* 520 kHz */ |
394 | v->rangehigh=26400; /* 1650 kHz */ | 395 | v->rangehigh=26400; /* 1650 kHz */ |
395 | v->flags=0; | 396 | v->flags=0; |
396 | v->flags|=VIDEO_TUNER_LOW; | 397 | v->flags|=VIDEO_TUNER_LOW; |
397 | v->mode=0; | 398 | v->mode=0; |
398 | v->mode|=VIDEO_MODE_AUTO; | 399 | v->mode|=VIDEO_MODE_AUTO; |
399 | v->signal=sigstrength; | 400 | v->signal=sigstrength; |
400 | break; | 401 | break; |
401 | } | 402 | } |
402 | return 0; | 403 | return 0; |
403 | } | 404 | } |
@@ -407,49 +408,49 @@ static int cadet_do_ioctl(struct inode *inode, struct file *file, | |||
407 | if((v->tuner<0)||(v->tuner>1)) { | 408 | if((v->tuner<0)||(v->tuner>1)) { |
408 | return -EINVAL; | 409 | return -EINVAL; |
409 | } | 410 | } |
410 | curtuner=v->tuner; | 411 | curtuner=v->tuner; |
411 | return 0; | 412 | return 0; |
412 | } | 413 | } |
413 | case VIDIOCGFREQ: | 414 | case VIDIOCGFREQ: |
414 | { | 415 | { |
415 | unsigned long *freq = arg; | 416 | unsigned long *freq = arg; |
416 | *freq = cadet_getfreq(); | 417 | *freq = cadet_getfreq(); |
417 | return 0; | 418 | return 0; |
418 | } | 419 | } |
419 | case VIDIOCSFREQ: | 420 | case VIDIOCSFREQ: |
420 | { | 421 | { |
421 | unsigned long *freq = arg; | 422 | unsigned long *freq = arg; |
422 | if((curtuner==0)&&((*freq<1400)||(*freq>1728))) { | 423 | if((curtuner==0)&&((*freq<1400)||(*freq>1728))) { |
423 | return -EINVAL; | 424 | return -EINVAL; |
424 | } | 425 | } |
425 | if((curtuner==1)&&((*freq<8320)||(*freq>26400))) { | 426 | if((curtuner==1)&&((*freq<8320)||(*freq>26400))) { |
426 | return -EINVAL; | 427 | return -EINVAL; |
427 | } | 428 | } |
428 | cadet_setfreq(*freq); | 429 | cadet_setfreq(*freq); |
429 | return 0; | 430 | return 0; |
430 | } | 431 | } |
431 | case VIDIOCGAUDIO: | 432 | case VIDIOCGAUDIO: |
432 | { | 433 | { |
433 | struct video_audio *v = arg; | 434 | struct video_audio *v = arg; |
434 | memset(v,0, sizeof(*v)); | 435 | memset(v,0, sizeof(*v)); |
435 | v->flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; | 436 | v->flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; |
436 | if(cadet_getstereo()==0) { | 437 | if(cadet_getstereo()==0) { |
437 | v->mode=VIDEO_SOUND_MONO; | 438 | v->mode=VIDEO_SOUND_MONO; |
438 | } else { | 439 | } else { |
439 | v->mode=VIDEO_SOUND_STEREO; | 440 | v->mode=VIDEO_SOUND_STEREO; |
440 | } | 441 | } |
441 | v->volume=cadet_getvol(); | 442 | v->volume=cadet_getvol(); |
442 | v->step=0xffff; | 443 | v->step=0xffff; |
443 | strcpy(v->name, "Radio"); | 444 | strcpy(v->name, "Radio"); |
444 | return 0; | 445 | return 0; |
445 | } | 446 | } |
446 | case VIDIOCSAUDIO: | 447 | case VIDIOCSAUDIO: |
447 | { | 448 | { |
448 | struct video_audio *v = arg; | 449 | struct video_audio *v = arg; |
449 | if(v->audio) | 450 | if(v->audio) |
450 | return -EINVAL; | 451 | return -EINVAL; |
451 | cadet_setvol(v->volume); | 452 | cadet_setvol(v->volume); |
452 | if(v->flags&VIDEO_AUDIO_MUTE) | 453 | if(v->flags&VIDEO_AUDIO_MUTE) |
453 | cadet_setvol(0); | 454 | cadet_setvol(0); |
454 | else | 455 | else |
455 | cadet_setvol(0xffff); | 456 | cadet_setvol(0xffff); |
@@ -539,16 +540,16 @@ static struct pnp_driver cadet_pnp_driver = { | |||
539 | 540 | ||
540 | static int cadet_probe(void) | 541 | static int cadet_probe(void) |
541 | { | 542 | { |
542 | static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e}; | 543 | static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e}; |
543 | int i; | 544 | int i; |
544 | 545 | ||
545 | for(i=0;i<8;i++) { | 546 | for(i=0;i<8;i++) { |
546 | io=iovals[i]; | 547 | io=iovals[i]; |
547 | if (request_region(io, 2, "cadet-probe")) { | 548 | if (request_region(io, 2, "cadet-probe")) { |
548 | cadet_setfreq(1410); | 549 | cadet_setfreq(1410); |
549 | if(cadet_getfreq()==1410) { | 550 | if(cadet_getfreq()==1410) { |
550 | release_region(io, 2); | 551 | release_region(io, 2); |
551 | return io; | 552 | return io; |
552 | } | 553 | } |
553 | release_region(io, 2); | 554 | release_region(io, 2); |
554 | } | 555 | } |
@@ -556,7 +557,7 @@ static int cadet_probe(void) | |||
556 | return -1; | 557 | return -1; |
557 | } | 558 | } |
558 | 559 | ||
559 | /* | 560 | /* |
560 | * io should only be set if the user has used something like | 561 | * io should only be set if the user has used something like |
561 | * isapnp (the userspace program) to initialize this card for us | 562 | * isapnp (the userspace program) to initialize this card for us |
562 | */ | 563 | */ |
@@ -564,7 +565,7 @@ static int cadet_probe(void) | |||
564 | static int __init cadet_init(void) | 565 | static int __init cadet_init(void) |
565 | { | 566 | { |
566 | spin_lock_init(&cadet_io_lock); | 567 | spin_lock_init(&cadet_io_lock); |
567 | 568 | ||
568 | /* | 569 | /* |
569 | * If a probe was requested then probe ISAPnP first (safest) | 570 | * If a probe was requested then probe ISAPnP first (safest) |
570 | */ | 571 | */ |
@@ -579,12 +580,12 @@ static int __init cadet_init(void) | |||
579 | /* | 580 | /* |
580 | * Else we bail out | 581 | * Else we bail out |
581 | */ | 582 | */ |
582 | 583 | ||
583 | if(io < 0) { | 584 | if(io < 0) { |
584 | #ifdef MODULE | 585 | #ifdef MODULE |
585 | printk(KERN_ERR "You must set an I/O address with io=0x???\n"); | 586 | printk(KERN_ERR "You must set an I/O address with io=0x???\n"); |
586 | #endif | 587 | #endif |
587 | goto fail; | 588 | goto fail; |
588 | } | 589 | } |
589 | if (!request_region(io,2,"cadet")) | 590 | if (!request_region(io,2,"cadet")) |
590 | goto fail; | 591 | goto fail; |
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 8e499b8f64c7..9f249e7e60c9 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | *************************************************************************** | 2 | *************************************************************************** |
3 | * | 3 | * |
4 | * radio-gemtek-pci.c - Gemtek PCI Radio driver | 4 | * radio-gemtek-pci.c - Gemtek PCI Radio driver |
5 | * (C) 2001 Vladimir Shebordaev <vshebordaev@mail.ru> | 5 | * (C) 2001 Vladimir Shebordaev <vshebordaev@mail.ru> |
6 | * | 6 | * |
@@ -31,7 +31,7 @@ | |||
31 | * radio device driver. | 31 | * radio device driver. |
32 | * | 32 | * |
33 | * Please, let me know if this piece of code was useful :) | 33 | * Please, let me know if this piece of code was useful :) |
34 | * | 34 | * |
35 | * TODO: multiple device support and portability were not tested | 35 | * TODO: multiple device support and portability were not tested |
36 | * | 36 | * |
37 | *************************************************************************** | 37 | *************************************************************************** |
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
46 | #include <linux/videodev.h> | 46 | #include <linux/videodev.h> |
47 | #include <media/v4l2-common.h> | ||
47 | #include <linux/errno.h> | 48 | #include <linux/errno.h> |
48 | 49 | ||
49 | #include <asm/io.h> | 50 | #include <asm/io.h> |
@@ -69,18 +70,18 @@ | |||
69 | #define TRUE (1) | 70 | #define TRUE (1) |
70 | #endif | 71 | #endif |
71 | 72 | ||
72 | #ifndef FALSE | 73 | #ifndef FALSE |
73 | #define FALSE (0) | 74 | #define FALSE (0) |
74 | #endif | 75 | #endif |
75 | 76 | ||
76 | struct gemtek_pci_card { | 77 | struct gemtek_pci_card { |
77 | struct video_device *videodev; | 78 | struct video_device *videodev; |
78 | 79 | ||
79 | u32 iobase; | 80 | u32 iobase; |
80 | u32 length; | 81 | u32 length; |
81 | u8 chiprev; | 82 | u8 chiprev; |
82 | u16 model; | 83 | u16 model; |
83 | 84 | ||
84 | u32 current_frequency; | 85 | u32 current_frequency; |
85 | u8 mute; | 86 | u8 mute; |
86 | }; | 87 | }; |
@@ -96,7 +97,7 @@ static inline u8 gemtek_pci_out( u16 value, u32 port ) | |||
96 | return (u8)value; | 97 | return (u8)value; |
97 | } | 98 | } |
98 | 99 | ||
99 | #define _b0( v ) *((u8 *)&v) | 100 | #define _b0( v ) *((u8 *)&v) |
100 | static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) | 101 | static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) |
101 | { | 102 | { |
102 | register u8 byte = *last_byte; | 103 | register u8 byte = *last_byte; |
@@ -104,7 +105,7 @@ static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) | |||
104 | if ( !value ) { | 105 | if ( !value ) { |
105 | if ( !keep ) | 106 | if ( !keep ) |
106 | value = (u16)port; | 107 | value = (u16)port; |
107 | byte &= 0xfd; | 108 | byte &= 0xfd; |
108 | } else | 109 | } else |
109 | byte |= 2; | 110 | byte |= 2; |
110 | 111 | ||
@@ -116,7 +117,7 @@ static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) | |||
116 | byte &= 0xfe; | 117 | byte &= 0xfe; |
117 | _b0( value ) = byte; | 118 | _b0( value ) = byte; |
118 | outw( value, port ); | 119 | outw( value, port ); |
119 | 120 | ||
120 | *last_byte = byte; | 121 | *last_byte = byte; |
121 | } | 122 | } |
122 | 123 | ||
@@ -193,13 +194,13 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, | |||
193 | c->audios = 1; | 194 | c->audios = 1; |
194 | strcpy( c->name, "Gemtek PCI Radio" ); | 195 | strcpy( c->name, "Gemtek PCI Radio" ); |
195 | return 0; | 196 | return 0; |
196 | } | 197 | } |
197 | 198 | ||
198 | case VIDIOCGTUNER: | 199 | case VIDIOCGTUNER: |
199 | { | 200 | { |
200 | struct video_tuner *t = arg; | 201 | struct video_tuner *t = arg; |
201 | 202 | ||
202 | if ( t->tuner ) | 203 | if ( t->tuner ) |
203 | return -EINVAL; | 204 | return -EINVAL; |
204 | 205 | ||
205 | t->rangelow = GEMTEK_PCI_RANGE_LOW; | 206 | t->rangelow = GEMTEK_PCI_RANGE_LOW; |
@@ -228,7 +229,7 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, | |||
228 | case VIDIOCSFREQ: | 229 | case VIDIOCSFREQ: |
229 | { | 230 | { |
230 | unsigned long *freq = arg; | 231 | unsigned long *freq = arg; |
231 | 232 | ||
232 | if ( (*freq < GEMTEK_PCI_RANGE_LOW) || | 233 | if ( (*freq < GEMTEK_PCI_RANGE_LOW) || |
233 | (*freq > GEMTEK_PCI_RANGE_HIGH) ) | 234 | (*freq > GEMTEK_PCI_RANGE_HIGH) ) |
234 | return -EINVAL; | 235 | return -EINVAL; |
@@ -239,9 +240,9 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, | |||
239 | 240 | ||
240 | return 0; | 241 | return 0; |
241 | } | 242 | } |
242 | 243 | ||
243 | case VIDIOCGAUDIO: | 244 | case VIDIOCGAUDIO: |
244 | { | 245 | { |
245 | struct video_audio *a = arg; | 246 | struct video_audio *a = arg; |
246 | 247 | ||
247 | memset( a, 0, sizeof( *a ) ); | 248 | memset( a, 0, sizeof( *a ) ); |
@@ -249,17 +250,17 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, | |||
249 | a->volume = 1; | 250 | a->volume = 1; |
250 | a->step = 65535; | 251 | a->step = 65535; |
251 | strcpy( a->name, "Radio" ); | 252 | strcpy( a->name, "Radio" ); |
252 | return 0; | 253 | return 0; |
253 | } | 254 | } |
254 | 255 | ||
255 | case VIDIOCSAUDIO: | 256 | case VIDIOCSAUDIO: |
256 | { | 257 | { |
257 | struct video_audio *a = arg; | 258 | struct video_audio *a = arg; |
258 | 259 | ||
259 | if ( a->audio ) | 260 | if ( a->audio ) |
260 | return -EINVAL; | 261 | return -EINVAL; |
261 | 262 | ||
262 | if ( a->flags & VIDEO_AUDIO_MUTE ) | 263 | if ( a->flags & VIDEO_AUDIO_MUTE ) |
263 | gemtek_pci_mute( card ); | 264 | gemtek_pci_mute( card ); |
264 | else | 265 | else |
265 | gemtek_pci_unmute( card ); | 266 | gemtek_pci_unmute( card ); |
@@ -323,9 +324,9 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci | |||
323 | return -ENOMEM; | 324 | return -ENOMEM; |
324 | } | 325 | } |
325 | 326 | ||
326 | if ( pci_enable_device( pci_dev ) ) | 327 | if ( pci_enable_device( pci_dev ) ) |
327 | goto err_pci; | 328 | goto err_pci; |
328 | 329 | ||
329 | card->iobase = pci_resource_start( pci_dev, 0 ); | 330 | card->iobase = pci_resource_start( pci_dev, 0 ); |
330 | card->length = pci_resource_len( pci_dev, 0 ); | 331 | card->length = pci_resource_len( pci_dev, 0 ); |
331 | 332 | ||
@@ -338,7 +339,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci | |||
338 | pci_read_config_word( pci_dev, PCI_SUBSYSTEM_ID, &card->model ); | 339 | pci_read_config_word( pci_dev, PCI_SUBSYSTEM_ID, &card->model ); |
339 | 340 | ||
340 | pci_set_drvdata( pci_dev, card ); | 341 | pci_set_drvdata( pci_dev, card ); |
341 | 342 | ||
342 | if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) { | 343 | if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) { |
343 | printk( KERN_ERR "gemtek_pci: out of memory\n" ); | 344 | printk( KERN_ERR "gemtek_pci: out of memory\n" ); |
344 | goto err_video; | 345 | goto err_video; |
@@ -354,7 +355,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci | |||
354 | devradio->priv = card; | 355 | devradio->priv = card; |
355 | gemtek_pci_mute( card ); | 356 | gemtek_pci_mute( card ); |
356 | 357 | ||
357 | printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", | 358 | printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", |
358 | card->chiprev, card->iobase, card->iobase + card->length - 1 ); | 359 | card->chiprev, card->iobase, card->iobase + card->length - 1 ); |
359 | 360 | ||
360 | return 0; | 361 | return 0; |
@@ -364,7 +365,7 @@ err_video: | |||
364 | 365 | ||
365 | err_pci: | 366 | err_pci: |
366 | kfree( card ); | 367 | kfree( card ); |
367 | return -ENODEV; | 368 | return -ENODEV; |
368 | } | 369 | } |
369 | 370 | ||
370 | static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev ) | 371 | static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev ) |
@@ -375,12 +376,12 @@ static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev ) | |||
375 | kfree( card->videodev ); | 376 | kfree( card->videodev ); |
376 | 377 | ||
377 | release_region( card->iobase, card->length ); | 378 | release_region( card->iobase, card->length ); |
378 | 379 | ||
379 | if ( mx ) | 380 | if ( mx ) |
380 | gemtek_pci_mute( card ); | 381 | gemtek_pci_mute( card ); |
381 | 382 | ||
382 | kfree( card ); | 383 | kfree( card ); |
383 | 384 | ||
384 | pci_set_drvdata( pci_dev, NULL ); | 385 | pci_set_drvdata( pci_dev, NULL ); |
385 | } | 386 | } |
386 | 387 | ||
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 47173be97b9f..162f37d8bf96 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Besides the protocol changes, this is mostly a copy of: | 6 | * Besides the protocol changes, this is mostly a copy of: |
7 | * | 7 | * |
8 | * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff | 8 | * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff |
9 | * | 9 | * |
10 | * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood | 10 | * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood |
11 | * Converted to new API by Alan Cox <Alan.Cox@linux.org> | 11 | * Converted to new API by Alan Cox <Alan.Cox@linux.org> |
12 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> | 12 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> |
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/io.h> /* outb, outb_p */ | 22 | #include <asm/io.h> /* outb, outb_p */ |
23 | #include <asm/uaccess.h> /* copy to/from user */ | 23 | #include <asm/uaccess.h> /* copy to/from user */ |
24 | #include <linux/videodev.h> /* kernel radio structs */ | 24 | #include <linux/videodev.h> /* kernel radio structs */ |
25 | #include <media/v4l2-common.h> | ||
25 | #include <linux/config.h> /* CONFIG_RADIO_GEMTEK_PORT */ | 26 | #include <linux/config.h> /* CONFIG_RADIO_GEMTEK_PORT */ |
26 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
27 | 28 | ||
@@ -29,7 +30,7 @@ | |||
29 | #define CONFIG_RADIO_GEMTEK_PORT -1 | 30 | #define CONFIG_RADIO_GEMTEK_PORT -1 |
30 | #endif | 31 | #endif |
31 | 32 | ||
32 | static int io = CONFIG_RADIO_GEMTEK_PORT; | 33 | static int io = CONFIG_RADIO_GEMTEK_PORT; |
33 | static int radio_nr = -1; | 34 | static int radio_nr = -1; |
34 | static spinlock_t lock; | 35 | static spinlock_t lock; |
35 | 36 | ||
@@ -48,7 +49,7 @@ struct gemtek_device | |||
48 | */ | 49 | */ |
49 | static void gemtek_mute(struct gemtek_device *dev) | 50 | static void gemtek_mute(struct gemtek_device *dev) |
50 | { | 51 | { |
51 | if(dev->muted) | 52 | if(dev->muted) |
52 | return; | 53 | return; |
53 | spin_lock(&lock); | 54 | spin_lock(&lock); |
54 | outb(0x10, io); | 55 | outb(0x10, io); |
@@ -94,20 +95,20 @@ static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq) | |||
94 | freq /= 100000; | 95 | freq /= 100000; |
95 | 96 | ||
96 | spin_lock(&lock); | 97 | spin_lock(&lock); |
97 | 98 | ||
98 | /* 2 start bits */ | 99 | /* 2 start bits */ |
99 | outb_p(0x03, io); | 100 | outb_p(0x03, io); |
100 | udelay(5); | 101 | udelay(5); |
101 | outb_p(0x07, io); | 102 | outb_p(0x07, io); |
102 | udelay(5); | 103 | udelay(5); |
103 | 104 | ||
104 | /* 28 frequency bits (lsb first) */ | 105 | /* 28 frequency bits (lsb first) */ |
105 | for (i = 0; i < 14; i++) | 106 | for (i = 0; i < 14; i++) |
106 | if (freq & (1 << i)) | 107 | if (freq & (1 << i)) |
107 | one(); | 108 | one(); |
108 | else | 109 | else |
109 | zero(); | 110 | zero(); |
110 | /* 36 unknown bits */ | 111 | /* 36 unknown bits */ |
111 | for (i = 0; i < 11; i++) | 112 | for (i = 0; i < 11; i++) |
112 | zero(); | 113 | zero(); |
113 | one(); | 114 | one(); |
@@ -123,7 +124,7 @@ static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq) | |||
123 | udelay(5); | 124 | udelay(5); |
124 | 125 | ||
125 | spin_unlock(&lock); | 126 | spin_unlock(&lock); |
126 | 127 | ||
127 | return 0; | 128 | return 0; |
128 | } | 129 | } |
129 | 130 | ||
@@ -159,7 +160,7 @@ static int gemtek_do_ioctl(struct inode *inode, struct file *file, | |||
159 | case VIDIOCGTUNER: | 160 | case VIDIOCGTUNER: |
160 | { | 161 | { |
161 | struct video_tuner *v = arg; | 162 | struct video_tuner *v = arg; |
162 | if(v->tuner) /* Only 1 tuner */ | 163 | if(v->tuner) /* Only 1 tuner */ |
163 | return -EINVAL; | 164 | return -EINVAL; |
164 | v->rangelow=87*16000; | 165 | v->rangelow=87*16000; |
165 | v->rangehigh=108*16000; | 166 | v->rangehigh=108*16000; |
@@ -193,25 +194,25 @@ static int gemtek_do_ioctl(struct inode *inode, struct file *file, | |||
193 | return 0; | 194 | return 0; |
194 | } | 195 | } |
195 | case VIDIOCGAUDIO: | 196 | case VIDIOCGAUDIO: |
196 | { | 197 | { |
197 | struct video_audio *v = arg; | 198 | struct video_audio *v = arg; |
198 | memset(v,0, sizeof(*v)); | 199 | memset(v,0, sizeof(*v)); |
199 | v->flags|=VIDEO_AUDIO_MUTABLE; | 200 | v->flags|=VIDEO_AUDIO_MUTABLE; |
200 | v->volume=1; | 201 | v->volume=1; |
201 | v->step=65535; | 202 | v->step=65535; |
202 | strcpy(v->name, "Radio"); | 203 | strcpy(v->name, "Radio"); |
203 | return 0; | 204 | return 0; |
204 | } | 205 | } |
205 | case VIDIOCSAUDIO: | 206 | case VIDIOCSAUDIO: |
206 | { | 207 | { |
207 | struct video_audio *v = arg; | 208 | struct video_audio *v = arg; |
208 | if(v->audio) | 209 | if(v->audio) |
209 | return -EINVAL; | 210 | return -EINVAL; |
210 | 211 | ||
211 | if(v->flags&VIDEO_AUDIO_MUTE) | 212 | if(v->flags&VIDEO_AUDIO_MUTE) |
212 | gemtek_mute(rt); | 213 | gemtek_mute(rt); |
213 | else | 214 | else |
214 | gemtek_unmute(rt); | 215 | gemtek_unmute(rt); |
215 | 216 | ||
216 | return 0; | 217 | return 0; |
217 | } | 218 | } |
@@ -254,14 +255,14 @@ static int __init gemtek_init(void) | |||
254 | return -EINVAL; | 255 | return -EINVAL; |
255 | } | 256 | } |
256 | 257 | ||
257 | if (!request_region(io, 4, "gemtek")) | 258 | if (!request_region(io, 4, "gemtek")) |
258 | { | 259 | { |
259 | printk(KERN_ERR "gemtek: port 0x%x already in use\n", io); | 260 | printk(KERN_ERR "gemtek: port 0x%x already in use\n", io); |
260 | return -EBUSY; | 261 | return -EBUSY; |
261 | } | 262 | } |
262 | 263 | ||
263 | gemtek_radio.priv=&gemtek_unit; | 264 | gemtek_radio.priv=&gemtek_unit; |
264 | 265 | ||
265 | if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr)==-1) | 266 | if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr)==-1) |
266 | { | 267 | { |
267 | release_region(io, 4); | 268 | release_region(io, 4); |
@@ -274,7 +275,7 @@ static int __init gemtek_init(void) | |||
274 | /* this is _maybe_ unnecessary */ | 275 | /* this is _maybe_ unnecessary */ |
275 | outb(0x01, io); | 276 | outb(0x01, io); |
276 | 277 | ||
277 | /* mute card - prevents noisy bootups */ | 278 | /* mute card - prevents noisy bootups */ |
278 | gemtek_unit.muted = 0; | 279 | gemtek_unit.muted = 0; |
279 | gemtek_mute(&gemtek_unit); | 280 | gemtek_mute(&gemtek_unit); |
280 | 281 | ||
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 39c1d9118636..fcfa6c9fe225 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * (c) 2000 A. Tlalka, atlka@pg.gda.pl | 2 | * (c) 2000 A. Tlalka, atlka@pg.gda.pl |
3 | * Notes on the hardware | 3 | * Notes on the hardware |
4 | * | 4 | * |
5 | * + Frequency control is done digitally | 5 | * + Frequency control is done digitally |
6 | * + No volume control - only mute/unmute - you have to use Aux line volume | 6 | * + No volume control - only mute/unmute - you have to use Aux line volume |
7 | * control on Maestro card to set the volume | 7 | * control on Maestro card to set the volume |
8 | * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after | 8 | * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after |
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/videodev.h> | 28 | #include <linux/videodev.h> |
29 | 29 | #include <media/v4l2-common.h> | |
30 | 30 | ||
31 | #define DRIVER_VERSION "0.05" | 31 | #define DRIVER_VERSION "0.05" |
32 | 32 | ||
@@ -103,7 +103,7 @@ static struct video_device maestro_radio = { | |||
103 | struct radio_device { | 103 | struct radio_device { |
104 | u16 io, /* base of Maestro card radio io (GPIO_DATA)*/ | 104 | u16 io, /* base of Maestro card radio io (GPIO_DATA)*/ |
105 | muted, /* VIDEO_AUDIO_MUTE */ | 105 | muted, /* VIDEO_AUDIO_MUTE */ |
106 | stereo, /* VIDEO_TUNER_STEREO_ON */ | 106 | stereo, /* VIDEO_TUNER_STEREO_ON */ |
107 | tuned; /* signal strength (0 or 0xffff) */ | 107 | tuned; /* signal strength (0 or 0xffff) */ |
108 | struct mutex lock; | 108 | struct mutex lock; |
109 | }; | 109 | }; |
@@ -122,14 +122,14 @@ static u32 radio_bits_get(struct radio_device *dev) | |||
122 | for (l=24;l--;) { | 122 | for (l=24;l--;) { |
123 | outw(STR_CLK, io); /* HI state */ | 123 | outw(STR_CLK, io); /* HI state */ |
124 | udelay(2); | 124 | udelay(2); |
125 | if(!l) | 125 | if(!l) |
126 | dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff; | 126 | dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff; |
127 | outw(0, io); /* LO state */ | 127 | outw(0, io); /* LO state */ |
128 | udelay(2); | 128 | udelay(2); |
129 | data <<= 1; /* shift data */ | 129 | data <<= 1; /* shift data */ |
130 | rdata = inw(io); | 130 | rdata = inw(io); |
131 | if(!l) | 131 | if(!l) |
132 | dev->stereo = rdata & STR_MOST ? | 132 | dev->stereo = rdata & STR_MOST ? |
133 | 0 : VIDEO_TUNER_STEREO_ON; | 133 | 0 : VIDEO_TUNER_STEREO_ON; |
134 | else | 134 | else |
135 | if(rdata & STR_DATA) | 135 | if(rdata & STR_DATA) |
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index f0bf47bcb64c..f93d7afe7304 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c | |||
@@ -1,15 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux | 2 | * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux |
3 | * (C) 2001 Dimitromanolakis Apostolos <apdim@grecian.net> | 3 | * (C) 2001 Dimitromanolakis Apostolos <apdim@grecian.net> |
4 | * | 4 | * |
5 | * Based in the radio Maestro PCI driver. Actually it uses the same chip | 5 | * Based in the radio Maestro PCI driver. Actually it uses the same chip |
6 | * for radio but different pci controller. | 6 | * for radio but different pci controller. |
7 | * | 7 | * |
8 | * I didn't have any specs I reversed engineered the protocol from | 8 | * I didn't have any specs I reversed engineered the protocol from |
9 | * the windows driver (radio.dll). | 9 | * the windows driver (radio.dll). |
10 | * | 10 | * |
11 | * The card uses the TEA5757 chip that includes a search function but it | 11 | * The card uses the TEA5757 chip that includes a search function but it |
12 | * is useless as I haven't found any way to read back the frequency. If | 12 | * is useless as I haven't found any way to read back the frequency. If |
13 | * anybody does please mail me. | 13 | * anybody does please mail me. |
14 | * | 14 | * |
15 | * For the pdf file see: | 15 | * For the pdf file see: |
@@ -24,7 +24,7 @@ | |||
24 | * - tiding up | 24 | * - tiding up |
25 | * - removed support for multiple devices as it didn't work anyway | 25 | * - removed support for multiple devices as it didn't work anyway |
26 | * | 26 | * |
27 | * BUGS: | 27 | * BUGS: |
28 | * - card unmutes if you change frequency | 28 | * - card unmutes if you change frequency |
29 | * | 29 | * |
30 | */ | 30 | */ |
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | #include <linux/pci.h> | 42 | #include <linux/pci.h> |
43 | #include <linux/videodev.h> | 43 | #include <linux/videodev.h> |
44 | #include <media/v4l2-common.h> | ||
44 | 45 | ||
45 | /* version 0.75 Sun Feb 4 22:51:27 EET 2001 */ | 46 | /* version 0.75 Sun Feb 4 22:51:27 EET 2001 */ |
46 | #define DRIVER_VERSION "0.75" | 47 | #define DRIVER_VERSION "0.75" |
@@ -80,7 +81,7 @@ static struct file_operations maxiradio_fops = { | |||
80 | .owner = THIS_MODULE, | 81 | .owner = THIS_MODULE, |
81 | .open = video_exclusive_open, | 82 | .open = video_exclusive_open, |
82 | .release = video_exclusive_release, | 83 | .release = video_exclusive_release, |
83 | .ioctl = radio_ioctl, | 84 | .ioctl = radio_ioctl, |
84 | .compat_ioctl = v4l_compat_ioctl32, | 85 | .compat_ioctl = v4l_compat_ioctl32, |
85 | .llseek = no_llseek, | 86 | .llseek = no_llseek, |
86 | }; | 87 | }; |
@@ -97,11 +98,11 @@ static struct radio_device | |||
97 | { | 98 | { |
98 | __u16 io, /* base of radio io */ | 99 | __u16 io, /* base of radio io */ |
99 | muted, /* VIDEO_AUDIO_MUTE */ | 100 | muted, /* VIDEO_AUDIO_MUTE */ |
100 | stereo, /* VIDEO_TUNER_STEREO_ON */ | 101 | stereo, /* VIDEO_TUNER_STEREO_ON */ |
101 | tuned; /* signal strength (0 or 0xffff) */ | 102 | tuned; /* signal strength (0 or 0xffff) */ |
102 | 103 | ||
103 | unsigned long freq; | 104 | unsigned long freq; |
104 | 105 | ||
105 | struct mutex lock; | 106 | struct mutex lock; |
106 | } radio_unit = {0, 0, 0, 0, }; | 107 | } radio_unit = {0, 0, 0, 0, }; |
107 | 108 | ||
@@ -114,7 +115,7 @@ static void outbit(unsigned long bit, __u16 io) | |||
114 | outb( power|wren|data|clk ,io); udelay(4); | 115 | outb( power|wren|data|clk ,io); udelay(4); |
115 | outb( power|wren|data ,io); udelay(4); | 116 | outb( power|wren|data ,io); udelay(4); |
116 | } | 117 | } |
117 | else | 118 | else |
118 | { | 119 | { |
119 | outb( power|wren ,io); udelay(4); | 120 | outb( power|wren ,io); udelay(4); |
120 | outb( power|wren|clk ,io); udelay(4); | 121 | outb( power|wren|clk ,io); udelay(4); |
@@ -132,12 +133,12 @@ static void set_freq(__u16 io, __u32 data) | |||
132 | { | 133 | { |
133 | unsigned long int si; | 134 | unsigned long int si; |
134 | int bl; | 135 | int bl; |
135 | 136 | ||
136 | /* TEA5757 shift register bits (see pdf) */ | 137 | /* TEA5757 shift register bits (see pdf) */ |
137 | 138 | ||
138 | outbit(0,io); // 24 search | 139 | outbit(0,io); // 24 search |
139 | outbit(1,io); // 23 search up/down | 140 | outbit(1,io); // 23 search up/down |
140 | 141 | ||
141 | outbit(0,io); // 22 stereo/mono | 142 | outbit(0,io); // 22 stereo/mono |
142 | 143 | ||
143 | outbit(0,io); // 21 band | 144 | outbit(0,io); // 21 band |
@@ -145,24 +146,24 @@ static void set_freq(__u16 io, __u32 data) | |||
145 | 146 | ||
146 | outbit(0,io); // 19 port ? | 147 | outbit(0,io); // 19 port ? |
147 | outbit(0,io); // 18 port ? | 148 | outbit(0,io); // 18 port ? |
148 | 149 | ||
149 | outbit(0,io); // 17 search level | 150 | outbit(0,io); // 17 search level |
150 | outbit(0,io); // 16 search level | 151 | outbit(0,io); // 16 search level |
151 | 152 | ||
152 | si = 0x8000; | 153 | si = 0x8000; |
153 | for(bl = 1; bl <= 16 ; bl++) { outbit(data & si,io); si >>=1; } | 154 | for(bl = 1; bl <= 16 ; bl++) { outbit(data & si,io); si >>=1; } |
154 | 155 | ||
155 | outb(power,io); | 156 | outb(power,io); |
156 | } | 157 | } |
157 | 158 | ||
158 | static int get_stereo(__u16 io) | 159 | static int get_stereo(__u16 io) |
159 | { | 160 | { |
160 | outb(power,io); udelay(4); | 161 | outb(power,io); udelay(4); |
161 | return !(inb(io) & mo_st); | 162 | return !(inb(io) & mo_st); |
162 | } | 163 | } |
163 | 164 | ||
164 | static int get_tune(__u16 io) | 165 | static int get_tune(__u16 io) |
165 | { | 166 | { |
166 | outb(power+clk,io); udelay(4); | 167 | outb(power+clk,io); udelay(4); |
167 | return !(inb(io) & mo_st); | 168 | return !(inb(io) & mo_st); |
168 | } | 169 | } |
@@ -177,7 +178,7 @@ static inline int radio_function(struct inode *inode, struct file *file, | |||
177 | switch(cmd) { | 178 | switch(cmd) { |
178 | case VIDIOCGCAP: { | 179 | case VIDIOCGCAP: { |
179 | struct video_capability *v = arg; | 180 | struct video_capability *v = arg; |
180 | 181 | ||
181 | memset(v,0,sizeof(*v)); | 182 | memset(v,0,sizeof(*v)); |
182 | strcpy(v->name, "Maxi Radio FM2000 radio"); | 183 | strcpy(v->name, "Maxi Radio FM2000 radio"); |
183 | v->type=VID_TYPE_TUNER; | 184 | v->type=VID_TYPE_TUNER; |
@@ -186,22 +187,22 @@ static inline int radio_function(struct inode *inode, struct file *file, | |||
186 | } | 187 | } |
187 | case VIDIOCGTUNER: { | 188 | case VIDIOCGTUNER: { |
188 | struct video_tuner *v = arg; | 189 | struct video_tuner *v = arg; |
189 | 190 | ||
190 | if(v->tuner) | 191 | if(v->tuner) |
191 | return -EINVAL; | 192 | return -EINVAL; |
192 | 193 | ||
193 | card->stereo = 0xffff * get_stereo(card->io); | 194 | card->stereo = 0xffff * get_stereo(card->io); |
194 | card->tuned = 0xffff * get_tune(card->io); | 195 | card->tuned = 0xffff * get_tune(card->io); |
195 | 196 | ||
196 | v->flags = VIDEO_TUNER_LOW | card->stereo; | 197 | v->flags = VIDEO_TUNER_LOW | card->stereo; |
197 | v->signal = card->tuned; | 198 | v->signal = card->tuned; |
198 | 199 | ||
199 | strcpy(v->name, "FM"); | 200 | strcpy(v->name, "FM"); |
200 | 201 | ||
201 | v->rangelow = FREQ_LO; | 202 | v->rangelow = FREQ_LO; |
202 | v->rangehigh = FREQ_HI; | 203 | v->rangehigh = FREQ_HI; |
203 | v->mode = VIDEO_MODE_AUTO; | 204 | v->mode = VIDEO_MODE_AUTO; |
204 | 205 | ||
205 | return 0; | 206 | return 0; |
206 | } | 207 | } |
207 | case VIDIOCSTUNER: { | 208 | case VIDIOCSTUNER: { |
@@ -212,13 +213,13 @@ static inline int radio_function(struct inode *inode, struct file *file, | |||
212 | } | 213 | } |
213 | case VIDIOCGFREQ: { | 214 | case VIDIOCGFREQ: { |
214 | unsigned long *freq = arg; | 215 | unsigned long *freq = arg; |
215 | 216 | ||
216 | *freq = card->freq; | 217 | *freq = card->freq; |
217 | return 0; | 218 | return 0; |
218 | } | 219 | } |
219 | case VIDIOCSFREQ: { | 220 | case VIDIOCSFREQ: { |
220 | unsigned long *freq = arg; | 221 | unsigned long *freq = arg; |
221 | 222 | ||
222 | if (*freq < FREQ_LO || *freq > FREQ_HI) | 223 | if (*freq < FREQ_LO || *freq > FREQ_HI) |
223 | return -EINVAL; | 224 | return -EINVAL; |
224 | card->freq = *freq; | 225 | card->freq = *freq; |
@@ -226,18 +227,18 @@ static inline int radio_function(struct inode *inode, struct file *file, | |||
226 | msleep(125); | 227 | msleep(125); |
227 | return 0; | 228 | return 0; |
228 | } | 229 | } |
229 | case VIDIOCGAUDIO: { | 230 | case VIDIOCGAUDIO: { |
230 | struct video_audio *v = arg; | 231 | struct video_audio *v = arg; |
231 | memset(v,0,sizeof(*v)); | 232 | memset(v,0,sizeof(*v)); |
232 | strcpy(v->name, "Radio"); | 233 | strcpy(v->name, "Radio"); |
233 | v->flags=VIDEO_AUDIO_MUTABLE | card->muted; | 234 | v->flags=VIDEO_AUDIO_MUTABLE | card->muted; |
234 | v->mode=VIDEO_SOUND_STEREO; | 235 | v->mode=VIDEO_SOUND_STEREO; |
235 | return 0; | 236 | return 0; |
236 | } | 237 | } |
237 | 238 | ||
238 | case VIDIOCSAUDIO: { | 239 | case VIDIOCSAUDIO: { |
239 | struct video_audio *v = arg; | 240 | struct video_audio *v = arg; |
240 | 241 | ||
241 | if(v->audio) | 242 | if(v->audio) |
242 | return -EINVAL; | 243 | return -EINVAL; |
243 | card->muted = v->flags & VIDEO_AUDIO_MUTE; | 244 | card->muted = v->flags & VIDEO_AUDIO_MUTE; |
@@ -249,13 +250,13 @@ static inline int radio_function(struct inode *inode, struct file *file, | |||
249 | } | 250 | } |
250 | case VIDIOCGUNIT: { | 251 | case VIDIOCGUNIT: { |
251 | struct video_unit *v = arg; | 252 | struct video_unit *v = arg; |
252 | 253 | ||
253 | v->video=VIDEO_NO_UNIT; | 254 | v->video=VIDEO_NO_UNIT; |
254 | v->vbi=VIDEO_NO_UNIT; | 255 | v->vbi=VIDEO_NO_UNIT; |
255 | v->radio=dev->minor; | 256 | v->radio=dev->minor; |
256 | v->audio=0; | 257 | v->audio=0; |
257 | v->teletext=VIDEO_NO_UNIT; | 258 | v->teletext=VIDEO_NO_UNIT; |
258 | return 0; | 259 | return 0; |
259 | } | 260 | } |
260 | default: return -ENOIOCTLCMD; | 261 | default: return -ENOIOCTLCMD; |
261 | } | 262 | } |
@@ -267,7 +268,7 @@ static int radio_ioctl(struct inode *inode, struct file *file, | |||
267 | struct video_device *dev = video_devdata(file); | 268 | struct video_device *dev = video_devdata(file); |
268 | struct radio_device *card=dev->priv; | 269 | struct radio_device *card=dev->priv; |
269 | int ret; | 270 | int ret; |
270 | 271 | ||
271 | mutex_lock(&card->lock); | 272 | mutex_lock(&card->lock); |
272 | ret = video_usercopy(inode, file, cmd, arg, radio_function); | 273 | ret = video_usercopy(inode, file, cmd, arg, radio_function); |
273 | mutex_unlock(&card->lock); | 274 | mutex_unlock(&card->lock); |
@@ -282,21 +283,21 @@ MODULE_LICENSE("GPL"); | |||
282 | static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 283 | static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
283 | { | 284 | { |
284 | if(!request_region(pci_resource_start(pdev, 0), | 285 | if(!request_region(pci_resource_start(pdev, 0), |
285 | pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) { | 286 | pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) { |
286 | printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n"); | 287 | printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n"); |
287 | goto err_out; | 288 | goto err_out; |
288 | } | 289 | } |
289 | 290 | ||
290 | if (pci_enable_device(pdev)) | 291 | if (pci_enable_device(pdev)) |
291 | goto err_out_free_region; | 292 | goto err_out_free_region; |
292 | 293 | ||
293 | radio_unit.io = pci_resource_start(pdev, 0); | 294 | radio_unit.io = pci_resource_start(pdev, 0); |
294 | mutex_init(&radio_unit.lock); | 295 | mutex_init(&radio_unit.lock); |
295 | maxiradio_radio.priv = &radio_unit; | 296 | maxiradio_radio.priv = &radio_unit; |
296 | 297 | ||
297 | if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { | 298 | if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { |
298 | printk("radio-maxiradio: can't register device!"); | 299 | printk("radio-maxiradio: can't register device!"); |
299 | goto err_out_free_region; | 300 | goto err_out_free_region; |
300 | } | 301 | } |
301 | 302 | ||
302 | printk(KERN_INFO "radio-maxiradio: version " | 303 | printk(KERN_INFO "radio-maxiradio: version " |
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index 28a47c9e7a81..5b68ac4c7322 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff | 1 | /* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff |
2 | * | 2 | * |
3 | * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood | 3 | * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood |
4 | * Converted to new API by Alan Cox <Alan.Cox@linux.org> | 4 | * Converted to new API by Alan Cox <Alan.Cox@linux.org> |
5 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> | 5 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> |
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/io.h> /* outb, outb_p */ | 15 | #include <asm/io.h> /* outb, outb_p */ |
16 | #include <asm/uaccess.h> /* copy to/from user */ | 16 | #include <asm/uaccess.h> /* copy to/from user */ |
17 | #include <linux/videodev.h> /* kernel radio structs */ | 17 | #include <linux/videodev.h> /* kernel radio structs */ |
18 | #include <media/v4l2-common.h> | ||
18 | #include <linux/config.h> /* CONFIG_RADIO_RTRACK2_PORT */ | 19 | #include <linux/config.h> /* CONFIG_RADIO_RTRACK2_PORT */ |
19 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
20 | 21 | ||
@@ -22,7 +23,7 @@ | |||
22 | #define CONFIG_RADIO_RTRACK2_PORT -1 | 23 | #define CONFIG_RADIO_RTRACK2_PORT -1 |
23 | #endif | 24 | #endif |
24 | 25 | ||
25 | static int io = CONFIG_RADIO_RTRACK2_PORT; | 26 | static int io = CONFIG_RADIO_RTRACK2_PORT; |
26 | static int radio_nr = -1; | 27 | static int radio_nr = -1; |
27 | static spinlock_t lock; | 28 | static spinlock_t lock; |
28 | 29 | ||
@@ -38,7 +39,7 @@ struct rt_device | |||
38 | 39 | ||
39 | static void rt_mute(struct rt_device *dev) | 40 | static void rt_mute(struct rt_device *dev) |
40 | { | 41 | { |
41 | if(dev->muted) | 42 | if(dev->muted) |
42 | return; | 43 | return; |
43 | spin_lock(&lock); | 44 | spin_lock(&lock); |
44 | outb(1, io); | 45 | outb(1, io); |
@@ -58,14 +59,14 @@ static void rt_unmute(struct rt_device *dev) | |||
58 | 59 | ||
59 | static void zero(void) | 60 | static void zero(void) |
60 | { | 61 | { |
61 | outb_p(1, io); | 62 | outb_p(1, io); |
62 | outb_p(3, io); | 63 | outb_p(3, io); |
63 | outb_p(1, io); | 64 | outb_p(1, io); |
64 | } | 65 | } |
65 | 66 | ||
66 | static void one(void) | 67 | static void one(void) |
67 | { | 68 | { |
68 | outb_p(5, io); | 69 | outb_p(5, io); |
69 | outb_p(7, io); | 70 | outb_p(7, io); |
70 | outb_p(5, io); | 71 | outb_p(5, io); |
71 | } | 72 | } |
@@ -75,7 +76,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) | |||
75 | int i; | 76 | int i; |
76 | 77 | ||
77 | freq = freq / 200 + 856; | 78 | freq = freq / 200 + 856; |
78 | 79 | ||
79 | spin_lock(&lock); | 80 | spin_lock(&lock); |
80 | 81 | ||
81 | outb_p(0xc8, io); | 82 | outb_p(0xc8, io); |
@@ -94,7 +95,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) | |||
94 | outb_p(0xc8, io); | 95 | outb_p(0xc8, io); |
95 | if (!dev->muted) | 96 | if (!dev->muted) |
96 | outb_p(0, io); | 97 | outb_p(0, io); |
97 | 98 | ||
98 | spin_unlock(&lock); | 99 | spin_unlock(&lock); |
99 | return 0; | 100 | return 0; |
100 | } | 101 | } |
@@ -127,7 +128,7 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, | |||
127 | case VIDIOCGTUNER: | 128 | case VIDIOCGTUNER: |
128 | { | 129 | { |
129 | struct video_tuner *v = arg; | 130 | struct video_tuner *v = arg; |
130 | if(v->tuner) /* Only 1 tuner */ | 131 | if(v->tuner) /* Only 1 tuner */ |
131 | return -EINVAL; | 132 | return -EINVAL; |
132 | v->rangelow=88*16000; | 133 | v->rangelow=88*16000; |
133 | v->rangehigh=108*16000; | 134 | v->rangehigh=108*16000; |
@@ -159,25 +160,25 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, | |||
159 | return 0; | 160 | return 0; |
160 | } | 161 | } |
161 | case VIDIOCGAUDIO: | 162 | case VIDIOCGAUDIO: |
162 | { | 163 | { |
163 | struct video_audio *v = arg; | 164 | struct video_audio *v = arg; |
164 | memset(v,0, sizeof(*v)); | 165 | memset(v,0, sizeof(*v)); |
165 | v->flags|=VIDEO_AUDIO_MUTABLE; | 166 | v->flags|=VIDEO_AUDIO_MUTABLE; |
166 | v->volume=1; | 167 | v->volume=1; |
167 | v->step=65535; | 168 | v->step=65535; |
168 | strcpy(v->name, "Radio"); | 169 | strcpy(v->name, "Radio"); |
169 | return 0; | 170 | return 0; |
170 | } | 171 | } |
171 | case VIDIOCSAUDIO: | 172 | case VIDIOCSAUDIO: |
172 | { | 173 | { |
173 | struct video_audio *v = arg; | 174 | struct video_audio *v = arg; |
174 | if(v->audio) | 175 | if(v->audio) |
175 | return -EINVAL; | 176 | return -EINVAL; |
176 | 177 | ||
177 | if(v->flags&VIDEO_AUDIO_MUTE) | 178 | if(v->flags&VIDEO_AUDIO_MUTE) |
178 | rt_mute(rt); | 179 | rt_mute(rt); |
179 | else | 180 | else |
180 | rt_unmute(rt); | 181 | rt_unmute(rt); |
181 | 182 | ||
182 | return 0; | 183 | return 0; |
183 | } | 184 | } |
@@ -219,7 +220,7 @@ static int __init rtrack2_init(void) | |||
219 | printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n"); | 220 | printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n"); |
220 | return -EINVAL; | 221 | return -EINVAL; |
221 | } | 222 | } |
222 | if (!request_region(io, 4, "rtrack2")) | 223 | if (!request_region(io, 4, "rtrack2")) |
223 | { | 224 | { |
224 | printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io); | 225 | printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io); |
225 | return -EBUSY; | 226 | return -EBUSY; |
@@ -227,16 +228,16 @@ static int __init rtrack2_init(void) | |||
227 | 228 | ||
228 | rtrack2_radio.priv=&rtrack2_unit; | 229 | rtrack2_radio.priv=&rtrack2_unit; |
229 | 230 | ||
230 | spin_lock_init(&lock); | 231 | spin_lock_init(&lock); |
231 | if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr)==-1) | 232 | if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr)==-1) |
232 | { | 233 | { |
233 | release_region(io, 4); | 234 | release_region(io, 4); |
234 | return -EINVAL; | 235 | return -EINVAL; |
235 | } | 236 | } |
236 | 237 | ||
237 | printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n"); | 238 | printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n"); |
238 | 239 | ||
239 | /* mute card - prevents noisy bootups */ | 240 | /* mute card - prevents noisy bootups */ |
240 | outb(1, io); | 241 | outb(1, io); |
241 | rtrack2_unit.muted = 1; | 242 | rtrack2_unit.muted = 1; |
242 | 243 | ||
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 53073b424107..efee6e339d15 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); | 12 | * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); |
13 | * No volume control - only mute/unmute - you have to use line volume | 13 | * No volume control - only mute/unmute - you have to use line volume |
14 | * control on SB-part of SF16FMI | 14 | * control on SB-part of SF16FMI |
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/kernel.h> /* __setup */ | 18 | #include <linux/kernel.h> /* __setup */ |
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/ioport.h> /* request_region */ | 21 | #include <linux/ioport.h> /* request_region */ |
22 | #include <linux/delay.h> /* udelay */ | 22 | #include <linux/delay.h> /* udelay */ |
23 | #include <linux/videodev.h> /* kernel radio structs */ | 23 | #include <linux/videodev.h> /* kernel radio structs */ |
24 | #include <media/v4l2-common.h> | ||
24 | #include <linux/isapnp.h> | 25 | #include <linux/isapnp.h> |
25 | #include <asm/io.h> /* outb, outb_p */ | 26 | #include <asm/io.h> /* outb, outb_p */ |
26 | #include <asm/uaccess.h> /* copy to/from user */ | 27 | #include <asm/uaccess.h> /* copy to/from user */ |
@@ -29,19 +30,19 @@ | |||
29 | struct fmi_device | 30 | struct fmi_device |
30 | { | 31 | { |
31 | int port; | 32 | int port; |
32 | int curvol; /* 1 or 0 */ | 33 | int curvol; /* 1 or 0 */ |
33 | unsigned long curfreq; /* freq in kHz */ | 34 | unsigned long curfreq; /* freq in kHz */ |
34 | __u32 flags; | 35 | __u32 flags; |
35 | }; | 36 | }; |
36 | 37 | ||
37 | static int io = -1; | 38 | static int io = -1; |
38 | static int radio_nr = -1; | 39 | static int radio_nr = -1; |
39 | static struct pnp_dev *dev = NULL; | 40 | static struct pnp_dev *dev = NULL; |
40 | static struct mutex lock; | 41 | static struct mutex lock; |
41 | 42 | ||
42 | /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ | 43 | /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ |
43 | /* It is only useful to give freq in intervall of 800 (=0.05Mhz), | 44 | /* It is only useful to give freq in intervall of 800 (=0.05Mhz), |
44 | * other bits will be truncated, e.g 92.7400016 -> 92.7, but | 45 | * other bits will be truncated, e.g 92.7400016 -> 92.7, but |
45 | * 92.7400017 -> 92.75 | 46 | * 92.7400017 -> 92.75 |
46 | */ | 47 | */ |
47 | #define RSF16_ENCODE(x) ((x)/800+214) | 48 | #define RSF16_ENCODE(x) ((x)/800+214) |
@@ -51,7 +52,7 @@ static struct mutex lock; | |||
51 | static void outbits(int bits, unsigned int data, int port) | 52 | static void outbits(int bits, unsigned int data, int port) |
52 | { | 53 | { |
53 | while(bits--) { | 54 | while(bits--) { |
54 | if(data & 1) { | 55 | if(data & 1) { |
55 | outb(5, port); | 56 | outb(5, port); |
56 | udelay(6); | 57 | udelay(6); |
57 | outb(7, port); | 58 | outb(7, port); |
@@ -101,7 +102,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev) | |||
101 | int res; | 102 | int res; |
102 | int myport = dev->port; | 103 | int myport = dev->port; |
103 | 104 | ||
104 | 105 | ||
105 | mutex_lock(&lock); | 106 | mutex_lock(&lock); |
106 | val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */ | 107 | val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */ |
107 | outb(val, myport); | 108 | outb(val, myport); |
@@ -109,7 +110,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev) | |||
109 | msleep(143); /* was schedule_timeout(HZ/7) */ | 110 | msleep(143); /* was schedule_timeout(HZ/7) */ |
110 | res = (int)inb(myport+1); | 111 | res = (int)inb(myport+1); |
111 | outb(val, myport); | 112 | outb(val, myport); |
112 | 113 | ||
113 | mutex_unlock(&lock); | 114 | mutex_unlock(&lock); |
114 | return (res & 2) ? 0 : 0xFFFF; | 115 | return (res & 2) ? 0 : 0xFFFF; |
115 | } | 116 | } |
@@ -119,7 +120,7 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, | |||
119 | { | 120 | { |
120 | struct video_device *dev = video_devdata(file); | 121 | struct video_device *dev = video_devdata(file); |
121 | struct fmi_device *fmi=dev->priv; | 122 | struct fmi_device *fmi=dev->priv; |
122 | 123 | ||
123 | switch(cmd) | 124 | switch(cmd) |
124 | { | 125 | { |
125 | case VIDIOCGCAP: | 126 | case VIDIOCGCAP: |
@@ -174,18 +175,18 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, | |||
174 | return -EINVAL; | 175 | return -EINVAL; |
175 | /*rounding in steps of 800 to match th freq | 176 | /*rounding in steps of 800 to match th freq |
176 | that will be used */ | 177 | that will be used */ |
177 | fmi->curfreq = (*freq/800)*800; | 178 | fmi->curfreq = (*freq/800)*800; |
178 | fmi_setfreq(fmi); | 179 | fmi_setfreq(fmi); |
179 | return 0; | 180 | return 0; |
180 | } | 181 | } |
181 | case VIDIOCGAUDIO: | 182 | case VIDIOCGAUDIO: |
182 | { | 183 | { |
183 | struct video_audio *v = arg; | 184 | struct video_audio *v = arg; |
184 | memset(v,0,sizeof(*v)); | 185 | memset(v,0,sizeof(*v)); |
185 | v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); | 186 | v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); |
186 | strcpy(v->name, "Radio"); | 187 | strcpy(v->name, "Radio"); |
187 | v->mode=VIDEO_SOUND_STEREO; | 188 | v->mode=VIDEO_SOUND_STEREO; |
188 | return 0; | 189 | return 0; |
189 | } | 190 | } |
190 | case VIDIOCSAUDIO: | 191 | case VIDIOCSAUDIO: |
191 | { | 192 | { |
@@ -193,19 +194,19 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, | |||
193 | if(v->audio) | 194 | if(v->audio) |
194 | return -EINVAL; | 195 | return -EINVAL; |
195 | fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1; | 196 | fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1; |
196 | fmi->curvol ? | 197 | fmi->curvol ? |
197 | fmi_unmute(fmi->port) : fmi_mute(fmi->port); | 198 | fmi_unmute(fmi->port) : fmi_mute(fmi->port); |
198 | return 0; | 199 | return 0; |
199 | } | 200 | } |
200 | case VIDIOCGUNIT: | 201 | case VIDIOCGUNIT: |
201 | { | 202 | { |
202 | struct video_unit *v = arg; | 203 | struct video_unit *v = arg; |
203 | v->video=VIDEO_NO_UNIT; | 204 | v->video=VIDEO_NO_UNIT; |
204 | v->vbi=VIDEO_NO_UNIT; | 205 | v->vbi=VIDEO_NO_UNIT; |
205 | v->radio=dev->minor; | 206 | v->radio=dev->minor; |
206 | v->audio=0; /* How do we find out this??? */ | 207 | v->audio=0; /* How do we find out this??? */ |
207 | v->teletext=VIDEO_NO_UNIT; | 208 | v->teletext=VIDEO_NO_UNIT; |
208 | return 0; | 209 | return 0; |
209 | } | 210 | } |
210 | default: | 211 | default: |
211 | return -ENOIOCTLCMD; | 212 | return -ENOIOCTLCMD; |
@@ -295,14 +296,14 @@ static int __init fmi_init(void) | |||
295 | fmi_unit.curfreq = 0; | 296 | fmi_unit.curfreq = 0; |
296 | fmi_unit.flags = VIDEO_TUNER_LOW; | 297 | fmi_unit.flags = VIDEO_TUNER_LOW; |
297 | fmi_radio.priv = &fmi_unit; | 298 | fmi_radio.priv = &fmi_unit; |
298 | 299 | ||
299 | mutex_init(&lock); | 300 | mutex_init(&lock); |
300 | 301 | ||
301 | if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { | 302 | if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { |
302 | release_region(io, 2); | 303 | release_region(io, 2); |
303 | return -EINVAL; | 304 | return -EINVAL; |
304 | } | 305 | } |
305 | 306 | ||
306 | printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io); | 307 | printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io); |
307 | /* mute card - prevents noisy bootups */ | 308 | /* mute card - prevents noisy bootups */ |
308 | fmi_mute(io); | 309 | fmi_mute(io); |
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index bcebd8cb19ad..3483b2c7bc9d 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/io.h> /* outb, outb_p */ | 19 | #include <asm/io.h> /* outb, outb_p */ |
20 | #include <asm/uaccess.h> /* copy to/from user */ | 20 | #include <asm/uaccess.h> /* copy to/from user */ |
21 | #include <linux/videodev.h> /* kernel radio structs */ | 21 | #include <linux/videodev.h> /* kernel radio structs */ |
22 | #include <media/v4l2-common.h> | ||
22 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
23 | 24 | ||
24 | static struct mutex lock; | 25 | static struct mutex lock; |
@@ -202,7 +203,7 @@ static int fmr2_setvolume(struct fmr2_device *dev) | |||
202 | } | 203 | } |
203 | 204 | ||
204 | static int fmr2_do_ioctl(struct inode *inode, struct file *file, | 205 | static int fmr2_do_ioctl(struct inode *inode, struct file *file, |
205 | unsigned int cmd, void *arg) | 206 | unsigned int cmd, void *arg) |
206 | { | 207 | { |
207 | struct video_device *dev = video_devdata(file); | 208 | struct video_device *dev = video_devdata(file); |
208 | struct fmr2_device *fmr2 = dev->priv; | 209 | struct fmr2_device *fmr2 = dev->priv; |
@@ -344,7 +345,7 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, | |||
344 | } | 345 | } |
345 | 346 | ||
346 | static int fmr2_ioctl(struct inode *inode, struct file *file, | 347 | static int fmr2_ioctl(struct inode *inode, struct file *file, |
347 | unsigned int cmd, unsigned long arg) | 348 | unsigned int cmd, unsigned long arg) |
348 | { | 349 | { |
349 | return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl); | 350 | return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl); |
350 | } | 351 | } |
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index fcfde2e4f195..dfba4ae596cd 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
@@ -2,11 +2,11 @@ | |||
2 | * (c) 1999 R. Offermanns (rolf@offermanns.de) | 2 | * (c) 1999 R. Offermanns (rolf@offermanns.de) |
3 | * based on the aimslab radio driver from M. Kirkwood | 3 | * based on the aimslab radio driver from M. Kirkwood |
4 | * many thanks to Michael Becker and Friedhelm Birth (from TerraTec) | 4 | * many thanks to Michael Becker and Friedhelm Birth (from TerraTec) |
5 | * | 5 | * |
6 | * | 6 | * |
7 | * History: | 7 | * History: |
8 | * 1999-05-21 First preview release | 8 | * 1999-05-21 First preview release |
9 | * | 9 | * |
10 | * Notes on the hardware: | 10 | * Notes on the hardware: |
11 | * There are two "main" chips on the card: | 11 | * There are two "main" chips on the card: |
12 | * - Philips OM5610 (http://www-us.semiconductors.philips.com/acrobat/datasheets/OM5610_2.pdf) | 12 | * - Philips OM5610 (http://www-us.semiconductors.philips.com/acrobat/datasheets/OM5610_2.pdf) |
@@ -20,7 +20,7 @@ | |||
20 | * (as soon i have understand how to get started :) | 20 | * (as soon i have understand how to get started :) |
21 | * If you can help me out with that, please contact me!! | 21 | * If you can help me out with that, please contact me!! |
22 | * | 22 | * |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/module.h> /* Modules */ | 26 | #include <linux/module.h> /* Modules */ |
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/io.h> /* outb, outb_p */ | 30 | #include <asm/io.h> /* outb, outb_p */ |
31 | #include <asm/uaccess.h> /* copy to/from user */ | 31 | #include <asm/uaccess.h> /* copy to/from user */ |
32 | #include <linux/videodev.h> /* kernel radio structs */ | 32 | #include <linux/videodev.h> /* kernel radio structs */ |
33 | #include <media/v4l2-common.h> | ||
33 | #include <linux/config.h> /* CONFIG_RADIO_TERRATEC_PORT */ | 34 | #include <linux/config.h> /* CONFIG_RADIO_TERRATEC_PORT */ |
34 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
35 | 36 | ||
@@ -49,7 +50,7 @@ | |||
49 | #define WRT_EN 0x10 | 50 | #define WRT_EN 0x10 |
50 | /*******************************************************************/ | 51 | /*******************************************************************/ |
51 | 52 | ||
52 | static int io = CONFIG_RADIO_TERRATEC_PORT; | 53 | static int io = CONFIG_RADIO_TERRATEC_PORT; |
53 | static int radio_nr = -1; | 54 | static int radio_nr = -1; |
54 | static spinlock_t lock; | 55 | static spinlock_t lock; |
55 | 56 | ||
@@ -88,15 +89,15 @@ static void tt_mute(struct tt_device *dev) | |||
88 | 89 | ||
89 | static int tt_setvol(struct tt_device *dev, int vol) | 90 | static int tt_setvol(struct tt_device *dev, int vol) |
90 | { | 91 | { |
91 | 92 | ||
92 | // printk(KERN_ERR "setvol called, vol = %d\n", vol); | 93 | // printk(KERN_ERR "setvol called, vol = %d\n", vol); |
93 | 94 | ||
94 | if(vol == dev->curvol) { /* requested volume = current */ | 95 | if(vol == dev->curvol) { /* requested volume = current */ |
95 | if (dev->muted) { /* user is unmuting the card */ | 96 | if (dev->muted) { /* user is unmuting the card */ |
96 | dev->muted = 0; | 97 | dev->muted = 0; |
97 | cardWriteVol(vol); /* enable card */ | 98 | cardWriteVol(vol); /* enable card */ |
98 | } | 99 | } |
99 | 100 | ||
100 | return 0; | 101 | return 0; |
101 | } | 102 | } |
102 | 103 | ||
@@ -107,9 +108,9 @@ static int tt_setvol(struct tt_device *dev, int vol) | |||
107 | } | 108 | } |
108 | 109 | ||
109 | dev->muted = 0; | 110 | dev->muted = 0; |
110 | 111 | ||
111 | cardWriteVol(vol); | 112 | cardWriteVol(vol); |
112 | 113 | ||
113 | dev->curvol = vol; | 114 | dev->curvol = vol; |
114 | 115 | ||
115 | return 0; | 116 | return 0; |
@@ -121,13 +122,13 @@ static int tt_setvol(struct tt_device *dev, int vol) | |||
121 | /* many more or less strange things are going on here, but hey, it works :) */ | 122 | /* many more or less strange things are going on here, but hey, it works :) */ |
122 | 123 | ||
123 | static int tt_setfreq(struct tt_device *dev, unsigned long freq1) | 124 | static int tt_setfreq(struct tt_device *dev, unsigned long freq1) |
124 | { | 125 | { |
125 | int freq; | 126 | int freq; |
126 | int i; | 127 | int i; |
127 | int p; | 128 | int p; |
128 | int temp; | 129 | int temp; |
129 | long rest; | 130 | long rest; |
130 | 131 | ||
131 | unsigned char buffer[25]; /* we have to bit shift 25 registers */ | 132 | unsigned char buffer[25]; /* we have to bit shift 25 registers */ |
132 | freq = freq1/160; /* convert the freq. to a nice to handle value */ | 133 | freq = freq1/160; /* convert the freq. to a nice to handle value */ |
133 | for(i=24;i>-1;i--) | 134 | for(i=24;i>-1;i--) |
@@ -142,9 +143,9 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1) | |||
142 | { | 143 | { |
143 | if (rest%temp == rest) | 144 | if (rest%temp == rest) |
144 | buffer[i] = 0; | 145 | buffer[i] = 0; |
145 | else | 146 | else |
146 | { | 147 | { |
147 | buffer[i] = 1; | 148 | buffer[i] = 1; |
148 | rest = rest-temp; | 149 | rest = rest-temp; |
149 | } | 150 | } |
150 | i--; | 151 | i--; |
@@ -153,10 +154,10 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1) | |||
153 | } | 154 | } |
154 | 155 | ||
155 | spin_lock(&lock); | 156 | spin_lock(&lock); |
156 | 157 | ||
157 | for (i=24;i>-1;i--) /* bit shift the values to the radiocard */ | 158 | for (i=24;i>-1;i--) /* bit shift the values to the radiocard */ |
158 | { | 159 | { |
159 | if (buffer[i]==1) | 160 | if (buffer[i]==1) |
160 | { | 161 | { |
161 | outb(WRT_EN|DATA, BASEPORT); | 162 | outb(WRT_EN|DATA, BASEPORT); |
162 | outb(WRT_EN|DATA|CLK_ON , BASEPORT); | 163 | outb(WRT_EN|DATA|CLK_ON , BASEPORT); |
@@ -168,11 +169,11 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1) | |||
168 | outb(WRT_EN|0x00|CLK_ON , BASEPORT); | 169 | outb(WRT_EN|0x00|CLK_ON , BASEPORT); |
169 | } | 170 | } |
170 | } | 171 | } |
171 | outb(0x00, BASEPORT); | 172 | outb(0x00, BASEPORT); |
172 | 173 | ||
173 | spin_unlock(&lock); | 174 | spin_unlock(&lock); |
174 | 175 | ||
175 | return 0; | 176 | return 0; |
176 | } | 177 | } |
177 | 178 | ||
178 | static int tt_getsigstr(struct tt_device *dev) /* TODO */ | 179 | static int tt_getsigstr(struct tt_device *dev) /* TODO */ |
@@ -190,7 +191,7 @@ static int tt_do_ioctl(struct inode *inode, struct file *file, | |||
190 | { | 191 | { |
191 | struct video_device *dev = video_devdata(file); | 192 | struct video_device *dev = video_devdata(file); |
192 | struct tt_device *tt=dev->priv; | 193 | struct tt_device *tt=dev->priv; |
193 | 194 | ||
194 | switch(cmd) | 195 | switch(cmd) |
195 | { | 196 | { |
196 | case VIDIOCGCAP: | 197 | case VIDIOCGCAP: |
@@ -206,7 +207,7 @@ static int tt_do_ioctl(struct inode *inode, struct file *file, | |||
206 | case VIDIOCGTUNER: | 207 | case VIDIOCGTUNER: |
207 | { | 208 | { |
208 | struct video_tuner *v = arg; | 209 | struct video_tuner *v = arg; |
209 | if(v->tuner) /* Only 1 tuner */ | 210 | if(v->tuner) /* Only 1 tuner */ |
210 | return -EINVAL; | 211 | return -EINVAL; |
211 | v->rangelow=(87*16000); | 212 | v->rangelow=(87*16000); |
212 | v->rangehigh=(108*16000); | 213 | v->rangehigh=(108*16000); |
@@ -238,21 +239,21 @@ static int tt_do_ioctl(struct inode *inode, struct file *file, | |||
238 | return 0; | 239 | return 0; |
239 | } | 240 | } |
240 | case VIDIOCGAUDIO: | 241 | case VIDIOCGAUDIO: |
241 | { | 242 | { |
242 | struct video_audio *v = arg; | 243 | struct video_audio *v = arg; |
243 | memset(v,0, sizeof(*v)); | 244 | memset(v,0, sizeof(*v)); |
244 | v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; | 245 | v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; |
245 | v->volume=tt->curvol * 6554; | 246 | v->volume=tt->curvol * 6554; |
246 | v->step=6554; | 247 | v->step=6554; |
247 | strcpy(v->name, "Radio"); | 248 | strcpy(v->name, "Radio"); |
248 | return 0; | 249 | return 0; |
249 | } | 250 | } |
250 | case VIDIOCSAUDIO: | 251 | case VIDIOCSAUDIO: |
251 | { | 252 | { |
252 | struct video_audio *v = arg; | 253 | struct video_audio *v = arg; |
253 | if(v->audio) | 254 | if(v->audio) |
254 | return -EINVAL; | 255 | return -EINVAL; |
255 | if(v->flags&VIDEO_AUDIO_MUTE) | 256 | if(v->flags&VIDEO_AUDIO_MUTE) |
256 | tt_mute(tt); | 257 | tt_mute(tt); |
257 | else | 258 | else |
258 | tt_setvol(tt,v->volume/6554); | 259 | tt_setvol(tt,v->volume/6554); |
@@ -296,25 +297,25 @@ static int __init terratec_init(void) | |||
296 | printk(KERN_ERR "You must set an I/O address with io=0x???\n"); | 297 | printk(KERN_ERR "You must set an I/O address with io=0x???\n"); |
297 | return -EINVAL; | 298 | return -EINVAL; |
298 | } | 299 | } |
299 | if (!request_region(io, 2, "terratec")) | 300 | if (!request_region(io, 2, "terratec")) |
300 | { | 301 | { |
301 | printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io); | 302 | printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io); |
302 | return -EBUSY; | 303 | return -EBUSY; |
303 | } | 304 | } |
304 | 305 | ||
305 | terratec_radio.priv=&terratec_unit; | 306 | terratec_radio.priv=&terratec_unit; |
306 | 307 | ||
307 | spin_lock_init(&lock); | 308 | spin_lock_init(&lock); |
308 | 309 | ||
309 | if(video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr)==-1) | 310 | if(video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr)==-1) |
310 | { | 311 | { |
311 | release_region(io,2); | 312 | release_region(io,2); |
312 | return -EINVAL; | 313 | return -EINVAL; |
313 | } | 314 | } |
314 | 315 | ||
315 | printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n"); | 316 | printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n"); |
316 | 317 | ||
317 | /* mute card - prevents noisy bootups */ | 318 | /* mute card - prevents noisy bootups */ |
318 | 319 | ||
319 | /* this ensures that the volume is all the way down */ | 320 | /* this ensures that the volume is all the way down */ |
320 | cardWriteVol(0); | 321 | cardWriteVol(0); |
@@ -334,7 +335,7 @@ static void __exit terratec_cleanup_module(void) | |||
334 | { | 335 | { |
335 | video_unregister_device(&terratec_radio); | 336 | video_unregister_device(&terratec_radio); |
336 | release_region(io,2); | 337 | release_region(io,2); |
337 | printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n"); | 338 | printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n"); |
338 | } | 339 | } |
339 | 340 | ||
340 | module_init(terratec_init); | 341 | module_init(terratec_init); |
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 5a099a50d4d0..8da4badc22b4 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
@@ -1,14 +1,14 @@ | |||
1 | /* radio-trust.c - Trust FM Radio card driver for Linux 2.2 | 1 | /* radio-trust.c - Trust FM Radio card driver for Linux 2.2 |
2 | * by Eric Lammerts <eric@scintilla.utwente.nl> | 2 | * by Eric Lammerts <eric@scintilla.utwente.nl> |
3 | * | 3 | * |
4 | * Based on radio-aztech.c. Original notes: | 4 | * Based on radio-aztech.c. Original notes: |
5 | * | 5 | * |
6 | * Adapted to support the Video for Linux API by | 6 | * Adapted to support the Video for Linux API by |
7 | * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: | 7 | * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: |
8 | * | 8 | * |
9 | * Quay Ly | 9 | * Quay Ly |
10 | * Donald Song | 10 | * Donald Song |
11 | * Jason Lewis (jlewis@twilight.vtc.vsc.edu) | 11 | * Jason Lewis (jlewis@twilight.vtc.vsc.edu) |
12 | * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) | 12 | * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) |
13 | * William McGrath (wmcgrath@twilight.vtc.vsc.edu) | 13 | * William McGrath (wmcgrath@twilight.vtc.vsc.edu) |
14 | * | 14 | * |
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
24 | #include <linux/videodev.h> | 24 | #include <linux/videodev.h> |
25 | #include <media/v4l2-common.h> | ||
25 | #include <linux/config.h> /* CONFIG_RADIO_TRUST_PORT */ | 26 | #include <linux/config.h> /* CONFIG_RADIO_TRUST_PORT */ |
26 | 27 | ||
27 | /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ | 28 | /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ |
@@ -30,7 +31,7 @@ | |||
30 | #define CONFIG_RADIO_TRUST_PORT -1 | 31 | #define CONFIG_RADIO_TRUST_PORT -1 |
31 | #endif | 32 | #endif |
32 | 33 | ||
33 | static int io = CONFIG_RADIO_TRUST_PORT; | 34 | static int io = CONFIG_RADIO_TRUST_PORT; |
34 | static int radio_nr = -1; | 35 | static int radio_nr = -1; |
35 | static int ioval = 0xf; | 36 | static int ioval = 0xf; |
36 | static __u16 curvol; | 37 | static __u16 curvol; |
@@ -135,7 +136,7 @@ static void tr_setmute(int mute) | |||
135 | static int tr_getsigstr(void) | 136 | static int tr_getsigstr(void) |
136 | { | 137 | { |
137 | int i, v; | 138 | int i, v; |
138 | 139 | ||
139 | for(i = 0, v = 0; i < 100; i++) v |= inb(io); | 140 | for(i = 0, v = 0; i < 100; i++) v |= inb(io); |
140 | return (v & 1)? 0 : 0xffff; | 141 | return (v & 1)? 0 : 0xffff; |
141 | } | 142 | } |
@@ -175,7 +176,7 @@ static int tr_do_ioctl(struct inode *inode, struct file *file, | |||
175 | { | 176 | { |
176 | struct video_tuner *v = arg; | 177 | struct video_tuner *v = arg; |
177 | 178 | ||
178 | if(v->tuner) /* Only 1 tuner */ | 179 | if(v->tuner) /* Only 1 tuner */ |
179 | return -EINVAL; | 180 | return -EINVAL; |
180 | 181 | ||
181 | v->rangelow = 87500 * 16; | 182 | v->rangelow = 87500 * 16; |
@@ -211,28 +212,28 @@ static int tr_do_ioctl(struct inode *inode, struct file *file, | |||
211 | return 0; | 212 | return 0; |
212 | } | 213 | } |
213 | case VIDIOCGAUDIO: | 214 | case VIDIOCGAUDIO: |
214 | { | 215 | { |
215 | struct video_audio *v = arg; | 216 | struct video_audio *v = arg; |
216 | 217 | ||
217 | memset(v,0, sizeof(*v)); | 218 | memset(v,0, sizeof(*v)); |
218 | v->flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME | | 219 | v->flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME | |
219 | VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE; | 220 | VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE; |
220 | v->mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; | 221 | v->mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; |
221 | v->volume = curvol * 2048; | 222 | v->volume = curvol * 2048; |
222 | v->step = 2048; | 223 | v->step = 2048; |
223 | v->bass = curbass * 4370; | 224 | v->bass = curbass * 4370; |
224 | v->treble = curtreble * 4370; | 225 | v->treble = curtreble * 4370; |
225 | 226 | ||
226 | strcpy(v->name, "Trust FM Radio"); | 227 | strcpy(v->name, "Trust FM Radio"); |
227 | return 0; | 228 | return 0; |
228 | } | 229 | } |
229 | case VIDIOCSAUDIO: | 230 | case VIDIOCSAUDIO: |
230 | { | 231 | { |
231 | struct video_audio *v = arg; | 232 | struct video_audio *v = arg; |
232 | 233 | ||
233 | if(v->audio) | 234 | if(v->audio) |
234 | return -EINVAL; | 235 | return -EINVAL; |
235 | tr_setvol(v->volume); | 236 | tr_setvol(v->volume); |
236 | tr_setbass(v->bass); | 237 | tr_setbass(v->bass); |
237 | tr_settreble(v->treble); | 238 | tr_settreble(v->treble); |
238 | tr_setstereo(v->mode & VIDEO_SOUND_STEREO); | 239 | tr_setstereo(v->mode & VIDEO_SOUND_STEREO); |
@@ -292,7 +293,7 @@ static int __init trust_init(void) | |||
292 | write_i2c(2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */ | 293 | write_i2c(2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */ |
293 | write_i2c(2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */ | 294 | write_i2c(2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */ |
294 | 295 | ||
295 | tr_setvol(0x8000); | 296 | tr_setvol(0x8000); |
296 | tr_setbass(0x8000); | 297 | tr_setbass(0x8000); |
297 | tr_settreble(0x8000); | 298 | tr_settreble(0x8000); |
298 | tr_setstereo(1); | 299 | tr_setstereo(1); |
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index e50955836d6b..edd012288669 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/io.h> /* outb, outb_p */ | 36 | #include <asm/io.h> /* outb, outb_p */ |
37 | #include <asm/uaccess.h> /* copy to/from user */ | 37 | #include <asm/uaccess.h> /* copy to/from user */ |
38 | #include <linux/videodev.h> /* kernel radio structs */ | 38 | #include <linux/videodev.h> /* kernel radio structs */ |
39 | #include <media/v4l2-common.h> | ||
39 | #include <linux/config.h> /* CONFIG_RADIO_TYPHOON_* */ | 40 | #include <linux/config.h> /* CONFIG_RADIO_TYPHOON_* */ |
40 | 41 | ||
41 | #define BANNER "Typhoon Radio Card driver v0.1\n" | 42 | #define BANNER "Typhoon Radio Card driver v0.1\n" |
@@ -361,8 +362,8 @@ static int __init typhoon_init(void) | |||
361 | 362 | ||
362 | #ifdef CONFIG_RADIO_TYPHOON_PROC_FS | 363 | #ifdef CONFIG_RADIO_TYPHOON_PROC_FS |
363 | if (!create_proc_info_entry("driver/radio-typhoon", 0, NULL, | 364 | if (!create_proc_info_entry("driver/radio-typhoon", 0, NULL, |
364 | typhoon_get_info)) | 365 | typhoon_get_info)) |
365 | printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n"); | 366 | printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n"); |
366 | #endif | 367 | #endif |
367 | 368 | ||
368 | return 0; | 369 | return 0; |
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 7bf1a4264891..59b86a6b4b0e 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* zoltrix radio plus driver for Linux radio support | 1 | /* zoltrix radio plus driver for Linux radio support |
2 | * (c) 1998 C. van Schaik <carl@leg.uct.ac.za> | 2 | * (c) 1998 C. van Schaik <carl@leg.uct.ac.za> |
3 | * | 3 | * |
4 | * BUGS | 4 | * BUGS |
5 | * Due to the inconsistency in reading from the signal flags | 5 | * Due to the inconsistency in reading from the signal flags |
6 | * it is difficult to get an accurate tuned signal. | 6 | * it is difficult to get an accurate tuned signal. |
7 | * | 7 | * |
@@ -14,7 +14,7 @@ | |||
14 | * | 14 | * |
15 | * 1999-05-06 - (C. van Schaik) | 15 | * 1999-05-06 - (C. van Schaik) |
16 | * - Make signal strength and stereo scans | 16 | * - Make signal strength and stereo scans |
17 | * kinder to cpu while in delay | 17 | * kinder to cpu while in delay |
18 | * 1999-01-05 - (C. van Schaik) | 18 | * 1999-01-05 - (C. van Schaik) |
19 | * - Changed tuning to 1/160Mhz accuracy | 19 | * - Changed tuning to 1/160Mhz accuracy |
20 | * - Added stereo support | 20 | * - Added stereo support |
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/io.h> /* outb, outb_p */ | 33 | #include <asm/io.h> /* outb, outb_p */ |
34 | #include <asm/uaccess.h> /* copy to/from user */ | 34 | #include <asm/uaccess.h> /* copy to/from user */ |
35 | #include <linux/videodev.h> /* kernel radio structs */ | 35 | #include <linux/videodev.h> /* kernel radio structs */ |
36 | #include <media/v4l2-common.h> | ||
36 | #include <linux/config.h> /* CONFIG_RADIO_ZOLTRIX_PORT */ | 37 | #include <linux/config.h> /* CONFIG_RADIO_ZOLTRIX_PORT */ |
37 | 38 | ||
38 | #ifndef CONFIG_RADIO_ZOLTRIX_PORT | 39 | #ifndef CONFIG_RADIO_ZOLTRIX_PORT |
@@ -105,7 +106,7 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) | |||
105 | i = 45; | 106 | i = 45; |
106 | 107 | ||
107 | mutex_lock(&dev->lock); | 108 | mutex_lock(&dev->lock); |
108 | 109 | ||
109 | outb(0, io); | 110 | outb(0, io); |
110 | outb(0, io); | 111 | outb(0, io); |
111 | inb(io + 3); /* Zoltrix needs to be read to confirm */ | 112 | inb(io + 3); /* Zoltrix needs to be read to confirm */ |
@@ -139,8 +140,8 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) | |||
139 | udelay(1000); | 140 | udelay(1000); |
140 | inb(io+2); | 141 | inb(io+2); |
141 | 142 | ||
142 | udelay(1000); | 143 | udelay(1000); |
143 | 144 | ||
144 | if (dev->muted) | 145 | if (dev->muted) |
145 | { | 146 | { |
146 | outb(0, io); | 147 | outb(0, io); |
@@ -148,12 +149,12 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) | |||
148 | inb(io + 3); | 149 | inb(io + 3); |
149 | udelay(1000); | 150 | udelay(1000); |
150 | } | 151 | } |
151 | 152 | ||
152 | mutex_unlock(&dev->lock); | 153 | mutex_unlock(&dev->lock); |
153 | 154 | ||
154 | if(!dev->muted) | 155 | if(!dev->muted) |
155 | { | 156 | { |
156 | zol_setvol(dev, dev->curvol); | 157 | zol_setvol(dev, dev->curvol); |
157 | } | 158 | } |
158 | return 0; | 159 | return 0; |
159 | } | 160 | } |
@@ -174,14 +175,14 @@ static int zol_getsigstr(struct zol_device *dev) | |||
174 | b = inb(io); | 175 | b = inb(io); |
175 | 176 | ||
176 | mutex_unlock(&dev->lock); | 177 | mutex_unlock(&dev->lock); |
177 | 178 | ||
178 | if (a != b) | 179 | if (a != b) |
179 | return (0); | 180 | return (0); |
180 | 181 | ||
181 | if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */ | 182 | if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */ |
182 | || (a == 0xef)) /* with a binary scanner on the card io */ | 183 | || (a == 0xef)) /* with a binary scanner on the card io */ |
183 | return (1); | 184 | return (1); |
184 | return (0); | 185 | return (0); |
185 | } | 186 | } |
186 | 187 | ||
187 | static int zol_is_stereo (struct zol_device *dev) | 188 | static int zol_is_stereo (struct zol_device *dev) |
@@ -189,7 +190,7 @@ static int zol_is_stereo (struct zol_device *dev) | |||
189 | int x1, x2; | 190 | int x1, x2; |
190 | 191 | ||
191 | mutex_lock(&dev->lock); | 192 | mutex_lock(&dev->lock); |
192 | 193 | ||
193 | outb(0x00, io); | 194 | outb(0x00, io); |
194 | outb(dev->curvol, io); | 195 | outb(dev->curvol, io); |
195 | msleep(20); | 196 | msleep(20); |
@@ -199,7 +200,7 @@ static int zol_is_stereo (struct zol_device *dev) | |||
199 | x2 = inb(io); | 200 | x2 = inb(io); |
200 | 201 | ||
201 | mutex_unlock(&dev->lock); | 202 | mutex_unlock(&dev->lock); |
202 | 203 | ||
203 | if ((x1 == x2) && (x1 == 0xcf)) | 204 | if ((x1 == x2) && (x1 == 0xcf)) |
204 | return 1; | 205 | return 1; |
205 | return 0; | 206 | return 0; |
@@ -226,7 +227,7 @@ static int zol_do_ioctl(struct inode *inode, struct file *file, | |||
226 | case VIDIOCGTUNER: | 227 | case VIDIOCGTUNER: |
227 | { | 228 | { |
228 | struct video_tuner *v = arg; | 229 | struct video_tuner *v = arg; |
229 | if (v->tuner) | 230 | if (v->tuner) |
230 | return -EINVAL; | 231 | return -EINVAL; |
231 | strcpy(v->name, "FM"); | 232 | strcpy(v->name, "FM"); |
232 | v->rangelow = (int) (88.0 * 16000); | 233 | v->rangelow = (int) (88.0 * 16000); |
@@ -351,7 +352,7 @@ static int __init zoltrix_init(void) | |||
351 | printk(KERN_INFO "Zoltrix Radio Plus card driver.\n"); | 352 | printk(KERN_INFO "Zoltrix Radio Plus card driver.\n"); |
352 | 353 | ||
353 | mutex_init(&zoltrix_unit.lock); | 354 | mutex_init(&zoltrix_unit.lock); |
354 | 355 | ||
355 | /* mute card - prevents noisy bootups */ | 356 | /* mute card - prevents noisy bootups */ |
356 | 357 | ||
357 | /* this ensures that the volume is all the way down */ | 358 | /* this ensures that the volume is all the way down */ |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 6b4197018561..824a63c92629 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -224,6 +224,12 @@ config VIDEO_ZORAN_LML33R10 | |||
224 | support for the Linux Media Labs LML33R10 MJPEG capture/playback | 224 | support for the Linux Media Labs LML33R10 MJPEG capture/playback |
225 | card. | 225 | card. |
226 | 226 | ||
227 | config VIDEO_ZORAN_AVS6EYES | ||
228 | tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" | ||
229 | depends on VIDEO_ZORAN && EXPERIMENTAL && VIDEO_V4L1 | ||
230 | help | ||
231 | Support for the AverMedia 6 Eyes video surveillance card. | ||
232 | |||
227 | config VIDEO_ZR36120 | 233 | config VIDEO_ZR36120 |
228 | tristate "Zoran ZR36120/36125 Video For Linux" | 234 | tristate "Zoran ZR36120/36125 Video For Linux" |
229 | depends on PCI && I2C && VIDEO_V4L1 && BROKEN | 235 | depends on PCI && I2C && VIDEO_V4L1 && BROKEN |
@@ -306,17 +312,6 @@ config VIDEO_HEXIUM_GEMINI | |||
306 | 312 | ||
307 | source "drivers/media/video/cx88/Kconfig" | 313 | source "drivers/media/video/cx88/Kconfig" |
308 | 314 | ||
309 | config VIDEO_OVCAMCHIP | ||
310 | tristate "OmniVision Camera Chip support" | ||
311 | depends on I2C && VIDEO_V4L1 | ||
312 | ---help--- | ||
313 | Support for the OmniVision OV6xxx and OV7xxx series of camera chips. | ||
314 | This driver is intended to be used with the ov511 and w9968cf USB | ||
315 | camera drivers. | ||
316 | |||
317 | To compile this driver as a module, choose M here: the | ||
318 | module will be called ovcamchip. | ||
319 | |||
320 | config VIDEO_M32R_AR | 315 | config VIDEO_M32R_AR |
321 | tristate "AR devices" | 316 | tristate "AR devices" |
322 | depends on M32R && VIDEO_V4L1 | 317 | depends on M32R && VIDEO_V4L1 |
@@ -357,6 +352,15 @@ config VIDEO_CS53L32A | |||
357 | To compile this driver as a module, choose M here: the | 352 | To compile this driver as a module, choose M here: the |
358 | module will be called cs53l32a. | 353 | module will be called cs53l32a. |
359 | 354 | ||
355 | config VIDEO_TLV320AIC23B | ||
356 | tristate "Texas Instruments TLV320AIC23B audio codec" | ||
357 | depends on VIDEO_DEV && I2C && EXPERIMENTAL | ||
358 | ---help--- | ||
359 | Support for the Texas Instruments TLV320AIC23B audio codec. | ||
360 | |||
361 | To compile this driver as a module, choose M here: the | ||
362 | module will be called tlv320aic23b. | ||
363 | |||
360 | config VIDEO_WM8775 | 364 | config VIDEO_WM8775 |
361 | tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer" | 365 | tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer" |
362 | depends on VIDEO_DEV && I2C && EXPERIMENTAL | 366 | depends on VIDEO_DEV && I2C && EXPERIMENTAL |
@@ -380,10 +384,10 @@ config VIDEO_WM8739 | |||
380 | source "drivers/media/video/cx25840/Kconfig" | 384 | source "drivers/media/video/cx25840/Kconfig" |
381 | 385 | ||
382 | config VIDEO_SAA711X | 386 | config VIDEO_SAA711X |
383 | tristate "Philips SAA7113/4/5 video decoders (OBSOLETED)" | 387 | tristate "Philips SAA7113/4/5 video decoders" |
384 | depends on VIDEO_V4L1 && I2C && EXPERIMENTAL | 388 | depends on VIDEO_DEV && I2C && EXPERIMENTAL |
385 | ---help--- | 389 | ---help--- |
386 | Old support for the Philips SAA7113/4 video decoders. | 390 | Support for the Philips SAA7113/4/5 video decoders. |
387 | 391 | ||
388 | To compile this driver as a module, choose M here: the | 392 | To compile this driver as a module, choose M here: the |
389 | module will be called saa7115. | 393 | module will be called saa7115. |
@@ -447,6 +451,35 @@ source "drivers/media/video/usbvideo/Kconfig" | |||
447 | 451 | ||
448 | source "drivers/media/video/et61x251/Kconfig" | 452 | source "drivers/media/video/et61x251/Kconfig" |
449 | 453 | ||
454 | config VIDEO_OVCAMCHIP | ||
455 | tristate "OmniVision Camera Chip support" | ||
456 | depends on I2C && VIDEO_V4L1 | ||
457 | ---help--- | ||
458 | Support for the OmniVision OV6xxx and OV7xxx series of camera chips. | ||
459 | This driver is intended to be used with the ov511 and w9968cf USB | ||
460 | camera drivers. | ||
461 | |||
462 | To compile this driver as a module, choose M here: the | ||
463 | module will be called ovcamchip. | ||
464 | |||
465 | config USB_W9968CF | ||
466 | tristate "USB W996[87]CF JPEG Dual Mode Camera support" | ||
467 | depends on USB && VIDEO_V4L1 && I2C | ||
468 | select VIDEO_OVCAMCHIP | ||
469 | ---help--- | ||
470 | Say Y here if you want support for cameras based on OV681 or | ||
471 | Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. | ||
472 | |||
473 | This driver has an optional plugin, which is distributed as a | ||
474 | separate module only (released under GPL). It allows to use higher | ||
475 | resolutions and framerates, but cannot be included in the official | ||
476 | Linux kernel for performance purposes. | ||
477 | |||
478 | See <file:Documentation/video4linux/w9968cf.txt> for more info. | ||
479 | |||
480 | To compile this driver as a module, choose M here: the | ||
481 | module will be called w9968cf. | ||
482 | |||
450 | config USB_OV511 | 483 | config USB_OV511 |
451 | tristate "USB OV511 Camera support" | 484 | tristate "USB OV511 Camera support" |
452 | depends on USB && VIDEO_V4L1 | 485 | depends on USB && VIDEO_V4L1 |
@@ -483,24 +516,6 @@ config USB_STV680 | |||
483 | To compile this driver as a module, choose M here: the | 516 | To compile this driver as a module, choose M here: the |
484 | module will be called stv680. | 517 | module will be called stv680. |
485 | 518 | ||
486 | config USB_W9968CF | ||
487 | tristate "USB W996[87]CF JPEG Dual Mode Camera support" | ||
488 | depends on USB && VIDEO_V4L1 && I2C | ||
489 | select VIDEO_OVCAMCHIP | ||
490 | ---help--- | ||
491 | Say Y here if you want support for cameras based on OV681 or | ||
492 | Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. | ||
493 | |||
494 | This driver has an optional plugin, which is distributed as a | ||
495 | separate module only (released under GPL). It allows to use higher | ||
496 | resolutions and framerates, but cannot be included in the official | ||
497 | Linux kernel for performance purposes. | ||
498 | |||
499 | See <file:Documentation/video4linux/w9968cf.txt> for more info. | ||
500 | |||
501 | To compile this driver as a module, choose M here: the | ||
502 | module will be called w9968cf. | ||
503 | |||
504 | source "drivers/media/video/zc0301/Kconfig" | 519 | source "drivers/media/video/zc0301/Kconfig" |
505 | 520 | ||
506 | source "drivers/media/video/pwc/Kconfig" | 521 | source "drivers/media/video/pwc/Kconfig" |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index e5bf2687b76d..6c401b46398a 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -6,7 +6,7 @@ zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o | |||
6 | zr36067-objs := zoran_procfs.o zoran_device.o \ | 6 | zr36067-objs := zoran_procfs.o zoran_device.o \ |
7 | zoran_driver.o zoran_card.o | 7 | zoran_driver.o zoran_card.o |
8 | tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ | 8 | tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ |
9 | mt20xx.o tda8290.o tea5767.o | 9 | mt20xx.o tda8290.o tea5767.o tda9887.o |
10 | 10 | ||
11 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o | 11 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o |
12 | 12 | ||
@@ -33,6 +33,7 @@ obj-$(CONFIG_VIDEO_ZORAN_DC30) += adv7175.o vpx3220.o zr36050.o \ | |||
33 | zr36016.o | 33 | zr36016.o |
34 | obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o zr36060.o | 34 | obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o zr36060.o |
35 | obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o | 35 | obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o |
36 | obj-$(CONFIG_VIDEO_ZORAN_AVS6EYES) += bt866.o ks0127.o zr36060.o | ||
36 | obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o | 37 | obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o |
37 | obj-$(CONFIG_VIDEO_PMS) += pms.o | 38 | obj-$(CONFIG_VIDEO_PMS) += pms.o |
38 | obj-$(CONFIG_VIDEO_PLANB) += planb.o | 39 | obj-$(CONFIG_VIDEO_PLANB) += planb.o |
@@ -48,6 +49,7 @@ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ | |||
48 | obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o | 49 | obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o |
49 | obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o | 50 | obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o |
50 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o | 51 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o |
52 | obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o | ||
51 | obj-$(CONFIG_VIDEO_WM8775) += wm8775.o | 53 | obj-$(CONFIG_VIDEO_WM8775) += wm8775.o |
52 | obj-$(CONFIG_VIDEO_WM8739) += wm8739.o | 54 | obj-$(CONFIG_VIDEO_WM8739) += wm8739.o |
53 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ | 55 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ |
@@ -58,7 +60,7 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o | |||
58 | obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o | 60 | obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o |
59 | obj-$(CONFIG_TUNER_3036) += tuner-3036.o | 61 | obj-$(CONFIG_TUNER_3036) += tuner-3036.o |
60 | 62 | ||
61 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o tda9887.o | 63 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o |
62 | obj-$(CONFIG_VIDEO_BUF) += video-buf.o | 64 | obj-$(CONFIG_VIDEO_BUF) += video-buf.o |
63 | obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o | 65 | obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o |
64 | obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o | 66 | obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o |
@@ -71,6 +73,7 @@ obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o | |||
71 | obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o | 73 | obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o |
72 | obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o | 74 | obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o |
73 | obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o | 75 | obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o |
76 | obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o | ||
74 | 77 | ||
75 | obj-$(CONFIG_USB_DABUSB) += dabusb.o | 78 | obj-$(CONFIG_USB_DABUSB) += dabusb.o |
76 | obj-$(CONFIG_USB_DSBR) += dsbr100.o | 79 | obj-$(CONFIG_USB_DSBR) += dsbr100.o |
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index dbe025170599..6e08e32346eb 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <linux/videodev.h> | 33 | #include <linux/videodev.h> |
34 | #include <media/v4l2-common.h> | ||
34 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
35 | 36 | ||
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
@@ -212,7 +213,7 @@ void init_iic(void) | |||
212 | ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */ | 213 | ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */ |
213 | ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */ | 214 | ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */ |
214 | 215 | ||
215 | /* I2C CLK */ | 216 | /* I2C CLK */ |
216 | /* 50MH-100k */ | 217 | /* 50MH-100k */ |
217 | if (freq == 75) { | 218 | if (freq == 75) { |
218 | ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */ | 219 | ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */ |
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c new file mode 100644 index 000000000000..05e42bbcfc3d --- /dev/null +++ b/drivers/media/video/bt866.c | |||
@@ -0,0 +1,377 @@ | |||
1 | /* | ||
2 | bt866 - BT866 Digital Video Encoder (Rockwell Part) | ||
3 | |||
4 | Copyright (C) 1999 Mike Bernson <mike@mlb.org> | ||
5 | Copyright (C) 1998 Dave Perks <dperks@ibm.net> | ||
6 | |||
7 | Modifications for LML33/DC10plus unified driver | ||
8 | Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> | ||
9 | |||
10 | This code was modify/ported from the saa7111 driver written | ||
11 | by Dave Perks. | ||
12 | |||
13 | This code was adapted for the bt866 by Christer Weinigel and ported | ||
14 | to 2.6 by Martin Samuelsson. | ||
15 | |||
16 | This program is free software; you can redistribute it and/or modify | ||
17 | it under the terms of the GNU General Public License as published by | ||
18 | the Free Software Foundation; either version 2 of the License, or | ||
19 | (at your option) any later version. | ||
20 | |||
21 | This program is distributed in the hope that it will be useful, | ||
22 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | GNU General Public License for more details. | ||
25 | |||
26 | You should have received a copy of the GNU General Public License | ||
27 | along with this program; if not, write to the Free Software | ||
28 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
29 | */ | ||
30 | |||
31 | #include <linux/module.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/fs.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/major.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/pci.h> | ||
41 | #include <linux/signal.h> | ||
42 | #include <asm/io.h> | ||
43 | #include <asm/pgtable.h> | ||
44 | #include <asm/page.h> | ||
45 | #include <linux/sched.h> | ||
46 | #include <linux/types.h> | ||
47 | #include <linux/i2c.h> | ||
48 | |||
49 | #include <linux/videodev.h> | ||
50 | #include <asm/uaccess.h> | ||
51 | |||
52 | #include <linux/video_encoder.h> | ||
53 | |||
54 | MODULE_LICENSE("GPL"); | ||
55 | |||
56 | #define BT866_DEVNAME "bt866" | ||
57 | #define I2C_BT866 0x88 | ||
58 | |||
59 | MODULE_LICENSE("GPL"); | ||
60 | |||
61 | #define DEBUG(x) /* Debug driver */ | ||
62 | |||
63 | /* ----------------------------------------------------------------------- */ | ||
64 | |||
65 | struct bt866 { | ||
66 | struct i2c_client *i2c; | ||
67 | int addr; | ||
68 | unsigned char reg[128]; | ||
69 | |||
70 | int norm; | ||
71 | int enable; | ||
72 | int bright; | ||
73 | int contrast; | ||
74 | int hue; | ||
75 | int sat; | ||
76 | }; | ||
77 | |||
78 | static int bt866_write(struct bt866 *dev, | ||
79 | unsigned char subaddr, unsigned char data); | ||
80 | |||
81 | static int bt866_do_command(struct bt866 *encoder, | ||
82 | unsigned int cmd, void *arg) | ||
83 | { | ||
84 | switch (cmd) { | ||
85 | case ENCODER_GET_CAPABILITIES: | ||
86 | { | ||
87 | struct video_encoder_capability *cap = arg; | ||
88 | |||
89 | DEBUG(printk | ||
90 | (KERN_INFO "%s: get capabilities\n", | ||
91 | encoder->i2c->name)); | ||
92 | |||
93 | cap->flags | ||
94 | = VIDEO_ENCODER_PAL | ||
95 | | VIDEO_ENCODER_NTSC | ||
96 | | VIDEO_ENCODER_CCIR; | ||
97 | cap->inputs = 2; | ||
98 | cap->outputs = 1; | ||
99 | } | ||
100 | break; | ||
101 | |||
102 | case ENCODER_SET_NORM: | ||
103 | { | ||
104 | int *iarg = arg; | ||
105 | |||
106 | DEBUG(printk(KERN_INFO "%s: set norm %d\n", | ||
107 | encoder->i2c->name, *iarg)); | ||
108 | |||
109 | switch (*iarg) { | ||
110 | |||
111 | case VIDEO_MODE_NTSC: | ||
112 | break; | ||
113 | |||
114 | case VIDEO_MODE_PAL: | ||
115 | break; | ||
116 | |||
117 | default: | ||
118 | return -EINVAL; | ||
119 | |||
120 | } | ||
121 | encoder->norm = *iarg; | ||
122 | } | ||
123 | break; | ||
124 | |||
125 | case ENCODER_SET_INPUT: | ||
126 | { | ||
127 | int *iarg = arg; | ||
128 | static const __u8 init[] = { | ||
129 | 0xc8, 0xcc, /* CRSCALE */ | ||
130 | 0xca, 0x91, /* CBSCALE */ | ||
131 | 0xcc, 0x24, /* YC16 | OSDNUM */ | ||
132 | 0xda, 0x00, /* */ | ||
133 | 0xdc, 0x24, /* SETMODE | PAL */ | ||
134 | 0xde, 0x02, /* EACTIVE */ | ||
135 | |||
136 | /* overlay colors */ | ||
137 | 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */ | ||
138 | 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */ | ||
139 | 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */ | ||
140 | 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */ | ||
141 | 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */ | ||
142 | 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */ | ||
143 | 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */ | ||
144 | 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */ | ||
145 | |||
146 | 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */ | ||
147 | 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */ | ||
148 | 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */ | ||
149 | 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */ | ||
150 | 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */ | ||
151 | 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */ | ||
152 | 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */ | ||
153 | 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */ | ||
154 | }; | ||
155 | int i; | ||
156 | u8 val; | ||
157 | |||
158 | for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) | ||
159 | bt866_write(encoder, init[i], init[i+1]); | ||
160 | |||
161 | val = encoder->reg[0xdc]; | ||
162 | |||
163 | if (*iarg == 0) | ||
164 | val |= 0x40; /* CBSWAP */ | ||
165 | else | ||
166 | val &= ~0x40; /* !CBSWAP */ | ||
167 | |||
168 | bt866_write(encoder, 0xdc, val); | ||
169 | |||
170 | val = encoder->reg[0xcc]; | ||
171 | if (*iarg == 2) | ||
172 | val |= 0x01; /* OSDBAR */ | ||
173 | else | ||
174 | val &= ~0x01; /* !OSDBAR */ | ||
175 | bt866_write(encoder, 0xcc, val); | ||
176 | |||
177 | DEBUG(printk(KERN_INFO "%s: set input %d\n", | ||
178 | encoder->i2c->name, *iarg)); | ||
179 | |||
180 | switch (*iarg) { | ||
181 | case 0: | ||
182 | break; | ||
183 | case 1: | ||
184 | break; | ||
185 | default: | ||
186 | return -EINVAL; | ||
187 | |||
188 | } | ||
189 | } | ||
190 | break; | ||
191 | |||
192 | case ENCODER_SET_OUTPUT: | ||
193 | { | ||
194 | int *iarg = arg; | ||
195 | |||
196 | DEBUG(printk(KERN_INFO "%s: set output %d\n", | ||
197 | encoder->i2c->name, *iarg)); | ||
198 | |||
199 | /* not much choice of outputs */ | ||
200 | if (*iarg != 0) | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | break; | ||
204 | |||
205 | case ENCODER_ENABLE_OUTPUT: | ||
206 | { | ||
207 | int *iarg = arg; | ||
208 | encoder->enable = !!*iarg; | ||
209 | |||
210 | DEBUG(printk | ||
211 | (KERN_INFO "%s: enable output %d\n", | ||
212 | encoder->i2c->name, encoder->enable)); | ||
213 | } | ||
214 | break; | ||
215 | |||
216 | case 4711: | ||
217 | { | ||
218 | int *iarg = arg; | ||
219 | __u8 val; | ||
220 | |||
221 | printk("bt866: square = %d\n", *iarg); | ||
222 | |||
223 | val = encoder->reg[0xdc]; | ||
224 | if (*iarg) | ||
225 | val |= 1; /* SQUARE */ | ||
226 | else | ||
227 | val &= ~1; /* !SQUARE */ | ||
228 | bt866_write(encoder, 0xdc, val); | ||
229 | break; | ||
230 | } | ||
231 | |||
232 | default: | ||
233 | return -EINVAL; | ||
234 | } | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static int bt866_write(struct bt866 *encoder, | ||
240 | unsigned char subaddr, unsigned char data) | ||
241 | { | ||
242 | unsigned char buffer[2]; | ||
243 | int err; | ||
244 | |||
245 | buffer[0] = subaddr; | ||
246 | buffer[1] = data; | ||
247 | |||
248 | encoder->reg[subaddr] = data; | ||
249 | |||
250 | DEBUG(printk | ||
251 | ("%s: write 0x%02X = 0x%02X\n", | ||
252 | encoder->i2c->name, subaddr, data)); | ||
253 | |||
254 | for (err = 0; err < 3;) { | ||
255 | if (i2c_master_send(encoder->i2c, buffer, 2) == 2) | ||
256 | break; | ||
257 | err++; | ||
258 | printk(KERN_WARNING "%s: I/O error #%d " | ||
259 | "(write 0x%02x/0x%02x)\n", | ||
260 | encoder->i2c->name, err, encoder->addr, subaddr); | ||
261 | schedule_timeout_interruptible(HZ/10); | ||
262 | } | ||
263 | if (err == 3) { | ||
264 | printk(KERN_WARNING "%s: giving up\n", | ||
265 | encoder->i2c->name); | ||
266 | return -1; | ||
267 | } | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int bt866_attach(struct i2c_adapter *adapter); | ||
273 | static int bt866_detach(struct i2c_client *client); | ||
274 | static int bt866_command(struct i2c_client *client, | ||
275 | unsigned int cmd, void *arg); | ||
276 | |||
277 | |||
278 | /* Addresses to scan */ | ||
279 | static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END}; | ||
280 | static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; | ||
281 | static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; | ||
282 | |||
283 | static struct i2c_client_address_data addr_data = { | ||
284 | normal_i2c, | ||
285 | probe, | ||
286 | ignore, | ||
287 | }; | ||
288 | |||
289 | static struct i2c_driver i2c_driver_bt866 = { | ||
290 | .driver.name = BT866_DEVNAME, | ||
291 | .id = I2C_DRIVERID_BT866, | ||
292 | .attach_adapter = bt866_attach, | ||
293 | .detach_client = bt866_detach, | ||
294 | .command = bt866_command | ||
295 | }; | ||
296 | |||
297 | |||
298 | static struct i2c_client bt866_client_tmpl = | ||
299 | { | ||
300 | .name = "(nil)", | ||
301 | .addr = 0, | ||
302 | .adapter = NULL, | ||
303 | .driver = &i2c_driver_bt866, | ||
304 | .usage_count = 0 | ||
305 | }; | ||
306 | |||
307 | static int bt866_found_proc(struct i2c_adapter *adapter, | ||
308 | int addr, int kind) | ||
309 | { | ||
310 | struct bt866 *encoder; | ||
311 | struct i2c_client *client; | ||
312 | |||
313 | client = kzalloc(sizeof(*client), GFP_KERNEL); | ||
314 | if (client == NULL) | ||
315 | return -ENOMEM; | ||
316 | memcpy(client, &bt866_client_tmpl, sizeof(*client)); | ||
317 | |||
318 | encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); | ||
319 | if (encoder == NULL) { | ||
320 | kfree(client); | ||
321 | return -ENOMEM; | ||
322 | } | ||
323 | |||
324 | i2c_set_clientdata(client, encoder); | ||
325 | client->adapter = adapter; | ||
326 | client->addr = addr; | ||
327 | sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id); | ||
328 | |||
329 | encoder->i2c = client; | ||
330 | encoder->addr = addr; | ||
331 | //encoder->encoder_type = ENCODER_TYPE_UNKNOWN; | ||
332 | |||
333 | /* initialize */ | ||
334 | |||
335 | i2c_attach_client(client); | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | static int bt866_attach(struct i2c_adapter *adapter) | ||
341 | { | ||
342 | if (adapter->id == I2C_HW_B_ZR36067) | ||
343 | return i2c_probe(adapter, &addr_data, bt866_found_proc); | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | static int bt866_detach(struct i2c_client *client) | ||
348 | { | ||
349 | struct bt866 *encoder = i2c_get_clientdata(client); | ||
350 | |||
351 | i2c_detach_client(client); | ||
352 | kfree(encoder); | ||
353 | kfree(client); | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int bt866_command(struct i2c_client *client, | ||
359 | unsigned int cmd, void *arg) | ||
360 | { | ||
361 | struct bt866 *encoder = i2c_get_clientdata(client); | ||
362 | return bt866_do_command(encoder, cmd, arg); | ||
363 | } | ||
364 | |||
365 | static int __devinit bt866_init(void) | ||
366 | { | ||
367 | i2c_add_driver(&i2c_driver_bt866); | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static void __devexit bt866_exit(void) | ||
372 | { | ||
373 | i2c_del_driver(&i2c_driver_bt866); | ||
374 | } | ||
375 | |||
376 | module_init(bt866_init); | ||
377 | module_exit(bt866_exit); | ||
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 2b64aa835b42..3116345c93b1 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -269,7 +269,7 @@ static struct CARD { | |||
269 | { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, | 269 | { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, |
270 | { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" }, | 270 | { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" }, |
271 | 271 | ||
272 | { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" }, | 272 | { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" }, |
273 | { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, | 273 | { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, |
274 | 274 | ||
275 | { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" }, | 275 | { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" }, |
@@ -309,6 +309,7 @@ static struct CARD { | |||
309 | { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, | 309 | { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, |
310 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, | 310 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, |
311 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, | 311 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, |
312 | { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "}, | ||
312 | 313 | ||
313 | { 0, -1, NULL } | 314 | { 0, -1, NULL } |
314 | }; | 315 | }; |
@@ -1903,7 +1904,7 @@ struct tvcard bttv_tvcards[] = { | |||
1903 | .no_tda7432 = 1, | 1904 | .no_tda7432 = 1, |
1904 | }, | 1905 | }, |
1905 | [BTTV_BOARD_OSPREY2x0] = { | 1906 | [BTTV_BOARD_OSPREY2x0] = { |
1906 | .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ | 1907 | .name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */ |
1907 | .video_inputs = 2, | 1908 | .video_inputs = 2, |
1908 | .audio_inputs = 1, | 1909 | .audio_inputs = 1, |
1909 | .tuner = -1, | 1910 | .tuner = -1, |
@@ -2745,7 +2746,7 @@ struct tvcard bttv_tvcards[] = { | |||
2745 | /* Michael Krufky <mkrufky@m1k.net> */ | 2746 | /* Michael Krufky <mkrufky@m1k.net> */ |
2746 | .name = "DViCO FusionHDTV 5 Lite", | 2747 | .name = "DViCO FusionHDTV 5 Lite", |
2747 | .tuner = 0, | 2748 | .tuner = 0, |
2748 | .tuner_type = TUNER_LG_TDVS_H062F, | 2749 | .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ |
2749 | .tuner_addr = ADDR_UNSET, | 2750 | .tuner_addr = ADDR_UNSET, |
2750 | .radio_addr = ADDR_UNSET, | 2751 | .radio_addr = ADDR_UNSET, |
2751 | .video_inputs = 3, | 2752 | .video_inputs = 3, |
@@ -2762,7 +2763,7 @@ struct tvcard bttv_tvcards[] = { | |||
2762 | }, | 2763 | }, |
2763 | /* ---- card 0x88---------------------------------- */ | 2764 | /* ---- card 0x88---------------------------------- */ |
2764 | [BTTV_BOARD_ACORP_Y878F] = { | 2765 | [BTTV_BOARD_ACORP_Y878F] = { |
2765 | /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */ | 2766 | /* Mauro Carvalho Chehab <mchehab@infradead.org> */ |
2766 | .name = "Acorp Y878F", | 2767 | .name = "Acorp Y878F", |
2767 | .video_inputs = 3, | 2768 | .video_inputs = 3, |
2768 | .audio_inputs = 1, | 2769 | .audio_inputs = 1, |
@@ -3790,6 +3791,7 @@ static void __devinit osprey_eeprom(struct bttv *btv) | |||
3790 | break; | 3791 | break; |
3791 | case 0x0060: | 3792 | case 0x0060: |
3792 | case 0x0070: | 3793 | case 0x0070: |
3794 | case 0x00A0: | ||
3793 | btv->c.type = BTTV_BOARD_OSPREY2x0; | 3795 | btv->c.type = BTTV_BOARD_OSPREY2x0; |
3794 | /* enable output on select control lines */ | 3796 | /* enable output on select control lines */ |
3795 | gpio_inout(0xffffff,0x000303); | 3797 | gpio_inout(0xffffff,0x000303); |
diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c index c4d5e2b70c28..ba081f6f8c82 100644 --- a/drivers/media/video/bt8xx/bttv-gpio.c +++ b/drivers/media/video/bt8xx/bttv-gpio.c | |||
@@ -118,20 +118,6 @@ int bttv_sub_del_devices(struct bttv_core *core) | |||
118 | return 0; | 118 | return 0; |
119 | } | 119 | } |
120 | 120 | ||
121 | void bttv_gpio_irq(struct bttv_core *core) | ||
122 | { | ||
123 | struct bttv_sub_driver *drv; | ||
124 | struct bttv_sub_device *dev; | ||
125 | struct list_head *item; | ||
126 | |||
127 | list_for_each(item,&core->subs) { | ||
128 | dev = list_entry(item,struct bttv_sub_device,list); | ||
129 | drv = to_bttv_sub_drv(dev->dev.driver); | ||
130 | if (drv && drv->gpio_irq) | ||
131 | drv->gpio_irq(dev); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | /* ----------------------------------------------------------------------- */ | 121 | /* ----------------------------------------------------------------------- */ |
136 | /* external: sub-driver register/unregister */ | 122 | /* external: sub-driver register/unregister */ |
137 | 123 | ||
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index 69efa0e5174d..b41f81d2372c 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c | |||
@@ -355,7 +355,7 @@ int bttv_input_init(struct bttv *btv) | |||
355 | 355 | ||
356 | if (ir->rc5_gpio) { | 356 | if (ir->rc5_gpio) { |
357 | u32 gpio; | 357 | u32 gpio; |
358 | /* enable remote irq */ | 358 | /* enable remote irq */ |
359 | bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4); | 359 | bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4); |
360 | gpio = bttv_gpio_read(&btv->c); | 360 | gpio = bttv_gpio_read(&btv->c); |
361 | bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); | 361 | bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); |
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index 3a23265c1538..f9c9e3c4d111 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h | |||
@@ -350,7 +350,6 @@ struct bttv_sub_driver { | |||
350 | char wanted[BUS_ID_SIZE]; | 350 | char wanted[BUS_ID_SIZE]; |
351 | int (*probe)(struct bttv_sub_device *sub); | 351 | int (*probe)(struct bttv_sub_device *sub); |
352 | void (*remove)(struct bttv_sub_device *sub); | 352 | void (*remove)(struct bttv_sub_device *sub); |
353 | void (*gpio_irq)(struct bttv_sub_device *sub); | ||
354 | }; | 353 | }; |
355 | #define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) | 354 | #define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) |
356 | 355 | ||
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index ee989d2e15d9..d2956010f763 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
34 | #include <linux/i2c-algo-bit.h> | 34 | #include <linux/i2c-algo-bit.h> |
35 | #include <linux/videodev.h> | 35 | #include <linux/videodev.h> |
36 | #include <media/v4l2-common.h> | ||
36 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
37 | #include <linux/input.h> | 38 | #include <linux/input.h> |
38 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
@@ -214,7 +215,6 @@ extern struct videobuf_queue_ops bttv_vbi_qops; | |||
214 | extern struct bus_type bttv_sub_bus_type; | 215 | extern struct bus_type bttv_sub_bus_type; |
215 | int bttv_sub_add_device(struct bttv_core *core, char *name); | 216 | int bttv_sub_add_device(struct bttv_core *core, char *name); |
216 | int bttv_sub_del_devices(struct bttv_core *core); | 217 | int bttv_sub_del_devices(struct bttv_core *core); |
217 | void bttv_gpio_irq(struct bttv_core *core); | ||
218 | 218 | ||
219 | 219 | ||
220 | /* ---------------------------------------------------------- */ | 220 | /* ---------------------------------------------------------- */ |
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index cf61c590f4ad..7d0b6e59c6e2 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c | |||
@@ -73,6 +73,7 @@ OTHER DEALINGS IN THE SOFTWARE. | |||
73 | #include <linux/parport.h> | 73 | #include <linux/parport.h> |
74 | #include <linux/sched.h> | 74 | #include <linux/sched.h> |
75 | #include <linux/videodev.h> | 75 | #include <linux/videodev.h> |
76 | #include <media/v4l2-common.h> | ||
76 | #include <linux/mutex.h> | 77 | #include <linux/mutex.h> |
77 | #include <asm/uaccess.h> | 78 | #include <asm/uaccess.h> |
78 | 79 | ||
@@ -759,7 +760,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, | |||
759 | { | 760 | { |
760 | struct video_picture *p = arg; | 761 | struct video_picture *p = arg; |
761 | if(p->palette!=VIDEO_PALETTE_GREY) | 762 | if(p->palette!=VIDEO_PALETTE_GREY) |
762 | return -EINVAL; | 763 | return -EINVAL; |
763 | if(p->depth!=4 && p->depth!=6) | 764 | if(p->depth!=4 && p->depth!=6) |
764 | return -EINVAL; | 765 | return -EINVAL; |
765 | 766 | ||
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 22a7386bbea6..a3989bd2f81b 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/parport.h> | 34 | #include <linux/parport.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/videodev.h> | 36 | #include <linux/videodev.h> |
37 | #include <media/v4l2-common.h> | ||
37 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
38 | 39 | ||
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 85d84e89d8f4..95c5aceecc5b 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c | |||
@@ -47,13 +47,6 @@ | |||
47 | 47 | ||
48 | #include "cpia.h" | 48 | #include "cpia.h" |
49 | 49 | ||
50 | #ifdef CONFIG_VIDEO_CPIA_PP | ||
51 | extern int cpia_pp_init(void); | ||
52 | #endif | ||
53 | #ifdef CONFIG_VIDEO_CPIA_USB | ||
54 | extern int cpia_usb_init(void); | ||
55 | #endif | ||
56 | |||
57 | static int video_nr = -1; | 50 | static int video_nr = -1; |
58 | 51 | ||
59 | #ifdef MODULE | 52 | #ifdef MODULE |
@@ -67,10 +60,10 @@ MODULE_SUPPORTED_DEVICE("video"); | |||
67 | static unsigned short colorspace_conv; | 60 | static unsigned short colorspace_conv; |
68 | module_param(colorspace_conv, ushort, 0444); | 61 | module_param(colorspace_conv, ushort, 0444); |
69 | MODULE_PARM_DESC(colorspace_conv, | 62 | MODULE_PARM_DESC(colorspace_conv, |
70 | " Colorspace conversion:" | 63 | " Colorspace conversion:" |
71 | "\n 0 = disable, 1 = enable" | 64 | "\n 0 = disable, 1 = enable" |
72 | "\n Default value is 0" | 65 | "\n Default value is 0" |
73 | ); | 66 | ); |
74 | 67 | ||
75 | #define ABOUT "V4L-Driver for Vision CPiA based cameras" | 68 | #define ABOUT "V4L-Driver for Vision CPiA based cameras" |
76 | 69 | ||
@@ -4047,13 +4040,6 @@ static int __init cpia_init(void) | |||
4047 | proc_cpia_create(); | 4040 | proc_cpia_create(); |
4048 | #endif | 4041 | #endif |
4049 | 4042 | ||
4050 | #ifdef CONFIG_VIDEO_CPIA_PP | ||
4051 | cpia_pp_init(); | ||
4052 | #endif | ||
4053 | #ifdef CONFIG_VIDEO_CPIA_USB | ||
4054 | cpia_usb_init(); | ||
4055 | #endif | ||
4056 | |||
4057 | return 0; | 4043 | return 0; |
4058 | } | 4044 | } |
4059 | 4045 | ||
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h index dde27a6a4a09..6eaa692021c5 100644 --- a/drivers/media/video/cpia.h +++ b/drivers/media/video/cpia.h | |||
@@ -45,6 +45,7 @@ | |||
45 | 45 | ||
46 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
47 | #include <linux/videodev.h> | 47 | #include <linux/videodev.h> |
48 | #include <media/v4l2-common.h> | ||
48 | #include <linux/list.h> | 49 | #include <linux/list.h> |
49 | #include <linux/smp_lock.h> | 50 | #include <linux/smp_lock.h> |
50 | #include <linux/mutex.h> | 51 | #include <linux/mutex.h> |
@@ -247,7 +248,7 @@ enum v4l_camstates { | |||
247 | struct cam_data { | 248 | struct cam_data { |
248 | struct list_head cam_data_list; | 249 | struct list_head cam_data_list; |
249 | 250 | ||
250 | struct mutex busy_lock; /* guard against SMP multithreading */ | 251 | struct mutex busy_lock; /* guard against SMP multithreading */ |
251 | struct cpia_camera_ops *ops; /* lowlevel driver operations */ | 252 | struct cpia_camera_ops *ops; /* lowlevel driver operations */ |
252 | void *lowlevel_data; /* private data for lowlevel driver */ | 253 | void *lowlevel_data; /* private data for lowlevel driver */ |
253 | u8 *raw_image; /* buffer for raw image data */ | 254 | u8 *raw_image; /* buffer for raw image data */ |
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h index 1764991b0ac9..c5ecb2be5f93 100644 --- a/drivers/media/video/cpia2/cpia2.h +++ b/drivers/media/video/cpia2/cpia2.h | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include <linux/version.h> | 34 | #include <linux/version.h> |
35 | #include <linux/videodev.h> | 35 | #include <linux/videodev.h> |
36 | #include <media/v4l2-common.h> | ||
36 | #include <linux/usb.h> | 37 | #include <linux/usb.h> |
37 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
38 | 39 | ||
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 481e178ef56d..d129db57fcd4 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
@@ -343,7 +343,9 @@ static int cpia2_close(struct inode *inode, struct file *file) | |||
343 | cpia2_free_buffers(cam); | 343 | cpia2_free_buffers(cam); |
344 | if (!cam->present) { | 344 | if (!cam->present) { |
345 | video_unregister_device(dev); | 345 | video_unregister_device(dev); |
346 | mutex_unlock(&cam->busy_lock); | ||
346 | kfree(cam); | 347 | kfree(cam); |
348 | return 0; | ||
347 | } | 349 | } |
348 | } | 350 | } |
349 | 351 | ||
@@ -1167,9 +1169,9 @@ static int ioctl_g_ctrl(void *arg,struct camera_data *cam) | |||
1167 | } else { | 1169 | } else { |
1168 | if(cam->params.flicker_control.cam_register & | 1170 | if(cam->params.flicker_control.cam_register & |
1169 | CPIA2_VP_FLICKER_MODES_50HZ) { | 1171 | CPIA2_VP_FLICKER_MODES_50HZ) { |
1170 | mode = FLICKER_50; | 1172 | mode = FLICKER_50; |
1171 | } else { | 1173 | } else { |
1172 | mode = FLICKER_60; | 1174 | mode = FLICKER_60; |
1173 | } | 1175 | } |
1174 | } | 1176 | } |
1175 | for(i=0; i<NUM_FLICKER_CONTROLS; i++) { | 1177 | for(i=0; i<NUM_FLICKER_CONTROLS; i++) { |
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c index 0b00e6027dfb..4c89bd395d3e 100644 --- a/drivers/media/video/cpia_pp.c +++ b/drivers/media/video/cpia_pp.c | |||
@@ -803,7 +803,7 @@ static struct parport_driver cpia_pp_driver = { | |||
803 | .detach = cpia_pp_detach, | 803 | .detach = cpia_pp_detach, |
804 | }; | 804 | }; |
805 | 805 | ||
806 | int cpia_pp_init(void) | 806 | static int cpia_pp_init(void) |
807 | { | 807 | { |
808 | printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, | 808 | printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, |
809 | CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER); | 809 | CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER); |
@@ -860,6 +860,8 @@ void cleanup_module(void) | |||
860 | 860 | ||
861 | static int __init cpia_pp_setup(char *str) | 861 | static int __init cpia_pp_setup(char *str) |
862 | { | 862 | { |
863 | int err; | ||
864 | |||
863 | if (!strncmp(str, "parport", 7)) { | 865 | if (!strncmp(str, "parport", 7)) { |
864 | int n = simple_strtoul(str + 7, NULL, 10); | 866 | int n = simple_strtoul(str + 7, NULL, 10); |
865 | if (parport_ptr < PARPORT_MAX) { | 867 | if (parport_ptr < PARPORT_MAX) { |
@@ -873,6 +875,10 @@ static int __init cpia_pp_setup(char *str) | |||
873 | parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE; | 875 | parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE; |
874 | } | 876 | } |
875 | 877 | ||
878 | err=cpia_pp_init(); | ||
879 | if (err) | ||
880 | return err; | ||
881 | |||
876 | return 1; | 882 | return 1; |
877 | } | 883 | } |
878 | 884 | ||
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c index 9c49a4b00116..2ee34a3b9280 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/media/video/cpia_usb.c | |||
@@ -474,12 +474,6 @@ static int cpia_usb_close(void *privdata) | |||
474 | return 0; | 474 | return 0; |
475 | } | 475 | } |
476 | 476 | ||
477 | int cpia_usb_init(void) | ||
478 | { | ||
479 | /* return -ENODEV; */ | ||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | /* Probing and initializing */ | 477 | /* Probing and initializing */ |
484 | 478 | ||
485 | static int cpia_probe(struct usb_interface *intf, | 479 | static int cpia_probe(struct usb_interface *intf, |
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c new file mode 100644 index 000000000000..554813e6f65d --- /dev/null +++ b/drivers/media/video/cx2341x.c | |||
@@ -0,0 +1,915 @@ | |||
1 | /* | ||
2 | * cx2341x - generic code for cx23415/6 based devices | ||
3 | * | ||
4 | * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/moduleparam.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/videodev2.h> | ||
29 | #include <linux/i2c.h> | ||
30 | |||
31 | #include <media/tuner.h> | ||
32 | #include <media/cx2341x.h> | ||
33 | #include <media/v4l2-common.h> | ||
34 | |||
35 | MODULE_DESCRIPTION("cx23415/6 driver"); | ||
36 | MODULE_AUTHOR("Hans Verkuil"); | ||
37 | MODULE_LICENSE("GPL"); | ||
38 | |||
39 | static int debug = 0; | ||
40 | module_param(debug, int, 0644); | ||
41 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | ||
42 | |||
43 | const u32 cx2341x_mpeg_ctrls[] = { | ||
44 | V4L2_CID_MPEG_CLASS, | ||
45 | V4L2_CID_MPEG_STREAM_TYPE, | ||
46 | V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, | ||
47 | V4L2_CID_MPEG_AUDIO_ENCODING, | ||
48 | V4L2_CID_MPEG_AUDIO_L2_BITRATE, | ||
49 | V4L2_CID_MPEG_AUDIO_MODE, | ||
50 | V4L2_CID_MPEG_AUDIO_MODE_EXTENSION, | ||
51 | V4L2_CID_MPEG_AUDIO_EMPHASIS, | ||
52 | V4L2_CID_MPEG_AUDIO_CRC, | ||
53 | V4L2_CID_MPEG_VIDEO_ENCODING, | ||
54 | V4L2_CID_MPEG_VIDEO_ASPECT, | ||
55 | V4L2_CID_MPEG_VIDEO_B_FRAMES, | ||
56 | V4L2_CID_MPEG_VIDEO_GOP_SIZE, | ||
57 | V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, | ||
58 | V4L2_CID_MPEG_VIDEO_PULLDOWN, | ||
59 | V4L2_CID_MPEG_VIDEO_BITRATE_MODE, | ||
60 | V4L2_CID_MPEG_VIDEO_BITRATE, | ||
61 | V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, | ||
62 | V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, | ||
63 | V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE, | ||
64 | V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER, | ||
65 | V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE, | ||
66 | V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE, | ||
67 | V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE, | ||
68 | V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER, | ||
69 | V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE, | ||
70 | V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM, | ||
71 | V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP, | ||
72 | V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM, | ||
73 | V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP, | ||
74 | 0 | ||
75 | }; | ||
76 | |||
77 | |||
78 | /* Map the control ID to the correct field in the cx2341x_mpeg_params | ||
79 | struct. Return -EINVAL if the ID is unknown, else return 0. */ | ||
80 | static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params, | ||
81 | struct v4l2_ext_control *ctrl) | ||
82 | { | ||
83 | switch (ctrl->id) { | ||
84 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | ||
85 | ctrl->value = params->audio_sampling_freq; | ||
86 | break; | ||
87 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
88 | ctrl->value = params->audio_encoding; | ||
89 | break; | ||
90 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: | ||
91 | ctrl->value = params->audio_l2_bitrate; | ||
92 | break; | ||
93 | case V4L2_CID_MPEG_AUDIO_MODE: | ||
94 | ctrl->value = params->audio_mode; | ||
95 | break; | ||
96 | case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: | ||
97 | ctrl->value = params->audio_mode_extension; | ||
98 | break; | ||
99 | case V4L2_CID_MPEG_AUDIO_EMPHASIS: | ||
100 | ctrl->value = params->audio_emphasis; | ||
101 | break; | ||
102 | case V4L2_CID_MPEG_AUDIO_CRC: | ||
103 | ctrl->value = params->audio_crc; | ||
104 | break; | ||
105 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
106 | ctrl->value = params->video_encoding; | ||
107 | break; | ||
108 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
109 | ctrl->value = params->video_aspect; | ||
110 | break; | ||
111 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
112 | ctrl->value = params->video_b_frames; | ||
113 | break; | ||
114 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | ||
115 | ctrl->value = params->video_gop_size; | ||
116 | break; | ||
117 | case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: | ||
118 | ctrl->value = params->video_gop_closure; | ||
119 | break; | ||
120 | case V4L2_CID_MPEG_VIDEO_PULLDOWN: | ||
121 | ctrl->value = params->video_pulldown; | ||
122 | break; | ||
123 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
124 | ctrl->value = params->video_bitrate_mode; | ||
125 | break; | ||
126 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
127 | ctrl->value = params->video_bitrate; | ||
128 | break; | ||
129 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
130 | ctrl->value = params->video_bitrate_peak; | ||
131 | break; | ||
132 | case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: | ||
133 | ctrl->value = params->video_temporal_decimation; | ||
134 | break; | ||
135 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
136 | ctrl->value = params->stream_type; | ||
137 | break; | ||
138 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: | ||
139 | ctrl->value = params->video_spatial_filter_mode; | ||
140 | break; | ||
141 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER: | ||
142 | ctrl->value = params->video_spatial_filter; | ||
143 | break; | ||
144 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: | ||
145 | ctrl->value = params->video_luma_spatial_filter_type; | ||
146 | break; | ||
147 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: | ||
148 | ctrl->value = params->video_chroma_spatial_filter_type; | ||
149 | break; | ||
150 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: | ||
151 | ctrl->value = params->video_temporal_filter_mode; | ||
152 | break; | ||
153 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER: | ||
154 | ctrl->value = params->video_temporal_filter; | ||
155 | break; | ||
156 | case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: | ||
157 | ctrl->value = params->video_median_filter_type; | ||
158 | break; | ||
159 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP: | ||
160 | ctrl->value = params->video_luma_median_filter_top; | ||
161 | break; | ||
162 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM: | ||
163 | ctrl->value = params->video_luma_median_filter_bottom; | ||
164 | break; | ||
165 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP: | ||
166 | ctrl->value = params->video_chroma_median_filter_top; | ||
167 | break; | ||
168 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: | ||
169 | ctrl->value = params->video_chroma_median_filter_bottom; | ||
170 | break; | ||
171 | default: | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | /* Map the control ID to the correct field in the cx2341x_mpeg_params | ||
178 | struct. Return -EINVAL if the ID is unknown, else return 0. */ | ||
179 | static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, | ||
180 | struct v4l2_ext_control *ctrl) | ||
181 | { | ||
182 | switch (ctrl->id) { | ||
183 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | ||
184 | params->audio_sampling_freq = ctrl->value; | ||
185 | break; | ||
186 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
187 | params->audio_encoding = ctrl->value; | ||
188 | break; | ||
189 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: | ||
190 | params->audio_l2_bitrate = ctrl->value; | ||
191 | break; | ||
192 | case V4L2_CID_MPEG_AUDIO_MODE: | ||
193 | params->audio_mode = ctrl->value; | ||
194 | break; | ||
195 | case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: | ||
196 | params->audio_mode_extension = ctrl->value; | ||
197 | break; | ||
198 | case V4L2_CID_MPEG_AUDIO_EMPHASIS: | ||
199 | params->audio_emphasis = ctrl->value; | ||
200 | break; | ||
201 | case V4L2_CID_MPEG_AUDIO_CRC: | ||
202 | params->audio_crc = ctrl->value; | ||
203 | break; | ||
204 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
205 | params->video_aspect = ctrl->value; | ||
206 | break; | ||
207 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: { | ||
208 | int b = ctrl->value + 1; | ||
209 | int gop = params->video_gop_size; | ||
210 | params->video_b_frames = ctrl->value; | ||
211 | params->video_gop_size = b * ((gop + b - 1) / b); | ||
212 | /* Max GOP size = 34 */ | ||
213 | while (params->video_gop_size > 34) | ||
214 | params->video_gop_size -= b; | ||
215 | break; | ||
216 | } | ||
217 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: { | ||
218 | int b = params->video_b_frames + 1; | ||
219 | int gop = ctrl->value; | ||
220 | params->video_gop_size = b * ((gop + b - 1) / b); | ||
221 | /* Max GOP size = 34 */ | ||
222 | while (params->video_gop_size > 34) | ||
223 | params->video_gop_size -= b; | ||
224 | ctrl->value = params->video_gop_size; | ||
225 | break; | ||
226 | } | ||
227 | case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: | ||
228 | params->video_gop_closure = ctrl->value; | ||
229 | break; | ||
230 | case V4L2_CID_MPEG_VIDEO_PULLDOWN: | ||
231 | params->video_pulldown = ctrl->value; | ||
232 | break; | ||
233 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
234 | /* MPEG-1 only allows CBR */ | ||
235 | if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 && | ||
236 | ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) | ||
237 | return -EINVAL; | ||
238 | params->video_bitrate_mode = ctrl->value; | ||
239 | break; | ||
240 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
241 | params->video_bitrate = ctrl->value; | ||
242 | break; | ||
243 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
244 | params->video_bitrate_peak = ctrl->value; | ||
245 | break; | ||
246 | case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: | ||
247 | params->video_temporal_decimation = ctrl->value; | ||
248 | break; | ||
249 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
250 | params->stream_type = ctrl->value; | ||
251 | params->video_encoding = | ||
252 | (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS || | ||
253 | params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ? | ||
254 | V4L2_MPEG_VIDEO_ENCODING_MPEG_1 : V4L2_MPEG_VIDEO_ENCODING_MPEG_2; | ||
255 | if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) { | ||
256 | /* MPEG-1 implies CBR */ | ||
257 | params->video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; | ||
258 | } | ||
259 | break; | ||
260 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: | ||
261 | params->video_spatial_filter_mode = ctrl->value; | ||
262 | break; | ||
263 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER: | ||
264 | params->video_spatial_filter = ctrl->value; | ||
265 | break; | ||
266 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: | ||
267 | params->video_luma_spatial_filter_type = ctrl->value; | ||
268 | break; | ||
269 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: | ||
270 | params->video_chroma_spatial_filter_type = ctrl->value; | ||
271 | break; | ||
272 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: | ||
273 | params->video_temporal_filter_mode = ctrl->value; | ||
274 | break; | ||
275 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER: | ||
276 | params->video_temporal_filter = ctrl->value; | ||
277 | break; | ||
278 | case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: | ||
279 | params->video_median_filter_type = ctrl->value; | ||
280 | break; | ||
281 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP: | ||
282 | params->video_luma_median_filter_top = ctrl->value; | ||
283 | break; | ||
284 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM: | ||
285 | params->video_luma_median_filter_bottom = ctrl->value; | ||
286 | break; | ||
287 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP: | ||
288 | params->video_chroma_median_filter_top = ctrl->value; | ||
289 | break; | ||
290 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: | ||
291 | params->video_chroma_median_filter_bottom = ctrl->value; | ||
292 | break; | ||
293 | default: | ||
294 | return -EINVAL; | ||
295 | } | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def) | ||
300 | { | ||
301 | const char *name; | ||
302 | |||
303 | qctrl->flags = 0; | ||
304 | switch (qctrl->id) { | ||
305 | /* MPEG controls */ | ||
306 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: | ||
307 | name = "Spatial Filter Mode"; | ||
308 | break; | ||
309 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER: | ||
310 | name = "Spatial Filter"; | ||
311 | break; | ||
312 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: | ||
313 | name = "Spatial Luma Filter Type"; | ||
314 | break; | ||
315 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: | ||
316 | name = "Spatial Chroma Filter Type"; | ||
317 | break; | ||
318 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: | ||
319 | name = "Temporal Filter Mode"; | ||
320 | break; | ||
321 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER: | ||
322 | name = "Temporal Filter"; | ||
323 | break; | ||
324 | case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: | ||
325 | name = "Median Filter Type"; | ||
326 | break; | ||
327 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP: | ||
328 | name = "Median Luma Filter Maximum"; | ||
329 | break; | ||
330 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM: | ||
331 | name = "Median Luma Filter Minimum"; | ||
332 | break; | ||
333 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP: | ||
334 | name = "Median Chroma Filter Maximum"; | ||
335 | break; | ||
336 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: | ||
337 | name = "Median Chroma Filter Minimum"; | ||
338 | break; | ||
339 | |||
340 | default: | ||
341 | return v4l2_ctrl_query_fill(qctrl, min, max, step, def); | ||
342 | } | ||
343 | switch (qctrl->id) { | ||
344 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: | ||
345 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: | ||
346 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: | ||
347 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: | ||
348 | case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: | ||
349 | qctrl->type = V4L2_CTRL_TYPE_MENU; | ||
350 | min = 0; | ||
351 | step = 1; | ||
352 | break; | ||
353 | default: | ||
354 | qctrl->type = V4L2_CTRL_TYPE_INTEGER; | ||
355 | break; | ||
356 | } | ||
357 | switch (qctrl->id) { | ||
358 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: | ||
359 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: | ||
360 | case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: | ||
361 | qctrl->flags |= V4L2_CTRL_FLAG_UPDATE; | ||
362 | break; | ||
363 | } | ||
364 | qctrl->minimum = min; | ||
365 | qctrl->maximum = max; | ||
366 | qctrl->step = step; | ||
367 | qctrl->default_value = def; | ||
368 | qctrl->reserved[0] = qctrl->reserved[1] = 0; | ||
369 | snprintf(qctrl->name, sizeof(qctrl->name), name); | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, struct v4l2_queryctrl *qctrl) | ||
374 | { | ||
375 | int err; | ||
376 | |||
377 | switch (qctrl->id) { | ||
378 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
379 | return v4l2_ctrl_query_fill(qctrl, | ||
380 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2, | ||
381 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1, | ||
382 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2); | ||
383 | |||
384 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: | ||
385 | return v4l2_ctrl_query_fill(qctrl, | ||
386 | V4L2_MPEG_AUDIO_L2_BITRATE_192K, | ||
387 | V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, | ||
388 | V4L2_MPEG_AUDIO_L2_BITRATE_224K); | ||
389 | |||
390 | case V4L2_CID_MPEG_AUDIO_L1_BITRATE: | ||
391 | case V4L2_CID_MPEG_AUDIO_L3_BITRATE: | ||
392 | return -EINVAL; | ||
393 | |||
394 | case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: | ||
395 | err = v4l2_ctrl_query_fill_std(qctrl); | ||
396 | if (err == 0 && params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) | ||
397 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
398 | return err; | ||
399 | |||
400 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
401 | /* this setting is read-only for the cx2341x since the | ||
402 | V4L2_CID_MPEG_STREAM_TYPE really determines the | ||
403 | MPEG-1/2 setting */ | ||
404 | err = v4l2_ctrl_query_fill_std(qctrl); | ||
405 | if (err == 0) | ||
406 | qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; | ||
407 | return err; | ||
408 | |||
409 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
410 | err = v4l2_ctrl_query_fill_std(qctrl); | ||
411 | if (err == 0 && params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) | ||
412 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
413 | return err; | ||
414 | |||
415 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
416 | err = v4l2_ctrl_query_fill_std(qctrl); | ||
417 | if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) | ||
418 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
419 | return err; | ||
420 | |||
421 | /* CX23415/6 specific */ | ||
422 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: | ||
423 | return cx2341x_ctrl_query_fill(qctrl, | ||
424 | V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL, | ||
425 | V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1, | ||
426 | V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL); | ||
427 | |||
428 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER: | ||
429 | cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0); | ||
430 | qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; | ||
431 | if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO) | ||
432 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
433 | return 0; | ||
434 | |||
435 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: | ||
436 | cx2341x_ctrl_query_fill(qctrl, | ||
437 | V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF, | ||
438 | V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE, 1, | ||
439 | V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF); | ||
440 | if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO) | ||
441 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
442 | return 0; | ||
443 | |||
444 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: | ||
445 | cx2341x_ctrl_query_fill(qctrl, | ||
446 | V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF, | ||
447 | V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, 1, | ||
448 | V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF); | ||
449 | if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO) | ||
450 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
451 | return 0; | ||
452 | |||
453 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: | ||
454 | return cx2341x_ctrl_query_fill(qctrl, | ||
455 | V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL, | ||
456 | V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1, | ||
457 | V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL); | ||
458 | |||
459 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER: | ||
460 | cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0); | ||
461 | qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; | ||
462 | if (params->video_temporal_filter_mode == V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO) | ||
463 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
464 | return 0; | ||
465 | |||
466 | case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: | ||
467 | return cx2341x_ctrl_query_fill(qctrl, | ||
468 | V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF, | ||
469 | V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1, | ||
470 | V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF); | ||
471 | |||
472 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP: | ||
473 | cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255); | ||
474 | qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; | ||
475 | if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) | ||
476 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
477 | return 0; | ||
478 | |||
479 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM: | ||
480 | cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0); | ||
481 | qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; | ||
482 | if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) | ||
483 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
484 | return 0; | ||
485 | |||
486 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP: | ||
487 | cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255); | ||
488 | qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; | ||
489 | if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) | ||
490 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
491 | return 0; | ||
492 | |||
493 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: | ||
494 | cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0); | ||
495 | qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; | ||
496 | if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) | ||
497 | qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | ||
498 | return 0; | ||
499 | |||
500 | default: | ||
501 | return v4l2_ctrl_query_fill_std(qctrl); | ||
502 | |||
503 | } | ||
504 | } | ||
505 | |||
506 | const char **cx2341x_ctrl_get_menu(u32 id) | ||
507 | { | ||
508 | static const char *mpeg_stream_type[] = { | ||
509 | "MPEG-2 Program Stream", | ||
510 | "", | ||
511 | "MPEG-1 System Stream", | ||
512 | "MPEG-2 DVD-compatible Stream", | ||
513 | "MPEG-1 VCD-compatible Stream", | ||
514 | "MPEG-2 SVCD-compatible Stream", | ||
515 | NULL | ||
516 | }; | ||
517 | |||
518 | static const char *cx2341x_video_spatial_filter_mode_menu[] = { | ||
519 | "Manual", | ||
520 | "Auto", | ||
521 | NULL | ||
522 | }; | ||
523 | |||
524 | static const char *cx2341x_video_luma_spatial_filter_type_menu[] = { | ||
525 | "Off", | ||
526 | "1D Horizontal", | ||
527 | "1D Vertical", | ||
528 | "2D H/V Separable", | ||
529 | "2D Symmetric non-separable", | ||
530 | NULL | ||
531 | }; | ||
532 | |||
533 | static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = { | ||
534 | "Off", | ||
535 | "1D Horizontal", | ||
536 | NULL | ||
537 | }; | ||
538 | |||
539 | static const char *cx2341x_video_temporal_filter_mode_menu[] = { | ||
540 | "Manual", | ||
541 | "Auto", | ||
542 | NULL | ||
543 | }; | ||
544 | |||
545 | static const char *cx2341x_video_median_filter_type_menu[] = { | ||
546 | "Off", | ||
547 | "Horizontal", | ||
548 | "Vertical", | ||
549 | "Horizontal/Vertical", | ||
550 | "Diagonal", | ||
551 | NULL | ||
552 | }; | ||
553 | |||
554 | switch (id) { | ||
555 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
556 | return mpeg_stream_type; | ||
557 | case V4L2_CID_MPEG_AUDIO_L1_BITRATE: | ||
558 | case V4L2_CID_MPEG_AUDIO_L3_BITRATE: | ||
559 | return NULL; | ||
560 | case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: | ||
561 | return cx2341x_video_spatial_filter_mode_menu; | ||
562 | case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: | ||
563 | return cx2341x_video_luma_spatial_filter_type_menu; | ||
564 | case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: | ||
565 | return cx2341x_video_chroma_spatial_filter_type_menu; | ||
566 | case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: | ||
567 | return cx2341x_video_temporal_filter_mode_menu; | ||
568 | case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: | ||
569 | return cx2341x_video_median_filter_type_menu; | ||
570 | default: | ||
571 | return v4l2_ctrl_get_menu(id); | ||
572 | } | ||
573 | } | ||
574 | |||
575 | static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params) | ||
576 | { | ||
577 | params->audio_properties = (params->audio_sampling_freq << 0) | | ||
578 | ((3 - params->audio_encoding) << 2) | | ||
579 | ((1 + params->audio_l2_bitrate) << 4) | | ||
580 | (params->audio_mode << 8) | | ||
581 | (params->audio_mode_extension << 10) | | ||
582 | (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17) ? | ||
583 | 3 : | ||
584 | params->audio_emphasis) << 12) | | ||
585 | (params->audio_crc << 14); | ||
586 | } | ||
587 | |||
588 | int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, | ||
589 | struct v4l2_ext_controls *ctrls, int cmd) | ||
590 | { | ||
591 | int err = 0; | ||
592 | int i; | ||
593 | |||
594 | if (cmd == VIDIOC_G_EXT_CTRLS) { | ||
595 | for (i = 0; i < ctrls->count; i++) { | ||
596 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
597 | |||
598 | err = cx2341x_get_ctrl(params, ctrl); | ||
599 | if (err) { | ||
600 | ctrls->error_idx = i; | ||
601 | break; | ||
602 | } | ||
603 | } | ||
604 | return err; | ||
605 | } | ||
606 | for (i = 0; i < ctrls->count; i++) { | ||
607 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
608 | struct v4l2_queryctrl qctrl; | ||
609 | const char **menu_items = NULL; | ||
610 | |||
611 | qctrl.id = ctrl->id; | ||
612 | err = cx2341x_ctrl_query(params, &qctrl); | ||
613 | if (err) | ||
614 | break; | ||
615 | if (qctrl.type == V4L2_CTRL_TYPE_MENU) | ||
616 | menu_items = cx2341x_ctrl_get_menu(qctrl.id); | ||
617 | err = v4l2_ctrl_check(ctrl, &qctrl, menu_items); | ||
618 | if (err) | ||
619 | break; | ||
620 | err = cx2341x_set_ctrl(params, ctrl); | ||
621 | if (err) | ||
622 | break; | ||
623 | } | ||
624 | if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && | ||
625 | params->video_bitrate_peak < params->video_bitrate) { | ||
626 | err = -ERANGE; | ||
627 | ctrls->error_idx = ctrls->count; | ||
628 | } | ||
629 | if (err) { | ||
630 | ctrls->error_idx = i; | ||
631 | } | ||
632 | else { | ||
633 | cx2341x_calc_audio_properties(params); | ||
634 | } | ||
635 | return err; | ||
636 | } | ||
637 | |||
638 | void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p) | ||
639 | { | ||
640 | static struct cx2341x_mpeg_params default_params = { | ||
641 | /* misc */ | ||
642 | .port = CX2341X_PORT_MEMORY, | ||
643 | .width = 720, | ||
644 | .height = 480, | ||
645 | .is_50hz = 0, | ||
646 | |||
647 | /* stream */ | ||
648 | .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS, | ||
649 | |||
650 | /* audio */ | ||
651 | .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, | ||
652 | .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2, | ||
653 | .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K, | ||
654 | .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO, | ||
655 | .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, | ||
656 | .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE, | ||
657 | .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE, | ||
658 | |||
659 | /* video */ | ||
660 | .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2, | ||
661 | .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3, | ||
662 | .video_b_frames = 2, | ||
663 | .video_gop_size = 12, | ||
664 | .video_gop_closure = 1, | ||
665 | .video_pulldown = 0, | ||
666 | .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, | ||
667 | .video_bitrate = 6000000, | ||
668 | .video_bitrate_peak = 8000000, | ||
669 | .video_temporal_decimation = 0, | ||
670 | |||
671 | /* encoding filters */ | ||
672 | .video_spatial_filter_mode = V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL, | ||
673 | .video_spatial_filter = 0, | ||
674 | .video_luma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR, | ||
675 | .video_chroma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, | ||
676 | .video_temporal_filter_mode = V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL, | ||
677 | .video_temporal_filter = 0, | ||
678 | .video_median_filter_type = V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF, | ||
679 | .video_luma_median_filter_top = 255, | ||
680 | .video_luma_median_filter_bottom = 0, | ||
681 | .video_chroma_median_filter_top = 255, | ||
682 | .video_chroma_median_filter_bottom = 0, | ||
683 | }; | ||
684 | |||
685 | *p = default_params; | ||
686 | cx2341x_calc_audio_properties(p); | ||
687 | } | ||
688 | |||
689 | static int cx2341x_api(void *priv, cx2341x_mbox_func func, int cmd, int args, ...) | ||
690 | { | ||
691 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
692 | va_list vargs; | ||
693 | int i; | ||
694 | |||
695 | va_start(vargs, args); | ||
696 | |||
697 | for (i = 0; i < args; i++) { | ||
698 | data[i] = va_arg(vargs, int); | ||
699 | } | ||
700 | va_end(vargs); | ||
701 | return func(priv, cmd, args, 0, data); | ||
702 | } | ||
703 | |||
704 | int cx2341x_update(void *priv, cx2341x_mbox_func func, | ||
705 | const struct cx2341x_mpeg_params *old, const struct cx2341x_mpeg_params *new) | ||
706 | { | ||
707 | static int mpeg_stream_type[] = { | ||
708 | 0, /* MPEG-2 PS */ | ||
709 | 1, /* MPEG-2 TS */ | ||
710 | 2, /* MPEG-1 SS */ | ||
711 | 14, /* DVD */ | ||
712 | 11, /* VCD */ | ||
713 | 12, /* SVCD */ | ||
714 | }; | ||
715 | |||
716 | int err = 0; | ||
717 | |||
718 | cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0); | ||
719 | |||
720 | if (old == NULL || old->is_50hz != new->is_50hz) { | ||
721 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, new->is_50hz); | ||
722 | if (err) return err; | ||
723 | } | ||
724 | |||
725 | if (old == NULL || old->width != new->width || old->height != new->height || | ||
726 | old->video_encoding != new->video_encoding) { | ||
727 | u16 w = new->width; | ||
728 | u16 h = new->height; | ||
729 | |||
730 | if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) { | ||
731 | w /= 2; | ||
732 | h /= 2; | ||
733 | } | ||
734 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w); | ||
735 | if (err) return err; | ||
736 | } | ||
737 | |||
738 | if (old == NULL || old->stream_type != new->stream_type) { | ||
739 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[new->stream_type]); | ||
740 | if (err) return err; | ||
741 | } | ||
742 | if (old == NULL || old->video_aspect != new->video_aspect) { | ||
743 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1, 1 + new->video_aspect); | ||
744 | if (err) return err; | ||
745 | } | ||
746 | if (old == NULL || old->video_b_frames != new->video_b_frames || | ||
747 | old->video_gop_size != new->video_gop_size) { | ||
748 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2, | ||
749 | new->video_gop_size, new->video_b_frames + 1); | ||
750 | if (err) return err; | ||
751 | } | ||
752 | if (old == NULL || old->video_gop_closure != new->video_gop_closure) { | ||
753 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1, new->video_gop_closure); | ||
754 | if (err) return err; | ||
755 | } | ||
756 | if (old == NULL || old->video_pulldown != new->video_pulldown) { | ||
757 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_3_2_PULLDOWN, 1, new->video_pulldown); | ||
758 | if (err) return err; | ||
759 | } | ||
760 | if (old == NULL || old->audio_properties != new->audio_properties) { | ||
761 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new->audio_properties); | ||
762 | if (err) return err; | ||
763 | } | ||
764 | if (old == NULL || old->video_bitrate_mode != new->video_bitrate_mode || | ||
765 | old->video_bitrate != new->video_bitrate || | ||
766 | old->video_bitrate_peak != new->video_bitrate_peak) { | ||
767 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5, | ||
768 | new->video_bitrate_mode, new->video_bitrate, | ||
769 | new->video_bitrate_peak / 400, 0, 0); | ||
770 | if (err) return err; | ||
771 | } | ||
772 | if (old == NULL || old->video_spatial_filter_mode != new->video_spatial_filter_mode || | ||
773 | old->video_temporal_filter_mode != new->video_temporal_filter_mode || | ||
774 | old->video_median_filter_type != new->video_median_filter_type) { | ||
775 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE, 2, | ||
776 | new->video_spatial_filter_mode | (new->video_temporal_filter_mode << 1), | ||
777 | new->video_median_filter_type); | ||
778 | if (err) return err; | ||
779 | } | ||
780 | if (old == NULL || | ||
781 | old->video_luma_median_filter_bottom != new->video_luma_median_filter_bottom || | ||
782 | old->video_luma_median_filter_top != new->video_luma_median_filter_top || | ||
783 | old->video_chroma_median_filter_bottom != new->video_chroma_median_filter_bottom || | ||
784 | old->video_chroma_median_filter_top != new->video_chroma_median_filter_top) { | ||
785 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4, | ||
786 | new->video_luma_median_filter_bottom, | ||
787 | new->video_luma_median_filter_top, | ||
788 | new->video_chroma_median_filter_bottom, | ||
789 | new->video_chroma_median_filter_top); | ||
790 | if (err) return err; | ||
791 | } | ||
792 | if (old == NULL || | ||
793 | old->video_luma_spatial_filter_type != new->video_luma_spatial_filter_type || | ||
794 | old->video_chroma_spatial_filter_type != new->video_chroma_spatial_filter_type) { | ||
795 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2, | ||
796 | new->video_luma_spatial_filter_type, new->video_chroma_spatial_filter_type); | ||
797 | if (err) return err; | ||
798 | } | ||
799 | if (old == NULL || | ||
800 | old->video_spatial_filter != new->video_spatial_filter || | ||
801 | old->video_temporal_filter != new->video_temporal_filter) { | ||
802 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2, | ||
803 | new->video_spatial_filter, new->video_temporal_filter); | ||
804 | if (err) return err; | ||
805 | } | ||
806 | if (old == NULL || old->video_temporal_decimation != new->video_temporal_decimation) { | ||
807 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE, 1, | ||
808 | new->video_temporal_decimation); | ||
809 | if (err) return err; | ||
810 | } | ||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id) | ||
815 | { | ||
816 | const char **menu = cx2341x_ctrl_get_menu(id); | ||
817 | struct v4l2_ext_control ctrl; | ||
818 | |||
819 | if (menu == NULL) | ||
820 | goto invalid; | ||
821 | ctrl.id = id; | ||
822 | if (cx2341x_get_ctrl(p, &ctrl)) | ||
823 | goto invalid; | ||
824 | while (ctrl.value-- && *menu) menu++; | ||
825 | if (*menu == NULL) | ||
826 | goto invalid; | ||
827 | return *menu; | ||
828 | |||
829 | invalid: | ||
830 | return "<invalid>"; | ||
831 | } | ||
832 | |||
833 | void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id) | ||
834 | { | ||
835 | int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; | ||
836 | |||
837 | /* Stream */ | ||
838 | printk(KERN_INFO "cx2341x-%d: Stream: %s\n", | ||
839 | card_id, | ||
840 | cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE)); | ||
841 | |||
842 | /* Video */ | ||
843 | printk(KERN_INFO "cx2341x-%d: Video: %dx%d, %d fps\n", | ||
844 | card_id, | ||
845 | p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1), | ||
846 | p->is_50hz ? 25 : 30); | ||
847 | printk(KERN_INFO "cx2341x-%d: Video: %s, %s, %s, %d", | ||
848 | card_id, | ||
849 | cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING), | ||
850 | cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT), | ||
851 | cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE), | ||
852 | p->video_bitrate); | ||
853 | if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { | ||
854 | printk(", Peak %d", p->video_bitrate_peak); | ||
855 | } | ||
856 | printk("\n"); | ||
857 | printk(KERN_INFO "cx2341x-%d: Video: GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n", | ||
858 | card_id, | ||
859 | p->video_gop_size, p->video_b_frames, | ||
860 | p->video_gop_closure ? "" : "No ", | ||
861 | p->video_pulldown ? "" : "No "); | ||
862 | if (p->video_temporal_decimation) { | ||
863 | printk(KERN_INFO "cx2341x-%d: Video: Temporal Decimation %d\n", | ||
864 | card_id, p->video_temporal_decimation); | ||
865 | } | ||
866 | |||
867 | /* Audio */ | ||
868 | printk(KERN_INFO "cx2341x-%d: Audio: %s, %s, %s, %s", | ||
869 | card_id, | ||
870 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ), | ||
871 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING), | ||
872 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE), | ||
873 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE)); | ||
874 | if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) { | ||
875 | printk(", %s", | ||
876 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION)); | ||
877 | } | ||
878 | printk(", %s, %s\n", | ||
879 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS), | ||
880 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC)); | ||
881 | |||
882 | /* Encoding filters */ | ||
883 | printk(KERN_INFO "cx2341x-%d: Spatial Filter: %s, Luma %s, Chroma %s, %d\n", | ||
884 | card_id, | ||
885 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE), | ||
886 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE), | ||
887 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE), | ||
888 | p->video_spatial_filter); | ||
889 | printk(KERN_INFO "cx2341x-%d: Temporal Filter: %s, %d\n", | ||
890 | card_id, | ||
891 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE), | ||
892 | p->video_temporal_filter); | ||
893 | printk(KERN_INFO "cx2341x-%d: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", | ||
894 | card_id, | ||
895 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE), | ||
896 | p->video_luma_median_filter_bottom, | ||
897 | p->video_luma_median_filter_top, | ||
898 | p->video_chroma_median_filter_bottom, | ||
899 | p->video_chroma_median_filter_top); | ||
900 | } | ||
901 | |||
902 | EXPORT_SYMBOL(cx2341x_fill_defaults); | ||
903 | EXPORT_SYMBOL(cx2341x_ctrl_query); | ||
904 | EXPORT_SYMBOL(cx2341x_ctrl_get_menu); | ||
905 | EXPORT_SYMBOL(cx2341x_ext_ctrls); | ||
906 | EXPORT_SYMBOL(cx2341x_update); | ||
907 | EXPORT_SYMBOL(cx2341x_log_status); | ||
908 | EXPORT_SYMBOL(cx2341x_mpeg_ctrls); | ||
909 | |||
910 | /* | ||
911 | * Local variables: | ||
912 | * c-basic-offset: 8 | ||
913 | * End: | ||
914 | */ | ||
915 | |||
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index 9a4b813152e5..f897c1ebd5f3 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c | |||
@@ -30,9 +30,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
30 | if (freq != 32000 && freq != 44100 && freq != 48000) | 30 | if (freq != 32000 && freq != 44100 && freq != 48000) |
31 | return -EINVAL; | 31 | return -EINVAL; |
32 | 32 | ||
33 | /* assert soft reset */ | ||
34 | cx25840_and_or(client, 0x810, ~0x1, 0x01); | ||
35 | |||
36 | /* common for all inputs and rates */ | 33 | /* common for all inputs and rates */ |
37 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ | 34 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ |
38 | cx25840_write(client, 0x127, 0x50); | 35 | cx25840_write(client, 0x127, 0x50); |
@@ -46,6 +43,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
46 | /* AUX_PLL_FRAC */ | 43 | /* AUX_PLL_FRAC */ |
47 | cx25840_write4(client, 0x110, 0xee39bb01); | 44 | cx25840_write4(client, 0x110, 0xee39bb01); |
48 | 45 | ||
46 | if (state->is_cx25836) | ||
47 | break; | ||
48 | |||
49 | /* src3/4/6_ctl = 0x0801f77f */ | 49 | /* src3/4/6_ctl = 0x0801f77f */ |
50 | cx25840_write4(client, 0x900, 0x7ff70108); | 50 | cx25840_write4(client, 0x900, 0x7ff70108); |
51 | cx25840_write4(client, 0x904, 0x7ff70108); | 51 | cx25840_write4(client, 0x904, 0x7ff70108); |
@@ -59,6 +59,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
59 | /* AUX_PLL_FRAC */ | 59 | /* AUX_PLL_FRAC */ |
60 | cx25840_write4(client, 0x110, 0xd66bec00); | 60 | cx25840_write4(client, 0x110, 0xd66bec00); |
61 | 61 | ||
62 | if (state->is_cx25836) | ||
63 | break; | ||
64 | |||
62 | /* src3/4/6_ctl = 0x08016d59 */ | 65 | /* src3/4/6_ctl = 0x08016d59 */ |
63 | cx25840_write4(client, 0x900, 0x596d0108); | 66 | cx25840_write4(client, 0x900, 0x596d0108); |
64 | cx25840_write4(client, 0x904, 0x596d0108); | 67 | cx25840_write4(client, 0x904, 0x596d0108); |
@@ -72,6 +75,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
72 | /* AUX_PLL_FRAC */ | 75 | /* AUX_PLL_FRAC */ |
73 | cx25840_write4(client, 0x110, 0xe5d69800); | 76 | cx25840_write4(client, 0x110, 0xe5d69800); |
74 | 77 | ||
78 | if (state->is_cx25836) | ||
79 | break; | ||
80 | |||
75 | /* src3/4/6_ctl = 0x08014faa */ | 81 | /* src3/4/6_ctl = 0x08014faa */ |
76 | cx25840_write4(client, 0x900, 0xaa4f0108); | 82 | cx25840_write4(client, 0x900, 0xaa4f0108); |
77 | cx25840_write4(client, 0x904, 0xaa4f0108); | 83 | cx25840_write4(client, 0x904, 0xaa4f0108); |
@@ -87,6 +93,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
87 | /* AUX_PLL_FRAC */ | 93 | /* AUX_PLL_FRAC */ |
88 | cx25840_write4(client, 0x110, 0x69082a01); | 94 | cx25840_write4(client, 0x110, 0x69082a01); |
89 | 95 | ||
96 | if (state->is_cx25836) | ||
97 | break; | ||
98 | |||
90 | /* src1_ctl = 0x08010000 */ | 99 | /* src1_ctl = 0x08010000 */ |
91 | cx25840_write4(client, 0x8f8, 0x00000108); | 100 | cx25840_write4(client, 0x8f8, 0x00000108); |
92 | 101 | ||
@@ -106,6 +115,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
106 | /* AUX_PLL_FRAC */ | 115 | /* AUX_PLL_FRAC */ |
107 | cx25840_write4(client, 0x110, 0xd66bec00); | 116 | cx25840_write4(client, 0x110, 0xd66bec00); |
108 | 117 | ||
118 | if (state->is_cx25836) | ||
119 | break; | ||
120 | |||
109 | /* src1_ctl = 0x08010000 */ | 121 | /* src1_ctl = 0x08010000 */ |
110 | cx25840_write4(client, 0x8f8, 0xcd600108); | 122 | cx25840_write4(client, 0x8f8, 0xcd600108); |
111 | 123 | ||
@@ -122,6 +134,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
122 | /* AUX_PLL_FRAC */ | 134 | /* AUX_PLL_FRAC */ |
123 | cx25840_write4(client, 0x110, 0xe5d69800); | 135 | cx25840_write4(client, 0x110, 0xe5d69800); |
124 | 136 | ||
137 | if (state->is_cx25836) | ||
138 | break; | ||
139 | |||
125 | /* src1_ctl = 0x08010000 */ | 140 | /* src1_ctl = 0x08010000 */ |
126 | cx25840_write4(client, 0x8f8, 0x00800108); | 141 | cx25840_write4(client, 0x8f8, 0x00800108); |
127 | 142 | ||
@@ -133,9 +148,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
133 | } | 148 | } |
134 | } | 149 | } |
135 | 150 | ||
136 | /* deassert soft reset */ | ||
137 | cx25840_and_or(client, 0x810, ~0x1, 0x00); | ||
138 | |||
139 | state->audclk_freq = freq; | 151 | state->audclk_freq = freq; |
140 | 152 | ||
141 | return 0; | 153 | return 0; |
@@ -148,6 +160,10 @@ void cx25840_audio_set_path(struct i2c_client *client) | |||
148 | /* stop microcontroller */ | 160 | /* stop microcontroller */ |
149 | cx25840_and_or(client, 0x803, ~0x10, 0); | 161 | cx25840_and_or(client, 0x803, ~0x10, 0); |
150 | 162 | ||
163 | /* assert soft reset */ | ||
164 | if (!state->is_cx25836) | ||
165 | cx25840_and_or(client, 0x810, ~0x1, 0x01); | ||
166 | |||
151 | /* Mute everything to prevent the PFFT! */ | 167 | /* Mute everything to prevent the PFFT! */ |
152 | cx25840_write(client, 0x8d3, 0x1f); | 168 | cx25840_write(client, 0x8d3, 0x1f); |
153 | 169 | ||
@@ -161,13 +177,19 @@ void cx25840_audio_set_path(struct i2c_client *client) | |||
161 | } else { | 177 | } else { |
162 | /* Set Path1 to Analog Demod Main Channel */ | 178 | /* Set Path1 to Analog Demod Main Channel */ |
163 | cx25840_write4(client, 0x8d0, 0x7038061f); | 179 | cx25840_write4(client, 0x8d0, 0x7038061f); |
180 | } | ||
164 | 181 | ||
182 | set_audclk_freq(client, state->audclk_freq); | ||
183 | |||
184 | /* deassert soft reset */ | ||
185 | if (!state->is_cx25836) | ||
186 | cx25840_and_or(client, 0x810, ~0x1, 0x00); | ||
187 | |||
188 | if (state->aud_input != CX25840_AUDIO_SERIAL) { | ||
165 | /* When the microcontroller detects the | 189 | /* When the microcontroller detects the |
166 | * audio format, it will unmute the lines */ | 190 | * audio format, it will unmute the lines */ |
167 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | 191 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
168 | } | 192 | } |
169 | |||
170 | set_audclk_freq(client, state->audclk_freq); | ||
171 | } | 193 | } |
172 | 194 | ||
173 | static int get_volume(struct i2c_client *client) | 195 | static int get_volume(struct i2c_client *client) |
@@ -291,11 +313,25 @@ static void set_mute(struct i2c_client *client, int mute) | |||
291 | 313 | ||
292 | int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | 314 | int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) |
293 | { | 315 | { |
316 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
294 | struct v4l2_control *ctrl = arg; | 317 | struct v4l2_control *ctrl = arg; |
318 | int retval; | ||
295 | 319 | ||
296 | switch (cmd) { | 320 | switch (cmd) { |
297 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | 321 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: |
298 | return set_audclk_freq(client, *(u32 *)arg); | 322 | if (state->aud_input != CX25840_AUDIO_SERIAL) { |
323 | cx25840_and_or(client, 0x803, ~0x10, 0); | ||
324 | cx25840_write(client, 0x8d3, 0x1f); | ||
325 | } | ||
326 | if (!state->is_cx25836) | ||
327 | cx25840_and_or(client, 0x810, ~0x1, 1); | ||
328 | retval = set_audclk_freq(client, *(u32 *)arg); | ||
329 | if (!state->is_cx25836) | ||
330 | cx25840_and_or(client, 0x810, ~0x1, 0); | ||
331 | if (state->aud_input != CX25840_AUDIO_SERIAL) { | ||
332 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | ||
333 | } | ||
334 | return retval; | ||
299 | 335 | ||
300 | case VIDIOC_G_CTRL: | 336 | case VIDIOC_G_CTRL: |
301 | switch (ctrl->id) { | 337 | switch (ctrl->id) { |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index a961bb2ab0fd..5c2036b40ea1 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -10,6 +10,9 @@ | |||
10 | * | 10 | * |
11 | * VBI support by Hans Verkuil <hverkuil@xs4all.nl>. | 11 | * VBI support by Hans Verkuil <hverkuil@xs4all.nl>. |
12 | * | 12 | * |
13 | * NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca> | ||
14 | * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>. | ||
15 | * | ||
13 | * This program is free software; you can redistribute it and/or | 16 | * This program is free software; you can redistribute it and/or |
14 | * modify it under the terms of the GNU General Public License | 17 | * modify it under the terms of the GNU General Public License |
15 | * as published by the Free Software Foundation; either version 2 | 18 | * as published by the Free Software Foundation; either version 2 |
@@ -43,7 +46,7 @@ MODULE_LICENSE("GPL"); | |||
43 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; | 46 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; |
44 | 47 | ||
45 | 48 | ||
46 | static int cx25840_debug; | 49 | int cx25840_debug; |
47 | 50 | ||
48 | module_param_named(debug,cx25840_debug, int, 0644); | 51 | module_param_named(debug,cx25840_debug, int, 0644); |
49 | 52 | ||
@@ -105,7 +108,7 @@ u32 cx25840_read4(struct i2c_client * client, u16 addr) | |||
105 | (buffer[2] << 8) | buffer[3]; | 108 | (buffer[2] << 8) | buffer[3]; |
106 | } | 109 | } |
107 | 110 | ||
108 | int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, | 111 | int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask, |
109 | u8 or_value) | 112 | u8 or_value) |
110 | { | 113 | { |
111 | return cx25840_write(client, addr, | 114 | return cx25840_write(client, addr, |
@@ -117,7 +120,8 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, | |||
117 | 120 | ||
118 | static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, | 121 | static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, |
119 | enum cx25840_audio_input aud_input); | 122 | enum cx25840_audio_input aud_input); |
120 | static void log_status(struct i2c_client *client); | 123 | static void log_audio_status(struct i2c_client *client); |
124 | static void log_video_status(struct i2c_client *client); | ||
121 | 125 | ||
122 | /* ----------------------------------------------------------------------- */ | 126 | /* ----------------------------------------------------------------------- */ |
123 | 127 | ||
@@ -147,6 +151,33 @@ static void init_dll2(struct i2c_client *client) | |||
147 | cx25840_write(client, 0x15d, 0xe1); | 151 | cx25840_write(client, 0x15d, 0xe1); |
148 | } | 152 | } |
149 | 153 | ||
154 | static void cx25836_initialize(struct i2c_client *client) | ||
155 | { | ||
156 | /* reset configuration is described on page 3-77 of the CX25836 datasheet */ | ||
157 | /* 2. */ | ||
158 | cx25840_and_or(client, 0x000, ~0x01, 0x01); | ||
159 | cx25840_and_or(client, 0x000, ~0x01, 0x00); | ||
160 | /* 3a. */ | ||
161 | cx25840_and_or(client, 0x15a, ~0x70, 0x00); | ||
162 | /* 3b. */ | ||
163 | cx25840_and_or(client, 0x15b, ~0x1e, 0x06); | ||
164 | /* 3c. */ | ||
165 | cx25840_and_or(client, 0x159, ~0x02, 0x02); | ||
166 | /* 3d. */ | ||
167 | /* There should be a 10-us delay here, but since the | ||
168 | i2c bus already has a 10-us delay we don't need to do | ||
169 | anything */ | ||
170 | /* 3e. */ | ||
171 | cx25840_and_or(client, 0x159, ~0x02, 0x00); | ||
172 | /* 3f. */ | ||
173 | cx25840_and_or(client, 0x159, ~0xc0, 0xc0); | ||
174 | /* 3g. */ | ||
175 | cx25840_and_or(client, 0x159, ~0x01, 0x00); | ||
176 | cx25840_and_or(client, 0x159, ~0x01, 0x01); | ||
177 | /* 3h. */ | ||
178 | cx25840_and_or(client, 0x15b, ~0x1e, 0x10); | ||
179 | } | ||
180 | |||
150 | static void cx25840_initialize(struct i2c_client *client, int loadfw) | 181 | static void cx25840_initialize(struct i2c_client *client, int loadfw) |
151 | { | 182 | { |
152 | struct cx25840_state *state = i2c_get_clientdata(client); | 183 | struct cx25840_state *state = i2c_get_clientdata(client); |
@@ -220,17 +251,7 @@ static void input_change(struct i2c_client *client) | |||
220 | cx25840_and_or(client, 0x401, ~0x60, 0); | 251 | cx25840_and_or(client, 0x401, ~0x60, 0); |
221 | cx25840_and_or(client, 0x401, ~0x60, 0x60); | 252 | cx25840_and_or(client, 0x401, ~0x60, 0x60); |
222 | 253 | ||
223 | /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC | 254 | if (std & V4L2_STD_525_60) { |
224 | instead of V4L2_STD_PAL. Someone needs to test this. */ | ||
225 | if (std & V4L2_STD_PAL) { | ||
226 | /* Follow tuner change procedure for PAL */ | ||
227 | cx25840_write(client, 0x808, 0xff); | ||
228 | cx25840_write(client, 0x80b, 0x10); | ||
229 | } else if (std & V4L2_STD_SECAM) { | ||
230 | /* Select autodetect for SECAM */ | ||
231 | cx25840_write(client, 0x808, 0xff); | ||
232 | cx25840_write(client, 0x80b, 0x10); | ||
233 | } else if (std & V4L2_STD_NTSC) { | ||
234 | /* Certain Hauppauge PVR150 models have a hardware bug | 255 | /* Certain Hauppauge PVR150 models have a hardware bug |
235 | that causes audio to drop out. For these models the | 256 | that causes audio to drop out. For these models the |
236 | audio standard must be set explicitly. | 257 | audio standard must be set explicitly. |
@@ -249,6 +270,14 @@ static void input_change(struct i2c_client *client) | |||
249 | cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6); | 270 | cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6); |
250 | } | 271 | } |
251 | cx25840_write(client, 0x80b, 0x00); | 272 | cx25840_write(client, 0x80b, 0x00); |
273 | } else if (std & V4L2_STD_PAL) { | ||
274 | /* Follow tuner change procedure for PAL */ | ||
275 | cx25840_write(client, 0x808, 0xff); | ||
276 | cx25840_write(client, 0x80b, 0x10); | ||
277 | } else if (std & V4L2_STD_SECAM) { | ||
278 | /* Select autodetect for SECAM */ | ||
279 | cx25840_write(client, 0x808, 0xff); | ||
280 | cx25840_write(client, 0x80b, 0x10); | ||
252 | } | 281 | } |
253 | 282 | ||
254 | if (cx25840_read(client, 0x803) & 0x10) { | 283 | if (cx25840_read(client, 0x803) & 0x10) { |
@@ -319,8 +348,10 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp | |||
319 | 348 | ||
320 | state->vid_input = vid_input; | 349 | state->vid_input = vid_input; |
321 | state->aud_input = aud_input; | 350 | state->aud_input = aud_input; |
322 | cx25840_audio_set_path(client); | 351 | if (!state->is_cx25836) { |
323 | input_change(client); | 352 | cx25840_audio_set_path(client); |
353 | input_change(client); | ||
354 | } | ||
324 | return 0; | 355 | return 0; |
325 | } | 356 | } |
326 | 357 | ||
@@ -354,6 +385,8 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
354 | } | 385 | } |
355 | } | 386 | } |
356 | 387 | ||
388 | v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt); | ||
389 | |||
357 | /* Follow step 9 of section 3.16 in the cx25840 datasheet. | 390 | /* Follow step 9 of section 3.16 in the cx25840 datasheet. |
358 | Without this PAL may display a vertical ghosting effect. | 391 | Without this PAL may display a vertical ghosting effect. |
359 | This happens for example with the Yuan MPC622. */ | 392 | This happens for example with the Yuan MPC622. */ |
@@ -370,6 +403,7 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
370 | 403 | ||
371 | v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) | 404 | v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) |
372 | { | 405 | { |
406 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
373 | /* check VID_FMT_SEL first */ | 407 | /* check VID_FMT_SEL first */ |
374 | u8 fmt = cx25840_read(client, 0x400) & 0xf; | 408 | u8 fmt = cx25840_read(client, 0x400) & 0xf; |
375 | 409 | ||
@@ -383,7 +417,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) | |||
383 | { | 417 | { |
384 | /* if the audio std is A2-M, then this is the South Korean | 418 | /* if the audio std is A2-M, then this is the South Korean |
385 | NTSC standard */ | 419 | NTSC standard */ |
386 | if (cx25840_read(client, 0x805) == 2) | 420 | if (!state->is_cx25836 && cx25840_read(client, 0x805) == 2) |
387 | return V4L2_STD_NTSC_M_KR; | 421 | return V4L2_STD_NTSC_M_KR; |
388 | return V4L2_STD_NTSC_M; | 422 | return V4L2_STD_NTSC_M; |
389 | } | 423 | } |
@@ -456,6 +490,8 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
456 | case V4L2_CID_AUDIO_TREBLE: | 490 | case V4L2_CID_AUDIO_TREBLE: |
457 | case V4L2_CID_AUDIO_BALANCE: | 491 | case V4L2_CID_AUDIO_BALANCE: |
458 | case V4L2_CID_AUDIO_MUTE: | 492 | case V4L2_CID_AUDIO_MUTE: |
493 | if (state->is_cx25836) | ||
494 | return -EINVAL; | ||
459 | return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); | 495 | return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); |
460 | 496 | ||
461 | default: | 497 | default: |
@@ -490,6 +526,8 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
490 | case V4L2_CID_AUDIO_TREBLE: | 526 | case V4L2_CID_AUDIO_TREBLE: |
491 | case V4L2_CID_AUDIO_BALANCE: | 527 | case V4L2_CID_AUDIO_BALANCE: |
492 | case V4L2_CID_AUDIO_MUTE: | 528 | case V4L2_CID_AUDIO_MUTE: |
529 | if (state->is_cx25836) | ||
530 | return -EINVAL; | ||
493 | return cx25840_audio(client, VIDIOC_G_CTRL, ctrl); | 531 | return cx25840_audio(client, VIDIOC_G_CTRL, ctrl); |
494 | default: | 532 | default: |
495 | return -EINVAL; | 533 | return -EINVAL; |
@@ -579,91 +617,6 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | |||
579 | 617 | ||
580 | /* ----------------------------------------------------------------------- */ | 618 | /* ----------------------------------------------------------------------- */ |
581 | 619 | ||
582 | static struct v4l2_queryctrl cx25840_qctrl[] = { | ||
583 | { | ||
584 | .id = V4L2_CID_BRIGHTNESS, | ||
585 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
586 | .name = "Brightness", | ||
587 | .minimum = 0, | ||
588 | .maximum = 255, | ||
589 | .step = 1, | ||
590 | .default_value = 128, | ||
591 | .flags = 0, | ||
592 | }, { | ||
593 | .id = V4L2_CID_CONTRAST, | ||
594 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
595 | .name = "Contrast", | ||
596 | .minimum = 0, | ||
597 | .maximum = 127, | ||
598 | .step = 1, | ||
599 | .default_value = 64, | ||
600 | .flags = 0, | ||
601 | }, { | ||
602 | .id = V4L2_CID_SATURATION, | ||
603 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
604 | .name = "Saturation", | ||
605 | .minimum = 0, | ||
606 | .maximum = 127, | ||
607 | .step = 1, | ||
608 | .default_value = 64, | ||
609 | .flags = 0, | ||
610 | }, { | ||
611 | .id = V4L2_CID_HUE, | ||
612 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
613 | .name = "Hue", | ||
614 | .minimum = -128, | ||
615 | .maximum = 127, | ||
616 | .step = 1, | ||
617 | .default_value = 0, | ||
618 | .flags = 0, | ||
619 | }, { | ||
620 | .id = V4L2_CID_AUDIO_VOLUME, | ||
621 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
622 | .name = "Volume", | ||
623 | .minimum = 0, | ||
624 | .maximum = 65535, | ||
625 | .step = 65535/100, | ||
626 | .default_value = 58880, | ||
627 | .flags = 0, | ||
628 | }, { | ||
629 | .id = V4L2_CID_AUDIO_BALANCE, | ||
630 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
631 | .name = "Balance", | ||
632 | .minimum = 0, | ||
633 | .maximum = 65535, | ||
634 | .step = 65535/100, | ||
635 | .default_value = 32768, | ||
636 | .flags = 0, | ||
637 | }, { | ||
638 | .id = V4L2_CID_AUDIO_MUTE, | ||
639 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
640 | .name = "Mute", | ||
641 | .minimum = 0, | ||
642 | .maximum = 1, | ||
643 | .step = 1, | ||
644 | .default_value = 1, | ||
645 | .flags = 0, | ||
646 | }, { | ||
647 | .id = V4L2_CID_AUDIO_BASS, | ||
648 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
649 | .name = "Bass", | ||
650 | .minimum = 0, | ||
651 | .maximum = 65535, | ||
652 | .step = 65535/100, | ||
653 | .default_value = 32768, | ||
654 | }, { | ||
655 | .id = V4L2_CID_AUDIO_TREBLE, | ||
656 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
657 | .name = "Treble", | ||
658 | .minimum = 0, | ||
659 | .maximum = 65535, | ||
660 | .step = 65535/100, | ||
661 | .default_value = 32768, | ||
662 | }, | ||
663 | }; | ||
664 | |||
665 | /* ----------------------------------------------------------------------- */ | ||
666 | |||
667 | static int cx25840_command(struct i2c_client *client, unsigned int cmd, | 620 | static int cx25840_command(struct i2c_client *client, unsigned int cmd, |
668 | void *arg) | 621 | void *arg) |
669 | { | 622 | { |
@@ -706,8 +659,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
706 | 659 | ||
707 | case VIDIOC_STREAMON: | 660 | case VIDIOC_STREAMON: |
708 | v4l_dbg(1, cx25840_debug, client, "enable output\n"); | 661 | v4l_dbg(1, cx25840_debug, client, "enable output\n"); |
709 | cx25840_write(client, 0x115, 0x8c); | 662 | cx25840_write(client, 0x115, state->is_cx25836 ? 0x0c : 0x8c); |
710 | cx25840_write(client, 0x116, 0x07); | 663 | cx25840_write(client, 0x116, state->is_cx25836 ? 0x04 : 0x07); |
711 | break; | 664 | break; |
712 | 665 | ||
713 | case VIDIOC_STREAMOFF: | 666 | case VIDIOC_STREAMOFF: |
@@ -717,7 +670,9 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
717 | break; | 670 | break; |
718 | 671 | ||
719 | case VIDIOC_LOG_STATUS: | 672 | case VIDIOC_LOG_STATUS: |
720 | log_status(client); | 673 | log_video_status(client); |
674 | if (!state->is_cx25836) | ||
675 | log_audio_status(client); | ||
721 | break; | 676 | break; |
722 | 677 | ||
723 | case VIDIOC_G_CTRL: | 678 | case VIDIOC_G_CTRL: |
@@ -729,13 +684,29 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
729 | case VIDIOC_QUERYCTRL: | 684 | case VIDIOC_QUERYCTRL: |
730 | { | 685 | { |
731 | struct v4l2_queryctrl *qc = arg; | 686 | struct v4l2_queryctrl *qc = arg; |
732 | int i; | ||
733 | 687 | ||
734 | for (i = 0; i < ARRAY_SIZE(cx25840_qctrl); i++) | 688 | switch (qc->id) { |
735 | if (qc->id && qc->id == cx25840_qctrl[i].id) { | 689 | case V4L2_CID_BRIGHTNESS: |
736 | memcpy(qc, &cx25840_qctrl[i], sizeof(*qc)); | 690 | case V4L2_CID_CONTRAST: |
737 | return 0; | 691 | case V4L2_CID_SATURATION: |
738 | } | 692 | case V4L2_CID_HUE: |
693 | return v4l2_ctrl_query_fill_std(qc); | ||
694 | default: | ||
695 | break; | ||
696 | } | ||
697 | if (state->is_cx25836) | ||
698 | return -EINVAL; | ||
699 | |||
700 | switch (qc->id) { | ||
701 | case V4L2_CID_AUDIO_VOLUME: | ||
702 | case V4L2_CID_AUDIO_MUTE: | ||
703 | case V4L2_CID_AUDIO_BALANCE: | ||
704 | case V4L2_CID_AUDIO_BASS: | ||
705 | case V4L2_CID_AUDIO_TREBLE: | ||
706 | return v4l2_ctrl_query_fill_std(qc); | ||
707 | default: | ||
708 | return -EINVAL; | ||
709 | } | ||
739 | return -EINVAL; | 710 | return -EINVAL; |
740 | } | 711 | } |
741 | 712 | ||
@@ -760,31 +731,41 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
760 | return set_input(client, route->input, state->aud_input); | 731 | return set_input(client, route->input, state->aud_input); |
761 | 732 | ||
762 | case VIDIOC_INT_G_AUDIO_ROUTING: | 733 | case VIDIOC_INT_G_AUDIO_ROUTING: |
734 | if (state->is_cx25836) | ||
735 | return -EINVAL; | ||
763 | route->input = state->aud_input; | 736 | route->input = state->aud_input; |
764 | route->output = 0; | 737 | route->output = 0; |
765 | break; | 738 | break; |
766 | 739 | ||
767 | case VIDIOC_INT_S_AUDIO_ROUTING: | 740 | case VIDIOC_INT_S_AUDIO_ROUTING: |
741 | if (state->is_cx25836) | ||
742 | return -EINVAL; | ||
768 | return set_input(client, state->vid_input, route->input); | 743 | return set_input(client, state->vid_input, route->input); |
769 | 744 | ||
770 | case VIDIOC_S_FREQUENCY: | 745 | case VIDIOC_S_FREQUENCY: |
771 | input_change(client); | 746 | if (!state->is_cx25836) { |
747 | input_change(client); | ||
748 | } | ||
772 | break; | 749 | break; |
773 | 750 | ||
774 | case VIDIOC_G_TUNER: | 751 | case VIDIOC_G_TUNER: |
775 | { | 752 | { |
776 | u8 mode = cx25840_read(client, 0x804); | 753 | u8 vpres = cx25840_read(client, 0x40e) & 0x20; |
777 | u8 vpres = cx25840_read(client, 0x80a) & 0x10; | 754 | u8 mode; |
778 | int val = 0; | 755 | int val = 0; |
779 | 756 | ||
780 | if (state->radio) | 757 | if (state->radio) |
781 | break; | 758 | break; |
782 | 759 | ||
760 | vt->signal = vpres ? 0xffff : 0x0; | ||
761 | if (state->is_cx25836) | ||
762 | break; | ||
763 | |||
783 | vt->capability |= | 764 | vt->capability |= |
784 | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | | 765 | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | |
785 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; | 766 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; |
786 | 767 | ||
787 | vt->signal = vpres ? 0xffff : 0x0; | 768 | mode = cx25840_read(client, 0x804); |
788 | 769 | ||
789 | /* get rxsubchans and audmode */ | 770 | /* get rxsubchans and audmode */ |
790 | if ((mode & 0xf) == 1) | 771 | if ((mode & 0xf) == 1) |
@@ -804,7 +785,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
804 | } | 785 | } |
805 | 786 | ||
806 | case VIDIOC_S_TUNER: | 787 | case VIDIOC_S_TUNER: |
807 | if (state->radio) | 788 | if (state->radio || state->is_cx25836) |
808 | break; | 789 | break; |
809 | 790 | ||
810 | switch (vt->audmode) { | 791 | switch (vt->audmode) { |
@@ -846,12 +827,14 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
846 | return set_v4lfmt(client, (struct v4l2_format *)arg); | 827 | return set_v4lfmt(client, (struct v4l2_format *)arg); |
847 | 828 | ||
848 | case VIDIOC_INT_RESET: | 829 | case VIDIOC_INT_RESET: |
849 | cx25840_initialize(client, 0); | 830 | if (state->is_cx25836) |
831 | cx25836_initialize(client); | ||
832 | else | ||
833 | cx25840_initialize(client, 0); | ||
850 | break; | 834 | break; |
851 | 835 | ||
852 | case VIDIOC_INT_G_CHIP_IDENT: | 836 | case VIDIOC_INT_G_CHIP_IDENT: |
853 | *(enum v4l2_chip_ident *)arg = | 837 | *(enum v4l2_chip_ident *)arg = state->id; |
854 | V4L2_IDENT_CX25840 + ((cx25840_read(client, 0x100) >> 4) & 0xf); | ||
855 | break; | 838 | break; |
856 | 839 | ||
857 | default: | 840 | default: |
@@ -870,6 +853,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
870 | { | 853 | { |
871 | struct i2c_client *client; | 854 | struct i2c_client *client; |
872 | struct cx25840_state *state; | 855 | struct cx25840_state *state; |
856 | enum v4l2_chip_ident id; | ||
873 | u16 device_id; | 857 | u16 device_id; |
874 | 858 | ||
875 | /* Check if the adapter supports the needed features | 859 | /* Check if the adapter supports the needed features |
@@ -878,10 +862,11 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
878 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) | 862 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) |
879 | return 0; | 863 | return 0; |
880 | 864 | ||
881 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 865 | state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL); |
882 | if (client == 0) | 866 | if (state == 0) |
883 | return -ENOMEM; | 867 | return -ENOMEM; |
884 | 868 | ||
869 | client = &state->c; | ||
885 | client->addr = address; | 870 | client->addr = address; |
886 | client->adapter = adapter; | 871 | client->adapter = adapter; |
887 | client->driver = &i2c_driver_cx25840; | 872 | client->driver = &i2c_driver_cx25840; |
@@ -893,10 +878,18 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
893 | device_id |= cx25840_read(client, 0x100); | 878 | device_id |= cx25840_read(client, 0x100); |
894 | 879 | ||
895 | /* The high byte of the device ID should be | 880 | /* The high byte of the device ID should be |
896 | * 0x84 if chip is present */ | 881 | * 0x83 for the cx2583x and 0x84 for the cx2584x */ |
897 | if ((device_id & 0xff00) != 0x8400) { | 882 | if ((device_id & 0xff00) == 0x8300) { |
883 | id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; | ||
884 | state->is_cx25836 = 1; | ||
885 | } | ||
886 | else if ((device_id & 0xff00) == 0x8400) { | ||
887 | id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); | ||
888 | state->is_cx25836 = 0; | ||
889 | } | ||
890 | else { | ||
898 | v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); | 891 | v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); |
899 | kfree(client); | 892 | kfree(state); |
900 | return 0; | 893 | return 0; |
901 | } | 894 | } |
902 | 895 | ||
@@ -905,21 +898,19 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
905 | (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, | 898 | (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, |
906 | address << 1, adapter->name); | 899 | address << 1, adapter->name); |
907 | 900 | ||
908 | state = kmalloc(sizeof(struct cx25840_state), GFP_KERNEL); | ||
909 | if (state == NULL) { | ||
910 | kfree(client); | ||
911 | return -ENOMEM; | ||
912 | } | ||
913 | |||
914 | i2c_set_clientdata(client, state); | 901 | i2c_set_clientdata(client, state); |
915 | memset(state, 0, sizeof(struct cx25840_state)); | ||
916 | state->vid_input = CX25840_COMPOSITE7; | 902 | state->vid_input = CX25840_COMPOSITE7; |
917 | state->aud_input = CX25840_AUDIO8; | 903 | state->aud_input = CX25840_AUDIO8; |
918 | state->audclk_freq = 48000; | 904 | state->audclk_freq = 48000; |
919 | state->pvr150_workaround = 0; | 905 | state->pvr150_workaround = 0; |
920 | state->audmode = V4L2_TUNER_MODE_LANG1; | 906 | state->audmode = V4L2_TUNER_MODE_LANG1; |
907 | state->vbi_line_offset = 8; | ||
908 | state->id = id; | ||
921 | 909 | ||
922 | cx25840_initialize(client, 1); | 910 | if (state->is_cx25836) |
911 | cx25836_initialize(client); | ||
912 | else | ||
913 | cx25840_initialize(client, 1); | ||
923 | 914 | ||
924 | i2c_attach_client(client); | 915 | i2c_attach_client(client); |
925 | 916 | ||
@@ -944,7 +935,6 @@ static int cx25840_detach_client(struct i2c_client *client) | |||
944 | } | 935 | } |
945 | 936 | ||
946 | kfree(state); | 937 | kfree(state); |
947 | kfree(client); | ||
948 | 938 | ||
949 | return 0; | 939 | return 0; |
950 | } | 940 | } |
@@ -977,7 +967,7 @@ module_exit(m__exit); | |||
977 | 967 | ||
978 | /* ----------------------------------------------------------------------- */ | 968 | /* ----------------------------------------------------------------------- */ |
979 | 969 | ||
980 | static void log_status(struct i2c_client *client) | 970 | static void log_video_status(struct i2c_client *client) |
981 | { | 971 | { |
982 | static const char *const fmt_strs[] = { | 972 | static const char *const fmt_strs[] = { |
983 | "0x0", | 973 | "0x0", |
@@ -989,9 +979,36 @@ static void log_status(struct i2c_client *client) | |||
989 | }; | 979 | }; |
990 | 980 | ||
991 | struct cx25840_state *state = i2c_get_clientdata(client); | 981 | struct cx25840_state *state = i2c_get_clientdata(client); |
992 | u8 microctrl_vidfmt = cx25840_read(client, 0x80a); | ||
993 | u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf; | 982 | u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf; |
994 | u8 gen_stat1 = cx25840_read(client, 0x40d); | 983 | u8 gen_stat1 = cx25840_read(client, 0x40d); |
984 | u8 gen_stat2 = cx25840_read(client, 0x40e); | ||
985 | int vid_input = state->vid_input; | ||
986 | |||
987 | v4l_info(client, "Video signal: %spresent\n", | ||
988 | (gen_stat2 & 0x20) ? "" : "not "); | ||
989 | v4l_info(client, "Detected format: %s\n", | ||
990 | fmt_strs[gen_stat1 & 0xf]); | ||
991 | |||
992 | v4l_info(client, "Specified standard: %s\n", | ||
993 | vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); | ||
994 | |||
995 | if (vid_input >= CX25840_COMPOSITE1 && | ||
996 | vid_input <= CX25840_COMPOSITE8) { | ||
997 | v4l_info(client, "Specified video input: Composite %d\n", | ||
998 | vid_input - CX25840_COMPOSITE1 + 1); | ||
999 | } else { | ||
1000 | v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", | ||
1001 | (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); | ||
1002 | } | ||
1003 | |||
1004 | v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq); | ||
1005 | } | ||
1006 | |||
1007 | /* ----------------------------------------------------------------------- */ | ||
1008 | |||
1009 | static void log_audio_status(struct i2c_client *client) | ||
1010 | { | ||
1011 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
995 | u8 download_ctl = cx25840_read(client, 0x803); | 1012 | u8 download_ctl = cx25840_read(client, 0x803); |
996 | u8 mod_det_stat0 = cx25840_read(client, 0x804); | 1013 | u8 mod_det_stat0 = cx25840_read(client, 0x804); |
997 | u8 mod_det_stat1 = cx25840_read(client, 0x805); | 1014 | u8 mod_det_stat1 = cx25840_read(client, 0x805); |
@@ -999,15 +1016,9 @@ static void log_status(struct i2c_client *client) | |||
999 | u8 pref_mode = cx25840_read(client, 0x809); | 1016 | u8 pref_mode = cx25840_read(client, 0x809); |
1000 | u8 afc0 = cx25840_read(client, 0x80b); | 1017 | u8 afc0 = cx25840_read(client, 0x80b); |
1001 | u8 mute_ctl = cx25840_read(client, 0x8d3); | 1018 | u8 mute_ctl = cx25840_read(client, 0x8d3); |
1002 | int vid_input = state->vid_input; | ||
1003 | int aud_input = state->aud_input; | 1019 | int aud_input = state->aud_input; |
1004 | char *p; | 1020 | char *p; |
1005 | 1021 | ||
1006 | v4l_info(client, "Video signal: %spresent\n", | ||
1007 | (microctrl_vidfmt & 0x10) ? "" : "not "); | ||
1008 | v4l_info(client, "Detected format: %s\n", | ||
1009 | fmt_strs[gen_stat1 & 0xf]); | ||
1010 | |||
1011 | switch (mod_det_stat0) { | 1022 | switch (mod_det_stat0) { |
1012 | case 0x00: p = "mono"; break; | 1023 | case 0x00: p = "mono"; break; |
1013 | case 0x01: p = "stereo"; break; | 1024 | case 0x01: p = "stereo"; break; |
@@ -1107,25 +1118,12 @@ static void log_status(struct i2c_client *client) | |||
1107 | v4l_info(client, "Configured audio system: %s\n", p); | 1118 | v4l_info(client, "Configured audio system: %s\n", p); |
1108 | } | 1119 | } |
1109 | 1120 | ||
1110 | v4l_info(client, "Specified standard: %s\n", | ||
1111 | vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); | ||
1112 | |||
1113 | if (vid_input >= CX25840_COMPOSITE1 && | ||
1114 | vid_input <= CX25840_COMPOSITE8) { | ||
1115 | v4l_info(client, "Specified video input: Composite %d\n", | ||
1116 | vid_input - CX25840_COMPOSITE1 + 1); | ||
1117 | } else { | ||
1118 | v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", | ||
1119 | (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); | ||
1120 | } | ||
1121 | if (aud_input) { | 1121 | if (aud_input) { |
1122 | v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input); | 1122 | v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input); |
1123 | } else { | 1123 | } else { |
1124 | v4l_info(client, "Specified audio input: External\n"); | 1124 | v4l_info(client, "Specified audio input: External\n"); |
1125 | } | 1125 | } |
1126 | 1126 | ||
1127 | v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq); | ||
1128 | |||
1129 | switch (pref_mode & 0xf) { | 1127 | switch (pref_mode & 0xf) { |
1130 | case 0: p = "mono/language A"; break; | 1128 | case 0: p = "mono/language A"; break; |
1131 | case 1: p = "language B"; break; | 1129 | case 1: p = "language B"; break; |
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h index 1736929fc204..28049064dd7d 100644 --- a/drivers/media/video/cx25840/cx25840-core.h +++ b/drivers/media/video/cx25840/cx25840-core.h | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/videodev2.h> | 24 | #include <linux/videodev2.h> |
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | 26 | ||
27 | extern int cx25840_debug; | ||
28 | |||
27 | /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is | 29 | /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is |
28 | present in Hauppauge PVR-150 (and possibly PVR-500) cards that have | 30 | present in Hauppauge PVR-150 (and possibly PVR-500) cards that have |
29 | certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The | 31 | certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The |
@@ -33,12 +35,16 @@ | |||
33 | #define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0) | 35 | #define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0) |
34 | 36 | ||
35 | struct cx25840_state { | 37 | struct cx25840_state { |
38 | struct i2c_client c; | ||
36 | int pvr150_workaround; | 39 | int pvr150_workaround; |
37 | int radio; | 40 | int radio; |
38 | enum cx25840_video_input vid_input; | 41 | enum cx25840_video_input vid_input; |
39 | enum cx25840_audio_input aud_input; | 42 | enum cx25840_audio_input aud_input; |
40 | u32 audclk_freq; | 43 | u32 audclk_freq; |
41 | int audmode; | 44 | int audmode; |
45 | int vbi_line_offset; | ||
46 | enum v4l2_chip_ident id; | ||
47 | int is_cx25836; | ||
42 | }; | 48 | }; |
43 | 49 | ||
44 | /* ----------------------------------------------------------------------- */ | 50 | /* ----------------------------------------------------------------------- */ |
@@ -47,7 +53,7 @@ int cx25840_write(struct i2c_client *client, u16 addr, u8 value); | |||
47 | int cx25840_write4(struct i2c_client *client, u16 addr, u32 value); | 53 | int cx25840_write4(struct i2c_client *client, u16 addr, u32 value); |
48 | u8 cx25840_read(struct i2c_client *client, u16 addr); | 54 | u8 cx25840_read(struct i2c_client *client, u16 addr); |
49 | u32 cx25840_read4(struct i2c_client *client, u16 addr); | 55 | u32 cx25840_read4(struct i2c_client *client, u16 addr); |
50 | int cx25840_and_or(struct i2c_client *client, u16 addr, u8 mask, u8 value); | 56 | int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value); |
51 | v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client); | 57 | v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client); |
52 | 58 | ||
53 | /* ----------------------------------------------------------------------- */ | 59 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index 57feca288d2b..6cc8bf215e85 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c | |||
@@ -84,67 +84,140 @@ static int decode_vps(u8 * dst, u8 * p) | |||
84 | 84 | ||
85 | void cx25840_vbi_setup(struct i2c_client *client) | 85 | void cx25840_vbi_setup(struct i2c_client *client) |
86 | { | 86 | { |
87 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
87 | v4l2_std_id std = cx25840_get_v4lstd(client); | 88 | v4l2_std_id std = cx25840_get_v4lstd(client); |
89 | int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation; | ||
90 | int luma_lpf,uv_lpf, comb; | ||
91 | u32 pll_int,pll_frac,pll_post; | ||
88 | 92 | ||
93 | /* datasheet startup, step 8d */ | ||
89 | if (std & ~V4L2_STD_NTSC) { | 94 | if (std & ~V4L2_STD_NTSC) { |
90 | /* datasheet startup, step 8d */ | ||
91 | cx25840_write(client, 0x49f, 0x11); | 95 | cx25840_write(client, 0x49f, 0x11); |
96 | } else { | ||
97 | cx25840_write(client, 0x49f, 0x14); | ||
98 | } | ||
92 | 99 | ||
93 | cx25840_write(client, 0x470, 0x84); | 100 | if (std & V4L2_STD_625_50) { |
94 | cx25840_write(client, 0x471, 0x00); | 101 | hblank=0x084; |
95 | cx25840_write(client, 0x472, 0x2d); | 102 | hactive=0x2d0; |
96 | cx25840_write(client, 0x473, 0x5d); | 103 | burst=0x5d; |
97 | 104 | vblank=0x024; | |
98 | cx25840_write(client, 0x474, 0x24); | 105 | vactive=0x244; |
99 | cx25840_write(client, 0x475, 0x40); | 106 | vblank656=0x28; |
100 | cx25840_write(client, 0x476, 0x24); | 107 | src_decimation=0x21f; |
101 | cx25840_write(client, 0x477, 0x28); | ||
102 | |||
103 | cx25840_write(client, 0x478, 0x1f); | ||
104 | cx25840_write(client, 0x479, 0x02); | ||
105 | 108 | ||
109 | luma_lpf=2; | ||
106 | if (std & V4L2_STD_SECAM) { | 110 | if (std & V4L2_STD_SECAM) { |
107 | cx25840_write(client, 0x47a, 0x80); | 111 | uv_lpf=0; |
108 | cx25840_write(client, 0x47b, 0x00); | 112 | comb=0; |
109 | cx25840_write(client, 0x47c, 0x5f); | 113 | sc=0x0a425f; |
110 | cx25840_write(client, 0x47d, 0x42); | ||
111 | } else { | 114 | } else { |
112 | cx25840_write(client, 0x47a, 0x90); | 115 | uv_lpf=1; |
113 | cx25840_write(client, 0x47b, 0x20); | 116 | comb=0x20; |
114 | cx25840_write(client, 0x47c, 0x63); | 117 | sc=0x0a8263; |
115 | cx25840_write(client, 0x47d, 0x82); | ||
116 | } | 118 | } |
117 | |||
118 | cx25840_write(client, 0x47e, 0x0a); | ||
119 | cx25840_write(client, 0x47f, 0x01); | ||
120 | } else { | 119 | } else { |
121 | /* datasheet startup, step 8d */ | 120 | hactive=720; |
122 | cx25840_write(client, 0x49f, 0x14); | 121 | hblank=122; |
122 | vactive=487; | ||
123 | luma_lpf=1; | ||
124 | uv_lpf=1; | ||
125 | |||
126 | src_decimation=0x21f; | ||
127 | if (std == V4L2_STD_PAL_M) { | ||
128 | vblank=20; | ||
129 | vblank656=24; | ||
130 | burst=0x61; | ||
131 | comb=0x20; | ||
132 | |||
133 | sc=555452; | ||
134 | } else { | ||
135 | vblank=26; | ||
136 | vblank656=26; | ||
137 | burst=0x5b; | ||
138 | comb=0x66; | ||
139 | sc=556063; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | /* DEBUG: Displays configured PLL frequency */ | ||
144 | pll_int=cx25840_read(client, 0x108); | ||
145 | pll_frac=cx25840_read4(client, 0x10c)&0x1ffffff; | ||
146 | pll_post=cx25840_read(client, 0x109); | ||
147 | v4l_dbg(1, cx25840_debug, client, | ||
148 | "PLL regs = int: %u, frac: %u, post: %u\n", | ||
149 | pll_int,pll_frac,pll_post); | ||
150 | |||
151 | if (pll_post) { | ||
152 | int fin, fsc; | ||
153 | int pll= (28636363L*((((u64)pll_int)<<25L)+pll_frac)) >>25L; | ||
154 | |||
155 | pll/=pll_post; | ||
156 | v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n", | ||
157 | pll/1000000, pll%1000000); | ||
158 | v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n", | ||
159 | pll/8000000, (pll/8)%1000000); | ||
160 | |||
161 | fin=((u64)src_decimation*pll)>>12; | ||
162 | v4l_dbg(1, cx25840_debug, client, "ADC Sampling freq = " | ||
163 | "%d.%06d MHz\n", | ||
164 | fin/1000000,fin%1000000); | ||
165 | |||
166 | fsc= (((u64)sc)*pll) >> 24L; | ||
167 | v4l_dbg(1, cx25840_debug, client, "Chroma sub-carrier freq = " | ||
168 | "%d.%06d MHz\n", | ||
169 | fsc/1000000,fsc%1000000); | ||
170 | |||
171 | v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, " | ||
172 | "vblank %i , vactive %i, vblank656 %i, src_dec %i," | ||
173 | "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x," | ||
174 | " sc 0x%06x\n", | ||
175 | hblank, hactive, vblank, vactive, vblank656, | ||
176 | src_decimation, burst, luma_lpf, uv_lpf, comb, sc); | ||
177 | } | ||
178 | |||
179 | /* Sets horizontal blanking delay and active lines */ | ||
180 | cx25840_write(client, 0x470, hblank); | ||
181 | cx25840_write(client, 0x471, 0xff&(((hblank>>8)&0x3)|(hactive <<4))); | ||
182 | cx25840_write(client, 0x472, hactive>>4); | ||
183 | |||
184 | /* Sets burst gate delay */ | ||
185 | cx25840_write(client, 0x473, burst); | ||
123 | 186 | ||
124 | cx25840_write(client, 0x470, 0x7a); | 187 | /* Sets vertical blanking delay and active duration */ |
125 | cx25840_write(client, 0x471, 0x00); | 188 | cx25840_write(client, 0x474, vblank); |
126 | cx25840_write(client, 0x472, 0x2d); | 189 | cx25840_write(client, 0x475, 0xff&(((vblank>>8)&0x3)|(vactive <<4))); |
127 | cx25840_write(client, 0x473, 0x5b); | 190 | cx25840_write(client, 0x476, vactive>>4); |
191 | cx25840_write(client, 0x477, vblank656); | ||
128 | 192 | ||
129 | cx25840_write(client, 0x474, 0x1a); | 193 | /* Sets src decimation rate */ |
130 | cx25840_write(client, 0x475, 0x70); | 194 | cx25840_write(client, 0x478, 0xff&src_decimation); |
131 | cx25840_write(client, 0x476, 0x1e); | 195 | cx25840_write(client, 0x479, 0xff&(src_decimation>>8)); |
132 | cx25840_write(client, 0x477, 0x1e); | ||
133 | 196 | ||
134 | cx25840_write(client, 0x478, 0x1f); | 197 | /* Sets Luma and UV Low pass filters */ |
135 | cx25840_write(client, 0x479, 0x02); | 198 | cx25840_write(client, 0x47a, luma_lpf<<6|((uv_lpf<<4)&0x30)); |
136 | cx25840_write(client, 0x47a, 0x50); | ||
137 | cx25840_write(client, 0x47b, 0x66); | ||
138 | 199 | ||
139 | cx25840_write(client, 0x47c, 0x1f); | 200 | /* Enables comb filters */ |
140 | cx25840_write(client, 0x47d, 0x7c); | 201 | cx25840_write(client, 0x47b, comb); |
141 | cx25840_write(client, 0x47e, 0x08); | 202 | |
203 | /* Sets SC Step*/ | ||
204 | cx25840_write(client, 0x47c, sc); | ||
205 | cx25840_write(client, 0x47d, 0xff&sc>>8); | ||
206 | cx25840_write(client, 0x47e, 0xff&sc>>16); | ||
207 | |||
208 | /* Sets VBI parameters */ | ||
209 | if (std & V4L2_STD_625_50) { | ||
210 | cx25840_write(client, 0x47f, 0x01); | ||
211 | state->vbi_line_offset = 5; | ||
212 | } else { | ||
142 | cx25840_write(client, 0x47f, 0x00); | 213 | cx25840_write(client, 0x47f, 0x00); |
214 | state->vbi_line_offset = 8; | ||
143 | } | 215 | } |
144 | } | 216 | } |
145 | 217 | ||
146 | int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | 218 | int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) |
147 | { | 219 | { |
220 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
148 | struct v4l2_format *fmt; | 221 | struct v4l2_format *fmt; |
149 | struct v4l2_sliced_vbi_format *svbi; | 222 | struct v4l2_sliced_vbi_format *svbi; |
150 | 223 | ||
@@ -182,7 +255,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
182 | 255 | ||
183 | case VIDIOC_S_FMT: | 256 | case VIDIOC_S_FMT: |
184 | { | 257 | { |
185 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC); | 258 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); |
186 | int vbi_offset = is_pal ? 1 : 0; | 259 | int vbi_offset = is_pal ? 1 : 0; |
187 | int i, x; | 260 | int i, x; |
188 | u8 lcr[24]; | 261 | u8 lcr[24]; |
@@ -211,7 +284,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
211 | cx25840_vbi_setup(client); | 284 | cx25840_vbi_setup(client); |
212 | 285 | ||
213 | /* Sliced VBI */ | 286 | /* Sliced VBI */ |
214 | cx25840_write(client, 0x404, 0x36); /* Ancillery data */ | 287 | cx25840_write(client, 0x404, 0x32); /* Ancillary data */ |
215 | cx25840_write(client, 0x406, 0x13); | 288 | cx25840_write(client, 0x406, 0x13); |
216 | cx25840_write(client, 0x47f, vbi_offset); | 289 | cx25840_write(client, 0x47f, vbi_offset); |
217 | 290 | ||
@@ -248,8 +321,18 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
248 | } | 321 | } |
249 | } | 322 | } |
250 | 323 | ||
251 | for (x = 1, i = 0x424; i <= 0x434; i++, x++) { | 324 | if (is_pal) { |
252 | cx25840_write(client, i, lcr[6 + x]); | 325 | for (x = 1, i = 0x424; i <= 0x434; i++, x++) { |
326 | cx25840_write(client, i, lcr[6 + x]); | ||
327 | } | ||
328 | } | ||
329 | else { | ||
330 | for (x = 1, i = 0x424; i <= 0x430; i++, x++) { | ||
331 | cx25840_write(client, i, lcr[9 + x]); | ||
332 | } | ||
333 | for (i = 0x431; i <= 0x434; i++) { | ||
334 | cx25840_write(client, i, 0); | ||
335 | } | ||
253 | } | 336 | } |
254 | 337 | ||
255 | cx25840_write(client, 0x43c, 0x16); | 338 | cx25840_write(client, 0x43c, 0x16); |
@@ -257,7 +340,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
257 | if (is_pal) { | 340 | if (is_pal) { |
258 | cx25840_write(client, 0x474, 0x2a); | 341 | cx25840_write(client, 0x474, 0x2a); |
259 | } else { | 342 | } else { |
260 | cx25840_write(client, 0x474, 0x1a + 6); | 343 | cx25840_write(client, 0x474, 0x22); |
261 | } | 344 | } |
262 | break; | 345 | break; |
263 | } | 346 | } |
@@ -278,7 +361,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
278 | id1 = p[-1]; | 361 | id1 = p[-1]; |
279 | id2 = p[0] & 0xf; | 362 | id2 = p[0] & 0xf; |
280 | l = p[2] & 0x3f; | 363 | l = p[2] & 0x3f; |
281 | l += 5; | 364 | l += state->vbi_line_offset; |
282 | p += 4; | 365 | p += 4; |
283 | 366 | ||
284 | switch (id2) { | 367 | switch (id2) { |
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 630273992a41..91e1c481a164 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -11,6 +11,7 @@ config VIDEO_CX88 | |||
11 | select VIDEO_BUF | 11 | select VIDEO_BUF |
12 | select VIDEO_TUNER | 12 | select VIDEO_TUNER |
13 | select VIDEO_TVEEPROM | 13 | select VIDEO_TVEEPROM |
14 | select VIDEO_CX2341X | ||
14 | select VIDEO_IR | 15 | select VIDEO_IR |
15 | ---help--- | 16 | ---help--- |
16 | This is a video4linux driver for Conexant 2388x based | 17 | This is a video4linux driver for Conexant 2388x based |
@@ -61,6 +62,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS | |||
61 | select DVB_LGDT330X | 62 | select DVB_LGDT330X |
62 | select DVB_NXT200X | 63 | select DVB_NXT200X |
63 | select DVB_CX24123 | 64 | select DVB_CX24123 |
65 | select DVB_ISL6421 | ||
64 | ---help--- | 66 | ---help--- |
65 | This builds cx88-dvb with all currently supported frontend | 67 | This builds cx88-dvb with all currently supported frontend |
66 | demodulators. If you wish to tweak your configuration, and | 68 | demodulators. If you wish to tweak your configuration, and |
@@ -139,6 +141,7 @@ config VIDEO_CX88_DVB_CX24123 | |||
139 | default y | 141 | default y |
140 | depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS | 142 | depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS |
141 | select DVB_CX24123 | 143 | select DVB_CX24123 |
144 | select DVB_ISL6421 | ||
142 | ---help--- | 145 | ---help--- |
143 | This adds DVB-S support for cards based on the | 146 | This adds DVB-S support for cards based on the |
144 | Connexant 2388x chip and the CX24123 demodulator. | 147 | Connexant 2388x chip and the CX24123 demodulator. |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 320b3d9384ba..2194cbeca33b 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * PCI function #1 of the cx2388x. | 4 | * PCI function #1 of the cx2388x. |
5 | * | 5 | * |
6 | * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org> | 6 | * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org> |
7 | * (c) 2005 Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 7 | * (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org> |
8 | * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org> | 8 | * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org> |
9 | * Based on dummy.c by Jaroslav Kysela <perex@suse.cz> | 9 | * Based on dummy.c by Jaroslav Kysela <perex@suse.cz> |
10 | * | 10 | * |
@@ -111,7 +111,7 @@ MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s)."); | |||
111 | 111 | ||
112 | MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); | 112 | MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); |
113 | MODULE_AUTHOR("Ricardo Cerqueira"); | 113 | MODULE_AUTHOR("Ricardo Cerqueira"); |
114 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@brturbo.com.br>"); | 114 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); |
115 | MODULE_LICENSE("GPL"); | 115 | MODULE_LICENSE("GPL"); |
116 | MODULE_SUPPORTED_DEVICE("{{Conexant,23881}," | 116 | MODULE_SUPPORTED_DEVICE("{{Conexant,23881}," |
117 | "{{Conexant,23882}," | 117 | "{{Conexant,23882}," |
@@ -696,7 +696,6 @@ static int __devinit snd_cx88_create(struct snd_card *card, | |||
696 | chip->irq = -1; | 696 | chip->irq = -1; |
697 | spin_lock_init(&chip->reg_lock); | 697 | spin_lock_init(&chip->reg_lock); |
698 | 698 | ||
699 | cx88_reset(core); | ||
700 | chip->core = core; | 699 | chip->core = core; |
701 | 700 | ||
702 | /* get irq */ | 701 | /* get irq */ |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index e100d8ef369a..67fd3302e8f2 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -30,9 +30,10 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/device.h> | 31 | #include <linux/device.h> |
32 | #include <linux/firmware.h> | 32 | #include <linux/firmware.h> |
33 | #include <media/v4l2-common.h> | ||
34 | #include <media/cx2341x.h> | ||
33 | 35 | ||
34 | #include "cx88.h" | 36 | #include "cx88.h" |
35 | #include <media/v4l2-common.h> | ||
36 | 37 | ||
37 | MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); | 38 | MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); |
38 | MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 39 | MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
@@ -53,7 +54,6 @@ static LIST_HEAD(cx8802_devlist); | |||
53 | 54 | ||
54 | /* ------------------------------------------------------------------ */ | 55 | /* ------------------------------------------------------------------ */ |
55 | 56 | ||
56 | #define BLACKBIRD_FIRM_ENC_FILENAME "blackbird-fw-enc.bin" | ||
57 | #define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024 | 57 | #define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024 |
58 | 58 | ||
59 | /* defines below are from ivtv-driver.h */ | 59 | /* defines below are from ivtv-driver.h */ |
@@ -63,8 +63,6 @@ static LIST_HEAD(cx8802_devlist); | |||
63 | /* Firmware API commands */ | 63 | /* Firmware API commands */ |
64 | #define IVTV_API_STD_TIMEOUT 500 | 64 | #define IVTV_API_STD_TIMEOUT 500 |
65 | 65 | ||
66 | #define BLACKBIRD_API_PING 0x80 | ||
67 | #define BLACKBIRD_API_BEGIN_CAPTURE 0x81 | ||
68 | enum blackbird_capture_type { | 66 | enum blackbird_capture_type { |
69 | BLACKBIRD_MPEG_CAPTURE, | 67 | BLACKBIRD_MPEG_CAPTURE, |
70 | BLACKBIRD_RAW_CAPTURE, | 68 | BLACKBIRD_RAW_CAPTURE, |
@@ -78,205 +76,29 @@ enum blackbird_capture_bits { | |||
78 | BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08, | 76 | BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08, |
79 | BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10 | 77 | BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10 |
80 | }; | 78 | }; |
81 | #define BLACKBIRD_API_END_CAPTURE 0x82 | ||
82 | enum blackbird_capture_end { | 79 | enum blackbird_capture_end { |
83 | BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */ | 80 | BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */ |
84 | BLACKBIRD_END_NOW, /* stop immediately, no irq */ | 81 | BLACKBIRD_END_NOW, /* stop immediately, no irq */ |
85 | }; | 82 | }; |
86 | #define BLACKBIRD_API_SET_AUDIO_ID 0x89 | ||
87 | #define BLACKBIRD_API_SET_VIDEO_ID 0x8B | ||
88 | #define BLACKBIRD_API_SET_PCR_ID 0x8D | ||
89 | #define BLACKBIRD_API_SET_FRAMERATE 0x8F | ||
90 | enum blackbird_framerate { | 83 | enum blackbird_framerate { |
91 | BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */ | 84 | BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */ |
92 | BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */ | 85 | BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */ |
93 | }; | 86 | }; |
94 | #define BLACKBIRD_API_SET_RESOLUTION 0x91 | ||
95 | #define BLACKBIRD_API_SET_VIDEO_BITRATE 0x95 | ||
96 | enum blackbird_video_bitrate_type { | ||
97 | BLACKBIRD_VIDEO_VBR, | ||
98 | BLACKBIRD_VIDEO_CBR | ||
99 | }; | ||
100 | #define BLACKBIRD_PEAK_RATE_DIVISOR 400 | ||
101 | enum blackbird_mux_rate { | ||
102 | BLACKBIRD_MUX_RATE_DEFAULT, | ||
103 | /* dvd mux rate: multiply by 400 to get the actual rate */ | ||
104 | BLACKBIRD_MUX_RATE_DVD = 25200 | ||
105 | }; | ||
106 | #define BLACKBIRD_API_SET_GOP_STRUCTURE 0x97 | ||
107 | #define BLACKBIRD_API_SET_ASPECT_RATIO 0x99 | ||
108 | enum blackbird_aspect_ratio { | ||
109 | BLACKBIRD_ASPECT_RATIO_FORBIDDEN, | ||
110 | BLACKBIRD_ASPECT_RATIO_1_1_SQUARE, | ||
111 | BLACKBIRD_ASPECT_RATIO_4_3, | ||
112 | BLACKBIRD_ASPECT_RATIO_16_9, | ||
113 | BLACKBIRD_ASPECT_RATIO_221_100, | ||
114 | BLACKBIRD_ASPECT_RATIO_RESERVED | ||
115 | }; | ||
116 | #define BLACKBIRD_API_SET_DNR_MODE 0x9B | ||
117 | enum blackbird_dnr_bits { | ||
118 | BLACKBIRD_DNR_BITS_MANUAL, | ||
119 | BLACKBIRD_DNR_BITS_AUTO_SPATIAL, | ||
120 | BLACKBIRD_DNR_BITS_AUTO_TEMPORAL, | ||
121 | BLACKBIRD_DNR_BITS_AUTO | ||
122 | }; | ||
123 | enum blackbird_median_filter { | ||
124 | BLACKBIRD_MEDIAN_FILTER_DISABLED, | ||
125 | BLACKBIRD_MEDIAN_FILTER_HORIZONTAL, | ||
126 | BLACKBIRD_MEDIAN_FILTER_VERTICAL, | ||
127 | BLACKBIRD_MEDIAN_FILTER_HV, | ||
128 | BLACKBIRD_MEDIAN_FILTER_DIAGONAL | ||
129 | }; | ||
130 | #define BLACKBIRD_API_SET_MANUAL_DNR 0x9D | ||
131 | #define BLACKBIRD_API_SET_DNR_MEDIAN 0x9F | ||
132 | #define BLACKBIRD_API_SET_SPATIAL_FILTER 0xA1 | ||
133 | enum blackbird_spatial_filter_luma { | ||
134 | BLACKBIRD_SPATIAL_FILTER_LUMA_DISABLED, | ||
135 | BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, | ||
136 | BLACKBIRD_SPATIAL_FILTER_LUMA_1D_VERT, | ||
137 | BLACKBIRD_SPATIAL_FILTER_LUMA_2D_HV, /* separable, default */ | ||
138 | BLACKBIRD_SPATIAL_FILTER_LUMA_2D_SYMM /* symmetric non-separable */ | ||
139 | }; | ||
140 | enum blackbird_spatial_filter_chroma { | ||
141 | BLACKBIRD_SPATIAL_FILTER_CHROMA_DISABLED, | ||
142 | BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ /* default */ | ||
143 | }; | ||
144 | #define BLACKBIRD_API_SET_3_2_PULLDOWN 0xB1 | ||
145 | enum blackbird_pulldown { | ||
146 | BLACKBIRD_3_2_PULLDOWN_DISABLED, | ||
147 | BLACKBIRD_3_2_PULLDOWN_ENABLED | ||
148 | }; | ||
149 | #define BLACKBIRD_API_SET_VBI_LINE_NO 0xB7 | ||
150 | enum blackbird_vbi_line_bits { | ||
151 | BLACKBIRD_VBI_LINE_BITS_TOP_FIELD, | ||
152 | BLACKBIRD_VBI_LINE_BITS_BOT_FIELD = (1 << 31), | ||
153 | BLACKBIRD_VBI_LINE_BITS_ALL_LINES = 0xFFFFFFFF | ||
154 | }; | ||
155 | enum blackbird_vbi_line { | ||
156 | BLACKBIRD_VBI_LINE_DISABLED, | ||
157 | BLACKBIRD_VBI_LINE_ENABLED | ||
158 | }; | ||
159 | enum blackbird_vbi_slicing { | ||
160 | BLACKBIRD_VBI_SLICING_NONE, | ||
161 | BLACKBIRD_VBI_SLICING_CLOSED_CAPTION | ||
162 | }; | ||
163 | #define BLACKBIRD_API_SET_STREAM_TYPE 0xB9 | ||
164 | enum blackbird_stream_type { | ||
165 | BLACKBIRD_STREAM_PROGRAM, | ||
166 | BLACKBIRD_STREAM_TRANSPORT, | ||
167 | BLACKBIRD_STREAM_MPEG1, | ||
168 | BLACKBIRD_STREAM_PES_AV, | ||
169 | BLACKBIRD_STREAM_UNKNOWN4, | ||
170 | BLACKBIRD_STREAM_PES_VIDEO, | ||
171 | BLACKBIRD_STREAM_UNKNOWN6, | ||
172 | BLACKBIRD_STREAM_PES_AUDIO, | ||
173 | BLACKBIRD_STREAM_UNKNOWN8, | ||
174 | BLACKBIRD_STREAM_UNKNOWN9, /* audio/pcm ? */ | ||
175 | BLACKBIRD_STREAM_DVD, | ||
176 | BLACKBIRD_STREAM_VCD, | ||
177 | BLACKBIRD_STREAM_UNKNOWN12 /* svcd/xvcd ? */ | ||
178 | }; | ||
179 | #define BLACKBIRD_API_SET_OUTPUT_PORT 0xBB | ||
180 | enum blackbird_stream_port { | 87 | enum blackbird_stream_port { |
181 | BLACKBIRD_OUTPUT_PORT_MEMORY, | 88 | BLACKBIRD_OUTPUT_PORT_MEMORY, |
182 | BLACKBIRD_OUTPUT_PORT_STREAMING, | 89 | BLACKBIRD_OUTPUT_PORT_STREAMING, |
183 | BLACKBIRD_OUTPUT_PORT_SERIAL | 90 | BLACKBIRD_OUTPUT_PORT_SERIAL |
184 | }; | 91 | }; |
185 | #define BLACKBIRD_API_SET_AUDIO_PARAMS 0xBD | ||
186 | enum blackbird_audio_bits_sample_rate { | ||
187 | BLACKBIRD_AUDIO_BITS_44100HZ, | ||
188 | BLACKBIRD_AUDIO_BITS_48000HZ, | ||
189 | BLACKBIRD_AUDIO_BITS_32000HZ, | ||
190 | BLACKBIRD_AUDIO_BITS_RESERVED_HZ, | ||
191 | }; | ||
192 | enum blackbird_audio_bits_encoding { | ||
193 | BLACKBIRD_AUDIO_BITS_LAYER_1 = 0x1 << 2, | ||
194 | BLACKBIRD_AUDIO_BITS_LAYER_2 = 0x2 << 2, | ||
195 | }; | ||
196 | enum blackbird_audio_bits_bitrate_layer_1 { | ||
197 | BLACKBIRD_AUDIO_BITS_LAYER_1_FREE_FORMAT, | ||
198 | BLACKBIRD_AUDIO_BITS_LAYER_1_32 = 0x01 << 4, | ||
199 | BLACKBIRD_AUDIO_BITS_LAYER_1_64 = 0x02 << 4, | ||
200 | BLACKBIRD_AUDIO_BITS_LAYER_1_96 = 0x03 << 4, | ||
201 | BLACKBIRD_AUDIO_BITS_LAYER_1_128 = 0x04 << 4, | ||
202 | BLACKBIRD_AUDIO_BITS_LAYER_1_160 = 0x05 << 4, | ||
203 | BLACKBIRD_AUDIO_BITS_LAYER_1_192 = 0x06 << 4, | ||
204 | BLACKBIRD_AUDIO_BITS_LAYER_1_224 = 0x07 << 4, | ||
205 | BLACKBIRD_AUDIO_BITS_LAYER_1_256 = 0x08 << 4, | ||
206 | BLACKBIRD_AUDIO_BITS_LAYER_1_288 = 0x09 << 4, | ||
207 | BLACKBIRD_AUDIO_BITS_LAYER_1_320 = 0x0A << 4, | ||
208 | BLACKBIRD_AUDIO_BITS_LAYER_1_352 = 0x0B << 4, | ||
209 | BLACKBIRD_AUDIO_BITS_LAYER_1_384 = 0x0C << 4, | ||
210 | BLACKBIRD_AUDIO_BITS_LAYER_1_416 = 0x0D << 4, | ||
211 | BLACKBIRD_AUDIO_BITS_LAYER_1_448 = 0x0E << 4, | ||
212 | }; | ||
213 | enum blackbird_audio_bits_bitrate_layer_2 { | ||
214 | BLACKBIRD_AUDIO_BITS_LAYER_2_FREE_FORMAT, | ||
215 | BLACKBIRD_AUDIO_BITS_LAYER_2_32 = 0x01 << 4, | ||
216 | BLACKBIRD_AUDIO_BITS_LAYER_2_48 = 0x02 << 4, | ||
217 | BLACKBIRD_AUDIO_BITS_LAYER_2_56 = 0x03 << 4, | ||
218 | BLACKBIRD_AUDIO_BITS_LAYER_2_64 = 0x04 << 4, | ||
219 | BLACKBIRD_AUDIO_BITS_LAYER_2_80 = 0x05 << 4, | ||
220 | BLACKBIRD_AUDIO_BITS_LAYER_2_96 = 0x06 << 4, | ||
221 | BLACKBIRD_AUDIO_BITS_LAYER_2_112 = 0x07 << 4, | ||
222 | BLACKBIRD_AUDIO_BITS_LAYER_2_128 = 0x08 << 4, | ||
223 | BLACKBIRD_AUDIO_BITS_LAYER_2_160 = 0x09 << 4, | ||
224 | BLACKBIRD_AUDIO_BITS_LAYER_2_192 = 0x0A << 4, | ||
225 | BLACKBIRD_AUDIO_BITS_LAYER_2_224 = 0x0B << 4, | ||
226 | BLACKBIRD_AUDIO_BITS_LAYER_2_256 = 0x0C << 4, | ||
227 | BLACKBIRD_AUDIO_BITS_LAYER_2_320 = 0x0D << 4, | ||
228 | BLACKBIRD_AUDIO_BITS_LAYER_2_384 = 0x0E << 4, | ||
229 | }; | ||
230 | enum blackbird_audio_bits_mode { | ||
231 | BLACKBIRD_AUDIO_BITS_STEREO, | ||
232 | BLACKBIRD_AUDIO_BITS_JOINT_STEREO = 0x1 << 8, | ||
233 | BLACKBIRD_AUDIO_BITS_DUAL = 0x2 << 8, | ||
234 | BLACKBIRD_AUDIO_BITS_MONO = 0x3 << 8, | ||
235 | }; | ||
236 | enum blackbird_audio_bits_mode_extension { | ||
237 | BLACKBIRD_AUDIO_BITS_BOUND_4, | ||
238 | BLACKBIRD_AUDIO_BITS_BOUND_8 = 0x1 << 10, | ||
239 | BLACKBIRD_AUDIO_BITS_BOUND_12 = 0x2 << 10, | ||
240 | BLACKBIRD_AUDIO_BITS_BOUND_16 = 0x3 << 10, | ||
241 | }; | ||
242 | enum blackbird_audio_bits_emphasis { | ||
243 | BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE, | ||
244 | BLACKBIRD_AUDIO_BITS_EMPHASIS_50_15 = 0x1 << 12, | ||
245 | BLACKBIRD_AUDIO_BITS_EMPHASIS_RESERVED = 0x2 << 12, | ||
246 | BLACKBIRD_AUDIO_BITS_EMPHASIS_CCITT_J17 = 0x3 << 12, | ||
247 | }; | ||
248 | enum blackbird_audio_bits_crc { | ||
249 | BLACKBIRD_AUDIO_BITS_CRC_OFF, | ||
250 | BLACKBIRD_AUDIO_BITS_CRC_ON = 0x1 << 14, | ||
251 | }; | ||
252 | enum blackbird_audio_bits_copyright { | ||
253 | BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF, | ||
254 | BLACKBIRD_AUDIO_BITS_COPYRIGHT_ON = 0x1 << 15, | ||
255 | }; | ||
256 | enum blackbird_audio_bits_original { | ||
257 | BLACKBIRD_AUDIO_BITS_COPY, | ||
258 | BLACKBIRD_AUDIO_BITS_ORIGINAL = 0x1 << 16, | ||
259 | }; | ||
260 | #define BLACKBIRD_API_HALT 0xC3 | ||
261 | #define BLACKBIRD_API_GET_VERSION 0xC4 | ||
262 | #define BLACKBIRD_API_SET_GOP_CLOSURE 0xC5 | ||
263 | enum blackbird_gop_closure { | ||
264 | BLACKBIRD_GOP_CLOSURE_OFF, | ||
265 | BLACKBIRD_GOP_CLOSURE_ON, | ||
266 | }; | ||
267 | #define BLACKBIRD_API_DATA_XFER_STATUS 0xC6 | ||
268 | enum blackbird_data_xfer_status { | 92 | enum blackbird_data_xfer_status { |
269 | BLACKBIRD_MORE_BUFFERS_FOLLOW, | 93 | BLACKBIRD_MORE_BUFFERS_FOLLOW, |
270 | BLACKBIRD_LAST_BUFFER, | 94 | BLACKBIRD_LAST_BUFFER, |
271 | }; | 95 | }; |
272 | #define BLACKBIRD_API_PROGRAM_INDEX_INFO 0xC7 | ||
273 | enum blackbird_picture_mask { | 96 | enum blackbird_picture_mask { |
274 | BLACKBIRD_PICTURE_MASK_NONE, | 97 | BLACKBIRD_PICTURE_MASK_NONE, |
275 | BLACKBIRD_PICTURE_MASK_I_FRAMES, | 98 | BLACKBIRD_PICTURE_MASK_I_FRAMES, |
276 | BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3, | 99 | BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3, |
277 | BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7, | 100 | BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7, |
278 | }; | 101 | }; |
279 | #define BLACKBIRD_API_SET_VBI_PARAMS 0xC8 | ||
280 | enum blackbird_vbi_mode_bits { | 102 | enum blackbird_vbi_mode_bits { |
281 | BLACKBIRD_VBI_BITS_SLICED, | 103 | BLACKBIRD_VBI_BITS_SLICED, |
282 | BLACKBIRD_VBI_BITS_RAW, | 104 | BLACKBIRD_VBI_BITS_RAW, |
@@ -288,33 +110,23 @@ enum blackbird_vbi_insertion_bits { | |||
288 | BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, | 110 | BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, |
289 | BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, | 111 | BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, |
290 | }; | 112 | }; |
291 | #define BLACKBIRD_API_SET_DMA_BLOCK_SIZE 0xC9 | ||
292 | enum blackbird_dma_unit { | 113 | enum blackbird_dma_unit { |
293 | BLACKBIRD_DMA_BYTES, | 114 | BLACKBIRD_DMA_BYTES, |
294 | BLACKBIRD_DMA_FRAMES, | 115 | BLACKBIRD_DMA_FRAMES, |
295 | }; | 116 | }; |
296 | #define BLACKBIRD_API_DMA_TRANSFER_INFO 0xCA | ||
297 | #define BLACKBIRD_API_DMA_TRANSFER_STAT 0xCB | ||
298 | enum blackbird_dma_transfer_status_bits { | 117 | enum blackbird_dma_transfer_status_bits { |
299 | BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01, | 118 | BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01, |
300 | BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04, | 119 | BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04, |
301 | BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10, | 120 | BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10, |
302 | }; | 121 | }; |
303 | #define BLACKBIRD_API_SET_DMA2HOST_ADDR 0xCC | ||
304 | #define BLACKBIRD_API_INIT_VIDEO_INPUT 0xCD | ||
305 | #define BLACKBIRD_API_SET_FRAMESKIP 0xD0 | ||
306 | #define BLACKBIRD_API_PAUSE 0xD2 | ||
307 | enum blackbird_pause { | 122 | enum blackbird_pause { |
308 | BLACKBIRD_PAUSE_ENCODING, | 123 | BLACKBIRD_PAUSE_ENCODING, |
309 | BLACKBIRD_RESUME_ENCODING, | 124 | BLACKBIRD_RESUME_ENCODING, |
310 | }; | 125 | }; |
311 | #define BLACKBIRD_API_REFRESH_INPUT 0xD3 | ||
312 | #define BLACKBIRD_API_SET_COPYRIGHT 0xD4 | ||
313 | enum blackbird_copyright { | 126 | enum blackbird_copyright { |
314 | BLACKBIRD_COPYRIGHT_OFF, | 127 | BLACKBIRD_COPYRIGHT_OFF, |
315 | BLACKBIRD_COPYRIGHT_ON, | 128 | BLACKBIRD_COPYRIGHT_ON, |
316 | }; | 129 | }; |
317 | #define BLACKBIRD_API_SET_NOTIFICATION 0xD5 | ||
318 | enum blackbird_notification_type { | 130 | enum blackbird_notification_type { |
319 | BLACKBIRD_NOTIFICATION_REFRESH, | 131 | BLACKBIRD_NOTIFICATION_REFRESH, |
320 | }; | 132 | }; |
@@ -325,7 +137,6 @@ enum blackbird_notification_status { | |||
325 | enum blackbird_notification_mailbox { | 137 | enum blackbird_notification_mailbox { |
326 | BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1, | 138 | BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1, |
327 | }; | 139 | }; |
328 | #define BLACKBIRD_API_SET_CAPTURE_LINES 0xD6 | ||
329 | enum blackbird_field1_lines { | 140 | enum blackbird_field1_lines { |
330 | BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */ | 141 | BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */ |
331 | BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */ | 142 | BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */ |
@@ -336,12 +147,10 @@ enum blackbird_field2_lines { | |||
336 | BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */ | 147 | BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */ |
337 | BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */ | 148 | BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */ |
338 | }; | 149 | }; |
339 | #define BLACKBIRD_API_SET_CUSTOM_DATA 0xD7 | ||
340 | enum blackbird_custom_data_type { | 150 | enum blackbird_custom_data_type { |
341 | BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, | 151 | BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, |
342 | BLACKBIRD_CUSTOM_PRIVATE_PACKET, | 152 | BLACKBIRD_CUSTOM_PRIVATE_PACKET, |
343 | }; | 153 | }; |
344 | #define BLACKBIRD_API_MUTE_VIDEO 0xD9 | ||
345 | enum blackbird_mute { | 154 | enum blackbird_mute { |
346 | BLACKBIRD_UNMUTE, | 155 | BLACKBIRD_UNMUTE, |
347 | BLACKBIRD_MUTE, | 156 | BLACKBIRD_MUTE, |
@@ -356,7 +165,6 @@ enum blackbird_mute_video_shift { | |||
356 | BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16, | 165 | BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16, |
357 | BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24, | 166 | BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24, |
358 | }; | 167 | }; |
359 | #define BLACKBIRD_API_MUTE_AUDIO 0xDA | ||
360 | 168 | ||
361 | /* Registers */ | 169 | /* Registers */ |
362 | #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/) | 170 | #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/) |
@@ -498,15 +306,12 @@ static int register_read(struct cx88_core *core, u32 address, u32 *value) | |||
498 | 306 | ||
499 | /* ------------------------------------------------------------------ */ | 307 | /* ------------------------------------------------------------------ */ |
500 | 308 | ||
501 | /* We don't need to call the API often, so using just one mailbox will probably suffice */ | 309 | static int blackbird_mbox_func(void *priv, int command, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]) |
502 | static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, | ||
503 | u32 inputcnt, u32 outputcnt, ...) | ||
504 | { | 310 | { |
311 | struct cx8802_dev *dev = priv; | ||
505 | unsigned long timeout; | 312 | unsigned long timeout; |
506 | u32 value, flag, retval; | 313 | u32 value, flag, retval; |
507 | int i; | 314 | int i; |
508 | va_list args; | ||
509 | va_start(args, outputcnt); | ||
510 | 315 | ||
511 | dprintk(1,"%s: 0x%X\n", __FUNCTION__, command); | 316 | dprintk(1,"%s: 0x%X\n", __FUNCTION__, command); |
512 | 317 | ||
@@ -530,12 +335,11 @@ static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, | |||
530 | /* write command + args + fill remaining with zeros */ | 335 | /* write command + args + fill remaining with zeros */ |
531 | memory_write(dev->core, dev->mailbox + 1, command); /* command code */ | 336 | memory_write(dev->core, dev->mailbox + 1, command); /* command code */ |
532 | memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */ | 337 | memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */ |
533 | for (i = 0; i < inputcnt ; i++) { | 338 | for (i = 0; i < in; i++) { |
534 | value = va_arg(args, int); | 339 | memory_write(dev->core, dev->mailbox + 4 + i, data[i]); |
535 | memory_write(dev->core, dev->mailbox + 4 + i, value); | 340 | dprintk(1, "API Input %d = %d\n", i, data[i]); |
536 | dprintk(1, "API Input %d = %d\n", i, value); | ||
537 | } | 341 | } |
538 | for (; i < 16 ; i++) | 342 | for (; i < CX2341X_MBOX_MAX_DATA; i++) |
539 | memory_write(dev->core, dev->mailbox + 4 + i, 0); | 343 | memory_write(dev->core, dev->mailbox + 4 + i, 0); |
540 | 344 | ||
541 | flag |= 3; /* tell 'em we're done writing */ | 345 | flag |= 3; /* tell 'em we're done writing */ |
@@ -555,12 +359,10 @@ static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, | |||
555 | } | 359 | } |
556 | 360 | ||
557 | /* read output values */ | 361 | /* read output values */ |
558 | for (i = 0; i < outputcnt ; i++) { | 362 | for (i = 0; i < out; i++) { |
559 | int *vptr = va_arg(args, int *); | 363 | memory_read(dev->core, dev->mailbox + 4 + i, data + i); |
560 | memory_read(dev->core, dev->mailbox + 4 + i, vptr); | 364 | dprintk(1, "API Output %d = %d\n", i, data[i]); |
561 | dprintk(1, "API Output %d = %d\n", i, *vptr); | ||
562 | } | 365 | } |
563 | va_end(args); | ||
564 | 366 | ||
565 | memory_read(dev->core, dev->mailbox + 2, &retval); | 367 | memory_read(dev->core, dev->mailbox + 2, &retval); |
566 | dprintk(1, "API result = %d\n",retval); | 368 | dprintk(1, "API result = %d\n",retval); |
@@ -569,7 +371,29 @@ static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, | |||
569 | memory_write(dev->core, dev->mailbox, flag); | 371 | memory_write(dev->core, dev->mailbox, flag); |
570 | return retval; | 372 | return retval; |
571 | } | 373 | } |
374 | /* ------------------------------------------------------------------ */ | ||
572 | 375 | ||
376 | /* We don't need to call the API often, so using just one mailbox will probably suffice */ | ||
377 | static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, | ||
378 | u32 inputcnt, u32 outputcnt, ...) | ||
379 | { | ||
380 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
381 | va_list vargs; | ||
382 | int i, err; | ||
383 | |||
384 | va_start(vargs, outputcnt); | ||
385 | |||
386 | for (i = 0; i < inputcnt; i++) { | ||
387 | data[i] = va_arg(vargs, int); | ||
388 | } | ||
389 | err = blackbird_mbox_func(dev, command, inputcnt, outputcnt, data); | ||
390 | for (i = 0; i < outputcnt; i++) { | ||
391 | int *vptr = va_arg(vargs, int *); | ||
392 | *vptr = data[i]; | ||
393 | } | ||
394 | va_end(vargs); | ||
395 | return err; | ||
396 | } | ||
573 | 397 | ||
574 | static int blackbird_find_mailbox(struct cx8802_dev *dev) | 398 | static int blackbird_find_mailbox(struct cx8802_dev *dev) |
575 | { | 399 | { |
@@ -614,13 +438,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) | |||
614 | if (retval < 0) | 438 | if (retval < 0) |
615 | dprintk(0, "Error with register_write\n"); | 439 | dprintk(0, "Error with register_write\n"); |
616 | 440 | ||
617 | retval = request_firmware(&firmware, BLACKBIRD_FIRM_ENC_FILENAME, | 441 | retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME, |
618 | &dev->pci->dev); | 442 | &dev->pci->dev); |
619 | 443 | ||
620 | 444 | ||
621 | if (retval != 0) { | 445 | if (retval != 0) { |
622 | dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n", | 446 | dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n", |
623 | BLACKBIRD_FIRM_ENC_FILENAME); | 447 | CX2341X_FIRM_ENC_FILENAME); |
624 | dprintk(0, "Please fix your hotplug setup, the board will " | 448 | dprintk(0, "Please fix your hotplug setup, the board will " |
625 | "not work without firmware loaded!\n"); | 449 | "not work without firmware loaded!\n"); |
626 | return -1; | 450 | return -1; |
@@ -686,12 +510,19 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M | |||
686 | *DB: "DirectBurn" | 510 | *DB: "DirectBurn" |
687 | */ | 511 | */ |
688 | 512 | ||
689 | static struct blackbird_dnr default_dnr_params = { | 513 | static void blackbird_codec_settings(struct cx8802_dev *dev) |
690 | .mode = BLACKBIRD_DNR_BITS_MANUAL, | 514 | { |
691 | .type = BLACKBIRD_MEDIAN_FILTER_DISABLED, | 515 | /* assign frame size */ |
692 | .spatial = 0, | 516 | blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, |
693 | .temporal = 0 | 517 | dev->height, dev->width); |
694 | }; | 518 | |
519 | dev->params.width = dev->width; | ||
520 | dev->params.height = dev->height; | ||
521 | dev->params.is_50hz = (dev->core->tvnorm->id & V4L2_STD_625_50) != 0; | ||
522 | |||
523 | cx2341x_update(dev, blackbird_mbox_func, NULL, &dev->params); | ||
524 | } | ||
525 | |||
695 | static struct v4l2_mpeg_compression default_mpeg_params = { | 526 | static struct v4l2_mpeg_compression default_mpeg_params = { |
696 | .st_type = V4L2_MPEG_PS_2, | 527 | .st_type = V4L2_MPEG_PS_2, |
697 | .st_bitrate = { | 528 | .st_bitrate = { |
@@ -712,7 +543,7 @@ static struct v4l2_mpeg_compression default_mpeg_params = { | |||
712 | .target = 224, | 543 | .target = 224, |
713 | .max = 224 | 544 | .max = 224 |
714 | }, | 545 | }, |
715 | .au_sample_rate = 44100, | 546 | .au_sample_rate = 48000, |
716 | .au_pesid = 0, | 547 | .au_pesid = 0, |
717 | .vi_type = V4L2_MPEG_VI_2, | 548 | .vi_type = V4L2_MPEG_VI_2, |
718 | .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3, | 549 | .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3, |
@@ -723,524 +554,13 @@ static struct v4l2_mpeg_compression default_mpeg_params = { | |||
723 | .max = 6000 | 554 | .max = 6000 |
724 | }, | 555 | }, |
725 | .vi_frame_rate = 25, | 556 | .vi_frame_rate = 25, |
726 | .vi_frames_per_gop = 15, | 557 | .vi_frames_per_gop = 12, |
727 | .vi_bframes_count = 2, | 558 | .vi_bframes_count = 2, |
728 | .vi_pesid = 0, | 559 | .vi_pesid = 0, |
729 | .closed_gops = 0, | 560 | .closed_gops = 1, |
730 | .pulldown = 0 | 561 | .pulldown = 0 |
731 | }; | 562 | }; |
732 | 563 | ||
733 | static enum blackbird_stream_type mpeg_stream_types[] = { | ||
734 | [V4L2_MPEG_SS_1] = BLACKBIRD_STREAM_MPEG1, | ||
735 | [V4L2_MPEG_PS_2] = BLACKBIRD_STREAM_PROGRAM, | ||
736 | [V4L2_MPEG_TS_2] = BLACKBIRD_STREAM_TRANSPORT, | ||
737 | [V4L2_MPEG_PS_DVD] = BLACKBIRD_STREAM_DVD, | ||
738 | }; | ||
739 | static enum blackbird_aspect_ratio mpeg_stream_ratios[] = { | ||
740 | [V4L2_MPEG_ASPECT_SQUARE] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE, | ||
741 | [V4L2_MPEG_ASPECT_4_3] = BLACKBIRD_ASPECT_RATIO_4_3, | ||
742 | [V4L2_MPEG_ASPECT_16_9] = BLACKBIRD_ASPECT_RATIO_16_9, | ||
743 | [V4L2_MPEG_ASPECT_1_221] = BLACKBIRD_ASPECT_RATIO_221_100, | ||
744 | }; | ||
745 | static enum blackbird_video_bitrate_type mpeg_video_bitrates[] = { | ||
746 | [V4L2_BITRATE_NONE] = BLACKBIRD_VIDEO_CBR, | ||
747 | [V4L2_BITRATE_CBR] = BLACKBIRD_VIDEO_CBR, | ||
748 | [V4L2_BITRATE_VBR] = BLACKBIRD_VIDEO_VBR, | ||
749 | }; | ||
750 | /* find the best layer I/II bitrate to fit a given numeric value */ | ||
751 | struct bitrate_bits { | ||
752 | u32 bits; /* layer bits for the best fit */ | ||
753 | u32 rate; /* actual numeric value for the layer best fit */ | ||
754 | }; | ||
755 | struct bitrate_approximation { | ||
756 | u32 target; /* numeric value of the rate we want */ | ||
757 | struct bitrate_bits layer[2]; | ||
758 | }; | ||
759 | static struct bitrate_approximation mpeg_audio_bitrates[] = { | ||
760 | /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */ | ||
761 | { 0, { { 0, 0, }, { 0, 0, }, }, }, | ||
762 | { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32 , 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32 , 32, }, }, }, | ||
763 | { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48 , 48, }, }, }, | ||
764 | { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56 , 56, }, }, }, | ||
765 | { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64 , 64, }, }, }, | ||
766 | { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80 , 80, }, }, }, | ||
767 | { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96 , 96, }, }, }, | ||
768 | { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112, 112, }, }, }, | ||
769 | { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128, 128, }, }, }, | ||
770 | { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160, 160, }, }, }, | ||
771 | { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192, 192, }, }, }, | ||
772 | { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224, 224, }, }, }, | ||
773 | { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256, 256, }, }, }, | ||
774 | { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, }, | ||
775 | { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, }, | ||
776 | { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, | ||
777 | { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, | ||
778 | { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, | ||
779 | { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, | ||
780 | }; | ||
781 | static const int BITRATES_SIZE = ARRAY_SIZE(mpeg_audio_bitrates); | ||
782 | |||
783 | static void blackbird_set_default_params(struct cx8802_dev *dev) | ||
784 | { | ||
785 | struct v4l2_mpeg_compression *params = &dev->params; | ||
786 | u32 au_params; | ||
787 | |||
788 | /* assign stream type */ | ||
789 | if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) ) | ||
790 | params->st_type = V4L2_MPEG_PS_2; | ||
791 | if( params->st_type == V4L2_MPEG_SS_1 ) | ||
792 | params->vi_type = V4L2_MPEG_VI_1; | ||
793 | else | ||
794 | params->vi_type = V4L2_MPEG_VI_2; | ||
795 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]); | ||
796 | |||
797 | /* assign framerate */ | ||
798 | if( params->vi_frame_rate <= 25 ) | ||
799 | { | ||
800 | params->vi_frame_rate = 25; | ||
801 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); | ||
802 | } | ||
803 | else | ||
804 | { | ||
805 | params->vi_frame_rate = 30; | ||
806 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30); | ||
807 | } | ||
808 | |||
809 | /* assign aspect ratio */ | ||
810 | if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) ) | ||
811 | params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3; | ||
812 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]); | ||
813 | |||
814 | /* assign gop properties */ | ||
815 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1); | ||
816 | |||
817 | /* assign gop closure */ | ||
818 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops); | ||
819 | |||
820 | /* assign 3 2 pulldown */ | ||
821 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown); | ||
822 | |||
823 | /* make sure the params are within bounds */ | ||
824 | if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
825 | params->vi_bitrate.mode = V4L2_BITRATE_NONE; | ||
826 | if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
827 | params->vi_bitrate.mode = V4L2_BITRATE_NONE; | ||
828 | if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
829 | params->au_bitrate.mode = V4L2_BITRATE_NONE; | ||
830 | |||
831 | /* assign audio properties */ | ||
832 | /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ | ||
833 | au_params = BLACKBIRD_AUDIO_BITS_STEREO | | ||
834 | /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ | ||
835 | BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | | ||
836 | BLACKBIRD_AUDIO_BITS_CRC_OFF | | ||
837 | BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | | ||
838 | BLACKBIRD_AUDIO_BITS_COPY | | ||
839 | 0; | ||
840 | if( params->au_sample_rate <= 32000 ) | ||
841 | { | ||
842 | params->au_sample_rate = 32000; | ||
843 | au_params |= BLACKBIRD_AUDIO_BITS_32000HZ; | ||
844 | } | ||
845 | else if( params->au_sample_rate <= 44100 ) | ||
846 | { | ||
847 | params->au_sample_rate = 44100; | ||
848 | au_params |= BLACKBIRD_AUDIO_BITS_44100HZ; | ||
849 | } | ||
850 | else | ||
851 | { | ||
852 | params->au_sample_rate = 48000; | ||
853 | au_params |= BLACKBIRD_AUDIO_BITS_48000HZ; | ||
854 | } | ||
855 | if( params->au_type == V4L2_MPEG_AU_2_I ) | ||
856 | { | ||
857 | au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1; | ||
858 | } | ||
859 | else | ||
860 | { | ||
861 | /* TODO: try to handle the other formats more gracefully */ | ||
862 | params->au_type = V4L2_MPEG_AU_2_II; | ||
863 | au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2; | ||
864 | } | ||
865 | if( params->au_bitrate.mode ) | ||
866 | { | ||
867 | int layer; | ||
868 | |||
869 | if( params->au_bitrate.mode == V4L2_BITRATE_CBR ) | ||
870 | params->au_bitrate.max = params->vi_bitrate.target; | ||
871 | else | ||
872 | params->au_bitrate.target = params->vi_bitrate.max; | ||
873 | |||
874 | layer = params->au_type; | ||
875 | if( params->au_bitrate.target == 0 ) | ||
876 | { | ||
877 | /* TODO: use the minimum possible bitrate instead of 0 ? */ | ||
878 | au_params |= 0; | ||
879 | } | ||
880 | else if( params->au_bitrate.target >= | ||
881 | mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate ) | ||
882 | { | ||
883 | /* clamp the bitrate to the max supported by the standard */ | ||
884 | params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate; | ||
885 | params->au_bitrate.max = params->au_bitrate.target; | ||
886 | au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits; | ||
887 | } | ||
888 | else | ||
889 | { | ||
890 | /* round up to the nearest supported bitrate */ | ||
891 | int i; | ||
892 | for(i = 1; i < BITRATES_SIZE; i++) | ||
893 | { | ||
894 | if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate && | ||
895 | params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate ) | ||
896 | { | ||
897 | params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate; | ||
898 | params->au_bitrate.max = params->au_bitrate.target; | ||
899 | au_params |= mpeg_audio_bitrates[i].layer[layer].bits; | ||
900 | break; | ||
901 | } | ||
902 | } | ||
903 | } | ||
904 | } | ||
905 | else | ||
906 | { | ||
907 | /* TODO: ??? */ | ||
908 | params->au_bitrate.target = params->au_bitrate.max = 0; | ||
909 | au_params |= 0; | ||
910 | } | ||
911 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params ); | ||
912 | |||
913 | /* assign bitrates */ | ||
914 | if( params->vi_bitrate.mode ) | ||
915 | { | ||
916 | /* bitrate is set, let's figure out the cbr/vbr mess */ | ||
917 | if( params->vi_bitrate.max < params->vi_bitrate.target ) | ||
918 | { | ||
919 | if( params->vi_bitrate.mode == V4L2_BITRATE_CBR ) | ||
920 | params->vi_bitrate.max = params->vi_bitrate.target; | ||
921 | else | ||
922 | params->vi_bitrate.target = params->vi_bitrate.max; | ||
923 | } | ||
924 | } | ||
925 | else | ||
926 | { | ||
927 | if( params->st_bitrate.max < params->st_bitrate.target ) | ||
928 | { | ||
929 | if( params->st_bitrate.mode == V4L2_BITRATE_VBR ) | ||
930 | params->st_bitrate.target = params->st_bitrate.max; | ||
931 | else | ||
932 | params->st_bitrate.max = params->st_bitrate.target; | ||
933 | } | ||
934 | /* calculate vi_bitrate = st_bitrate - au_bitrate */ | ||
935 | params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max; | ||
936 | params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target; | ||
937 | } | ||
938 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0, | ||
939 | mpeg_video_bitrates[params->vi_bitrate.mode], | ||
940 | params->vi_bitrate.target * 1000, /* kbps -> bps */ | ||
941 | params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */ | ||
942 | BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */ | ||
943 | |||
944 | /* TODO: implement the stream ID stuff: | ||
945 | ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr, | ||
946 | ps_size, au_pesid, vi_pesid | ||
947 | */ | ||
948 | } | ||
949 | #define CHECK_PARAM( name ) ( dev->params.name != params->name ) | ||
950 | #define IF_PARAM( name ) if( CHECK_PARAM( name ) ) | ||
951 | #define UPDATE_PARAM( name ) dev->params.name = params->name | ||
952 | void blackbird_set_params(struct cx8802_dev *dev, struct v4l2_mpeg_compression *params) | ||
953 | { | ||
954 | u32 au_params; | ||
955 | |||
956 | /* assign stream type */ | ||
957 | if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) ) | ||
958 | params->st_type = V4L2_MPEG_PS_2; | ||
959 | if( params->st_type == V4L2_MPEG_SS_1 ) | ||
960 | params->vi_type = V4L2_MPEG_VI_1; | ||
961 | else | ||
962 | params->vi_type = V4L2_MPEG_VI_2; | ||
963 | if( CHECK_PARAM( st_type ) || CHECK_PARAM( vi_type ) ) | ||
964 | { | ||
965 | UPDATE_PARAM( st_type ); | ||
966 | UPDATE_PARAM( vi_type ); | ||
967 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]); | ||
968 | } | ||
969 | |||
970 | /* assign framerate */ | ||
971 | if( params->vi_frame_rate <= 25 ) | ||
972 | params->vi_frame_rate = 25; | ||
973 | else | ||
974 | params->vi_frame_rate = 30; | ||
975 | IF_PARAM( vi_frame_rate ) | ||
976 | { | ||
977 | UPDATE_PARAM( vi_frame_rate ); | ||
978 | if( params->vi_frame_rate == 25 ) | ||
979 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); | ||
980 | else | ||
981 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30); | ||
982 | } | ||
983 | |||
984 | /* assign aspect ratio */ | ||
985 | if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) ) | ||
986 | params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3; | ||
987 | IF_PARAM( vi_aspect_ratio ) | ||
988 | { | ||
989 | UPDATE_PARAM( vi_aspect_ratio ); | ||
990 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]); | ||
991 | } | ||
992 | |||
993 | /* assign gop properties */ | ||
994 | if( CHECK_PARAM( vi_frames_per_gop ) || CHECK_PARAM( vi_bframes_count ) ) | ||
995 | { | ||
996 | UPDATE_PARAM( vi_frames_per_gop ); | ||
997 | UPDATE_PARAM( vi_bframes_count ); | ||
998 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1); | ||
999 | } | ||
1000 | |||
1001 | /* assign gop closure */ | ||
1002 | IF_PARAM( closed_gops ) | ||
1003 | { | ||
1004 | UPDATE_PARAM( closed_gops ); | ||
1005 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops); | ||
1006 | } | ||
1007 | |||
1008 | /* assign 3 2 pulldown */ | ||
1009 | IF_PARAM( pulldown ) | ||
1010 | { | ||
1011 | UPDATE_PARAM( pulldown ); | ||
1012 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown); | ||
1013 | } | ||
1014 | |||
1015 | /* make sure the params are within bounds */ | ||
1016 | if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
1017 | params->vi_bitrate.mode = V4L2_BITRATE_NONE; | ||
1018 | if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
1019 | params->vi_bitrate.mode = V4L2_BITRATE_NONE; | ||
1020 | if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
1021 | params->au_bitrate.mode = V4L2_BITRATE_NONE; | ||
1022 | |||
1023 | /* assign audio properties */ | ||
1024 | /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ | ||
1025 | au_params = BLACKBIRD_AUDIO_BITS_STEREO | | ||
1026 | /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ | ||
1027 | BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | | ||
1028 | BLACKBIRD_AUDIO_BITS_CRC_OFF | | ||
1029 | BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | | ||
1030 | BLACKBIRD_AUDIO_BITS_COPY | | ||
1031 | 0; | ||
1032 | if( params->au_sample_rate < 32000 ) | ||
1033 | { | ||
1034 | params->au_sample_rate = 32000; | ||
1035 | au_params |= BLACKBIRD_AUDIO_BITS_32000HZ; | ||
1036 | } | ||
1037 | else if( params->au_sample_rate < 44100 ) | ||
1038 | { | ||
1039 | params->au_sample_rate = 44100; | ||
1040 | au_params |= BLACKBIRD_AUDIO_BITS_44100HZ; | ||
1041 | } | ||
1042 | else | ||
1043 | { | ||
1044 | params->au_sample_rate = 48000; | ||
1045 | au_params |= BLACKBIRD_AUDIO_BITS_48000HZ; | ||
1046 | } | ||
1047 | if( params->au_type == V4L2_MPEG_AU_2_I ) | ||
1048 | { | ||
1049 | au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1; | ||
1050 | } | ||
1051 | else | ||
1052 | { | ||
1053 | /* TODO: try to handle the other formats more gracefully */ | ||
1054 | params->au_type = V4L2_MPEG_AU_2_II; | ||
1055 | au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2; | ||
1056 | } | ||
1057 | if( params->au_bitrate.mode ) | ||
1058 | { | ||
1059 | int layer; | ||
1060 | |||
1061 | if( params->au_bitrate.mode == V4L2_BITRATE_CBR ) | ||
1062 | params->au_bitrate.max = params->vi_bitrate.target; | ||
1063 | else | ||
1064 | params->au_bitrate.target = params->vi_bitrate.max; | ||
1065 | |||
1066 | layer = params->au_type; | ||
1067 | if( params->au_bitrate.target == 0 ) | ||
1068 | { | ||
1069 | /* TODO: use the minimum possible bitrate instead of 0 ? */ | ||
1070 | au_params |= 0; | ||
1071 | } | ||
1072 | else if( params->au_bitrate.target >= | ||
1073 | mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate ) | ||
1074 | { | ||
1075 | /* clamp the bitrate to the max supported by the standard */ | ||
1076 | params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate; | ||
1077 | params->au_bitrate.max = params->au_bitrate.target; | ||
1078 | au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits; | ||
1079 | } | ||
1080 | else | ||
1081 | { | ||
1082 | /* round up to the nearest supported bitrate */ | ||
1083 | int i; | ||
1084 | for(i = 1; i < BITRATES_SIZE; i++) | ||
1085 | { | ||
1086 | if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate && | ||
1087 | params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate ) | ||
1088 | { | ||
1089 | params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate; | ||
1090 | params->au_bitrate.max = params->au_bitrate.target; | ||
1091 | au_params |= mpeg_audio_bitrates[i].layer[layer].bits; | ||
1092 | break; | ||
1093 | } | ||
1094 | } | ||
1095 | } | ||
1096 | } | ||
1097 | else | ||
1098 | { | ||
1099 | /* TODO: ??? */ | ||
1100 | params->au_bitrate.target = params->au_bitrate.max = 0; | ||
1101 | au_params |= 0; | ||
1102 | } | ||
1103 | if( CHECK_PARAM( au_type ) || CHECK_PARAM( au_sample_rate ) | ||
1104 | || CHECK_PARAM( au_bitrate.mode ) || CHECK_PARAM( au_bitrate.max ) | ||
1105 | || CHECK_PARAM( au_bitrate.target ) | ||
1106 | ) | ||
1107 | { | ||
1108 | UPDATE_PARAM( au_type ); | ||
1109 | UPDATE_PARAM( au_sample_rate ); | ||
1110 | UPDATE_PARAM( au_bitrate ); | ||
1111 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params ); | ||
1112 | } | ||
1113 | |||
1114 | /* assign bitrates */ | ||
1115 | if( params->vi_bitrate.mode ) | ||
1116 | { | ||
1117 | /* bitrate is set, let's figure out the cbr/vbr mess */ | ||
1118 | if( params->vi_bitrate.max < params->vi_bitrate.target ) | ||
1119 | { | ||
1120 | if( params->vi_bitrate.mode == V4L2_BITRATE_CBR ) | ||
1121 | params->vi_bitrate.max = params->vi_bitrate.target; | ||
1122 | else | ||
1123 | params->vi_bitrate.target = params->vi_bitrate.max; | ||
1124 | } | ||
1125 | } | ||
1126 | else | ||
1127 | { | ||
1128 | if( params->st_bitrate.max < params->st_bitrate.target ) | ||
1129 | { | ||
1130 | if( params->st_bitrate.mode == V4L2_BITRATE_VBR ) | ||
1131 | params->st_bitrate.target = params->st_bitrate.max; | ||
1132 | else | ||
1133 | params->st_bitrate.max = params->st_bitrate.target; | ||
1134 | } | ||
1135 | /* calculate vi_bitrate = st_bitrate - au_bitrate */ | ||
1136 | params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max; | ||
1137 | params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target; | ||
1138 | } | ||
1139 | UPDATE_PARAM( st_bitrate ); | ||
1140 | if( CHECK_PARAM( vi_bitrate.mode ) || CHECK_PARAM( vi_bitrate.max ) | ||
1141 | || CHECK_PARAM( vi_bitrate.target ) | ||
1142 | ) | ||
1143 | { | ||
1144 | UPDATE_PARAM( vi_bitrate ); | ||
1145 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0, | ||
1146 | mpeg_video_bitrates[params->vi_bitrate.mode], | ||
1147 | params->vi_bitrate.target * 1000, /* kbps -> bps */ | ||
1148 | params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */ | ||
1149 | BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */ | ||
1150 | } | ||
1151 | |||
1152 | /* TODO: implement the stream ID stuff: | ||
1153 | ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr, | ||
1154 | ps_size, au_pesid, vi_pesid | ||
1155 | */ | ||
1156 | UPDATE_PARAM( ts_pid_pmt ); | ||
1157 | UPDATE_PARAM( ts_pid_audio ); | ||
1158 | UPDATE_PARAM( ts_pid_video ); | ||
1159 | UPDATE_PARAM( ts_pid_pcr ); | ||
1160 | UPDATE_PARAM( ps_size ); | ||
1161 | UPDATE_PARAM( au_pesid ); | ||
1162 | UPDATE_PARAM( vi_pesid ); | ||
1163 | } | ||
1164 | |||
1165 | static void blackbird_set_default_dnr_params(struct cx8802_dev *dev) | ||
1166 | { | ||
1167 | /* assign dnr filter mode */ | ||
1168 | if( dev->dnr_params.mode > BLACKBIRD_DNR_BITS_AUTO ) | ||
1169 | dev->dnr_params.mode = BLACKBIRD_DNR_BITS_MANUAL; | ||
1170 | if( dev->dnr_params.type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL ) | ||
1171 | dev->dnr_params.type = BLACKBIRD_MEDIAN_FILTER_DISABLED; | ||
1172 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, | ||
1173 | dev->dnr_params.mode, | ||
1174 | dev->dnr_params.type | ||
1175 | ); | ||
1176 | |||
1177 | /* assign dnr filter props*/ | ||
1178 | if( dev->dnr_params.spatial > 15 ) | ||
1179 | dev->dnr_params.spatial = 15; | ||
1180 | if( dev->dnr_params.temporal > 31 ) | ||
1181 | dev->dnr_params.temporal = 31; | ||
1182 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, | ||
1183 | dev->dnr_params.spatial, | ||
1184 | dev->dnr_params.temporal | ||
1185 | ); | ||
1186 | } | ||
1187 | #define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name ) | ||
1188 | #define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name | ||
1189 | void blackbird_set_dnr_params(struct cx8802_dev *dev, struct blackbird_dnr* dnr_params) | ||
1190 | { | ||
1191 | /* assign dnr filter mode */ | ||
1192 | /* clamp values */ | ||
1193 | if( dnr_params->mode > BLACKBIRD_DNR_BITS_AUTO ) | ||
1194 | dnr_params->mode = BLACKBIRD_DNR_BITS_MANUAL; | ||
1195 | if( dnr_params->type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL ) | ||
1196 | dnr_params->type = BLACKBIRD_MEDIAN_FILTER_DISABLED; | ||
1197 | /* check if the params actually changed */ | ||
1198 | if( CHECK_DNR_PARAM( mode ) || CHECK_DNR_PARAM( type ) ) | ||
1199 | { | ||
1200 | UPDATE_DNR_PARAM( mode ); | ||
1201 | UPDATE_DNR_PARAM( type ); | ||
1202 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, dnr_params->mode, dnr_params->type); | ||
1203 | } | ||
1204 | |||
1205 | /* assign dnr filter props*/ | ||
1206 | if( dnr_params->spatial > 15 ) | ||
1207 | dnr_params->spatial = 15; | ||
1208 | if( dnr_params->temporal > 31 ) | ||
1209 | dnr_params->temporal = 31; | ||
1210 | if( CHECK_DNR_PARAM( spatial ) || CHECK_DNR_PARAM( temporal ) ) | ||
1211 | { | ||
1212 | UPDATE_DNR_PARAM( spatial ); | ||
1213 | UPDATE_DNR_PARAM( temporal ); | ||
1214 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, dnr_params->spatial, dnr_params->temporal); | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1218 | static void blackbird_codec_settings(struct cx8802_dev *dev) | ||
1219 | { | ||
1220 | |||
1221 | /* assign output port */ | ||
1222 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ | ||
1223 | |||
1224 | /* assign frame size */ | ||
1225 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0, | ||
1226 | dev->height, dev->width); | ||
1227 | |||
1228 | /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ | ||
1229 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255); | ||
1230 | |||
1231 | /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */ | ||
1232 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0, | ||
1233 | BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, | ||
1234 | BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ | ||
1235 | ); | ||
1236 | |||
1237 | /* assign frame drop rate */ | ||
1238 | /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */ | ||
1239 | |||
1240 | blackbird_set_default_params(dev); | ||
1241 | blackbird_set_default_dnr_params(dev); | ||
1242 | } | ||
1243 | |||
1244 | static int blackbird_initialize_codec(struct cx8802_dev *dev) | 564 | static int blackbird_initialize_codec(struct cx8802_dev *dev) |
1245 | { | 565 | { |
1246 | struct cx88_core *core = dev->core; | 566 | struct cx88_core *core = dev->core; |
@@ -1248,7 +568,7 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) | |||
1248 | int retval; | 568 | int retval; |
1249 | 569 | ||
1250 | dprintk(1,"Initialize codec\n"); | 570 | dprintk(1,"Initialize codec\n"); |
1251 | retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */ | 571 | retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ |
1252 | if (retval < 0) { | 572 | if (retval < 0) { |
1253 | /* ping was not successful, reset and upload firmware */ | 573 | /* ping was not successful, reset and upload firmware */ |
1254 | cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */ | 574 | cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */ |
@@ -1263,13 +583,13 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) | |||
1263 | if (dev->mailbox < 0) | 583 | if (dev->mailbox < 0) |
1264 | return -1; | 584 | return -1; |
1265 | 585 | ||
1266 | retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */ | 586 | retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ |
1267 | if (retval < 0) { | 587 | if (retval < 0) { |
1268 | dprintk(0, "ERROR: Firmware ping failed!\n"); | 588 | dprintk(0, "ERROR: Firmware ping failed!\n"); |
1269 | return -1; | 589 | return -1; |
1270 | } | 590 | } |
1271 | 591 | ||
1272 | retval = blackbird_api_cmd(dev, BLACKBIRD_API_GET_VERSION, 0, 1, &version); | 592 | retval = blackbird_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); |
1273 | if (retval < 0) { | 593 | if (retval < 0) { |
1274 | dprintk(0, "ERROR: Firmware get encoder version failed!\n"); | 594 | dprintk(0, "ERROR: Firmware get encoder version failed!\n"); |
1275 | return -1; | 595 | return -1; |
@@ -1289,35 +609,35 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) | |||
1289 | /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef); | 609 | /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef); |
1290 | blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0); | 610 | blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0); |
1291 | blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */ | 611 | blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */ |
1292 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_CAPTURE_LINES, 2, 0, | 612 | blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0, |
1293 | BLACKBIRD_FIELD1_SAA7115, | 613 | BLACKBIRD_FIELD1_SAA7115, |
1294 | BLACKBIRD_FIELD1_SAA7115 | 614 | BLACKBIRD_FIELD2_SAA7115 |
1295 | ); | 615 | ); |
1296 | 616 | ||
1297 | /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */ | 617 | /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */ |
1298 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_CUSTOM_DATA, 12, 0, | 618 | blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0, |
1299 | BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, | 619 | BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, |
1300 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); | 620 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); |
1301 | 621 | ||
1302 | /* initialize the video input */ | 622 | /* initialize the video input */ |
1303 | blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0); | 623 | blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0); |
1304 | 624 | ||
1305 | msleep(1); | 625 | msleep(1); |
1306 | 626 | ||
1307 | blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE); | 627 | blackbird_api_cmd(dev, CX2341X_ENC_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE); |
1308 | msleep(1); | 628 | msleep(1); |
1309 | blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE); | 629 | blackbird_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE); |
1310 | msleep(1); | 630 | msleep(1); |
1311 | 631 | ||
1312 | /* start capturing to the host interface */ | 632 | /* start capturing to the host interface */ |
1313 | /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); */ | 633 | /* blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, 0, 0x13); */ |
1314 | blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, | 634 | blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, |
1315 | BLACKBIRD_MPEG_CAPTURE, | 635 | BLACKBIRD_MPEG_CAPTURE, |
1316 | BLACKBIRD_RAW_BITS_NONE | 636 | BLACKBIRD_RAW_BITS_NONE |
1317 | ); | 637 | ); |
1318 | msleep(10); | 638 | msleep(10); |
1319 | 639 | ||
1320 | blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0); | 640 | blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0,0); |
1321 | return 0; | 641 | return 0; |
1322 | } | 642 | } |
1323 | 643 | ||
@@ -1485,14 +805,52 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, | |||
1485 | { | 805 | { |
1486 | struct v4l2_mpeg_compression *f = arg; | 806 | struct v4l2_mpeg_compression *f = arg; |
1487 | 807 | ||
1488 | memcpy(f,&dev->params,sizeof(*f)); | 808 | printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. " |
809 | "Replace with VIDIOC_G_EXT_CTRLS!"); | ||
810 | memcpy(f,&default_mpeg_params,sizeof(*f)); | ||
1489 | return 0; | 811 | return 0; |
1490 | } | 812 | } |
1491 | case VIDIOC_S_MPEGCOMP: | 813 | case VIDIOC_S_MPEGCOMP: |
814 | printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. " | ||
815 | "Replace with VIDIOC_S_EXT_CTRLS!"); | ||
816 | return 0; | ||
817 | case VIDIOC_G_EXT_CTRLS: | ||
1492 | { | 818 | { |
1493 | struct v4l2_mpeg_compression *f = arg; | 819 | struct v4l2_ext_controls *f = arg; |
1494 | 820 | ||
1495 | blackbird_set_params(dev, f); | 821 | if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) |
822 | return -EINVAL; | ||
823 | return cx2341x_ext_ctrls(&dev->params, f, cmd); | ||
824 | } | ||
825 | case VIDIOC_S_EXT_CTRLS: | ||
826 | case VIDIOC_TRY_EXT_CTRLS: | ||
827 | { | ||
828 | struct v4l2_ext_controls *f = arg; | ||
829 | struct cx2341x_mpeg_params p; | ||
830 | int err; | ||
831 | |||
832 | if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
833 | return -EINVAL; | ||
834 | p = dev->params; | ||
835 | err = cx2341x_ext_ctrls(&p, f, cmd); | ||
836 | if (err == 0 && cmd == VIDIOC_S_EXT_CTRLS) { | ||
837 | err = cx2341x_update(dev, blackbird_mbox_func, &dev->params, &p); | ||
838 | dev->params = p; | ||
839 | } | ||
840 | return err; | ||
841 | } | ||
842 | case VIDIOC_S_FREQUENCY: | ||
843 | { | ||
844 | blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, | ||
845 | BLACKBIRD_END_NOW, | ||
846 | BLACKBIRD_MPEG_CAPTURE, | ||
847 | BLACKBIRD_RAW_BITS_NONE); | ||
848 | |||
849 | cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook ); | ||
850 | |||
851 | blackbird_initialize_codec(dev); | ||
852 | cx88_set_scale(dev->core, dev->width, dev->height, | ||
853 | fh->mpegq.field); | ||
1496 | return 0; | 854 | return 0; |
1497 | } | 855 | } |
1498 | 856 | ||
@@ -1562,13 +920,14 @@ static int mpeg_release(struct inode *inode, struct file *file) | |||
1562 | { | 920 | { |
1563 | struct cx8802_fh *fh = file->private_data; | 921 | struct cx8802_fh *fh = file->private_data; |
1564 | 922 | ||
1565 | /* blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */ | 923 | /* blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */ |
1566 | blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, | 924 | blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, |
1567 | BLACKBIRD_END_NOW, | 925 | BLACKBIRD_END_NOW, |
1568 | BLACKBIRD_MPEG_CAPTURE, | 926 | BLACKBIRD_MPEG_CAPTURE, |
1569 | BLACKBIRD_RAW_BITS_NONE | 927 | BLACKBIRD_RAW_BITS_NONE |
1570 | ); | 928 | ); |
1571 | 929 | ||
930 | cx8802_cancel_buffers(fh->dev); | ||
1572 | /* stop mpeg capture */ | 931 | /* stop mpeg capture */ |
1573 | if (fh->mpegq.streaming) | 932 | if (fh->mpegq.streaming) |
1574 | videobuf_streamoff(&fh->mpegq); | 933 | videobuf_streamoff(&fh->mpegq); |
@@ -1683,19 +1042,13 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev, | |||
1683 | dev->core = core; | 1042 | dev->core = core; |
1684 | dev->width = 720; | 1043 | dev->width = 720; |
1685 | dev->height = 576; | 1044 | dev->height = 576; |
1686 | memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params)); | 1045 | cx2341x_fill_defaults(&dev->params); |
1687 | memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params)); | 1046 | dev->params.port = CX2341X_PORT_STREAMING; |
1688 | |||
1689 | if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) { | ||
1690 | |||
1691 | if (core->tuner_formats & V4L2_STD_525_60) { | ||
1692 | dev->height = 480; | ||
1693 | dev->params.vi_frame_rate = 30; | ||
1694 | } else { | ||
1695 | dev->height = 576; | ||
1696 | dev->params.vi_frame_rate = 25; | ||
1697 | } | ||
1698 | 1047 | ||
1048 | if (core->tvnorm->id & V4L2_STD_525_60) { | ||
1049 | dev->height = 480; | ||
1050 | } else { | ||
1051 | dev->height = 576; | ||
1699 | } | 1052 | } |
1700 | 1053 | ||
1701 | err = cx8802_init_common(dev); | 1054 | err = cx8802_init_common(dev); |
@@ -1781,8 +1134,6 @@ module_exit(blackbird_fini); | |||
1781 | 1134 | ||
1782 | EXPORT_SYMBOL(cx88_ioctl_hook); | 1135 | EXPORT_SYMBOL(cx88_ioctl_hook); |
1783 | EXPORT_SYMBOL(cx88_ioctl_translator); | 1136 | EXPORT_SYMBOL(cx88_ioctl_translator); |
1784 | EXPORT_SYMBOL(blackbird_set_params); | ||
1785 | EXPORT_SYMBOL(blackbird_set_dnr_params); | ||
1786 | 1137 | ||
1787 | /* ----------------------------------------------------------- */ | 1138 | /* ----------------------------------------------------------- */ |
1788 | /* | 1139 | /* |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index f80154b87d22..67cdd8270863 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -114,7 +114,7 @@ struct cx88_board cx88_boards[] = { | |||
114 | .radio = { | 114 | .radio = { |
115 | .type = CX88_RADIO, | 115 | .type = CX88_RADIO, |
116 | .gpio0 = 0xff10, | 116 | .gpio0 = 0xff10, |
117 | }, | 117 | }, |
118 | }, | 118 | }, |
119 | [CX88_BOARD_ATI_WONDER_PRO] = { | 119 | [CX88_BOARD_ATI_WONDER_PRO] = { |
120 | .name = "ATI TV Wonder Pro", | 120 | .name = "ATI TV Wonder Pro", |
@@ -267,7 +267,7 @@ struct cx88_board cx88_boards[] = { | |||
267 | .gpio1 = 0x00007004, | 267 | .gpio1 = 0x00007004, |
268 | .gpio2 = 0x0035d700, | 268 | .gpio2 = 0x0035d700, |
269 | .gpio3 = 0x02000000, | 269 | .gpio3 = 0x02000000, |
270 | }, | 270 | }, |
271 | }, | 271 | }, |
272 | [CX88_BOARD_LEADTEK_PVR2000] = { | 272 | [CX88_BOARD_LEADTEK_PVR2000] = { |
273 | // gpio values for PAL version from regspy by DScaler | 273 | // gpio values for PAL version from regspy by DScaler |
@@ -413,7 +413,7 @@ struct cx88_board cx88_boards[] = { | |||
413 | .type = CX88_VMUX_COMPOSITE1, | 413 | .type = CX88_VMUX_COMPOSITE1, |
414 | .vmux = 1, | 414 | .vmux = 1, |
415 | .gpio0 = 0x000027df, | 415 | .gpio0 = 0x000027df, |
416 | },{ | 416 | },{ |
417 | .type = CX88_VMUX_SVIDEO, | 417 | .type = CX88_VMUX_SVIDEO, |
418 | .vmux = 2, | 418 | .vmux = 2, |
419 | .gpio0 = 0x000027df, | 419 | .gpio0 = 0x000027df, |
@@ -536,7 +536,7 @@ struct cx88_board cx88_boards[] = { | |||
536 | .type = CX88_VMUX_COMPOSITE1, | 536 | .type = CX88_VMUX_COMPOSITE1, |
537 | .vmux = 1, | 537 | .vmux = 1, |
538 | .gpio0 = 0x000027df, | 538 | .gpio0 = 0x000027df, |
539 | },{ | 539 | },{ |
540 | .type = CX88_VMUX_SVIDEO, | 540 | .type = CX88_VMUX_SVIDEO, |
541 | .vmux = 2, | 541 | .vmux = 2, |
542 | .gpio0 = 0x000027df, | 542 | .gpio0 = 0x000027df, |
@@ -759,7 +759,7 @@ struct cx88_board cx88_boards[] = { | |||
759 | }, | 759 | }, |
760 | [CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = { | 760 | [CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = { |
761 | .name = "DViCO FusionHDTV 5 Gold", | 761 | .name = "DViCO FusionHDTV 5 Gold", |
762 | .tuner_type = TUNER_LG_TDVS_H062F, | 762 | .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H062F */ |
763 | .radio_type = UNSET, | 763 | .radio_type = UNSET, |
764 | .tuner_addr = ADDR_UNSET, | 764 | .tuner_addr = ADDR_UNSET, |
765 | .radio_addr = ADDR_UNSET, | 765 | .radio_addr = ADDR_UNSET, |
@@ -1050,11 +1050,7 @@ struct cx88_board cx88_boards[] = { | |||
1050 | .dvb = 1, | 1050 | .dvb = 1, |
1051 | }, | 1051 | }, |
1052 | [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = { | 1052 | [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = { |
1053 | /* FIXME: Standard video using the cx88 broadcast decoder is | 1053 | /* FIXME: Audio not working for s-video / composite inputs. */ |
1054 | * working, but blackbird isn't working yet, audio is only | ||
1055 | * working correctly for television mode. S-Video and Composite | ||
1056 | * are working for video-only, so I have them disabled for now. | ||
1057 | */ | ||
1058 | .name = "KWorld HardwareMpegTV XPert", | 1054 | .name = "KWorld HardwareMpegTV XPert", |
1059 | .tuner_type = TUNER_PHILIPS_TDA8290, | 1055 | .tuner_type = TUNER_PHILIPS_TDA8290, |
1060 | .radio_type = UNSET, | 1056 | .radio_type = UNSET, |
@@ -1065,12 +1061,21 @@ struct cx88_board cx88_boards[] = { | |||
1065 | .vmux = 0, | 1061 | .vmux = 0, |
1066 | .gpio0 = 0x3de2, | 1062 | .gpio0 = 0x3de2, |
1067 | .gpio2 = 0x00ff, | 1063 | .gpio2 = 0x00ff, |
1064 | },{ | ||
1065 | .type = CX88_VMUX_COMPOSITE1, | ||
1066 | .vmux = 1, | ||
1067 | .gpio0 = 0x3de6, | ||
1068 | },{ | ||
1069 | .type = CX88_VMUX_SVIDEO, | ||
1070 | .vmux = 2, | ||
1071 | .gpio0 = 0x3de6, | ||
1068 | }}, | 1072 | }}, |
1069 | .radio = { | 1073 | .radio = { |
1070 | .type = CX88_RADIO, | 1074 | .type = CX88_RADIO, |
1071 | .gpio0 = 0x3de6, | 1075 | .gpio0 = 0x3de6, |
1072 | .gpio2 = 0x00ff, | 1076 | .gpio2 = 0x00ff, |
1073 | }, | 1077 | }, |
1078 | .blackbird = 1, | ||
1074 | }, | 1079 | }, |
1075 | [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = { | 1080 | [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = { |
1076 | .name = "DViCO FusionHDTV DVB-T Hybrid", | 1081 | .name = "DViCO FusionHDTV DVB-T Hybrid", |
@@ -1093,7 +1098,102 @@ struct cx88_board cx88_boards[] = { | |||
1093 | }}, | 1098 | }}, |
1094 | .dvb = 1, | 1099 | .dvb = 1, |
1095 | }, | 1100 | }, |
1096 | 1101 | [CX88_BOARD_PCHDTV_HD5500] = { | |
1102 | .name = "pcHDTV HD5500 HDTV", | ||
1103 | .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ | ||
1104 | .radio_type = UNSET, | ||
1105 | .tuner_addr = ADDR_UNSET, | ||
1106 | .radio_addr = ADDR_UNSET, | ||
1107 | .tda9887_conf = TDA9887_PRESENT, | ||
1108 | .input = {{ | ||
1109 | .type = CX88_VMUX_TELEVISION, | ||
1110 | .vmux = 0, | ||
1111 | .gpio0 = 0x87fd, | ||
1112 | },{ | ||
1113 | .type = CX88_VMUX_COMPOSITE1, | ||
1114 | .vmux = 1, | ||
1115 | .gpio0 = 0x87f9, | ||
1116 | },{ | ||
1117 | .type = CX88_VMUX_SVIDEO, | ||
1118 | .vmux = 2, | ||
1119 | .gpio0 = 0x87f9, | ||
1120 | }}, | ||
1121 | .dvb = 1, | ||
1122 | }, | ||
1123 | [CX88_BOARD_KWORLD_MCE200_DELUXE] = { | ||
1124 | /* FIXME: tested TV input only, disabled composite, | ||
1125 | svideo and radio until they can be tested also. */ | ||
1126 | .name = "Kworld MCE 200 Deluxe", | ||
1127 | .tuner_type = TUNER_TENA_9533_DI, | ||
1128 | .radio_type = UNSET, | ||
1129 | .tda9887_conf = TDA9887_PRESENT, | ||
1130 | .tuner_addr = ADDR_UNSET, | ||
1131 | .radio_addr = ADDR_UNSET, | ||
1132 | .input = {{ | ||
1133 | .type = CX88_VMUX_TELEVISION, | ||
1134 | .vmux = 0, | ||
1135 | .gpio0 = 0x0000BDE6 | ||
1136 | }}, | ||
1137 | .blackbird = 1, | ||
1138 | }, | ||
1139 | [CX88_BOARD_PIXELVIEW_PLAYTV_P7000] = { | ||
1140 | /* FIXME: SVideo, Composite and FM inputs are untested */ | ||
1141 | .name = "PixelView PlayTV P7000", | ||
1142 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
1143 | .radio_type = UNSET, | ||
1144 | .tuner_addr = ADDR_UNSET, | ||
1145 | .radio_addr = ADDR_UNSET, | ||
1146 | .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | | ||
1147 | TDA9887_PORT2_ACTIVE, | ||
1148 | .input = {{ | ||
1149 | .type = CX88_VMUX_TELEVISION, | ||
1150 | .vmux = 0, | ||
1151 | .gpio0 = 0x5da6, | ||
1152 | }}, | ||
1153 | .blackbird = 1, | ||
1154 | }, | ||
1155 | [CX88_BOARD_NPGTECH_REALTV_TOP10FM] = { | ||
1156 | .name = "NPG Tech Real TV FM Top 10", | ||
1157 | .tuner_type = TUNER_TNF_5335MF, /* Actually a TNF9535 */ | ||
1158 | .radio_type = UNSET, | ||
1159 | .tuner_addr = ADDR_UNSET, | ||
1160 | .radio_addr = ADDR_UNSET, | ||
1161 | .input = {{ | ||
1162 | .type = CX88_VMUX_TELEVISION, | ||
1163 | .vmux = 0, | ||
1164 | .gpio0 = 0x0788, | ||
1165 | },{ | ||
1166 | .type = CX88_VMUX_COMPOSITE1, | ||
1167 | .vmux = 1, | ||
1168 | .gpio0 = 0x078b, | ||
1169 | },{ | ||
1170 | .type = CX88_VMUX_SVIDEO, | ||
1171 | .vmux = 2, | ||
1172 | .gpio0 = 0x078b, | ||
1173 | }}, | ||
1174 | .radio = { | ||
1175 | .type = CX88_RADIO, | ||
1176 | .gpio0 = 0x074a, | ||
1177 | }, | ||
1178 | }, | ||
1179 | [CX88_BOARD_WINFAST_DTV2000H] = { | ||
1180 | /* video inputs and radio still in testing */ | ||
1181 | .name = "WinFast DTV2000 H", | ||
1182 | .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, | ||
1183 | .radio_type = UNSET, | ||
1184 | .tuner_addr = ADDR_UNSET, | ||
1185 | .radio_addr = ADDR_UNSET, | ||
1186 | .tda9887_conf = TDA9887_PRESENT, | ||
1187 | .input = {{ | ||
1188 | .type = CX88_VMUX_TELEVISION, | ||
1189 | .vmux = 0, | ||
1190 | .gpio0 = 0x00017304, | ||
1191 | .gpio1 = 0x00008203, | ||
1192 | .gpio2 = 0x00017304, | ||
1193 | .gpio3 = 0x02000000, | ||
1194 | }}, | ||
1195 | .dvb = 1, | ||
1196 | }, | ||
1097 | }; | 1197 | }; |
1098 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); | 1198 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); |
1099 | 1199 | ||
@@ -1311,6 +1411,34 @@ struct cx88_subid cx88_subids[] = { | |||
1311 | .subvendor = 0x18ac, | 1411 | .subvendor = 0x18ac, |
1312 | .subdevice = 0xdb44, | 1412 | .subdevice = 0xdb44, |
1313 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID, | 1413 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID, |
1414 | },{ | ||
1415 | .subvendor = 0x7063, | ||
1416 | .subdevice = 0x5500, | ||
1417 | .card = CX88_BOARD_PCHDTV_HD5500, | ||
1418 | },{ | ||
1419 | .subvendor = 0x17de, | ||
1420 | .subdevice = 0x0841, | ||
1421 | .card = CX88_BOARD_KWORLD_MCE200_DELUXE, | ||
1422 | },{ | ||
1423 | .subvendor = 0x1822, | ||
1424 | .subdevice = 0x0019, | ||
1425 | .card = CX88_BOARD_DNTV_LIVE_DVB_T_PRO, | ||
1426 | },{ | ||
1427 | .subvendor = 0x1554, | ||
1428 | .subdevice = 0x4813, | ||
1429 | .card = CX88_BOARD_PIXELVIEW_PLAYTV_P7000, | ||
1430 | },{ | ||
1431 | .subvendor = 0x14f1, | ||
1432 | .subdevice = 0x0842, | ||
1433 | .card = CX88_BOARD_NPGTECH_REALTV_TOP10FM, | ||
1434 | },{ | ||
1435 | .subvendor = 0x107d, | ||
1436 | .subdevice = 0x665e, | ||
1437 | .card = CX88_BOARD_WINFAST_DTV2000H, | ||
1438 | },{ | ||
1439 | .subvendor = 0x18ac, | ||
1440 | .subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */ | ||
1441 | .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q, | ||
1314 | }, | 1442 | }, |
1315 | }; | 1443 | }; |
1316 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); | 1444 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index e1092d5d4628..c56292d8d93b 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -677,7 +677,7 @@ static unsigned int inline norm_htotal(struct cx88_tvnorm *norm) | |||
677 | 677 | ||
678 | static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm) | 678 | static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm) |
679 | { | 679 | { |
680 | return (norm->id & V4L2_STD_625_50) ? 511 : 288; | 680 | return (norm->id & V4L2_STD_625_50) ? 511 : 400; |
681 | } | 681 | } |
682 | 682 | ||
683 | int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height, | 683 | int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height, |
@@ -932,9 +932,9 @@ int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm) | |||
932 | htotal, cx_read(MO_HTOTAL), (u32)tmp64); | 932 | htotal, cx_read(MO_HTOTAL), (u32)tmp64); |
933 | cx_write(MO_HTOTAL, htotal); | 933 | cx_write(MO_HTOTAL, htotal); |
934 | 934 | ||
935 | // vbi stuff | 935 | // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes |
936 | cx_write(MO_VBI_PACKET, ((1 << 11) | /* (norm_vdelay(norm) << 11) | */ | 936 | // the effective vbi offset ~244 samples, the same as the Bt8x8 |
937 | norm_vbipack(norm))); | 937 | cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm)); |
938 | 938 | ||
939 | // this is needed as well to set all tvnorm parameter | 939 | // this is needed as well to set all tvnorm parameter |
940 | cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED); | 940 | cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED); |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 3619a449aefd..dce1feddd55d 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #endif | 51 | #endif |
52 | #ifdef HAVE_LGDT330X | 52 | #ifdef HAVE_LGDT330X |
53 | # include "lgdt330x.h" | 53 | # include "lgdt330x.h" |
54 | # include "lg_h06xf.h" | ||
54 | #endif | 55 | #endif |
55 | #ifdef HAVE_NXT200X | 56 | #ifdef HAVE_NXT200X |
56 | # include "nxt200x.h" | 57 | # include "nxt200x.h" |
@@ -58,6 +59,7 @@ | |||
58 | #ifdef HAVE_CX24123 | 59 | #ifdef HAVE_CX24123 |
59 | # include "cx24123.h" | 60 | # include "cx24123.h" |
60 | #endif | 61 | #endif |
62 | #include "isl6421.h" | ||
61 | 63 | ||
62 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); | 64 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); |
63 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); | 65 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); |
@@ -113,21 +115,6 @@ static struct videobuf_queue_ops dvb_qops = { | |||
113 | 115 | ||
114 | /* ------------------------------------------------------------------ */ | 116 | /* ------------------------------------------------------------------ */ |
115 | 117 | ||
116 | #if defined(HAVE_MT352) || defined(HAVE_ZL10353) | ||
117 | static int zarlink_pll_set(struct dvb_frontend *fe, | ||
118 | struct dvb_frontend_parameters *params, | ||
119 | u8 *pllbuf) | ||
120 | { | ||
121 | struct cx8802_dev *dev = fe->dvb->priv; | ||
122 | |||
123 | pllbuf[0] = dev->core->pll_addr << 1; | ||
124 | dvb_pll_configure(dev->core->pll_desc, pllbuf + 1, | ||
125 | params->frequency, | ||
126 | params->u.ofdm.bandwidth); | ||
127 | return 0; | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | #ifdef HAVE_MT352 | 118 | #ifdef HAVE_MT352 |
132 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) | 119 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) |
133 | { | 120 | { |
@@ -196,19 +183,16 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) | |||
196 | static struct mt352_config dvico_fusionhdtv = { | 183 | static struct mt352_config dvico_fusionhdtv = { |
197 | .demod_address = 0x0F, | 184 | .demod_address = 0x0F, |
198 | .demod_init = dvico_fusionhdtv_demod_init, | 185 | .demod_init = dvico_fusionhdtv_demod_init, |
199 | .pll_set = zarlink_pll_set, | ||
200 | }; | 186 | }; |
201 | 187 | ||
202 | static struct mt352_config dntv_live_dvbt_config = { | 188 | static struct mt352_config dntv_live_dvbt_config = { |
203 | .demod_address = 0x0f, | 189 | .demod_address = 0x0f, |
204 | .demod_init = dntv_live_dvbt_demod_init, | 190 | .demod_init = dntv_live_dvbt_demod_init, |
205 | .pll_set = zarlink_pll_set, | ||
206 | }; | 191 | }; |
207 | 192 | ||
208 | static struct mt352_config dvico_fusionhdtv_dual = { | 193 | static struct mt352_config dvico_fusionhdtv_dual = { |
209 | .demod_address = 0x0F, | 194 | .demod_address = 0x0F, |
210 | .demod_init = dvico_dual_demod_init, | 195 | .demod_init = dvico_dual_demod_init, |
211 | .pll_set = zarlink_pll_set, | ||
212 | }; | 196 | }; |
213 | 197 | ||
214 | #ifdef HAVE_VP3054_I2C | 198 | #ifdef HAVE_VP3054_I2C |
@@ -246,6 +230,8 @@ static int philips_fmd1216_pll_init(struct dvb_frontend *fe) | |||
246 | .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; | 230 | .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; |
247 | int err; | 231 | int err; |
248 | 232 | ||
233 | if (fe->ops.i2c_gate_ctrl) | ||
234 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
249 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | 235 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { |
250 | if (err < 0) | 236 | if (err < 0) |
251 | return err; | 237 | return err; |
@@ -256,14 +242,14 @@ static int philips_fmd1216_pll_init(struct dvb_frontend *fe) | |||
256 | return 0; | 242 | return 0; |
257 | } | 243 | } |
258 | 244 | ||
259 | static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe, | 245 | static int dntv_live_dvbt_pro_tuner_set_params(struct dvb_frontend* fe, |
260 | struct dvb_frontend_parameters* params, | 246 | struct dvb_frontend_parameters* params) |
261 | u8* pllbuf) | ||
262 | { | 247 | { |
263 | struct cx8802_dev *dev= fe->dvb->priv; | 248 | struct cx8802_dev *dev= fe->dvb->priv; |
249 | u8 buf[4]; | ||
264 | struct i2c_msg msg = | 250 | struct i2c_msg msg = |
265 | { .addr = dev->core->pll_addr, .flags = 0, | 251 | { .addr = dev->core->pll_addr, .flags = 0, |
266 | .buf = pllbuf+1, .len = 4 }; | 252 | .buf = buf, .len = 4 }; |
267 | int err; | 253 | int err; |
268 | 254 | ||
269 | /* Switch PLL to DVB mode */ | 255 | /* Switch PLL to DVB mode */ |
@@ -272,14 +258,16 @@ static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe, | |||
272 | return err; | 258 | return err; |
273 | 259 | ||
274 | /* Tune PLL */ | 260 | /* Tune PLL */ |
275 | pllbuf[0] = dev->core->pll_addr << 1; | 261 | dvb_pll_configure(dev->core->pll_desc, buf, |
276 | dvb_pll_configure(dev->core->pll_desc, pllbuf+1, | ||
277 | params->frequency, | 262 | params->frequency, |
278 | params->u.ofdm.bandwidth); | 263 | params->u.ofdm.bandwidth); |
264 | if (fe->ops.i2c_gate_ctrl) | ||
265 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
279 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | 266 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { |
267 | |||
280 | printk(KERN_WARNING "cx88-dvb: %s error " | 268 | printk(KERN_WARNING "cx88-dvb: %s error " |
281 | "(addr %02x <- %02x, err = %i)\n", | 269 | "(addr %02x <- %02x, err = %i)\n", |
282 | __FUNCTION__, pllbuf[0], pllbuf[1], err); | 270 | __FUNCTION__, dev->core->pll_addr, buf[0], err); |
283 | if (err < 0) | 271 | if (err < 0) |
284 | return err; | 272 | return err; |
285 | else | 273 | else |
@@ -293,27 +281,27 @@ static struct mt352_config dntv_live_dvbt_pro_config = { | |||
293 | .demod_address = 0x0f, | 281 | .demod_address = 0x0f, |
294 | .no_tuner = 1, | 282 | .no_tuner = 1, |
295 | .demod_init = dntv_live_dvbt_pro_demod_init, | 283 | .demod_init = dntv_live_dvbt_pro_demod_init, |
296 | .pll_set = dntv_live_dvbt_pro_pll_set, | ||
297 | }; | 284 | }; |
298 | #endif | 285 | #endif |
299 | #endif | 286 | #endif |
300 | 287 | ||
301 | #ifdef HAVE_ZL10353 | 288 | #ifdef HAVE_ZL10353 |
302 | static int dvico_hybrid_tune_pll(struct dvb_frontend *fe, | 289 | static int dvico_hybrid_tuner_set_params(struct dvb_frontend *fe, |
303 | struct dvb_frontend_parameters *params, | 290 | struct dvb_frontend_parameters *params) |
304 | u8 *pllbuf) | ||
305 | { | 291 | { |
292 | u8 pllbuf[4]; | ||
306 | struct cx8802_dev *dev= fe->dvb->priv; | 293 | struct cx8802_dev *dev= fe->dvb->priv; |
307 | struct i2c_msg msg = | 294 | struct i2c_msg msg = |
308 | { .addr = dev->core->pll_addr, .flags = 0, | 295 | { .addr = dev->core->pll_addr, .flags = 0, |
309 | .buf = pllbuf + 1, .len = 4 }; | 296 | .buf = pllbuf, .len = 4 }; |
310 | int err; | 297 | int err; |
311 | 298 | ||
312 | pllbuf[0] = dev->core->pll_addr << 1; | 299 | dvb_pll_configure(dev->core->pll_desc, pllbuf, |
313 | dvb_pll_configure(dev->core->pll_desc, pllbuf + 1, | ||
314 | params->frequency, | 300 | params->frequency, |
315 | params->u.ofdm.bandwidth); | 301 | params->u.ofdm.bandwidth); |
316 | 302 | ||
303 | if (fe->ops.i2c_gate_ctrl) | ||
304 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
317 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | 305 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { |
318 | printk(KERN_WARNING "cx88-dvb: %s error " | 306 | printk(KERN_WARNING "cx88-dvb: %s error " |
319 | "(addr %02x <- %02x, err = %i)\n", | 307 | "(addr %02x <- %02x, err = %i)\n", |
@@ -329,12 +317,11 @@ static int dvico_hybrid_tune_pll(struct dvb_frontend *fe, | |||
329 | 317 | ||
330 | static struct zl10353_config dvico_fusionhdtv_hybrid = { | 318 | static struct zl10353_config dvico_fusionhdtv_hybrid = { |
331 | .demod_address = 0x0F, | 319 | .demod_address = 0x0F, |
332 | .pll_set = dvico_hybrid_tune_pll, | 320 | .no_tuner = 1, |
333 | }; | 321 | }; |
334 | 322 | ||
335 | static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { | 323 | static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { |
336 | .demod_address = 0x0F, | 324 | .demod_address = 0x0F, |
337 | .pll_set = zarlink_pll_set, | ||
338 | }; | 325 | }; |
339 | #endif | 326 | #endif |
340 | 327 | ||
@@ -342,21 +329,15 @@ static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { | |||
342 | static struct cx22702_config connexant_refboard_config = { | 329 | static struct cx22702_config connexant_refboard_config = { |
343 | .demod_address = 0x43, | 330 | .demod_address = 0x43, |
344 | .output_mode = CX22702_SERIAL_OUTPUT, | 331 | .output_mode = CX22702_SERIAL_OUTPUT, |
345 | .pll_address = 0x60, | ||
346 | .pll_desc = &dvb_pll_thomson_dtt7579, | ||
347 | }; | 332 | }; |
348 | 333 | ||
349 | static struct cx22702_config hauppauge_novat_config = { | 334 | static struct cx22702_config hauppauge_novat_config = { |
350 | .demod_address = 0x43, | 335 | .demod_address = 0x43, |
351 | .output_mode = CX22702_SERIAL_OUTPUT, | 336 | .output_mode = CX22702_SERIAL_OUTPUT, |
352 | .pll_address = 0x61, | ||
353 | .pll_desc = &dvb_pll_thomson_dtt759x, | ||
354 | }; | 337 | }; |
355 | static struct cx22702_config hauppauge_hvr1100_config = { | 338 | static struct cx22702_config hauppauge_hvr1100_config = { |
356 | .demod_address = 0x63, | 339 | .demod_address = 0x63, |
357 | .output_mode = CX22702_SERIAL_OUTPUT, | 340 | .output_mode = CX22702_SERIAL_OUTPUT, |
358 | .pll_address = 0x61, | ||
359 | .pll_desc = &dvb_pll_fmd1216me, | ||
360 | }; | 341 | }; |
361 | #endif | 342 | #endif |
362 | 343 | ||
@@ -371,15 +352,13 @@ static int or51132_set_ts_param(struct dvb_frontend* fe, | |||
371 | 352 | ||
372 | static struct or51132_config pchdtv_hd3000 = { | 353 | static struct or51132_config pchdtv_hd3000 = { |
373 | .demod_address = 0x15, | 354 | .demod_address = 0x15, |
374 | .pll_address = 0x61, | ||
375 | .pll_desc = &dvb_pll_thomson_dtt761x, | ||
376 | .set_ts_params = or51132_set_ts_param, | 355 | .set_ts_params = or51132_set_ts_param, |
377 | }; | 356 | }; |
378 | #endif | 357 | #endif |
379 | 358 | ||
380 | #ifdef HAVE_LGDT330X | 359 | #ifdef HAVE_LGDT330X |
381 | static int lgdt330x_pll_set(struct dvb_frontend* fe, | 360 | static int lgdt3302_tuner_set_params(struct dvb_frontend* fe, |
382 | struct dvb_frontend_parameters* params) | 361 | struct dvb_frontend_parameters* params) |
383 | { | 362 | { |
384 | /* FIXME make this routine use the tuner-simple code. | 363 | /* FIXME make this routine use the tuner-simple code. |
385 | * It could probably be shared with a number of ATSC | 364 | * It could probably be shared with a number of ATSC |
@@ -392,12 +371,12 @@ static int lgdt330x_pll_set(struct dvb_frontend* fe, | |||
392 | { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; | 371 | { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; |
393 | int err; | 372 | int err; |
394 | 373 | ||
395 | /* Put the analog decoder in standby to keep it quiet */ | ||
396 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | ||
397 | |||
398 | dvb_pll_configure(core->pll_desc, buf, params->frequency, 0); | 374 | dvb_pll_configure(core->pll_desc, buf, params->frequency, 0); |
399 | dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", | 375 | dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", |
400 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); | 376 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); |
377 | |||
378 | if (fe->ops.i2c_gate_ctrl) | ||
379 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
401 | if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) { | 380 | if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) { |
402 | printk(KERN_WARNING "cx88-dvb: %s error " | 381 | printk(KERN_WARNING "cx88-dvb: %s error " |
403 | "(addr %02x <- %02x, err = %i)\n", | 382 | "(addr %02x <- %02x, err = %i)\n", |
@@ -407,16 +386,21 @@ static int lgdt330x_pll_set(struct dvb_frontend* fe, | |||
407 | else | 386 | else |
408 | return -EREMOTEIO; | 387 | return -EREMOTEIO; |
409 | } | 388 | } |
410 | if (core->tuner_type == TUNER_LG_TDVS_H062F) { | ||
411 | /* Set the Auxiliary Byte. */ | ||
412 | buf[2] &= ~0x20; | ||
413 | buf[2] |= 0x18; | ||
414 | buf[3] = 0x50; | ||
415 | i2c_transfer(&core->i2c_adap, &msg, 1); | ||
416 | } | ||
417 | return 0; | 389 | return 0; |
418 | } | 390 | } |
419 | 391 | ||
392 | static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, | ||
393 | struct dvb_frontend_parameters* params) | ||
394 | { | ||
395 | struct cx8802_dev *dev= fe->dvb->priv; | ||
396 | struct cx88_core *core = dev->core; | ||
397 | |||
398 | /* Put the analog decoder in standby to keep it quiet */ | ||
399 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | ||
400 | |||
401 | return lg_h06xf_pll_set(fe, &core->i2c_adap, params); | ||
402 | } | ||
403 | |||
420 | static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) | 404 | static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) |
421 | { | 405 | { |
422 | struct cx8802_dev *dev= fe->dvb->priv; | 406 | struct cx8802_dev *dev= fe->dvb->priv; |
@@ -444,7 +428,6 @@ static struct lgdt330x_config fusionhdtv_3_gold = { | |||
444 | .demod_address = 0x0e, | 428 | .demod_address = 0x0e, |
445 | .demod_chip = LGDT3302, | 429 | .demod_chip = LGDT3302, |
446 | .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ | 430 | .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ |
447 | .pll_set = lgdt330x_pll_set, | ||
448 | .set_ts_params = lgdt330x_set_ts_param, | 431 | .set_ts_params = lgdt330x_set_ts_param, |
449 | }; | 432 | }; |
450 | 433 | ||
@@ -452,7 +435,13 @@ static struct lgdt330x_config fusionhdtv_5_gold = { | |||
452 | .demod_address = 0x0e, | 435 | .demod_address = 0x0e, |
453 | .demod_chip = LGDT3303, | 436 | .demod_chip = LGDT3303, |
454 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | 437 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ |
455 | .pll_set = lgdt330x_pll_set, | 438 | .set_ts_params = lgdt330x_set_ts_param, |
439 | }; | ||
440 | |||
441 | static struct lgdt330x_config pchdtv_hd5500 = { | ||
442 | .demod_address = 0x59, | ||
443 | .demod_chip = LGDT3303, | ||
444 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | ||
456 | .set_ts_params = lgdt330x_set_ts_param, | 445 | .set_ts_params = lgdt330x_set_ts_param, |
457 | }; | 446 | }; |
458 | #endif | 447 | #endif |
@@ -477,8 +466,6 @@ static int nxt200x_set_pll_input(u8* buf, int input) | |||
477 | 466 | ||
478 | static struct nxt200x_config ati_hdtvwonder = { | 467 | static struct nxt200x_config ati_hdtvwonder = { |
479 | .demod_address = 0x0a, | 468 | .demod_address = 0x0a, |
480 | .pll_address = 0x61, | ||
481 | .pll_desc = &dvb_pll_tuv1236d, | ||
482 | .set_pll_input = nxt200x_set_pll_input, | 469 | .set_pll_input = nxt200x_set_pll_input, |
483 | .set_ts_params = nxt200x_set_ts_param, | 470 | .set_ts_params = nxt200x_set_ts_param, |
484 | }; | 471 | }; |
@@ -493,28 +480,30 @@ static int cx24123_set_ts_param(struct dvb_frontend* fe, | |||
493 | return 0; | 480 | return 0; |
494 | } | 481 | } |
495 | 482 | ||
496 | static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on) | 483 | static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) |
497 | { | 484 | { |
498 | struct cx8802_dev *dev= fe->dvb->priv; | 485 | struct cx8802_dev *dev= fe->dvb->priv; |
499 | struct cx88_core *core = dev->core; | 486 | struct cx88_core *core = dev->core; |
500 | 487 | ||
501 | if (on) | 488 | if (voltage == SEC_VOLTAGE_OFF) { |
502 | cx_write(MO_GP0_IO, 0x000006f9); | ||
503 | else | ||
504 | cx_write(MO_GP0_IO, 0x000006fB); | 489 | cx_write(MO_GP0_IO, 0x000006fB); |
490 | } else { | ||
491 | cx_write(MO_GP0_IO, 0x000006f9); | ||
492 | } | ||
493 | |||
494 | if (core->prev_set_voltage) | ||
495 | return core->prev_set_voltage(fe, voltage); | ||
496 | return 0; | ||
505 | } | 497 | } |
506 | 498 | ||
507 | static struct cx24123_config hauppauge_novas_config = { | 499 | static struct cx24123_config hauppauge_novas_config = { |
508 | .demod_address = 0x55, | 500 | .demod_address = 0x55, |
509 | .use_isl6421 = 1, | ||
510 | .set_ts_params = cx24123_set_ts_param, | 501 | .set_ts_params = cx24123_set_ts_param, |
511 | }; | 502 | }; |
512 | 503 | ||
513 | static struct cx24123_config kworld_dvbs_100_config = { | 504 | static struct cx24123_config kworld_dvbs_100_config = { |
514 | .demod_address = 0x15, | 505 | .demod_address = 0x15, |
515 | .use_isl6421 = 0, | ||
516 | .set_ts_params = cx24123_set_ts_param, | 506 | .set_ts_params = cx24123_set_ts_param, |
517 | .enable_lnb_voltage = cx24123_enable_lnb_voltage, | ||
518 | }; | 507 | }; |
519 | #endif | 508 | #endif |
520 | 509 | ||
@@ -530,6 +519,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
530 | case CX88_BOARD_HAUPPAUGE_DVB_T1: | 519 | case CX88_BOARD_HAUPPAUGE_DVB_T1: |
531 | dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config, | 520 | dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config, |
532 | &dev->core->i2c_adap); | 521 | &dev->core->i2c_adap); |
522 | if (dev->dvb.frontend != NULL) { | ||
523 | dvb_pll_attach(dev->dvb.frontend, 0x61, | ||
524 | &dev->core->i2c_adap, | ||
525 | &dvb_pll_thomson_dtt759x); | ||
526 | } | ||
533 | break; | 527 | break; |
534 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: | 528 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: |
535 | case CX88_BOARD_CONEXANT_DVB_T1: | 529 | case CX88_BOARD_CONEXANT_DVB_T1: |
@@ -537,44 +531,92 @@ static int dvb_register(struct cx8802_dev *dev) | |||
537 | case CX88_BOARD_WINFAST_DTV1000: | 531 | case CX88_BOARD_WINFAST_DTV1000: |
538 | dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, | 532 | dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, |
539 | &dev->core->i2c_adap); | 533 | &dev->core->i2c_adap); |
534 | if (dev->dvb.frontend != NULL) { | ||
535 | dvb_pll_attach(dev->dvb.frontend, 0x60, | ||
536 | &dev->core->i2c_adap, | ||
537 | &dvb_pll_thomson_dtt7579); | ||
538 | } | ||
540 | break; | 539 | break; |
540 | case CX88_BOARD_WINFAST_DTV2000H: | ||
541 | case CX88_BOARD_HAUPPAUGE_HVR1100: | 541 | case CX88_BOARD_HAUPPAUGE_HVR1100: |
542 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: | 542 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: |
543 | dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config, | 543 | dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config, |
544 | &dev->core->i2c_adap); | 544 | &dev->core->i2c_adap); |
545 | if (dev->dvb.frontend != NULL) { | ||
546 | dvb_pll_attach(dev->dvb.frontend, 0x61, | ||
547 | &dev->core->i2c_adap, | ||
548 | &dvb_pll_fmd1216me); | ||
549 | } | ||
545 | break; | 550 | break; |
546 | #endif | 551 | #endif |
547 | #if defined(HAVE_MT352) || defined(HAVE_ZL10353) | 552 | #if defined(HAVE_MT352) || defined(HAVE_ZL10353) |
548 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: | 553 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: |
549 | dev->core->pll_addr = 0x60; | ||
550 | dev->core->pll_desc = &dvb_pll_thomson_dtt7579; | ||
551 | #ifdef HAVE_MT352 | 554 | #ifdef HAVE_MT352 |
552 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, | 555 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, |
553 | &dev->core->i2c_adap); | 556 | &dev->core->i2c_adap); |
554 | if (dev->dvb.frontend != NULL) | 557 | if (dev->dvb.frontend != NULL) { |
558 | dvb_pll_attach(dev->dvb.frontend, 0x60, | ||
559 | &dev->core->i2c_adap, | ||
560 | &dvb_pll_thomson_dtt7579); | ||
555 | break; | 561 | break; |
562 | } | ||
556 | #endif | 563 | #endif |
557 | #ifdef HAVE_ZL10353 | 564 | #ifdef HAVE_ZL10353 |
558 | /* ZL10353 replaces MT352 on later cards */ | 565 | /* ZL10353 replaces MT352 on later cards */ |
559 | dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1, | 566 | dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1, |
560 | &dev->core->i2c_adap); | 567 | &dev->core->i2c_adap); |
568 | if (dev->dvb.frontend != NULL) { | ||
569 | dvb_pll_attach(dev->dvb.frontend, 0x60, | ||
570 | &dev->core->i2c_adap, | ||
571 | &dvb_pll_thomson_dtt7579); | ||
572 | } | ||
573 | #endif | ||
574 | break; | ||
575 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | ||
576 | #ifdef HAVE_MT352 | ||
577 | /* The tin box says DEE1601, but it seems to be DTT7579 | ||
578 | * compatible, with a slightly different MT352 AGC gain. */ | ||
579 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual, | ||
580 | &dev->core->i2c_adap); | ||
581 | if (dev->dvb.frontend != NULL) { | ||
582 | dvb_pll_attach(dev->dvb.frontend, 0x61, | ||
583 | &dev->core->i2c_adap, | ||
584 | &dvb_pll_thomson_dtt7579); | ||
585 | break; | ||
586 | } | ||
587 | #endif | ||
588 | #ifdef HAVE_ZL10353 | ||
589 | /* ZL10353 replaces MT352 on later cards */ | ||
590 | dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1, | ||
591 | &dev->core->i2c_adap); | ||
592 | if (dev->dvb.frontend != NULL) { | ||
593 | dvb_pll_attach(dev->dvb.frontend, 0x61, | ||
594 | &dev->core->i2c_adap, | ||
595 | &dvb_pll_thomson_dtt7579); | ||
596 | } | ||
561 | #endif | 597 | #endif |
562 | break; | 598 | break; |
563 | #endif /* HAVE_MT352 || HAVE_ZL10353 */ | 599 | #endif /* HAVE_MT352 || HAVE_ZL10353 */ |
564 | #ifdef HAVE_MT352 | 600 | #ifdef HAVE_MT352 |
565 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: | 601 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: |
566 | dev->core->pll_addr = 0x61; | ||
567 | dev->core->pll_desc = &dvb_pll_lg_z201; | ||
568 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, | 602 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, |
569 | &dev->core->i2c_adap); | 603 | &dev->core->i2c_adap); |
604 | if (dev->dvb.frontend != NULL) { | ||
605 | dvb_pll_attach(dev->dvb.frontend, 0x61, | ||
606 | &dev->core->i2c_adap, | ||
607 | &dvb_pll_lg_z201); | ||
608 | } | ||
570 | break; | 609 | break; |
571 | case CX88_BOARD_KWORLD_DVB_T: | 610 | case CX88_BOARD_KWORLD_DVB_T: |
572 | case CX88_BOARD_DNTV_LIVE_DVB_T: | 611 | case CX88_BOARD_DNTV_LIVE_DVB_T: |
573 | case CX88_BOARD_ADSTECH_DVB_T_PCI: | 612 | case CX88_BOARD_ADSTECH_DVB_T_PCI: |
574 | dev->core->pll_addr = 0x61; | ||
575 | dev->core->pll_desc = &dvb_pll_unknown_1; | ||
576 | dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, | 613 | dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, |
577 | &dev->core->i2c_adap); | 614 | &dev->core->i2c_adap); |
615 | if (dev->dvb.frontend != NULL) { | ||
616 | dvb_pll_attach(dev->dvb.frontend, 0x61, | ||
617 | &dev->core->i2c_adap, | ||
618 | &dvb_pll_unknown_1); | ||
619 | } | ||
578 | break; | 620 | break; |
579 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: | 621 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: |
580 | #ifdef HAVE_VP3054_I2C | 622 | #ifdef HAVE_VP3054_I2C |
@@ -582,18 +624,13 @@ static int dvb_register(struct cx8802_dev *dev) | |||
582 | dev->core->pll_desc = &dvb_pll_fmd1216me; | 624 | dev->core->pll_desc = &dvb_pll_fmd1216me; |
583 | dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config, | 625 | dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config, |
584 | &((struct vp3054_i2c_state *)dev->card_priv)->adap); | 626 | &((struct vp3054_i2c_state *)dev->card_priv)->adap); |
627 | if (dev->dvb.frontend != NULL) { | ||
628 | dev->dvb.frontend->ops.tuner_ops.set_params = dntv_live_dvbt_pro_tuner_set_params; | ||
629 | } | ||
585 | #else | 630 | #else |
586 | printk("%s: built without vp3054 support\n", dev->core->name); | 631 | printk("%s: built without vp3054 support\n", dev->core->name); |
587 | #endif | 632 | #endif |
588 | break; | 633 | break; |
589 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | ||
590 | /* The tin box says DEE1601, but it seems to be DTT7579 | ||
591 | * compatible, with a slightly different MT352 AGC gain. */ | ||
592 | dev->core->pll_addr = 0x61; | ||
593 | dev->core->pll_desc = &dvb_pll_thomson_dtt7579; | ||
594 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual, | ||
595 | &dev->core->i2c_adap); | ||
596 | break; | ||
597 | #endif | 634 | #endif |
598 | #ifdef HAVE_ZL10353 | 635 | #ifdef HAVE_ZL10353 |
599 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: | 636 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: |
@@ -601,12 +638,20 @@ static int dvb_register(struct cx8802_dev *dev) | |||
601 | dev->core->pll_desc = &dvb_pll_thomson_fe6600; | 638 | dev->core->pll_desc = &dvb_pll_thomson_fe6600; |
602 | dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid, | 639 | dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid, |
603 | &dev->core->i2c_adap); | 640 | &dev->core->i2c_adap); |
641 | if (dev->dvb.frontend != NULL) { | ||
642 | dev->dvb.frontend->ops.tuner_ops.set_params = dvico_hybrid_tuner_set_params; | ||
643 | } | ||
604 | break; | 644 | break; |
605 | #endif | 645 | #endif |
606 | #ifdef HAVE_OR51132 | 646 | #ifdef HAVE_OR51132 |
607 | case CX88_BOARD_PCHDTV_HD3000: | 647 | case CX88_BOARD_PCHDTV_HD3000: |
608 | dev->dvb.frontend = or51132_attach(&pchdtv_hd3000, | 648 | dev->dvb.frontend = or51132_attach(&pchdtv_hd3000, |
609 | &dev->core->i2c_adap); | 649 | &dev->core->i2c_adap); |
650 | if (dev->dvb.frontend != NULL) { | ||
651 | dvb_pll_attach(dev->dvb.frontend, 0x61, | ||
652 | &dev->core->i2c_adap, | ||
653 | &dvb_pll_thomson_dtt761x); | ||
654 | } | ||
610 | break; | 655 | break; |
611 | #endif | 656 | #endif |
612 | #ifdef HAVE_LGDT330X | 657 | #ifdef HAVE_LGDT330X |
@@ -627,6 +672,9 @@ static int dvb_register(struct cx8802_dev *dev) | |||
627 | dev->core->pll_desc = &dvb_pll_microtune_4042; | 672 | dev->core->pll_desc = &dvb_pll_microtune_4042; |
628 | dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, | 673 | dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, |
629 | &dev->core->i2c_adap); | 674 | &dev->core->i2c_adap); |
675 | if (dev->dvb.frontend != NULL) { | ||
676 | dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3302_tuner_set_params; | ||
677 | } | ||
630 | } | 678 | } |
631 | break; | 679 | break; |
632 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: | 680 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: |
@@ -643,6 +691,9 @@ static int dvb_register(struct cx8802_dev *dev) | |||
643 | dev->core->pll_desc = &dvb_pll_thomson_dtt761x; | 691 | dev->core->pll_desc = &dvb_pll_thomson_dtt761x; |
644 | dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, | 692 | dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, |
645 | &dev->core->i2c_adap); | 693 | &dev->core->i2c_adap); |
694 | if (dev->dvb.frontend != NULL) { | ||
695 | dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3302_tuner_set_params; | ||
696 | } | ||
646 | } | 697 | } |
647 | break; | 698 | break; |
648 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: | 699 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: |
@@ -655,10 +706,28 @@ static int dvb_register(struct cx8802_dev *dev) | |||
655 | mdelay(100); | 706 | mdelay(100); |
656 | cx_set(MO_GP0_IO, 1); | 707 | cx_set(MO_GP0_IO, 1); |
657 | mdelay(200); | 708 | mdelay(200); |
658 | dev->core->pll_addr = 0x61; | ||
659 | dev->core->pll_desc = &dvb_pll_tdvs_tua6034; | ||
660 | dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold, | 709 | dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold, |
661 | &dev->core->i2c_adap); | 710 | &dev->core->i2c_adap); |
711 | if (dev->dvb.frontend != NULL) { | ||
712 | dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; | ||
713 | } | ||
714 | } | ||
715 | break; | ||
716 | case CX88_BOARD_PCHDTV_HD5500: | ||
717 | dev->ts_gen_cntrl = 0x08; | ||
718 | { | ||
719 | /* Do a hardware reset of chip before using it. */ | ||
720 | struct cx88_core *core = dev->core; | ||
721 | |||
722 | cx_clear(MO_GP0_IO, 1); | ||
723 | mdelay(100); | ||
724 | cx_set(MO_GP0_IO, 1); | ||
725 | mdelay(200); | ||
726 | dev->dvb.frontend = lgdt330x_attach(&pchdtv_hd5500, | ||
727 | &dev->core->i2c_adap); | ||
728 | if (dev->dvb.frontend != NULL) { | ||
729 | dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; | ||
730 | } | ||
662 | } | 731 | } |
663 | break; | 732 | break; |
664 | #endif | 733 | #endif |
@@ -666,6 +735,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
666 | case CX88_BOARD_ATI_HDTVWONDER: | 735 | case CX88_BOARD_ATI_HDTVWONDER: |
667 | dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder, | 736 | dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder, |
668 | &dev->core->i2c_adap); | 737 | &dev->core->i2c_adap); |
738 | if (dev->dvb.frontend != NULL) { | ||
739 | dvb_pll_attach(dev->dvb.frontend, 0x61, | ||
740 | &dev->core->i2c_adap, | ||
741 | &dvb_pll_tuv1236d); | ||
742 | } | ||
669 | break; | 743 | break; |
670 | #endif | 744 | #endif |
671 | #ifdef HAVE_CX24123 | 745 | #ifdef HAVE_CX24123 |
@@ -673,10 +747,18 @@ static int dvb_register(struct cx8802_dev *dev) | |||
673 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | 747 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: |
674 | dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config, | 748 | dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config, |
675 | &dev->core->i2c_adap); | 749 | &dev->core->i2c_adap); |
750 | if (dev->dvb.frontend) { | ||
751 | isl6421_attach(dev->dvb.frontend, &dev->core->i2c_adap, | ||
752 | 0x08, 0x00, 0x00); | ||
753 | } | ||
676 | break; | 754 | break; |
677 | case CX88_BOARD_KWORLD_DVBS_100: | 755 | case CX88_BOARD_KWORLD_DVBS_100: |
678 | dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config, | 756 | dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config, |
679 | &dev->core->i2c_adap); | 757 | &dev->core->i2c_adap); |
758 | if (dev->dvb.frontend) { | ||
759 | dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; | ||
760 | dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; | ||
761 | } | ||
680 | break; | 762 | break; |
681 | #endif | 763 | #endif |
682 | default: | 764 | default: |
@@ -690,15 +772,15 @@ static int dvb_register(struct cx8802_dev *dev) | |||
690 | } | 772 | } |
691 | 773 | ||
692 | if (dev->core->pll_desc) { | 774 | if (dev->core->pll_desc) { |
693 | dev->dvb.frontend->ops->info.frequency_min = dev->core->pll_desc->min; | 775 | dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min; |
694 | dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max; | 776 | dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max; |
695 | } | 777 | } |
696 | 778 | ||
697 | /* Put the analog decoder in standby to keep it quiet */ | 779 | /* Put the analog decoder in standby to keep it quiet */ |
698 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | 780 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); |
699 | 781 | ||
700 | /* register everything */ | 782 | /* register everything */ |
701 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); | 783 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); |
702 | } | 784 | } |
703 | 785 | ||
704 | /* ----------------------------------------------------------- */ | 786 | /* ----------------------------------------------------------- */ |
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index f720901e9638..7efa6def0bde 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -138,13 +138,13 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) | |||
138 | return; | 138 | return; |
139 | 139 | ||
140 | if (core->dvbdev) { | 140 | if (core->dvbdev) { |
141 | if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl) | 141 | if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) |
142 | core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); | 142 | core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); |
143 | 143 | ||
144 | i2c_clients_command(&core->i2c_adap, cmd, arg); | 144 | i2c_clients_command(&core->i2c_adap, cmd, arg); |
145 | 145 | ||
146 | if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl) | 146 | if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) |
147 | core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0); | 147 | core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0); |
148 | } else | 148 | } else |
149 | i2c_clients_command(&core->i2c_adap, cmd, arg); | 149 | i2c_clients_command(&core->i2c_adap, cmd, arg); |
150 | } | 150 | } |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 78a63b7dd380..72b630a91f41 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -70,14 +70,33 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | |||
70 | static void cx88_ir_handle_key(struct cx88_IR *ir) | 70 | static void cx88_ir_handle_key(struct cx88_IR *ir) |
71 | { | 71 | { |
72 | struct cx88_core *core = ir->core; | 72 | struct cx88_core *core = ir->core; |
73 | u32 gpio, data; | 73 | u32 gpio, data, auxgpio; |
74 | 74 | ||
75 | /* read gpio value */ | 75 | /* read gpio value */ |
76 | gpio = cx_read(ir->gpio_addr); | 76 | gpio = cx_read(ir->gpio_addr); |
77 | if (core->board == CX88_BOARD_NPGTECH_REALTV_TOP10FM) { | ||
78 | /* This board apparently uses a combination of 2 GPIO | ||
79 | to represent the keys. Additionally, the second GPIO | ||
80 | can be used for parity. | ||
81 | |||
82 | Example: | ||
83 | |||
84 | for key "5" | ||
85 | gpio = 0x758, auxgpio = 0xe5 or 0xf5 | ||
86 | for key "Power" | ||
87 | gpio = 0x758, auxgpio = 0xed or 0xfd | ||
88 | */ | ||
89 | |||
90 | auxgpio = cx_read(MO_GP1_IO); | ||
91 | /* Take out the parity part */ | ||
92 | gpio+=(gpio & 0x7fd) + (auxgpio & 0xef); | ||
93 | } else | ||
94 | auxgpio = gpio; | ||
95 | |||
77 | if (ir->polling) { | 96 | if (ir->polling) { |
78 | if (ir->last_gpio == gpio) | 97 | if (ir->last_gpio == auxgpio) |
79 | return; | 98 | return; |
80 | ir->last_gpio = gpio; | 99 | ir->last_gpio = auxgpio; |
81 | } | 100 | } |
82 | 101 | ||
83 | /* extract data */ | 102 | /* extract data */ |
@@ -172,12 +191,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
172 | ir_type = IR_TYPE_RC5; | 191 | ir_type = IR_TYPE_RC5; |
173 | ir->sampling = 1; | 192 | ir->sampling = 1; |
174 | break; | 193 | break; |
194 | case CX88_BOARD_WINFAST_DTV2000H: | ||
175 | case CX88_BOARD_WINFAST2000XP_EXPERT: | 195 | case CX88_BOARD_WINFAST2000XP_EXPERT: |
176 | ir_codes = ir_codes_winfast; | 196 | ir_codes = ir_codes_winfast; |
177 | ir->gpio_addr = MO_GP0_IO; | 197 | ir->gpio_addr = MO_GP0_IO; |
178 | ir->mask_keycode = 0x8f8; | 198 | ir->mask_keycode = 0x8f8; |
179 | ir->mask_keyup = 0x100; | 199 | ir->mask_keyup = 0x100; |
180 | ir->polling = 1; /* ms */ | 200 | ir->polling = 50; /* ms */ |
181 | break; | 201 | break; |
182 | case CX88_BOARD_IODATA_GVBCTV7E: | 202 | case CX88_BOARD_IODATA_GVBCTV7E: |
183 | ir_codes = ir_codes_iodata_bctv7e; | 203 | ir_codes = ir_codes_iodata_bctv7e; |
@@ -228,6 +248,12 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
228 | ir_type = IR_TYPE_PD; | 248 | ir_type = IR_TYPE_PD; |
229 | ir->sampling = 0xff00; /* address */ | 249 | ir->sampling = 0xff00; /* address */ |
230 | break; | 250 | break; |
251 | case CX88_BOARD_NPGTECH_REALTV_TOP10FM: | ||
252 | ir_codes = ir_codes_npgtech; | ||
253 | ir->gpio_addr = MO_GP0_IO; | ||
254 | ir->mask_keycode = 0xfa; | ||
255 | ir->polling = 50; /* ms */ | ||
256 | break; | ||
231 | } | 257 | } |
232 | 258 | ||
233 | if (NULL == ir_codes) { | 259 | if (NULL == ir_codes) { |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 7d16888b4a86..a9d7795a8e14 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -54,7 +54,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
54 | { | 54 | { |
55 | struct cx88_core *core = dev->core; | 55 | struct cx88_core *core = dev->core; |
56 | 56 | ||
57 | dprintk(0, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field); | 57 | dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field); |
58 | 58 | ||
59 | /* setup fifo + format */ | 59 | /* setup fifo + format */ |
60 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], | 60 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], |
@@ -76,6 +76,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
76 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: | 76 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: |
77 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: | 77 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: |
78 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: | 78 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: |
79 | case CX88_BOARD_PCHDTV_HD5500: | ||
79 | cx_write(TS_SOP_STAT, 1<<13); | 80 | cx_write(TS_SOP_STAT, 1<<13); |
80 | break; | 81 | break; |
81 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | 82 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
@@ -109,7 +110,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
109 | q->count = 1; | 110 | q->count = 1; |
110 | 111 | ||
111 | /* enable irqs */ | 112 | /* enable irqs */ |
112 | dprintk( 0, "setting the interrupt mask\n" ); | 113 | dprintk( 1, "setting the interrupt mask\n" ); |
113 | cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); | 114 | cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); |
114 | cx_set(MO_TS_INTMSK, 0x1f0011); | 115 | cx_set(MO_TS_INTMSK, 0x1f0011); |
115 | 116 | ||
@@ -122,7 +123,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
122 | static int cx8802_stop_dma(struct cx8802_dev *dev) | 123 | static int cx8802_stop_dma(struct cx8802_dev *dev) |
123 | { | 124 | { |
124 | struct cx88_core *core = dev->core; | 125 | struct cx88_core *core = dev->core; |
125 | dprintk( 0, "cx8802_stop_dma\n" ); | 126 | dprintk( 1, "cx8802_stop_dma\n" ); |
126 | 127 | ||
127 | /* stop dma */ | 128 | /* stop dma */ |
128 | cx_clear(MO_TS_DMACNTRL, 0x11); | 129 | cx_clear(MO_TS_DMACNTRL, 0x11); |
@@ -142,10 +143,43 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, | |||
142 | struct cx88_buffer *buf; | 143 | struct cx88_buffer *buf; |
143 | struct list_head *item; | 144 | struct list_head *item; |
144 | 145 | ||
145 | dprintk( 0, "cx8802_restart_queue\n" ); | 146 | dprintk( 1, "cx8802_restart_queue\n" ); |
146 | if (list_empty(&q->active)) | 147 | if (list_empty(&q->active)) |
147 | { | 148 | { |
148 | dprintk( 0, "cx8802_restart_queue: queue is empty\n" ); | 149 | struct cx88_buffer *prev; |
150 | prev = NULL; | ||
151 | |||
152 | dprintk(1, "cx8802_restart_queue: queue is empty\n" ); | ||
153 | |||
154 | for (;;) { | ||
155 | if (list_empty(&q->queued)) | ||
156 | return 0; | ||
157 | buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); | ||
158 | if (NULL == prev) { | ||
159 | list_del(&buf->vb.queue); | ||
160 | list_add_tail(&buf->vb.queue,&q->active); | ||
161 | cx8802_start_dma(dev, q, buf); | ||
162 | buf->vb.state = STATE_ACTIVE; | ||
163 | buf->count = q->count++; | ||
164 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | ||
165 | dprintk(1,"[%p/%d] restart_queue - first active\n", | ||
166 | buf,buf->vb.i); | ||
167 | |||
168 | } else if (prev->vb.width == buf->vb.width && | ||
169 | prev->vb.height == buf->vb.height && | ||
170 | prev->fmt == buf->fmt) { | ||
171 | list_del(&buf->vb.queue); | ||
172 | list_add_tail(&buf->vb.queue,&q->active); | ||
173 | buf->vb.state = STATE_ACTIVE; | ||
174 | buf->count = q->count++; | ||
175 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | ||
176 | dprintk(1,"[%p/%d] restart_queue - move to active\n", | ||
177 | buf,buf->vb.i); | ||
178 | } else { | ||
179 | return 0; | ||
180 | } | ||
181 | prev = buf; | ||
182 | } | ||
149 | return 0; | 183 | return 0; |
150 | } | 184 | } |
151 | 185 | ||
@@ -204,13 +238,13 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) | |||
204 | buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); | 238 | buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); |
205 | 239 | ||
206 | if (list_empty(&cx88q->active)) { | 240 | if (list_empty(&cx88q->active)) { |
207 | dprintk( 0, "queue is empty - first active\n" ); | 241 | dprintk( 1, "queue is empty - first active\n" ); |
208 | list_add_tail(&buf->vb.queue,&cx88q->active); | 242 | list_add_tail(&buf->vb.queue,&cx88q->active); |
209 | cx8802_start_dma(dev, cx88q, buf); | 243 | cx8802_start_dma(dev, cx88q, buf); |
210 | buf->vb.state = STATE_ACTIVE; | 244 | buf->vb.state = STATE_ACTIVE; |
211 | buf->count = cx88q->count++; | 245 | buf->count = cx88q->count++; |
212 | mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); | 246 | mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); |
213 | dprintk(0,"[%p/%d] %s - first active\n", | 247 | dprintk(1,"[%p/%d] %s - first active\n", |
214 | buf, buf->vb.i, __FUNCTION__); | 248 | buf, buf->vb.i, __FUNCTION__); |
215 | 249 | ||
216 | } else { | 250 | } else { |
@@ -244,7 +278,7 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart) | |||
244 | } | 278 | } |
245 | if (restart) | 279 | if (restart) |
246 | { | 280 | { |
247 | dprintk(0, "restarting queue\n" ); | 281 | dprintk(1, "restarting queue\n" ); |
248 | cx8802_restart_queue(dev,q); | 282 | cx8802_restart_queue(dev,q); |
249 | } | 283 | } |
250 | spin_unlock_irqrestore(&dev->slock,flags); | 284 | spin_unlock_irqrestore(&dev->slock,flags); |
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 641a0c5a6490..1e4278b588d8 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/init.h> | 52 | #include <linux/init.h> |
53 | #include <linux/smp_lock.h> | 53 | #include <linux/smp_lock.h> |
54 | #include <linux/delay.h> | 54 | #include <linux/delay.h> |
55 | #include <linux/config.h> | ||
55 | #include <linux/kthread.h> | 56 | #include <linux/kthread.h> |
56 | 57 | ||
57 | #include "cx88.h" | 58 | #include "cx88.h" |
@@ -137,21 +138,28 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) | |||
137 | { | 138 | { |
138 | u32 volume; | 139 | u32 volume; |
139 | 140 | ||
140 | #ifndef USING_CX88_ALSA | 141 | #ifndef CONFIG_VIDEO_CX88_ALSA |
141 | /* restart dma; This avoids buzz in NICAM and is good in others */ | 142 | /* restart dma; This avoids buzz in NICAM and is good in others */ |
142 | cx88_stop_audio_dma(core); | 143 | cx88_stop_audio_dma(core); |
143 | #endif | 144 | #endif |
144 | cx_write(AUD_RATE_THRES_DMD, 0x000000C0); | 145 | cx_write(AUD_RATE_THRES_DMD, 0x000000C0); |
145 | #ifndef USING_CX88_ALSA | 146 | #ifndef CONFIG_VIDEO_CX88_ALSA |
146 | cx88_start_audio_dma(core); | 147 | cx88_start_audio_dma(core); |
147 | #endif | 148 | #endif |
148 | 149 | ||
149 | if (cx88_boards[core->board].blackbird) { | 150 | if (cx88_boards[core->board].blackbird) { |
150 | /* sets sound input from external adc */ | 151 | /* sets sound input from external adc */ |
151 | if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) | 152 | switch (core->board) { |
153 | case CX88_BOARD_HAUPPAUGE_ROSLYN: | ||
154 | case CX88_BOARD_KWORLD_MCE200_DELUXE: | ||
155 | case CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT: | ||
156 | case CX88_BOARD_PIXELVIEW_PLAYTV_P7000: | ||
157 | case CX88_BOARD_ASUS_PVR_416: | ||
152 | cx_clear(AUD_CTL, EN_I2SIN_ENABLE); | 158 | cx_clear(AUD_CTL, EN_I2SIN_ENABLE); |
153 | else | 159 | break; |
160 | default: | ||
154 | cx_set(AUD_CTL, EN_I2SIN_ENABLE); | 161 | cx_set(AUD_CTL, EN_I2SIN_ENABLE); |
162 | } | ||
155 | 163 | ||
156 | cx_write(AUD_I2SINPUTCNTL, 4); | 164 | cx_write(AUD_I2SINPUTCNTL, 4); |
157 | cx_write(AUD_BAUDRATE, 1); | 165 | cx_write(AUD_BAUDRATE, 1); |
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c index 846faadc9f1c..aa2a69770098 100644 --- a/drivers/media/video/cx88/cx88-vbi.c +++ b/drivers/media/video/cx88/cx88-vbi.c | |||
@@ -34,8 +34,8 @@ void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f) | |||
34 | if (dev->core->tvnorm->id & V4L2_STD_525_60) { | 34 | if (dev->core->tvnorm->id & V4L2_STD_525_60) { |
35 | /* ntsc */ | 35 | /* ntsc */ |
36 | f->fmt.vbi.sampling_rate = 28636363; | 36 | f->fmt.vbi.sampling_rate = 28636363; |
37 | f->fmt.vbi.start[0] = 10 -1; | 37 | f->fmt.vbi.start[0] = 10; |
38 | f->fmt.vbi.start[1] = 273 -1; | 38 | f->fmt.vbi.start[1] = 273; |
39 | 39 | ||
40 | } else if (dev->core->tvnorm->id & V4L2_STD_625_50) { | 40 | } else if (dev->core->tvnorm->id & V4L2_STD_625_50) { |
41 | /* pal */ | 41 | /* pal */ |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 326a25f147f6..dc7bc35f18f4 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -25,9 +25,11 @@ | |||
25 | #include <linux/videodev2.h> | 25 | #include <linux/videodev2.h> |
26 | #include <linux/kdev_t.h> | 26 | #include <linux/kdev_t.h> |
27 | 27 | ||
28 | #include <media/v4l2-common.h> | ||
28 | #include <media/tuner.h> | 29 | #include <media/tuner.h> |
29 | #include <media/tveeprom.h> | 30 | #include <media/tveeprom.h> |
30 | #include <media/video-buf.h> | 31 | #include <media/video-buf.h> |
32 | #include <media/cx2341x.h> | ||
31 | #include <media/video-buf-dvb.h> | 33 | #include <media/video-buf-dvb.h> |
32 | 34 | ||
33 | #include "btcx-risc.h" | 35 | #include "btcx-risc.h" |
@@ -35,7 +37,7 @@ | |||
35 | 37 | ||
36 | #include <linux/version.h> | 38 | #include <linux/version.h> |
37 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
38 | #define CX88_VERSION_CODE KERNEL_VERSION(0,0,5) | 40 | #define CX88_VERSION_CODE KERNEL_VERSION(0,0,6) |
39 | 41 | ||
40 | #ifndef TRUE | 42 | #ifndef TRUE |
41 | # define TRUE (1==1) | 43 | # define TRUE (1==1) |
@@ -189,6 +191,11 @@ extern struct sram_channel cx88_sram_channels[]; | |||
189 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 | 191 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 |
190 | #define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45 | 192 | #define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45 |
191 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46 | 193 | #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46 |
194 | #define CX88_BOARD_PCHDTV_HD5500 47 | ||
195 | #define CX88_BOARD_KWORLD_MCE200_DELUXE 48 | ||
196 | #define CX88_BOARD_PIXELVIEW_PLAYTV_P7000 49 | ||
197 | #define CX88_BOARD_NPGTECH_REALTV_TOP10FM 50 | ||
198 | #define CX88_BOARD_WINFAST_DTV2000H 51 | ||
192 | 199 | ||
193 | enum cx88_itype { | 200 | enum cx88_itype { |
194 | CX88_VMUX_COMPOSITE1 = 1, | 201 | CX88_VMUX_COMPOSITE1 = 1, |
@@ -296,6 +303,7 @@ struct cx88_core { | |||
296 | /* config info -- dvb */ | 303 | /* config info -- dvb */ |
297 | struct dvb_pll_desc *pll_desc; | 304 | struct dvb_pll_desc *pll_desc; |
298 | unsigned int pll_addr; | 305 | unsigned int pll_addr; |
306 | int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | ||
299 | 307 | ||
300 | /* state info */ | 308 | /* state info */ |
301 | struct task_struct *kthread; | 309 | struct task_struct *kthread; |
@@ -391,14 +399,6 @@ struct cx8802_suspend_state { | |||
391 | int disabled; | 399 | int disabled; |
392 | }; | 400 | }; |
393 | 401 | ||
394 | /* TODO: move this to struct v4l2_mpeg_compression ? */ | ||
395 | struct blackbird_dnr { | ||
396 | u32 mode; | ||
397 | u32 type; | ||
398 | u32 spatial; | ||
399 | u32 temporal; | ||
400 | }; | ||
401 | |||
402 | struct cx8802_dev { | 402 | struct cx8802_dev { |
403 | struct cx88_core *core; | 403 | struct cx88_core *core; |
404 | spinlock_t slock; | 404 | spinlock_t slock; |
@@ -432,8 +432,7 @@ struct cx8802_dev { | |||
432 | unsigned char ts_gen_cntrl; | 432 | unsigned char ts_gen_cntrl; |
433 | 433 | ||
434 | /* mpeg params */ | 434 | /* mpeg params */ |
435 | struct v4l2_mpeg_compression params; | 435 | struct cx2341x_mpeg_params params; |
436 | struct blackbird_dnr dnr_params; | ||
437 | }; | 436 | }; |
438 | 437 | ||
439 | /* ----------------------------------------------------------- */ | 438 | /* ----------------------------------------------------------- */ |
@@ -598,10 +597,6 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
598 | extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, | 597 | extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, |
599 | unsigned int cmd, void *arg); | 598 | unsigned int cmd, void *arg); |
600 | extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); | 599 | extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); |
601 | void blackbird_set_params(struct cx8802_dev *dev, | ||
602 | struct v4l2_mpeg_compression *params); | ||
603 | void blackbird_set_dnr_params(struct cx8802_dev *dev, | ||
604 | struct blackbird_dnr* dnr_params); | ||
605 | 600 | ||
606 | /* | 601 | /* |
607 | * Local variables: | 602 | * Local variables: |
diff --git a/drivers/media/video/dsbr100.c b/drivers/media/video/dsbr100.c index 3b4e9985c3d7..f7e33f9ee8e9 100644 --- a/drivers/media/video/dsbr100.c +++ b/drivers/media/video/dsbr100.c | |||
@@ -72,6 +72,7 @@ | |||
72 | #include <linux/slab.h> | 72 | #include <linux/slab.h> |
73 | #include <linux/input.h> | 73 | #include <linux/input.h> |
74 | #include <linux/videodev.h> | 74 | #include <linux/videodev.h> |
75 | #include <media/v4l2-common.h> | ||
75 | #include <linux/usb.h> | 76 | #include <linux/usb.h> |
76 | #include <linux/smp_lock.h> | 77 | #include <linux/smp_lock.h> |
77 | 78 | ||
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 3ba3439db580..ed882ebc7b95 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
5 | Markus Rechberger <mrechberger@gmail.com> | 5 | Markus Rechberger <mrechberger@gmail.com> |
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 6 | Mauro Carvalho Chehab <mchehab@infradead.org> |
7 | Sascha Sommer <saschasommer@freenet.de> | 7 | Sascha Sommer <saschasommer@freenet.de> |
8 | 8 | ||
9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/usb.h> | 29 | #include <linux/usb.h> |
30 | #include <media/tuner.h> | 30 | #include <media/tuner.h> |
31 | #include <media/msp3400.h> | 31 | #include <media/msp3400.h> |
32 | #include <media/saa7115.h> | ||
33 | #include <media/tvp5150.h> | ||
32 | #include <media/tveeprom.h> | 34 | #include <media/tveeprom.h> |
33 | #include <media/audiochip.h> | 35 | #include <media/audiochip.h> |
34 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
@@ -46,11 +48,11 @@ struct em28xx_board em28xx_boards[] = { | |||
46 | .decoder = EM28XX_SAA7113, | 48 | .decoder = EM28XX_SAA7113, |
47 | .input = {{ | 49 | .input = {{ |
48 | .type = EM28XX_VMUX_COMPOSITE1, | 50 | .type = EM28XX_VMUX_COMPOSITE1, |
49 | .vmux = 0, | 51 | .vmux = SAA7115_COMPOSITE0, |
50 | .amux = 1, | 52 | .amux = 1, |
51 | },{ | 53 | },{ |
52 | .type = EM28XX_VMUX_SVIDEO, | 54 | .type = EM28XX_VMUX_SVIDEO, |
53 | .vmux = 9, | 55 | .vmux = SAA7115_SVIDEO3, |
54 | .amux = 1, | 56 | .amux = 1, |
55 | }}, | 57 | }}, |
56 | }, | 58 | }, |
@@ -64,11 +66,11 @@ struct em28xx_board em28xx_boards[] = { | |||
64 | .decoder = EM28XX_SAA7113, | 66 | .decoder = EM28XX_SAA7113, |
65 | .input = {{ | 67 | .input = {{ |
66 | .type = EM28XX_VMUX_COMPOSITE1, | 68 | .type = EM28XX_VMUX_COMPOSITE1, |
67 | .vmux = 0, | 69 | .vmux = SAA7115_COMPOSITE0, |
68 | .amux = 1, | 70 | .amux = 1, |
69 | },{ | 71 | },{ |
70 | .type = EM28XX_VMUX_SVIDEO, | 72 | .type = EM28XX_VMUX_SVIDEO, |
71 | .vmux = 9, | 73 | .vmux = SAA7115_SVIDEO3, |
72 | .amux = 1, | 74 | .amux = 1, |
73 | }}, | 75 | }}, |
74 | }, | 76 | }, |
@@ -82,11 +84,11 @@ struct em28xx_board em28xx_boards[] = { | |||
82 | .decoder = EM28XX_SAA7113, | 84 | .decoder = EM28XX_SAA7113, |
83 | .input = {{ | 85 | .input = {{ |
84 | .type = EM28XX_VMUX_COMPOSITE1, | 86 | .type = EM28XX_VMUX_COMPOSITE1, |
85 | .vmux = 0, | 87 | .vmux = SAA7115_COMPOSITE0, |
86 | .amux = 1, | 88 | .amux = 1, |
87 | },{ | 89 | },{ |
88 | .type = EM28XX_VMUX_SVIDEO, | 90 | .type = EM28XX_VMUX_SVIDEO, |
89 | .vmux = 9, | 91 | .vmux = SAA7115_SVIDEO3, |
90 | .amux = 1, | 92 | .amux = 1, |
91 | }}, | 93 | }}, |
92 | }, | 94 | }, |
@@ -100,15 +102,15 @@ struct em28xx_board em28xx_boards[] = { | |||
100 | .decoder = EM28XX_SAA7113, | 102 | .decoder = EM28XX_SAA7113, |
101 | .input = {{ | 103 | .input = {{ |
102 | .type = EM28XX_VMUX_TELEVISION, | 104 | .type = EM28XX_VMUX_TELEVISION, |
103 | .vmux = 2, | 105 | .vmux = SAA7115_COMPOSITE2, |
104 | .amux = 1, | 106 | .amux = 1, |
105 | },{ | 107 | },{ |
106 | .type = EM28XX_VMUX_COMPOSITE1, | 108 | .type = EM28XX_VMUX_COMPOSITE1, |
107 | .vmux = 0, | 109 | .vmux = SAA7115_COMPOSITE0, |
108 | .amux = 1, | 110 | .amux = 1, |
109 | },{ | 111 | },{ |
110 | .type = EM28XX_VMUX_SVIDEO, | 112 | .type = EM28XX_VMUX_SVIDEO, |
111 | .vmux = 9, | 113 | .vmux = SAA7115_SVIDEO3, |
112 | .amux = 1, | 114 | .amux = 1, |
113 | }}, | 115 | }}, |
114 | }, | 116 | }, |
@@ -122,15 +124,15 @@ struct em28xx_board em28xx_boards[] = { | |||
122 | .decoder = EM28XX_SAA7113, | 124 | .decoder = EM28XX_SAA7113, |
123 | .input = {{ | 125 | .input = {{ |
124 | .type = EM28XX_VMUX_TELEVISION, | 126 | .type = EM28XX_VMUX_TELEVISION, |
125 | .vmux = 2, | 127 | .vmux = SAA7115_COMPOSITE2, |
126 | .amux = 0, | 128 | .amux = 0, |
127 | },{ | 129 | },{ |
128 | .type = EM28XX_VMUX_COMPOSITE1, | 130 | .type = EM28XX_VMUX_COMPOSITE1, |
129 | .vmux = 0, | 131 | .vmux = SAA7115_COMPOSITE0, |
130 | .amux = 1, | 132 | .amux = 1, |
131 | },{ | 133 | },{ |
132 | .type = EM28XX_VMUX_SVIDEO, | 134 | .type = EM28XX_VMUX_SVIDEO, |
133 | .vmux = 9, | 135 | .vmux = SAA7115_SVIDEO3, |
134 | .amux = 1, | 136 | .amux = 1, |
135 | }}, | 137 | }}, |
136 | }, | 138 | }, |
@@ -146,11 +148,11 @@ struct em28xx_board em28xx_boards[] = { | |||
146 | /*FIXME: S-Video not tested */ | 148 | /*FIXME: S-Video not tested */ |
147 | .input = {{ | 149 | .input = {{ |
148 | .type = EM28XX_VMUX_TELEVISION, | 150 | .type = EM28XX_VMUX_TELEVISION, |
149 | .vmux = 0, | 151 | .vmux = TVP5150_COMPOSITE0, |
150 | .amux = MSP_INPUT_DEFAULT, | 152 | .amux = MSP_INPUT_DEFAULT, |
151 | },{ | 153 | },{ |
152 | .type = EM28XX_VMUX_SVIDEO, | 154 | .type = EM28XX_VMUX_SVIDEO, |
153 | .vmux = 2, | 155 | .vmux = TVP5150_SVIDEO, |
154 | .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, | 156 | .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, |
155 | MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), | 157 | MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), |
156 | }}, | 158 | }}, |
@@ -165,15 +167,15 @@ struct em28xx_board em28xx_boards[] = { | |||
165 | .decoder = EM28XX_SAA7114, | 167 | .decoder = EM28XX_SAA7114, |
166 | .input = {{ | 168 | .input = {{ |
167 | .type = EM28XX_VMUX_TELEVISION, | 169 | .type = EM28XX_VMUX_TELEVISION, |
168 | .vmux = 4, | 170 | .vmux = SAA7115_COMPOSITE4, |
169 | .amux = 0, | 171 | .amux = 0, |
170 | },{ | 172 | },{ |
171 | .type = EM28XX_VMUX_COMPOSITE1, | 173 | .type = EM28XX_VMUX_COMPOSITE1, |
172 | .vmux = 0, | 174 | .vmux = SAA7115_COMPOSITE0, |
173 | .amux = 1, | 175 | .amux = 1, |
174 | },{ | 176 | },{ |
175 | .type = EM28XX_VMUX_SVIDEO, | 177 | .type = EM28XX_VMUX_SVIDEO, |
176 | .vmux = 9, | 178 | .vmux = SAA7115_SVIDEO3, |
177 | .amux = 1, | 179 | .amux = 1, |
178 | }}, | 180 | }}, |
179 | }, | 181 | }, |
@@ -188,15 +190,15 @@ struct em28xx_board em28xx_boards[] = { | |||
188 | .decoder = EM28XX_SAA7113, | 190 | .decoder = EM28XX_SAA7113, |
189 | .input = {{ | 191 | .input = {{ |
190 | .type = EM28XX_VMUX_TELEVISION, | 192 | .type = EM28XX_VMUX_TELEVISION, |
191 | .vmux = 2, | 193 | .vmux = SAA7115_COMPOSITE2, |
192 | .amux = 0, | 194 | .amux = 0, |
193 | },{ | 195 | },{ |
194 | .type = EM28XX_VMUX_COMPOSITE1, | 196 | .type = EM28XX_VMUX_COMPOSITE1, |
195 | .vmux = 0, | 197 | .vmux = SAA7115_COMPOSITE0, |
196 | .amux = 1, | 198 | .amux = 1, |
197 | },{ | 199 | },{ |
198 | .type = EM28XX_VMUX_SVIDEO, | 200 | .type = EM28XX_VMUX_SVIDEO, |
199 | .vmux = 9, | 201 | .vmux = SAA7115_SVIDEO3, |
200 | .amux = 1, | 202 | .amux = 1, |
201 | }}, | 203 | }}, |
202 | }, | 204 | }, |
@@ -211,15 +213,15 @@ struct em28xx_board em28xx_boards[] = { | |||
211 | .decoder = EM28XX_SAA7113, | 213 | .decoder = EM28XX_SAA7113, |
212 | .input = {{ | 214 | .input = {{ |
213 | .type = EM28XX_VMUX_TELEVISION, | 215 | .type = EM28XX_VMUX_TELEVISION, |
214 | .vmux = 2, | 216 | .vmux = SAA7115_COMPOSITE2, |
215 | .amux = 0, | 217 | .amux = 0, |
216 | },{ | 218 | },{ |
217 | .type = EM28XX_VMUX_COMPOSITE1, | 219 | .type = EM28XX_VMUX_COMPOSITE1, |
218 | .vmux = 0, | 220 | .vmux = SAA7115_COMPOSITE0, |
219 | .amux = 1, | 221 | .amux = 1, |
220 | },{ | 222 | },{ |
221 | .type = EM28XX_VMUX_SVIDEO, | 223 | .type = EM28XX_VMUX_SVIDEO, |
222 | .vmux = 9, | 224 | .vmux = SAA7115_SVIDEO3, |
223 | .amux = 1, | 225 | .amux = 1, |
224 | }}, | 226 | }}, |
225 | }, | 227 | }, |
@@ -234,15 +236,15 @@ struct em28xx_board em28xx_boards[] = { | |||
234 | .decoder = EM28XX_SAA7113, | 236 | .decoder = EM28XX_SAA7113, |
235 | .input = {{ | 237 | .input = {{ |
236 | .type = EM28XX_VMUX_TELEVISION, | 238 | .type = EM28XX_VMUX_TELEVISION, |
237 | .vmux = 2, | 239 | .vmux = SAA7115_COMPOSITE2, |
238 | .amux = 0, | 240 | .amux = 0, |
239 | },{ | 241 | },{ |
240 | .type = EM28XX_VMUX_COMPOSITE1, | 242 | .type = EM28XX_VMUX_COMPOSITE1, |
241 | .vmux = 0, | 243 | .vmux = SAA7115_COMPOSITE0, |
242 | .amux = 1, | 244 | .amux = 1, |
243 | },{ | 245 | },{ |
244 | .type = EM28XX_VMUX_SVIDEO, | 246 | .type = EM28XX_VMUX_SVIDEO, |
245 | .vmux = 9, | 247 | .vmux = SAA7115_SVIDEO3, |
246 | .amux = 1, | 248 | .amux = 1, |
247 | }}, | 249 | }}, |
248 | }, | 250 | }, |
@@ -254,11 +256,11 @@ struct em28xx_board em28xx_boards[] = { | |||
254 | .decoder = EM28XX_SAA7113, | 256 | .decoder = EM28XX_SAA7113, |
255 | .input = {{ | 257 | .input = {{ |
256 | .type = EM28XX_VMUX_COMPOSITE1, | 258 | .type = EM28XX_VMUX_COMPOSITE1, |
257 | .vmux = 0, | 259 | .vmux = SAA7115_COMPOSITE0, |
258 | .amux = 1, | 260 | .amux = 1, |
259 | },{ | 261 | },{ |
260 | .type = EM28XX_VMUX_SVIDEO, | 262 | .type = EM28XX_VMUX_SVIDEO, |
261 | .vmux = 9, | 263 | .vmux = SAA7115_SVIDEO3, |
262 | .amux = 1, | 264 | .amux = 1, |
263 | }}, | 265 | }}, |
264 | }, | 266 | }, |
@@ -324,8 +326,4 @@ void em28xx_card_setup(struct em28xx *dev) | |||
324 | } | 326 | } |
325 | } | 327 | } |
326 | 328 | ||
327 | EXPORT_SYMBOL(em28xx_boards); | ||
328 | EXPORT_SYMBOL(em28xx_bcount); | ||
329 | EXPORT_SYMBOL(em28xx_id_table); | ||
330 | |||
331 | MODULE_DEVICE_TABLE (usb, em28xx_id_table); | 329 | MODULE_DEVICE_TABLE (usb, em28xx_id_table); |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index e5ee8bceb210..4350cc75b025 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
5 | Markus Rechberger <mrechberger@gmail.com> | 5 | Markus Rechberger <mrechberger@gmail.com> |
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 6 | Mauro Carvalho Chehab <mchehab@infradead.org> |
7 | Sascha Sommer <saschasommer@freenet.de> | 7 | Sascha Sommer <saschasommer@freenet.de> |
8 | 8 | ||
9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
@@ -317,8 +317,8 @@ int em28xx_outfmt_set_yuv422(struct em28xx *dev) | |||
317 | return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1); | 317 | return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1); |
318 | } | 318 | } |
319 | 319 | ||
320 | int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin, | 320 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, |
321 | u8 ymax) | 321 | u8 ymin, u8 ymax) |
322 | { | 322 | { |
323 | em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax); | 323 | em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax); |
324 | 324 | ||
@@ -328,7 +328,7 @@ int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin, | |||
328 | return em28xx_write_regs(dev, YMAX_REG, &ymax, 1); | 328 | return em28xx_write_regs(dev, YMAX_REG, &ymax, 1); |
329 | } | 329 | } |
330 | 330 | ||
331 | int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, | 331 | static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, |
332 | u16 width, u16 height) | 332 | u16 width, u16 height) |
333 | { | 333 | { |
334 | u8 cwidth = width; | 334 | u8 cwidth = width; |
@@ -345,7 +345,7 @@ int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, | |||
345 | return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1); | 345 | return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1); |
346 | } | 346 | } |
347 | 347 | ||
348 | int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | 348 | static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) |
349 | { | 349 | { |
350 | u8 mode; | 350 | u8 mode; |
351 | /* the em2800 scaler only supports scaling down to 50% */ | 351 | /* the em2800 scaler only supports scaling down to 50% */ |
@@ -534,7 +534,7 @@ static inline void em28xx_isoc_video_copy(struct em28xx *dev, | |||
534 | * em28xx_isoIrq() | 534 | * em28xx_isoIrq() |
535 | * handles the incoming isoc urbs and fills the frames from our inqueue | 535 | * handles the incoming isoc urbs and fills the frames from our inqueue |
536 | */ | 536 | */ |
537 | void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs) | 537 | static void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs) |
538 | { | 538 | { |
539 | struct em28xx *dev = urb->context; | 539 | struct em28xx *dev = urb->context; |
540 | int i, status; | 540 | int i, status; |
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 5b6cece37aee..d829d8f8c1f6 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
5 | Markus Rechberger <mrechberger@gmail.com> | 5 | Markus Rechberger <mrechberger@gmail.com> |
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 6 | Mauro Carvalho Chehab <mchehab@infradead.org> |
7 | Sascha Sommer <saschasommer@freenet.de> | 7 | Sascha Sommer <saschasommer@freenet.de> |
8 | 8 | ||
9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
@@ -399,17 +399,6 @@ static u32 functionality(struct i2c_adapter *adap) | |||
399 | return I2C_FUNC_SMBUS_EMUL; | 399 | return I2C_FUNC_SMBUS_EMUL; |
400 | } | 400 | } |
401 | 401 | ||
402 | #ifndef I2C_PEC | ||
403 | static void inc_use(struct i2c_adapter *adap) | ||
404 | { | ||
405 | MOD_INC_USE_COUNT; | ||
406 | } | ||
407 | |||
408 | static void dec_use(struct i2c_adapter *adap) | ||
409 | { | ||
410 | MOD_DEC_USE_COUNT; | ||
411 | } | ||
412 | #endif | ||
413 | 402 | ||
414 | static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client) | 403 | static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client) |
415 | { | 404 | { |
@@ -436,9 +425,19 @@ static int attach_inform(struct i2c_client *client) | |||
436 | struct em28xx *dev = client->adapter->algo_data; | 425 | struct em28xx *dev = client->adapter->algo_data; |
437 | 426 | ||
438 | switch (client->addr << 1) { | 427 | switch (client->addr << 1) { |
439 | case 0x86: | 428 | case 0x43: |
429 | case 0x4b: | ||
430 | { | ||
431 | struct tuner_setup tun_setup; | ||
432 | |||
433 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; | ||
434 | tun_setup.type = TUNER_TDA9887; | ||
435 | tun_setup.addr = client->addr; | ||
436 | |||
437 | em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); | ||
440 | em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf); | 438 | em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf); |
441 | break; | 439 | break; |
440 | } | ||
442 | case 0x42: | 441 | case 0x42: |
443 | dprintk1(1,"attach_inform: saa7114 detected.\n"); | 442 | dprintk1(1,"attach_inform: saa7114 detected.\n"); |
444 | break; | 443 | break; |
@@ -464,6 +463,7 @@ static int attach_inform(struct i2c_client *client) | |||
464 | case 0xba: | 463 | case 0xba: |
465 | dprintk1(1,"attach_inform: tvp5150 detected.\n"); | 464 | dprintk1(1,"attach_inform: tvp5150 detected.\n"); |
466 | break; | 465 | break; |
466 | |||
467 | default: | 467 | default: |
468 | dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1); | 468 | dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1); |
469 | dev->tuner_addr = client->addr; | 469 | dev->tuner_addr = client->addr; |
@@ -480,12 +480,7 @@ static struct i2c_algorithm em28xx_algo = { | |||
480 | }; | 480 | }; |
481 | 481 | ||
482 | static struct i2c_adapter em28xx_adap_template = { | 482 | static struct i2c_adapter em28xx_adap_template = { |
483 | #ifdef I2C_PEC | ||
484 | .owner = THIS_MODULE, | 483 | .owner = THIS_MODULE, |
485 | #else | ||
486 | .inc_use = inc_use, | ||
487 | .dec_use = dec_use, | ||
488 | #endif | ||
489 | .class = I2C_CLASS_TV_ANALOG, | 484 | .class = I2C_CLASS_TV_ANALOG, |
490 | .name = "em28xx", | 485 | .name = "em28xx", |
491 | .id = I2C_HW_B_EM28XX, | 486 | .id = I2C_HW_B_EM28XX, |
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 31e89e4f18be..3ffb5684f127 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
5 | Markus Rechberger <mrechberger@gmail.com> | 5 | Markus Rechberger <mrechberger@gmail.com> |
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 6 | Mauro Carvalho Chehab <mchehab@infradead.org> |
7 | Sascha Sommer <saschasommer@freenet.de> | 7 | Sascha Sommer <saschasommer@freenet.de> |
8 | 8 | ||
9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
@@ -105,7 +105,7 @@ static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
105 | return 1; | 105 | return 1; |
106 | } | 106 | } |
107 | 107 | ||
108 | static int get_key_pinnacle_usb(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 108 | static int get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
109 | { | 109 | { |
110 | unsigned char buf[3]; | 110 | unsigned char buf[3]; |
111 | 111 | ||
@@ -148,8 +148,8 @@ void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir) | |||
148 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); | 148 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); |
149 | break; | 149 | break; |
150 | case (EM2820_BOARD_PINNACLE_USB_2): | 150 | case (EM2820_BOARD_PINNACLE_USB_2): |
151 | ir->ir_codes = ir_codes_em_pinnacle_usb; | 151 | ir->ir_codes = ir_codes_pinnacle_grey; |
152 | ir->get_key = get_key_pinnacle_usb; | 152 | ir->get_key = get_key_pinnacle_usb_grey; |
153 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Pinnacle PCTV)"); | 153 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Pinnacle PCTV)"); |
154 | break; | 154 | break; |
155 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): | 155 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index cf7cdf9ef617..9286090817cd 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
5 | Markus Rechberger <mrechberger@gmail.com> | 5 | Markus Rechberger <mrechberger@gmail.com> |
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 6 | Mauro Carvalho Chehab <mchehab@infradead.org> |
7 | Sascha Sommer <saschasommer@freenet.de> | 7 | Sascha Sommer <saschasommer@freenet.de> |
8 | 8 | ||
9 | Some parts based on SN9C10x PC Camera Controllers GPL driver made | 9 | Some parts based on SN9C10x PC Camera Controllers GPL driver made |
@@ -42,7 +42,7 @@ | |||
42 | 42 | ||
43 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ | 43 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ |
44 | "Markus Rechberger <mrechberger@gmail.com>, " \ | 44 | "Markus Rechberger <mrechberger@gmail.com>, " \ |
45 | "Mauro Carvalho Chehab <mchehab@brturbo.com.br>, " \ | 45 | "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ |
46 | "Sascha Sommer <saschasommer@freenet.de>" | 46 | "Sascha Sommer <saschasommer@freenet.de>" |
47 | 47 | ||
48 | #define DRIVER_NAME "em28xx" | 48 | #define DRIVER_NAME "em28xx" |
@@ -170,8 +170,12 @@ static int em28xx_config(struct em28xx *dev) | |||
170 | static void em28xx_config_i2c(struct em28xx *dev) | 170 | static void em28xx_config_i2c(struct em28xx *dev) |
171 | { | 171 | { |
172 | struct v4l2_frequency f; | 172 | struct v4l2_frequency f; |
173 | struct v4l2_routing route; | ||
174 | |||
175 | route.input = INPUT(dev->ctl_input)->vmux; | ||
176 | route.output = 0; | ||
173 | em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL); | 177 | em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL); |
174 | em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &dev->ctl_input); | 178 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); |
175 | em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); | 179 | em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); |
176 | 180 | ||
177 | /* configure tuner */ | 181 | /* configure tuner */ |
@@ -206,19 +210,19 @@ static void em28xx_empty_framequeues(struct em28xx *dev) | |||
206 | 210 | ||
207 | static void video_mux(struct em28xx *dev, int index) | 211 | static void video_mux(struct em28xx *dev, int index) |
208 | { | 212 | { |
209 | int input, ainput; | 213 | int ainput; |
214 | struct v4l2_routing route; | ||
210 | 215 | ||
211 | input = INPUT(index)->vmux; | 216 | route.input = INPUT(index)->vmux; |
217 | route.output = 0; | ||
212 | dev->ctl_input = index; | 218 | dev->ctl_input = index; |
213 | dev->ctl_ainput = INPUT(index)->amux; | 219 | dev->ctl_ainput = INPUT(index)->amux; |
214 | 220 | ||
215 | em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &input); | 221 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); |
216 | 222 | ||
217 | em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); | 223 | em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,route.input,dev->ctl_ainput); |
218 | 224 | ||
219 | if (dev->has_msp34xx) { | 225 | if (dev->has_msp34xx) { |
220 | struct v4l2_routing route; | ||
221 | |||
222 | if (dev->i2s_speed) | 226 | if (dev->i2s_speed) |
223 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); | 227 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); |
224 | route.input = dev->ctl_ainput; | 228 | route.input = dev->ctl_ainput; |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index e1ddc2f27a21..d8fcc9e17ac0 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> | 4 | Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> |
5 | Ludovico Cavedon <cavedon@sssup.it> | 5 | Ludovico Cavedon <cavedon@sssup.it> |
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 6 | Mauro Carvalho Chehab <mchehab@infradead.org> |
7 | 7 | ||
8 | Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> | 8 | Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> |
9 | 9 | ||
@@ -319,13 +319,7 @@ int em28xx_audio_analog_set(struct em28xx *dev); | |||
319 | int em28xx_colorlevels_set_default(struct em28xx *dev); | 319 | int em28xx_colorlevels_set_default(struct em28xx *dev); |
320 | int em28xx_capture_start(struct em28xx *dev, int start); | 320 | int em28xx_capture_start(struct em28xx *dev, int start); |
321 | int em28xx_outfmt_set_yuv422(struct em28xx *dev); | 321 | int em28xx_outfmt_set_yuv422(struct em28xx *dev); |
322 | int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin, | ||
323 | u8 ymax); | ||
324 | int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, | ||
325 | u16 width, u16 height); | ||
326 | int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v); | ||
327 | int em28xx_resolution_set(struct em28xx *dev); | 322 | int em28xx_resolution_set(struct em28xx *dev); |
328 | void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs); | ||
329 | int em28xx_init_isoc(struct em28xx *dev); | 323 | int em28xx_init_isoc(struct em28xx *dev); |
330 | void em28xx_uninit_isoc(struct em28xx *dev); | 324 | void em28xx_uninit_isoc(struct em28xx *dev); |
331 | int em28xx_set_alternate(struct em28xx *dev); | 325 | int em28xx_set_alternate(struct em28xx *dev); |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index dfc9dd732c9d..8992b6e62b9f 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
@@ -2341,11 +2341,9 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
2341 | case VIDIOC_G_CTRL: | 2341 | case VIDIOC_G_CTRL: |
2342 | return et61x251_vidioc_g_ctrl(cam, arg); | 2342 | return et61x251_vidioc_g_ctrl(cam, arg); |
2343 | 2343 | ||
2344 | case VIDIOC_S_CTRL_OLD: | ||
2345 | case VIDIOC_S_CTRL: | 2344 | case VIDIOC_S_CTRL: |
2346 | return et61x251_vidioc_s_ctrl(cam, arg); | 2345 | return et61x251_vidioc_s_ctrl(cam, arg); |
2347 | 2346 | ||
2348 | case VIDIOC_CROPCAP_OLD: | ||
2349 | case VIDIOC_CROPCAP: | 2347 | case VIDIOC_CROPCAP: |
2350 | return et61x251_vidioc_cropcap(cam, arg); | 2348 | return et61x251_vidioc_cropcap(cam, arg); |
2351 | 2349 | ||
@@ -2392,7 +2390,6 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
2392 | case VIDIOC_G_PARM: | 2390 | case VIDIOC_G_PARM: |
2393 | return et61x251_vidioc_g_parm(cam, arg); | 2391 | return et61x251_vidioc_g_parm(cam, arg); |
2394 | 2392 | ||
2395 | case VIDIOC_S_PARM_OLD: | ||
2396 | case VIDIOC_S_PARM: | 2393 | case VIDIOC_S_PARM: |
2397 | return et61x251_vidioc_s_parm(cam, arg); | 2394 | return et61x251_vidioc_s_parm(cam, arg); |
2398 | 2395 | ||
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 7e66d83fe0ce..fba30a40e9c6 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -150,12 +150,11 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
150 | return 1; | 150 | return 1; |
151 | } | 151 | } |
152 | 152 | ||
153 | /* The new pinnacle PCTV remote (with the colored buttons) | 153 | /* Common (grey or coloured) pinnacle PCTV remote handling |
154 | * | 154 | * |
155 | * Ricardo Cerqueira <v4l@cerqueira.org> | ||
156 | */ | 155 | */ |
157 | 156 | static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, | |
158 | int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 157 | int parity_offset, int marker, int code_modulo) |
159 | { | 158 | { |
160 | unsigned char b[4]; | 159 | unsigned char b[4]; |
161 | unsigned int start = 0,parity = 0,code = 0; | 160 | unsigned int start = 0,parity = 0,code = 0; |
@@ -167,9 +166,9 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
167 | } | 166 | } |
168 | 167 | ||
169 | for (start = 0; start<4; start++) { | 168 | for (start = 0; start<4; start++) { |
170 | if (b[start] == 0x80) { | 169 | if (b[start] == marker) { |
171 | code=b[(start+3)%4]; | 170 | code=b[(start+parity_offset+1)%4]; |
172 | parity=b[(start+2)%4]; | 171 | parity=b[(start+parity_offset)%4]; |
173 | } | 172 | } |
174 | } | 173 | } |
175 | 174 | ||
@@ -181,16 +180,14 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
181 | if (ir->old == parity) | 180 | if (ir->old == parity) |
182 | return 0; | 181 | return 0; |
183 | 182 | ||
184 | |||
185 | ir->old = parity; | 183 | ir->old = parity; |
186 | 184 | ||
187 | /* Reduce code value to fit inside IR_KEYTAB_SIZE | 185 | /* drop special codes when a key is held down a long time for the grey controller |
188 | * | 186 | In this case, the second bit of the code is asserted */ |
189 | * this is the only value that results in 42 unique | 187 | if (marker == 0xfe && (code & 0x40)) |
190 | * codes < 128 | 188 | return 0; |
191 | */ | ||
192 | 189 | ||
193 | code %= 0x88; | 190 | code %= code_modulo; |
194 | 191 | ||
195 | *ir_raw = code; | 192 | *ir_raw = code; |
196 | *ir_key = code; | 193 | *ir_key = code; |
@@ -200,7 +197,40 @@ int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
200 | return 1; | 197 | return 1; |
201 | } | 198 | } |
202 | 199 | ||
203 | EXPORT_SYMBOL_GPL(get_key_pinnacle); | 200 | /* The grey pinnacle PCTV remote |
201 | * | ||
202 | * There are one issue with this remote: | ||
203 | * - I2c packet does not change when the same key is pressed quickly. The workaround | ||
204 | * is to hold down each key for about half a second, so that another code is generated | ||
205 | * in the i2c packet, and the function can distinguish key presses. | ||
206 | * | ||
207 | * Sylvain Pasche <sylvain.pasche@gmail.com> | ||
208 | */ | ||
209 | int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
210 | { | ||
211 | |||
212 | return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff); | ||
213 | } | ||
214 | |||
215 | EXPORT_SYMBOL_GPL(get_key_pinnacle_grey); | ||
216 | |||
217 | |||
218 | /* The new pinnacle PCTV remote (with the colored buttons) | ||
219 | * | ||
220 | * Ricardo Cerqueira <v4l@cerqueira.org> | ||
221 | */ | ||
222 | int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
223 | { | ||
224 | /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE | ||
225 | * | ||
226 | * this is the only value that results in 42 unique | ||
227 | * codes < 128 | ||
228 | */ | ||
229 | |||
230 | return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88); | ||
231 | } | ||
232 | |||
233 | EXPORT_SYMBOL_GPL(get_key_pinnacle_color); | ||
204 | 234 | ||
205 | /* ----------------------------------------------------------------------- */ | 235 | /* ----------------------------------------------------------------------- */ |
206 | 236 | ||
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c new file mode 100644 index 000000000000..3bf7ac4f5288 --- /dev/null +++ b/drivers/media/video/ks0127.c | |||
@@ -0,0 +1,846 @@ | |||
1 | /* | ||
2 | * Video Capture Driver (Video for Linux 1/2) | ||
3 | * for the Matrox Marvel G200,G400 and Rainbow Runner-G series | ||
4 | * | ||
5 | * This module is an interface to the KS0127 video decoder chip. | ||
6 | * | ||
7 | * Copyright (C) 1999 Ryan Drake <stiletto@mediaone.net> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version 2 | ||
12 | * of the License, or (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | * | ||
23 | ***************************************************************************** | ||
24 | * | ||
25 | * Modified and extended by | ||
26 | * Mike Bernson <mike@mlb.org> | ||
27 | * Gerard v.d. Horst | ||
28 | * Leon van Stuivenberg <l.vanstuivenberg@chello.nl> | ||
29 | * Gernot Ziegler <gz@lysator.liu.se> | ||
30 | * | ||
31 | * Version History: | ||
32 | * V1.0 Ryan Drake Initial version by Ryan Drake | ||
33 | * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard | ||
34 | */ | ||
35 | |||
36 | #ifndef __KERNEL__ | ||
37 | #define __KERNEL__ | ||
38 | #endif | ||
39 | |||
40 | #include <linux/init.h> | ||
41 | #include <linux/module.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/errno.h> | ||
44 | #include <linux/kernel.h> | ||
45 | #include <linux/slab.h> | ||
46 | #include <linux/proc_fs.h> | ||
47 | #include "ks0127.h" | ||
48 | |||
49 | #include <linux/i2c.h> | ||
50 | #include <linux/video_decoder.h> | ||
51 | |||
52 | #define dprintk if (debug) printk | ||
53 | |||
54 | /* i2c identification */ | ||
55 | #define I2C_KS0127_ADDON 0xD8 | ||
56 | #define I2C_KS0127_ONBOARD 0xDA | ||
57 | |||
58 | #define KS_TYPE_UNKNOWN 0 | ||
59 | #define KS_TYPE_0122S 1 | ||
60 | #define KS_TYPE_0127 2 | ||
61 | #define KS_TYPE_0127B 3 | ||
62 | |||
63 | /* ks0127 control registers */ | ||
64 | #define KS_STAT 0x00 | ||
65 | #define KS_CMDA 0x01 | ||
66 | #define KS_CMDB 0x02 | ||
67 | #define KS_CMDC 0x03 | ||
68 | #define KS_CMDD 0x04 | ||
69 | #define KS_HAVB 0x05 | ||
70 | #define KS_HAVE 0x06 | ||
71 | #define KS_HS1B 0x07 | ||
72 | #define KS_HS1E 0x08 | ||
73 | #define KS_HS2B 0x09 | ||
74 | #define KS_HS2E 0x0a | ||
75 | #define KS_AGC 0x0b | ||
76 | #define KS_HXTRA 0x0c | ||
77 | #define KS_CDEM 0x0d | ||
78 | #define KS_PORTAB 0x0e | ||
79 | #define KS_LUMA 0x0f | ||
80 | #define KS_CON 0x10 | ||
81 | #define KS_BRT 0x11 | ||
82 | #define KS_CHROMA 0x12 | ||
83 | #define KS_CHROMB 0x13 | ||
84 | #define KS_DEMOD 0x14 | ||
85 | #define KS_SAT 0x15 | ||
86 | #define KS_HUE 0x16 | ||
87 | #define KS_VERTIA 0x17 | ||
88 | #define KS_VERTIB 0x18 | ||
89 | #define KS_VERTIC 0x19 | ||
90 | #define KS_HSCLL 0x1a | ||
91 | #define KS_HSCLH 0x1b | ||
92 | #define KS_VSCLL 0x1c | ||
93 | #define KS_VSCLH 0x1d | ||
94 | #define KS_OFMTA 0x1e | ||
95 | #define KS_OFMTB 0x1f | ||
96 | #define KS_VBICTL 0x20 | ||
97 | #define KS_CCDAT2 0x21 | ||
98 | #define KS_CCDAT1 0x22 | ||
99 | #define KS_VBIL30 0x23 | ||
100 | #define KS_VBIL74 0x24 | ||
101 | #define KS_VBIL118 0x25 | ||
102 | #define KS_VBIL1512 0x26 | ||
103 | #define KS_TTFRAM 0x27 | ||
104 | #define KS_TESTA 0x28 | ||
105 | #define KS_UVOFFH 0x29 | ||
106 | #define KS_UVOFFL 0x2a | ||
107 | #define KS_UGAIN 0x2b | ||
108 | #define KS_VGAIN 0x2c | ||
109 | #define KS_VAVB 0x2d | ||
110 | #define KS_VAVE 0x2e | ||
111 | #define KS_CTRACK 0x2f | ||
112 | #define KS_POLCTL 0x30 | ||
113 | #define KS_REFCOD 0x31 | ||
114 | #define KS_INVALY 0x32 | ||
115 | #define KS_INVALU 0x33 | ||
116 | #define KS_INVALV 0x34 | ||
117 | #define KS_UNUSEY 0x35 | ||
118 | #define KS_UNUSEU 0x36 | ||
119 | #define KS_UNUSEV 0x37 | ||
120 | #define KS_USRSAV 0x38 | ||
121 | #define KS_USREAV 0x39 | ||
122 | #define KS_SHS1A 0x3a | ||
123 | #define KS_SHS1B 0x3b | ||
124 | #define KS_SHS1C 0x3c | ||
125 | #define KS_CMDE 0x3d | ||
126 | #define KS_VSDEL 0x3e | ||
127 | #define KS_CMDF 0x3f | ||
128 | #define KS_GAMMA0 0x40 | ||
129 | #define KS_GAMMA1 0x41 | ||
130 | #define KS_GAMMA2 0x42 | ||
131 | #define KS_GAMMA3 0x43 | ||
132 | #define KS_GAMMA4 0x44 | ||
133 | #define KS_GAMMA5 0x45 | ||
134 | #define KS_GAMMA6 0x46 | ||
135 | #define KS_GAMMA7 0x47 | ||
136 | #define KS_GAMMA8 0x48 | ||
137 | #define KS_GAMMA9 0x49 | ||
138 | #define KS_GAMMA10 0x4a | ||
139 | #define KS_GAMMA11 0x4b | ||
140 | #define KS_GAMMA12 0x4c | ||
141 | #define KS_GAMMA13 0x4d | ||
142 | #define KS_GAMMA14 0x4e | ||
143 | #define KS_GAMMA15 0x4f | ||
144 | #define KS_GAMMA16 0x50 | ||
145 | #define KS_GAMMA17 0x51 | ||
146 | #define KS_GAMMA18 0x52 | ||
147 | #define KS_GAMMA19 0x53 | ||
148 | #define KS_GAMMA20 0x54 | ||
149 | #define KS_GAMMA21 0x55 | ||
150 | #define KS_GAMMA22 0x56 | ||
151 | #define KS_GAMMA23 0x57 | ||
152 | #define KS_GAMMA24 0x58 | ||
153 | #define KS_GAMMA25 0x59 | ||
154 | #define KS_GAMMA26 0x5a | ||
155 | #define KS_GAMMA27 0x5b | ||
156 | #define KS_GAMMA28 0x5c | ||
157 | #define KS_GAMMA29 0x5d | ||
158 | #define KS_GAMMA30 0x5e | ||
159 | #define KS_GAMMA31 0x5f | ||
160 | #define KS_GAMMAD0 0x60 | ||
161 | #define KS_GAMMAD1 0x61 | ||
162 | #define KS_GAMMAD2 0x62 | ||
163 | #define KS_GAMMAD3 0x63 | ||
164 | #define KS_GAMMAD4 0x64 | ||
165 | #define KS_GAMMAD5 0x65 | ||
166 | #define KS_GAMMAD6 0x66 | ||
167 | #define KS_GAMMAD7 0x67 | ||
168 | #define KS_GAMMAD8 0x68 | ||
169 | #define KS_GAMMAD9 0x69 | ||
170 | #define KS_GAMMAD10 0x6a | ||
171 | #define KS_GAMMAD11 0x6b | ||
172 | #define KS_GAMMAD12 0x6c | ||
173 | #define KS_GAMMAD13 0x6d | ||
174 | #define KS_GAMMAD14 0x6e | ||
175 | #define KS_GAMMAD15 0x6f | ||
176 | #define KS_GAMMAD16 0x70 | ||
177 | #define KS_GAMMAD17 0x71 | ||
178 | #define KS_GAMMAD18 0x72 | ||
179 | #define KS_GAMMAD19 0x73 | ||
180 | #define KS_GAMMAD20 0x74 | ||
181 | #define KS_GAMMAD21 0x75 | ||
182 | #define KS_GAMMAD22 0x76 | ||
183 | #define KS_GAMMAD23 0x77 | ||
184 | #define KS_GAMMAD24 0x78 | ||
185 | #define KS_GAMMAD25 0x79 | ||
186 | #define KS_GAMMAD26 0x7a | ||
187 | #define KS_GAMMAD27 0x7b | ||
188 | #define KS_GAMMAD28 0x7c | ||
189 | #define KS_GAMMAD29 0x7d | ||
190 | #define KS_GAMMAD30 0x7e | ||
191 | #define KS_GAMMAD31 0x7f | ||
192 | |||
193 | |||
194 | /**************************************************************************** | ||
195 | * mga_dev : represents one ks0127 chip. | ||
196 | ****************************************************************************/ | ||
197 | |||
198 | struct adjust { | ||
199 | int contrast; | ||
200 | int bright; | ||
201 | int hue; | ||
202 | int ugain; | ||
203 | int vgain; | ||
204 | }; | ||
205 | |||
206 | struct ks0127 { | ||
207 | struct i2c_client *client; | ||
208 | unsigned char addr; | ||
209 | int format_width; | ||
210 | int format_height; | ||
211 | int cap_width; | ||
212 | int cap_height; | ||
213 | int norm; | ||
214 | int ks_type; | ||
215 | u8 regs[256]; | ||
216 | }; | ||
217 | |||
218 | |||
219 | static int debug; /* insmod parameter */ | ||
220 | |||
221 | module_param(debug, int, 0); | ||
222 | MODULE_PARM_DESC(debug, "Debug output"); | ||
223 | MODULE_LICENSE("GPL"); | ||
224 | |||
225 | static u8 reg_defaults[64]; | ||
226 | |||
227 | |||
228 | |||
229 | static void init_reg_defaults(void) | ||
230 | { | ||
231 | u8 *table = reg_defaults; | ||
232 | |||
233 | table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */ | ||
234 | table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */ | ||
235 | table[KS_CMDC] = 0x00; /* Test options */ | ||
236 | /* clock & input select, write 1 to PORTA */ | ||
237 | table[KS_CMDD] = 0x01; | ||
238 | table[KS_HAVB] = 0x00; /* HAV Start Control */ | ||
239 | table[KS_HAVE] = 0x00; /* HAV End Control */ | ||
240 | table[KS_HS1B] = 0x10; /* HS1 Start Control */ | ||
241 | table[KS_HS1E] = 0x00; /* HS1 End Control */ | ||
242 | table[KS_HS2B] = 0x00; /* HS2 Start Control */ | ||
243 | table[KS_HS2E] = 0x00; /* HS2 End Control */ | ||
244 | table[KS_AGC] = 0x53; /* Manual setting for AGC */ | ||
245 | table[KS_HXTRA] = 0x00; /* Extra Bits for HAV and HS1/2 */ | ||
246 | table[KS_CDEM] = 0x00; /* Chroma Demodulation Control */ | ||
247 | table[KS_PORTAB] = 0x0f; /* port B is input, port A output GPPORT */ | ||
248 | table[KS_LUMA] = 0x01; /* Luma control */ | ||
249 | table[KS_CON] = 0x00; /* Contrast Control */ | ||
250 | table[KS_BRT] = 0x00; /* Brightness Control */ | ||
251 | table[KS_CHROMA] = 0x2a; /* Chroma control A */ | ||
252 | table[KS_CHROMB] = 0x90; /* Chroma control B */ | ||
253 | table[KS_DEMOD] = 0x00; /* Chroma Demodulation Control & Status */ | ||
254 | table[KS_SAT] = 0x00; /* Color Saturation Control*/ | ||
255 | table[KS_HUE] = 0x00; /* Hue Control */ | ||
256 | table[KS_VERTIA] = 0x00; /* Vertical Processing Control A */ | ||
257 | /* Vertical Processing Control B, luma 1 line delayed */ | ||
258 | table[KS_VERTIB] = 0x12; | ||
259 | table[KS_VERTIC] = 0x0b; /* Vertical Processing Control C */ | ||
260 | table[KS_HSCLL] = 0x00; /* Horizontal Scaling Ratio Low */ | ||
261 | table[KS_HSCLH] = 0x00; /* Horizontal Scaling Ratio High */ | ||
262 | table[KS_VSCLL] = 0x00; /* Vertical Scaling Ratio Low */ | ||
263 | table[KS_VSCLH] = 0x00; /* Vertical Scaling Ratio High */ | ||
264 | /* 16 bit YCbCr 4:2:2 output; I can't make the bt866 like 8 bit /Sam */ | ||
265 | table[KS_OFMTA] = 0x30; | ||
266 | table[KS_OFMTB] = 0x00; /* Output Control B */ | ||
267 | /* VBI Decoder Control; 4bit fmt: avoid Y overflow */ | ||
268 | table[KS_VBICTL] = 0x5d; | ||
269 | table[KS_CCDAT2] = 0x00; /* Read Only register */ | ||
270 | table[KS_CCDAT1] = 0x00; /* Read Only register */ | ||
271 | table[KS_VBIL30] = 0xa8; /* VBI data decoding options */ | ||
272 | table[KS_VBIL74] = 0xaa; /* VBI data decoding options */ | ||
273 | table[KS_VBIL118] = 0x2a; /* VBI data decoding options */ | ||
274 | table[KS_VBIL1512] = 0x00; /* VBI data decoding options */ | ||
275 | table[KS_TTFRAM] = 0x00; /* Teletext frame alignment pattern */ | ||
276 | table[KS_TESTA] = 0x00; /* test register, shouldn't be written */ | ||
277 | table[KS_UVOFFH] = 0x00; /* UV Offset Adjustment High */ | ||
278 | table[KS_UVOFFL] = 0x00; /* UV Offset Adjustment Low */ | ||
279 | table[KS_UGAIN] = 0x00; /* U Component Gain Adjustment */ | ||
280 | table[KS_VGAIN] = 0x00; /* V Component Gain Adjustment */ | ||
281 | table[KS_VAVB] = 0x07; /* VAV Begin */ | ||
282 | table[KS_VAVE] = 0x00; /* VAV End */ | ||
283 | table[KS_CTRACK] = 0x00; /* Chroma Tracking Control */ | ||
284 | table[KS_POLCTL] = 0x41; /* Timing Signal Polarity Control */ | ||
285 | table[KS_REFCOD] = 0x80; /* Reference Code Insertion Control */ | ||
286 | table[KS_INVALY] = 0x10; /* Invalid Y Code */ | ||
287 | table[KS_INVALU] = 0x80; /* Invalid U Code */ | ||
288 | table[KS_INVALV] = 0x80; /* Invalid V Code */ | ||
289 | table[KS_UNUSEY] = 0x10; /* Unused Y Code */ | ||
290 | table[KS_UNUSEU] = 0x80; /* Unused U Code */ | ||
291 | table[KS_UNUSEV] = 0x80; /* Unused V Code */ | ||
292 | table[KS_USRSAV] = 0x00; /* reserved */ | ||
293 | table[KS_USREAV] = 0x00; /* reserved */ | ||
294 | table[KS_SHS1A] = 0x00; /* User Defined SHS1 A */ | ||
295 | /* User Defined SHS1 B, ALT656=1 on 0127B */ | ||
296 | table[KS_SHS1B] = 0x80; | ||
297 | table[KS_SHS1C] = 0x00; /* User Defined SHS1 C */ | ||
298 | table[KS_CMDE] = 0x00; /* Command Register E */ | ||
299 | table[KS_VSDEL] = 0x00; /* VS Delay Control */ | ||
300 | /* Command Register F, update -immediately- */ | ||
301 | /* (there might come no vsync)*/ | ||
302 | table[KS_CMDF] = 0x02; | ||
303 | } | ||
304 | |||
305 | |||
306 | /* We need to manually read because of a bug in the KS0127 chip. | ||
307 | * | ||
308 | * An explanation from kayork@mail.utexas.edu: | ||
309 | * | ||
310 | * During I2C reads, the KS0127 only samples for a stop condition | ||
311 | * during the place where the acknoledge bit should be. Any standard | ||
312 | * I2C implementation (correctly) throws in another clock transition | ||
313 | * at the 9th bit, and the KS0127 will not recognize the stop condition | ||
314 | * and will continue to clock out data. | ||
315 | * | ||
316 | * So we have to do the read ourself. Big deal. | ||
317 | workaround in i2c-algo-bit | ||
318 | */ | ||
319 | |||
320 | |||
321 | static u8 ks0127_read(struct ks0127 *ks, u8 reg) | ||
322 | { | ||
323 | struct i2c_client *c = ks->client; | ||
324 | char val = 0; | ||
325 | struct i2c_msg msgs[] = { | ||
326 | {c->addr, 0, sizeof(reg), ®}, | ||
327 | {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}}; | ||
328 | int ret; | ||
329 | |||
330 | ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs)); | ||
331 | if (ret != ARRAY_SIZE(msgs)) | ||
332 | dprintk("ks0127_write error\n"); | ||
333 | |||
334 | return val; | ||
335 | } | ||
336 | |||
337 | |||
338 | static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val) | ||
339 | { | ||
340 | char msg[] = {reg, val}; | ||
341 | |||
342 | if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg)) | ||
343 | dprintk("ks0127_write error\n"); | ||
344 | |||
345 | ks->regs[reg] = val; | ||
346 | } | ||
347 | |||
348 | |||
349 | /* generic bit-twiddling */ | ||
350 | static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v) | ||
351 | { | ||
352 | u8 val = ks->regs[reg]; | ||
353 | val = (val & and_v) | or_v; | ||
354 | ks0127_write(ks, reg, val); | ||
355 | } | ||
356 | |||
357 | |||
358 | |||
359 | /**************************************************************************** | ||
360 | * ks0127 private api | ||
361 | ****************************************************************************/ | ||
362 | static void ks0127_reset(struct ks0127* ks) | ||
363 | { | ||
364 | int i; | ||
365 | u8 *table = reg_defaults; | ||
366 | |||
367 | ks->ks_type = KS_TYPE_UNKNOWN; | ||
368 | |||
369 | dprintk("ks0127: reset\n"); | ||
370 | msleep(1); | ||
371 | |||
372 | /* initialize all registers to known values */ | ||
373 | /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */ | ||
374 | |||
375 | for(i = 1; i < 33; i++) | ||
376 | ks0127_write(ks, i, table[i]); | ||
377 | |||
378 | for(i = 35; i < 40; i++) | ||
379 | ks0127_write(ks, i, table[i]); | ||
380 | |||
381 | for(i = 41; i < 56; i++) | ||
382 | ks0127_write(ks, i, table[i]); | ||
383 | |||
384 | for(i = 58; i < 64; i++) | ||
385 | ks0127_write(ks, i, table[i]); | ||
386 | |||
387 | |||
388 | if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) { | ||
389 | ks->ks_type = KS_TYPE_0122S; | ||
390 | dprintk("ks0127: ks0122s Found\n"); | ||
391 | return; | ||
392 | } | ||
393 | |||
394 | switch(ks0127_read(ks, KS_CMDE) & 0x0f) { | ||
395 | |||
396 | case 0: | ||
397 | ks->ks_type = KS_TYPE_0127; | ||
398 | dprintk("ks0127: ks0127 found\n"); | ||
399 | break; | ||
400 | |||
401 | case 9: | ||
402 | ks->ks_type = KS_TYPE_0127B; | ||
403 | dprintk("ks0127: ks0127B Revision A found\n"); | ||
404 | break; | ||
405 | |||
406 | default: | ||
407 | dprintk("ks0127: unknown revision\n"); | ||
408 | break; | ||
409 | } | ||
410 | } | ||
411 | |||
412 | static int ks0127_command(struct i2c_client *client, | ||
413 | unsigned int cmd, void *arg) | ||
414 | { | ||
415 | struct ks0127 *ks = i2c_get_clientdata(client); | ||
416 | |||
417 | int *iarg = (int*)arg; | ||
418 | |||
419 | int status; | ||
420 | |||
421 | if (!ks) | ||
422 | return -ENODEV; | ||
423 | |||
424 | switch (cmd) { | ||
425 | |||
426 | case DECODER_INIT: | ||
427 | dprintk("ks0127: command DECODER_INIT\n"); | ||
428 | ks0127_reset(ks); | ||
429 | break; | ||
430 | |||
431 | case DECODER_SET_INPUT: | ||
432 | switch(*iarg) { | ||
433 | case KS_INPUT_COMPOSITE_1: | ||
434 | case KS_INPUT_COMPOSITE_2: | ||
435 | case KS_INPUT_COMPOSITE_3: | ||
436 | case KS_INPUT_COMPOSITE_4: | ||
437 | case KS_INPUT_COMPOSITE_5: | ||
438 | case KS_INPUT_COMPOSITE_6: | ||
439 | dprintk("ks0127: command DECODER_SET_INPUT %d: " | ||
440 | "Composite\n", *iarg); | ||
441 | /* autodetect 50/60 Hz */ | ||
442 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); | ||
443 | /* VSE=0 */ | ||
444 | ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); | ||
445 | /* set input line */ | ||
446 | ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); | ||
447 | /* non-freerunning mode */ | ||
448 | ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); | ||
449 | /* analog input */ | ||
450 | ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); | ||
451 | /* enable chroma demodulation */ | ||
452 | ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); | ||
453 | /* chroma trap, HYBWR=1 */ | ||
454 | ks0127_and_or(ks, KS_LUMA, 0x00, | ||
455 | (reg_defaults[KS_LUMA])|0x0c); | ||
456 | /* scaler fullbw, luma comb off */ | ||
457 | ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); | ||
458 | /* manual chroma comb .25 .5 .25 */ | ||
459 | ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90); | ||
460 | |||
461 | /* chroma path delay */ | ||
462 | ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90); | ||
463 | |||
464 | ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); | ||
465 | ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); | ||
466 | ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); | ||
467 | ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); | ||
468 | break; | ||
469 | |||
470 | case KS_INPUT_SVIDEO_1: | ||
471 | case KS_INPUT_SVIDEO_2: | ||
472 | case KS_INPUT_SVIDEO_3: | ||
473 | dprintk("ks0127: command DECODER_SET_INPUT %d: " | ||
474 | "S-Video\n", *iarg); | ||
475 | /* autodetect 50/60 Hz */ | ||
476 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); | ||
477 | /* VSE=0 */ | ||
478 | ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); | ||
479 | /* set input line */ | ||
480 | ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); | ||
481 | /* non-freerunning mode */ | ||
482 | ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); | ||
483 | /* analog input */ | ||
484 | ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); | ||
485 | /* enable chroma demodulation */ | ||
486 | ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); | ||
487 | ks0127_and_or(ks, KS_LUMA, 0x00, | ||
488 | reg_defaults[KS_LUMA]); | ||
489 | /* disable luma comb */ | ||
490 | ks0127_and_or(ks, KS_VERTIA, 0x08, | ||
491 | (reg_defaults[KS_VERTIA]&0xf0)|0x01); | ||
492 | ks0127_and_or(ks, KS_VERTIC, 0x0f, | ||
493 | reg_defaults[KS_VERTIC]&0xf0); | ||
494 | |||
495 | ks0127_and_or(ks, KS_CHROMB, 0x0f, | ||
496 | reg_defaults[KS_CHROMB]&0xf0); | ||
497 | |||
498 | ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); | ||
499 | ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); | ||
500 | ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); | ||
501 | ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); | ||
502 | break; | ||
503 | |||
504 | case KS_INPUT_YUV656: | ||
505 | dprintk("ks0127: command DECODER_SET_INPUT 15: " | ||
506 | "YUV656\n"); | ||
507 | if (ks->norm == VIDEO_MODE_NTSC || | ||
508 | ks->norm == KS_STD_PAL_M) | ||
509 | /* force 60 Hz */ | ||
510 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x03); | ||
511 | else | ||
512 | /* force 50 Hz */ | ||
513 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x02); | ||
514 | |||
515 | ks0127_and_or(ks, KS_CMDA, 0xff, 0x40); /* VSE=1 */ | ||
516 | /* set input line and VALIGN */ | ||
517 | ks0127_and_or(ks, KS_CMDB, 0xb0, (*iarg | 0x40)); | ||
518 | /* freerunning mode, */ | ||
519 | /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/ | ||
520 | ks0127_and_or(ks, KS_CMDC, 0x70, 0x87); | ||
521 | /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */ | ||
522 | ks0127_and_or(ks, KS_CMDD, 0x03, 0x08); | ||
523 | /* disable chroma demodulation */ | ||
524 | ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30); | ||
525 | /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */ | ||
526 | ks0127_and_or(ks, KS_LUMA, 0x00, 0x71); | ||
527 | ks0127_and_or(ks, KS_VERTIC, 0x0f, | ||
528 | reg_defaults[KS_VERTIC]&0xf0); | ||
529 | |||
530 | /* scaler fullbw, luma comb off */ | ||
531 | ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); | ||
532 | |||
533 | ks0127_and_or(ks, KS_CHROMB, 0x0f, | ||
534 | reg_defaults[KS_CHROMB]&0xf0); | ||
535 | |||
536 | ks0127_and_or(ks, KS_CON, 0x00, 0x00); | ||
537 | ks0127_and_or(ks, KS_BRT, 0x00, 32); /* spec: 34 */ | ||
538 | /* spec: 229 (e5) */ | ||
539 | ks0127_and_or(ks, KS_SAT, 0x00, 0xe8); | ||
540 | ks0127_and_or(ks, KS_HUE, 0x00, 0); | ||
541 | |||
542 | ks0127_and_or(ks, KS_UGAIN, 0x00, 238); | ||
543 | ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00); | ||
544 | |||
545 | /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */ | ||
546 | ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f); | ||
547 | ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00); | ||
548 | break; | ||
549 | |||
550 | default: | ||
551 | dprintk("ks0127: command DECODER_SET_INPUT: " | ||
552 | "Unknown input %d\n", *iarg); | ||
553 | break; | ||
554 | } | ||
555 | |||
556 | /* hack: CDMLPF sometimes spontaneously switches on; */ | ||
557 | /* force back off */ | ||
558 | ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]); | ||
559 | break; | ||
560 | |||
561 | case DECODER_SET_OUTPUT: | ||
562 | switch(*iarg) { | ||
563 | case KS_OUTPUT_YUV656E: | ||
564 | dprintk("ks0127: command DECODER_SET_OUTPUT: " | ||
565 | "OUTPUT_YUV656E (Missing)\n"); | ||
566 | return -EINVAL; | ||
567 | break; | ||
568 | |||
569 | case KS_OUTPUT_EXV: | ||
570 | dprintk("ks0127: command DECODER_SET_OUTPUT: " | ||
571 | "OUTPUT_EXV\n"); | ||
572 | ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09); | ||
573 | break; | ||
574 | } | ||
575 | break; | ||
576 | |||
577 | case DECODER_SET_NORM: //sam This block mixes old and new norm names... | ||
578 | /* Set to automatic SECAM/Fsc mode */ | ||
579 | ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); | ||
580 | |||
581 | ks->norm = *iarg; | ||
582 | switch(*iarg) | ||
583 | { | ||
584 | /* this is untested !! */ | ||
585 | /* It just detects PAL_N/NTSC_M (no special frequencies) */ | ||
586 | /* And you have to set the standard a second time afterwards */ | ||
587 | case VIDEO_MODE_AUTO: | ||
588 | dprintk("ks0127: command DECODER_SET_NORM: AUTO\n"); | ||
589 | |||
590 | /* The chip determines the format */ | ||
591 | /* based on the current field rate */ | ||
592 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); | ||
593 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); | ||
594 | /* This is wrong for PAL ! As I said, */ | ||
595 | /* you need to set the standard once again !! */ | ||
596 | ks->format_height = 240; | ||
597 | ks->format_width = 704; | ||
598 | break; | ||
599 | |||
600 | case VIDEO_MODE_NTSC: | ||
601 | dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n"); | ||
602 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); | ||
603 | ks->format_height = 240; | ||
604 | ks->format_width = 704; | ||
605 | break; | ||
606 | |||
607 | case KS_STD_NTSC_N: | ||
608 | dprintk("ks0127: command KS0127_SET_STANDARD: " | ||
609 | "NTSC_N (fixme)\n"); | ||
610 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); | ||
611 | ks->format_height = 240; | ||
612 | ks->format_width = 704; | ||
613 | break; | ||
614 | |||
615 | case VIDEO_MODE_PAL: | ||
616 | dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n"); | ||
617 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); | ||
618 | ks->format_height = 290; | ||
619 | ks->format_width = 704; | ||
620 | break; | ||
621 | |||
622 | case KS_STD_PAL_M: | ||
623 | dprintk("ks0127: command KS0127_SET_STANDARD: " | ||
624 | "PAL_M (fixme)\n"); | ||
625 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); | ||
626 | ks->format_height = 290; | ||
627 | ks->format_width = 704; | ||
628 | break; | ||
629 | |||
630 | case VIDEO_MODE_SECAM: | ||
631 | dprintk("ks0127: command KS0127_SET_STANDARD: " | ||
632 | "SECAM\n"); | ||
633 | ks->format_height = 290; | ||
634 | ks->format_width = 704; | ||
635 | |||
636 | /* set to secam autodetection */ | ||
637 | ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20); | ||
638 | ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); | ||
639 | schedule_timeout_interruptible(HZ/10+1); | ||
640 | |||
641 | /* did it autodetect? */ | ||
642 | if (ks0127_read(ks, KS_DEMOD) & 0x40) | ||
643 | break; | ||
644 | |||
645 | /* force to secam mode */ | ||
646 | ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f); | ||
647 | break; | ||
648 | |||
649 | default: | ||
650 | dprintk("ks0127: command DECODER_SET_NORM: " | ||
651 | "Unknown norm %d\n", *iarg); | ||
652 | break; | ||
653 | } | ||
654 | break; | ||
655 | |||
656 | case DECODER_SET_PICTURE: | ||
657 | dprintk("ks0127: command DECODER_SET_PICTURE " | ||
658 | "not yet supported (fixme)\n"); | ||
659 | return -EINVAL; | ||
660 | |||
661 | //sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE | ||
662 | //sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE | ||
663 | //sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? | ||
664 | //sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE | ||
665 | //sam todo: KS0127_SET_AGC_MODE: | ||
666 | //sam todo: KS0127_SET_AGC: | ||
667 | //sam todo: KS0127_SET_CHROMA_MODE: | ||
668 | //sam todo: KS0127_SET_PIXCLK_MODE: | ||
669 | //sam todo: KS0127_SET_GAMMA_MODE: | ||
670 | //sam todo: KS0127_SET_UGAIN: | ||
671 | //sam todo: KS0127_SET_VGAIN: | ||
672 | //sam todo: KS0127_SET_INVALY: | ||
673 | //sam todo: KS0127_SET_INVALU: | ||
674 | //sam todo: KS0127_SET_INVALV: | ||
675 | //sam todo: KS0127_SET_UNUSEY: | ||
676 | //sam todo: KS0127_SET_UNUSEU: | ||
677 | //sam todo: KS0127_SET_UNUSEV: | ||
678 | //sam todo: KS0127_SET_VSALIGN_MODE: | ||
679 | |||
680 | case DECODER_ENABLE_OUTPUT: | ||
681 | { | ||
682 | |||
683 | int *iarg = arg; | ||
684 | int enable = (*iarg != 0); | ||
685 | if (enable) { | ||
686 | dprintk("ks0127: command " | ||
687 | "DECODER_ENABLE_OUTPUT on " | ||
688 | "(%d)\n", enable); | ||
689 | /* All output pins on */ | ||
690 | ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30); | ||
691 | /* Obey the OEN pin */ | ||
692 | ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00); | ||
693 | } else { | ||
694 | dprintk("ks0127: command " | ||
695 | "DECODER_ENABLE_OUTPUT off " | ||
696 | "(%d)\n", enable); | ||
697 | /* Video output pins off */ | ||
698 | ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00); | ||
699 | /* Ignore the OEN pin */ | ||
700 | ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80); | ||
701 | } | ||
702 | } | ||
703 | break; | ||
704 | |||
705 | //sam todo: KS0127_SET_OUTPUT_MODE: | ||
706 | //sam todo: KS0127_SET_WIDTH: | ||
707 | //sam todo: KS0127_SET_HEIGHT: | ||
708 | //sam todo: KS0127_SET_HSCALE: | ||
709 | |||
710 | case DECODER_GET_STATUS: | ||
711 | dprintk("ks0127: command DECODER_GET_STATUS\n"); | ||
712 | *iarg = 0; | ||
713 | status = ks0127_read(ks, KS_STAT); | ||
714 | if (!(status & 0x20)) /* NOVID not set */ | ||
715 | *iarg = (*iarg & DECODER_STATUS_GOOD); | ||
716 | if ((status & 0x01)) /* CLOCK set */ | ||
717 | *iarg = (*iarg & DECODER_STATUS_COLOR); | ||
718 | if ((status & 0x08)) /* PALDET set */ | ||
719 | *iarg = (*iarg & DECODER_STATUS_PAL); | ||
720 | else | ||
721 | *iarg = (*iarg & DECODER_STATUS_NTSC); | ||
722 | break; | ||
723 | |||
724 | //Catch any unknown command | ||
725 | default: | ||
726 | dprintk("ks0127: command unknown: %04X\n", cmd); | ||
727 | return -EINVAL; | ||
728 | } | ||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | |||
733 | |||
734 | |||
735 | static int ks0127_probe(struct i2c_adapter *adapter); | ||
736 | static int ks0127_detach(struct i2c_client *client); | ||
737 | static int ks0127_command(struct i2c_client *client, | ||
738 | unsigned int cmd, void *arg); | ||
739 | |||
740 | |||
741 | |||
742 | /* Addresses to scan */ | ||
743 | static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1, | ||
744 | I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END}; | ||
745 | static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; | ||
746 | static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; | ||
747 | static struct i2c_client_address_data addr_data = { | ||
748 | normal_i2c, | ||
749 | probe, | ||
750 | ignore, | ||
751 | }; | ||
752 | |||
753 | static struct i2c_driver i2c_driver_ks0127 = { | ||
754 | .driver.name = "ks0127", | ||
755 | .id = I2C_DRIVERID_KS0127, | ||
756 | .attach_adapter = ks0127_probe, | ||
757 | .detach_client = ks0127_detach, | ||
758 | .command = ks0127_command | ||
759 | }; | ||
760 | |||
761 | static struct i2c_client ks0127_client_tmpl = | ||
762 | { | ||
763 | .name = "(ks0127 unset)", | ||
764 | .addr = 0, | ||
765 | .adapter = NULL, | ||
766 | .driver = &i2c_driver_ks0127, | ||
767 | .usage_count = 0 | ||
768 | }; | ||
769 | |||
770 | static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind) | ||
771 | { | ||
772 | struct ks0127 *ks; | ||
773 | struct i2c_client *client; | ||
774 | |||
775 | client = kzalloc(sizeof(*client), GFP_KERNEL); | ||
776 | if (client == NULL) | ||
777 | return -ENOMEM; | ||
778 | memcpy(client, &ks0127_client_tmpl, sizeof(*client)); | ||
779 | |||
780 | ks = kzalloc(sizeof(*ks), GFP_KERNEL); | ||
781 | if (ks == NULL) { | ||
782 | kfree(client); | ||
783 | return -ENOMEM; | ||
784 | } | ||
785 | |||
786 | i2c_set_clientdata(client, ks); | ||
787 | client->adapter = adapter; | ||
788 | client->addr = addr; | ||
789 | sprintf(client->name, "ks0127-%02x", adapter->id); | ||
790 | |||
791 | ks->client = client; | ||
792 | ks->addr = addr; | ||
793 | ks->ks_type = KS_TYPE_UNKNOWN; | ||
794 | |||
795 | /* power up */ | ||
796 | ks0127_write(ks, KS_CMDA, 0x2c); | ||
797 | mdelay(10); | ||
798 | |||
799 | /* reset the device */ | ||
800 | ks0127_reset(ks); | ||
801 | printk(KERN_INFO "ks0127: attach: %s video decoder\n", | ||
802 | ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board"); | ||
803 | |||
804 | i2c_attach_client(client); | ||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | |||
809 | static int ks0127_probe(struct i2c_adapter *adapter) | ||
810 | { | ||
811 | if (adapter->id == I2C_HW_B_ZR36067) | ||
812 | return i2c_probe(adapter, &addr_data, ks0127_found_proc); | ||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | static int ks0127_detach(struct i2c_client *client) | ||
817 | { | ||
818 | struct ks0127 *ks = i2c_get_clientdata(client); | ||
819 | |||
820 | ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/ | ||
821 | ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */ | ||
822 | |||
823 | i2c_detach_client(client); | ||
824 | kfree(ks); | ||
825 | kfree(client); | ||
826 | |||
827 | dprintk("ks0127: detach\n"); | ||
828 | return 0; | ||
829 | } | ||
830 | |||
831 | |||
832 | static int __devinit ks0127_init_module(void) | ||
833 | { | ||
834 | init_reg_defaults(); | ||
835 | i2c_add_driver(&i2c_driver_ks0127); | ||
836 | return 0; | ||
837 | } | ||
838 | |||
839 | static void __devexit ks0127_cleanup_module(void) | ||
840 | { | ||
841 | i2c_del_driver(&i2c_driver_ks0127); | ||
842 | } | ||
843 | |||
844 | |||
845 | module_init(ks0127_init_module); | ||
846 | module_exit(ks0127_cleanup_module); | ||
diff --git a/drivers/media/video/ks0127.h b/drivers/media/video/ks0127.h new file mode 100644 index 000000000000..1ec578833aea --- /dev/null +++ b/drivers/media/video/ks0127.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Video Capture Driver ( Video for Linux 1/2 ) | ||
3 | * for the Matrox Marvel G200,G400 and Rainbow Runner-G series | ||
4 | * | ||
5 | * This module is an interface to the KS0127 video decoder chip. | ||
6 | * | ||
7 | * Copyright (C) 1999 Ryan Drake <stiletto@mediaone.net> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version 2 | ||
12 | * of the License, or (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef KS0127_H | ||
25 | #define KS0127_H | ||
26 | |||
27 | #include <linux/videodev.h> | ||
28 | |||
29 | /* input channels */ | ||
30 | #define KS_INPUT_COMPOSITE_1 0 | ||
31 | #define KS_INPUT_COMPOSITE_2 1 | ||
32 | #define KS_INPUT_COMPOSITE_3 2 | ||
33 | #define KS_INPUT_COMPOSITE_4 4 | ||
34 | #define KS_INPUT_COMPOSITE_5 5 | ||
35 | #define KS_INPUT_COMPOSITE_6 6 | ||
36 | |||
37 | #define KS_INPUT_SVIDEO_1 8 | ||
38 | #define KS_INPUT_SVIDEO_2 9 | ||
39 | #define KS_INPUT_SVIDEO_3 10 | ||
40 | |||
41 | #define KS_INPUT_YUV656 15 | ||
42 | #define KS_INPUT_COUNT 10 | ||
43 | |||
44 | /* output channels */ | ||
45 | #define KS_OUTPUT_YUV656E 0 | ||
46 | #define KS_OUTPUT_EXV 1 | ||
47 | |||
48 | /* video standards */ | ||
49 | #define KS_STD_NTSC_N 112 /* 50 Hz NTSC */ | ||
50 | #define KS_STD_PAL_M 113 /* 60 Hz PAL */ | ||
51 | |||
52 | #endif /* KS0127_H */ | ||
53 | |||
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 850bee97090c..f68ca7d9f531 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/videodev.h> | 34 | #include <linux/videodev.h> |
35 | #include <media/v4l2-common.h> | ||
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
36 | #include <asm/io.h> | 37 | #include <asm/io.h> |
37 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
@@ -1682,13 +1683,13 @@ static unsigned int meye_poll(struct file *file, poll_table *wait) | |||
1682 | 1683 | ||
1683 | static void meye_vm_open(struct vm_area_struct *vma) | 1684 | static void meye_vm_open(struct vm_area_struct *vma) |
1684 | { | 1685 | { |
1685 | int idx = (int)vma->vm_private_data; | 1686 | long idx = (long)vma->vm_private_data; |
1686 | meye.vma_use_count[idx]++; | 1687 | meye.vma_use_count[idx]++; |
1687 | } | 1688 | } |
1688 | 1689 | ||
1689 | static void meye_vm_close(struct vm_area_struct *vma) | 1690 | static void meye_vm_close(struct vm_area_struct *vma) |
1690 | { | 1691 | { |
1691 | int idx = (int)vma->vm_private_data; | 1692 | long idx = (long)vma->vm_private_data; |
1692 | meye.vma_use_count[idx]--; | 1693 | meye.vma_use_count[idx]--; |
1693 | } | 1694 | } |
1694 | 1695 | ||
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index b806999d6e0f..dbb75a7db199 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -385,67 +385,6 @@ static int msp_mode_v4l1_to_v4l2(int mode) | |||
385 | return V4L2_TUNER_MODE_MONO; | 385 | return V4L2_TUNER_MODE_MONO; |
386 | } | 386 | } |
387 | 387 | ||
388 | static struct v4l2_queryctrl msp_qctrl_std[] = { | ||
389 | { | ||
390 | .id = V4L2_CID_AUDIO_VOLUME, | ||
391 | .name = "Volume", | ||
392 | .minimum = 0, | ||
393 | .maximum = 65535, | ||
394 | .step = 65535/100, | ||
395 | .default_value = 58880, | ||
396 | .flags = 0, | ||
397 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
398 | },{ | ||
399 | .id = V4L2_CID_AUDIO_MUTE, | ||
400 | .name = "Mute", | ||
401 | .minimum = 0, | ||
402 | .maximum = 1, | ||
403 | .step = 1, | ||
404 | .default_value = 1, | ||
405 | .flags = 0, | ||
406 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
407 | }, | ||
408 | }; | ||
409 | |||
410 | static struct v4l2_queryctrl msp_qctrl_sound_processing[] = { | ||
411 | { | ||
412 | .id = V4L2_CID_AUDIO_BALANCE, | ||
413 | .name = "Balance", | ||
414 | .minimum = 0, | ||
415 | .maximum = 65535, | ||
416 | .step = 65535/100, | ||
417 | .default_value = 32768, | ||
418 | .flags = 0, | ||
419 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
420 | },{ | ||
421 | .id = V4L2_CID_AUDIO_BASS, | ||
422 | .name = "Bass", | ||
423 | .minimum = 0, | ||
424 | .maximum = 65535, | ||
425 | .step = 65535/100, | ||
426 | .default_value = 32768, | ||
427 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
428 | },{ | ||
429 | .id = V4L2_CID_AUDIO_TREBLE, | ||
430 | .name = "Treble", | ||
431 | .minimum = 0, | ||
432 | .maximum = 65535, | ||
433 | .step = 65535/100, | ||
434 | .default_value = 32768, | ||
435 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
436 | },{ | ||
437 | .id = V4L2_CID_AUDIO_LOUDNESS, | ||
438 | .name = "Loudness", | ||
439 | .minimum = 0, | ||
440 | .maximum = 1, | ||
441 | .step = 1, | ||
442 | .default_value = 1, | ||
443 | .flags = 0, | ||
444 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
445 | }, | ||
446 | }; | ||
447 | |||
448 | |||
449 | static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | 388 | static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) |
450 | { | 389 | { |
451 | struct msp_state *state = i2c_get_clientdata(client); | 390 | struct msp_state *state = i2c_get_clientdata(client); |
@@ -674,22 +613,31 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
674 | int sc1_out = rt->output & 0xf; | 613 | int sc1_out = rt->output & 0xf; |
675 | int sc2_out = (rt->output >> 4) & 0xf; | 614 | int sc2_out = (rt->output >> 4) & 0xf; |
676 | u16 val, reg; | 615 | u16 val, reg; |
616 | int i; | ||
617 | int extern_input = 1; | ||
677 | 618 | ||
678 | if (state->routing.input == rt->input && | 619 | if (state->routing.input == rt->input && |
679 | state->routing.output == rt->output) | 620 | state->routing.output == rt->output) |
680 | break; | 621 | break; |
681 | state->routing = *rt; | 622 | state->routing = *rt; |
623 | /* check if the tuner input is used */ | ||
624 | for (i = 0; i < 5; i++) { | ||
625 | if (((rt->input >> (4 + i * 4)) & 0xf) == 0) | ||
626 | extern_input = 0; | ||
627 | } | ||
628 | if (extern_input) | ||
629 | state->mode = MSP_MODE_EXTERN; | ||
630 | else | ||
631 | state->mode = MSP_MODE_AM_DETECT; | ||
682 | msp_set_scart(client, sc_in, 0); | 632 | msp_set_scart(client, sc_in, 0); |
683 | msp_set_scart(client, sc1_out, 1); | 633 | msp_set_scart(client, sc1_out, 1); |
684 | msp_set_scart(client, sc2_out, 2); | 634 | msp_set_scart(client, sc2_out, 2); |
685 | msp_set_audmode(client); | 635 | msp_set_audmode(client); |
686 | reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb; | 636 | reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb; |
687 | val = msp_read_dem(client, reg); | 637 | val = msp_read_dem(client, reg); |
688 | if (tuner != ((val >> 8) & 1)) { | 638 | msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8)); |
689 | msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8)); | 639 | /* wake thread when a new input is chosen */ |
690 | /* wake thread when a new tuner input is chosen */ | 640 | msp_wake_thread(client); |
691 | msp_wake_thread(client); | ||
692 | } | ||
693 | break; | 641 | break; |
694 | } | 642 | } |
695 | 643 | ||
@@ -744,21 +692,25 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
744 | case VIDIOC_QUERYCTRL: | 692 | case VIDIOC_QUERYCTRL: |
745 | { | 693 | { |
746 | struct v4l2_queryctrl *qc = arg; | 694 | struct v4l2_queryctrl *qc = arg; |
747 | int i; | ||
748 | 695 | ||
749 | for (i = 0; i < ARRAY_SIZE(msp_qctrl_std); i++) | 696 | switch (qc->id) { |
750 | if (qc->id && qc->id == msp_qctrl_std[i].id) { | 697 | case V4L2_CID_AUDIO_VOLUME: |
751 | memcpy(qc, &msp_qctrl_std[i], sizeof(*qc)); | 698 | case V4L2_CID_AUDIO_MUTE: |
752 | return 0; | 699 | return v4l2_ctrl_query_fill_std(qc); |
753 | } | 700 | default: |
701 | break; | ||
702 | } | ||
754 | if (!state->has_sound_processing) | 703 | if (!state->has_sound_processing) |
755 | return -EINVAL; | 704 | return -EINVAL; |
756 | for (i = 0; i < ARRAY_SIZE(msp_qctrl_sound_processing); i++) | 705 | switch (qc->id) { |
757 | if (qc->id && qc->id == msp_qctrl_sound_processing[i].id) { | 706 | case V4L2_CID_AUDIO_LOUDNESS: |
758 | memcpy(qc, &msp_qctrl_sound_processing[i], sizeof(*qc)); | 707 | case V4L2_CID_AUDIO_BALANCE: |
759 | return 0; | 708 | case V4L2_CID_AUDIO_BASS: |
760 | } | 709 | case V4L2_CID_AUDIO_TREBLE: |
761 | return -EINVAL; | 710 | return v4l2_ctrl_query_fill_std(qc); |
711 | default: | ||
712 | return -EINVAL; | ||
713 | } | ||
762 | } | 714 | } |
763 | 715 | ||
764 | case VIDIOC_G_CTRL: | 716 | case VIDIOC_G_CTRL: |
@@ -794,7 +746,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
794 | case MSP_MODE_EXTERN: p = "External input"; break; | 746 | case MSP_MODE_EXTERN: p = "External input"; break; |
795 | default: p = "unknown"; break; | 747 | default: p = "unknown"; break; |
796 | } | 748 | } |
797 | if (state->opmode == OPMODE_MANUAL) { | 749 | if (state->mode == MSP_MODE_EXTERN) { |
750 | v4l_info(client, "Mode: %s\n", p); | ||
751 | } else if (state->opmode == OPMODE_MANUAL) { | ||
798 | v4l_info(client, "Mode: %s (%s%s)\n", p, | 752 | v4l_info(client, "Mode: %s (%s%s)\n", p, |
799 | (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", | 753 | (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", |
800 | (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); | 754 | (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); |
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 633a10213789..f2fd9195b3ac 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c | |||
@@ -244,19 +244,21 @@ static void msp3400c_set_audmode(struct i2c_client *client) | |||
244 | the hardware does not support SAP. So the rxsubchans combination | 244 | the hardware does not support SAP. So the rxsubchans combination |
245 | of STEREO | LANG2 does not occur. */ | 245 | of STEREO | LANG2 does not occur. */ |
246 | 246 | ||
247 | /* switch to mono if only mono is available */ | 247 | if (state->mode != MSP_MODE_EXTERN) { |
248 | if (state->rxsubchans == V4L2_TUNER_SUB_MONO) | 248 | /* switch to mono if only mono is available */ |
249 | audmode = V4L2_TUNER_MODE_MONO; | 249 | if (state->rxsubchans == V4L2_TUNER_SUB_MONO) |
250 | /* if bilingual */ | 250 | audmode = V4L2_TUNER_MODE_MONO; |
251 | else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { | 251 | /* if bilingual */ |
252 | /* and mono or stereo, then fallback to lang1 */ | 252 | else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { |
253 | if (audmode == V4L2_TUNER_MODE_MONO || | 253 | /* and mono or stereo, then fallback to lang1 */ |
254 | audmode == V4L2_TUNER_MODE_STEREO) | 254 | if (audmode == V4L2_TUNER_MODE_MONO || |
255 | audmode = V4L2_TUNER_MODE_LANG1; | 255 | audmode == V4L2_TUNER_MODE_STEREO) |
256 | audmode = V4L2_TUNER_MODE_LANG1; | ||
257 | } | ||
258 | /* if stereo, and audmode is not mono, then switch to stereo */ | ||
259 | else if (audmode != V4L2_TUNER_MODE_MONO) | ||
260 | audmode = V4L2_TUNER_MODE_STEREO; | ||
256 | } | 261 | } |
257 | /* if stereo, and audmode is not mono, then switch to stereo */ | ||
258 | else if (audmode != V4L2_TUNER_MODE_MONO) | ||
259 | audmode = V4L2_TUNER_MODE_STEREO; | ||
260 | 262 | ||
261 | /* switch demodulator */ | 263 | /* switch demodulator */ |
262 | switch (state->mode) { | 264 | switch (state->mode) { |
@@ -481,6 +483,7 @@ int msp3400c_thread(void *data) | |||
481 | /* no carrier scan, just unmute */ | 483 | /* no carrier scan, just unmute */ |
482 | v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); | 484 | v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); |
483 | state->scan_in_progress = 0; | 485 | state->scan_in_progress = 0; |
486 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
484 | msp_set_audio(client); | 487 | msp_set_audio(client); |
485 | continue; | 488 | continue; |
486 | } | 489 | } |
@@ -947,6 +950,14 @@ int msp34xxg_thread(void *data) | |||
947 | if (kthread_should_stop()) | 950 | if (kthread_should_stop()) |
948 | break; | 951 | break; |
949 | 952 | ||
953 | if (state->mode == MSP_MODE_EXTERN) { | ||
954 | /* no carrier scan needed, just unmute */ | ||
955 | v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); | ||
956 | state->scan_in_progress = 0; | ||
957 | msp_set_audio(client); | ||
958 | continue; | ||
959 | } | ||
960 | |||
950 | /* setup the chip*/ | 961 | /* setup the chip*/ |
951 | msp34xxg_reset(client); | 962 | msp34xxg_reset(client); |
952 | state->std = state->radio ? 0x40 : msp_standard; | 963 | state->std = state->radio ? 0x40 : msp_standard; |
@@ -978,6 +989,11 @@ int msp34xxg_thread(void *data) | |||
978 | v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n", | 989 | v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n", |
979 | msp_standard_std_name(state->std), state->std); | 990 | msp_standard_std_name(state->std), state->std); |
980 | 991 | ||
992 | if (state->std == 9) { | ||
993 | /* AM NICAM mode */ | ||
994 | msp_write_dsp(client, 0x0e, 0x7c00); | ||
995 | } | ||
996 | |||
981 | /* unmute: dispatch sound to scart output, set scart volume */ | 997 | /* unmute: dispatch sound to scart output, set scart volume */ |
982 | msp_set_audio(client); | 998 | msp_set_audio(client); |
983 | 999 | ||
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index fdc8e3f13937..a988df226aab 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c | |||
@@ -3239,7 +3239,7 @@ ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n) | |||
3239 | RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); | 3239 | RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); |
3240 | 3240 | ||
3241 | if (frame->scanstate == STATE_LINES) { | 3241 | if (frame->scanstate == STATE_LINES) { |
3242 | int nextf; | 3242 | int nextf; |
3243 | 3243 | ||
3244 | frame->grabstate = FRAME_DONE; | 3244 | frame->grabstate = FRAME_DONE; |
3245 | wake_up_interruptible(&frame->wq); | 3245 | wake_up_interruptible(&frame->wq); |
@@ -3405,7 +3405,7 @@ eof: | |||
3405 | RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); | 3405 | RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); |
3406 | 3406 | ||
3407 | if (frame->scanstate == STATE_LINES) { | 3407 | if (frame->scanstate == STATE_LINES) { |
3408 | int nextf; | 3408 | int nextf; |
3409 | 3409 | ||
3410 | frame->grabstate = FRAME_DONE; | 3410 | frame->grabstate = FRAME_DONE; |
3411 | wake_up_interruptible(&frame->wq); | 3411 | wake_up_interruptible(&frame->wq); |
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h index 12b3d51e1c34..68b082bcee1d 100644 --- a/drivers/media/video/ov511.h +++ b/drivers/media/video/ov511.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <asm/uaccess.h> | 4 | #include <asm/uaccess.h> |
5 | #include <linux/videodev.h> | 5 | #include <linux/videodev.h> |
6 | #include <media/v4l2-common.h> | ||
6 | #include <linux/smp_lock.h> | 7 | #include <linux/smp_lock.h> |
7 | #include <linux/usb.h> | 8 | #include <linux/usb.h> |
8 | #include <linux/mutex.h> | 9 | #include <linux/mutex.h> |
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c index d9e3cada52f4..3484e36b6801 100644 --- a/drivers/media/video/planb.c +++ b/drivers/media/video/planb.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/mm.h> | 40 | #include <linux/mm.h> |
41 | #include <linux/sched.h> | 41 | #include <linux/sched.h> |
42 | #include <linux/videodev.h> | 42 | #include <linux/videodev.h> |
43 | #include <media/v4l2-common.h> | ||
43 | #include <linux/wait.h> | 44 | #include <linux/wait.h> |
44 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
45 | #include <asm/io.h> | 46 | #include <asm/io.h> |
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 09835ca098b1..5d681fa8bcb1 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
32 | #include <linux/videodev.h> | 32 | #include <linux/videodev.h> |
33 | #include <media/v4l2-common.h> | ||
33 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
34 | 35 | ||
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
@@ -804,7 +805,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, | |||
804 | struct video_picture *p = arg; | 805 | struct video_picture *p = arg; |
805 | if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16) | 806 | if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16) |
806 | ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15))) | 807 | ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15))) |
807 | return -EINVAL; | 808 | return -EINVAL; |
808 | pd->picture= *p; | 809 | pd->picture= *p; |
809 | 810 | ||
810 | /* | 811 | /* |
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig index 53cbc950f95c..697145e0bf15 100644 --- a/drivers/media/video/pwc/Kconfig +++ b/drivers/media/video/pwc/Kconfig | |||
@@ -7,6 +7,7 @@ config USB_PWC | |||
7 | * Philips PCA645, PCA646 | 7 | * Philips PCA645, PCA646 |
8 | * Philips PCVC675, PCVC680, PCVC690 | 8 | * Philips PCVC675, PCVC680, PCVC690 |
9 | * Philips PCVC720/40, PCVC730, PCVC740, PCVC750 | 9 | * Philips PCVC720/40, PCVC730, PCVC740, PCVC750 |
10 | * Philips SPC900NC | ||
10 | * Askey VC010 | 11 | * Askey VC010 |
11 | * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro' | 12 | * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro' |
12 | and 'Orbit'/'Sphere' | 13 | and 'Orbit'/'Sphere' |
@@ -19,10 +20,18 @@ config USB_PWC | |||
19 | and never will be, but the 665 and 720/20 are supported by other | 20 | and never will be, but the 665 and 720/20 are supported by other |
20 | drivers. | 21 | drivers. |
21 | 22 | ||
22 | See <file:Documentation/usb/philips.txt> for more information and | 23 | Some newer logitech webcams are not handled by this driver but by the |
23 | installation instructions. | 24 | Usb Video Class driver (linux-uvc). |
24 | 25 | ||
25 | The built-in microphone is enabled by selecting USB Audio support. | 26 | The built-in microphone is enabled by selecting USB Audio support. |
26 | 27 | ||
27 | To compile this driver as a module, choose M here: the | 28 | To compile this driver as a module, choose M here: the |
28 | module will be called pwc. | 29 | module will be called pwc. |
30 | |||
31 | config USB_PWC_DEBUG | ||
32 | bool "USB Philips Cameras verbose debug" | ||
33 | depends USB_PWC | ||
34 | help | ||
35 | Say Y here in order to have the pwc driver generate verbose debugging | ||
36 | messages. | ||
37 | A special module options 'trace' is used to control the verbosity. | ||
diff --git a/drivers/media/video/pwc/Makefile b/drivers/media/video/pwc/Makefile index 33d60126c024..9db2260d10cc 100644 --- a/drivers/media/video/pwc/Makefile +++ b/drivers/media/video/pwc/Makefile | |||
@@ -1,3 +1,12 @@ | |||
1 | pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o | 1 | pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-v4l.o pwc-uncompress.o |
2 | pwc-objs += pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o | ||
2 | 3 | ||
3 | obj-$(CONFIG_USB_PWC) += pwc.o | 4 | obj-$(CONFIG_USB_PWC) += pwc.o |
5 | |||
6 | ifeq ($(CONFIG_USB_PWC_DEBUG),y) | ||
7 | EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=1 | ||
8 | else | ||
9 | EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=0 | ||
10 | endif | ||
11 | |||
12 | |||
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 4ba549bfa0e0..0bd115588f31 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -2,7 +2,7 @@ | |||
2 | Functions that send various control messages to the webcam, including | 2 | Functions that send various control messages to the webcam, including |
3 | video modes. | 3 | video modes. |
4 | (C) 1999-2003 Nemosoft Unv. | 4 | (C) 1999-2003 Nemosoft Unv. |
5 | (C) 2004 Luc Saillard (luc@saillard.org) | 5 | (C) 2004-2006 Luc Saillard (luc@saillard.org) |
6 | 6 | ||
7 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | 7 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx |
8 | driver and thus may have bugs that are not present in the original version. | 8 | driver and thus may have bugs that are not present in the original version. |
@@ -41,12 +41,14 @@ | |||
41 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
42 | #endif | 42 | #endif |
43 | #include <asm/errno.h> | 43 | #include <asm/errno.h> |
44 | #include <linux/version.h> | ||
44 | 45 | ||
45 | #include "pwc.h" | 46 | #include "pwc.h" |
46 | #include "pwc-ioctl.h" | ||
47 | #include "pwc-uncompress.h" | 47 | #include "pwc-uncompress.h" |
48 | #include "pwc-kiara.h" | 48 | #include "pwc-kiara.h" |
49 | #include "pwc-timon.h" | 49 | #include "pwc-timon.h" |
50 | #include "pwc-dec1.h" | ||
51 | #include "pwc-dec23.h" | ||
50 | 52 | ||
51 | /* Request types: video */ | 53 | /* Request types: video */ |
52 | #define SET_LUM_CTL 0x01 | 54 | #define SET_LUM_CTL 0x01 |
@@ -57,6 +59,10 @@ | |||
57 | #define GET_STATUS_CTL 0x06 | 59 | #define GET_STATUS_CTL 0x06 |
58 | #define SET_EP_STREAM_CTL 0x07 | 60 | #define SET_EP_STREAM_CTL 0x07 |
59 | #define GET_EP_STREAM_CTL 0x08 | 61 | #define GET_EP_STREAM_CTL 0x08 |
62 | #define GET_XX_CTL 0x09 | ||
63 | #define SET_XX_CTL 0x0A | ||
64 | #define GET_XY_CTL 0x0B | ||
65 | #define SET_XY_CTL 0x0C | ||
60 | #define SET_MPT_CTL 0x0D | 66 | #define SET_MPT_CTL 0x0D |
61 | #define GET_MPT_CTL 0x0E | 67 | #define GET_MPT_CTL 0x0E |
62 | 68 | ||
@@ -93,12 +99,20 @@ | |||
93 | #define READ_SHUTTER_FORMATTER 0x0600 | 99 | #define READ_SHUTTER_FORMATTER 0x0600 |
94 | #define READ_RED_GAIN_FORMATTER 0x0700 | 100 | #define READ_RED_GAIN_FORMATTER 0x0700 |
95 | #define READ_BLUE_GAIN_FORMATTER 0x0800 | 101 | #define READ_BLUE_GAIN_FORMATTER 0x0800 |
102 | #define GET_STATUS_B00 0x0B00 | ||
96 | #define SENSOR_TYPE_FORMATTER1 0x0C00 | 103 | #define SENSOR_TYPE_FORMATTER1 0x0C00 |
104 | #define GET_STATUS_3000 0x3000 | ||
97 | #define READ_RAW_Y_MEAN_FORMATTER 0x3100 | 105 | #define READ_RAW_Y_MEAN_FORMATTER 0x3100 |
98 | #define SET_POWER_SAVE_MODE_FORMATTER 0x3200 | 106 | #define SET_POWER_SAVE_MODE_FORMATTER 0x3200 |
99 | #define MIRROR_IMAGE_FORMATTER 0x3300 | 107 | #define MIRROR_IMAGE_FORMATTER 0x3300 |
100 | #define LED_FORMATTER 0x3400 | 108 | #define LED_FORMATTER 0x3400 |
109 | #define LOWLIGHT 0x3500 | ||
110 | #define GET_STATUS_3600 0x3600 | ||
101 | #define SENSOR_TYPE_FORMATTER2 0x3700 | 111 | #define SENSOR_TYPE_FORMATTER2 0x3700 |
112 | #define GET_STATUS_3800 0x3800 | ||
113 | #define GET_STATUS_4000 0x4000 | ||
114 | #define GET_STATUS_4100 0x4100 /* Get */ | ||
115 | #define CTL_STATUS_4200 0x4200 /* [GS] 1 */ | ||
102 | 116 | ||
103 | /* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */ | 117 | /* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */ |
104 | #define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100 | 118 | #define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100 |
@@ -138,6 +152,7 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][8] = | |||
138 | #include "pwc-nala.h" | 152 | #include "pwc-nala.h" |
139 | }; | 153 | }; |
140 | 154 | ||
155 | static void pwc_set_image_buffer_size(struct pwc_device *pdev); | ||
141 | 156 | ||
142 | /****************************************************************************/ | 157 | /****************************************************************************/ |
143 | 158 | ||
@@ -159,31 +174,7 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][8] = | |||
159 | &buf, buflen, 500) | 174 | &buf, buflen, 500) |
160 | 175 | ||
161 | 176 | ||
162 | #if PWC_DEBUG | 177 | static int send_video_command(struct usb_device *udev, int index, void *buf, int buflen) |
163 | void pwc_hexdump(void *p, int len) | ||
164 | { | ||
165 | int i; | ||
166 | unsigned char *s; | ||
167 | char buf[100], *d; | ||
168 | |||
169 | s = (unsigned char *)p; | ||
170 | d = buf; | ||
171 | *d = '\0'; | ||
172 | Debug("Doing hexdump @ %p, %d bytes.\n", p, len); | ||
173 | for (i = 0; i < len; i++) { | ||
174 | d += sprintf(d, "%02X ", *s++); | ||
175 | if ((i & 0xF) == 0xF) { | ||
176 | Debug("%s\n", buf); | ||
177 | d = buf; | ||
178 | *d = '\0'; | ||
179 | } | ||
180 | } | ||
181 | if ((i & 0xF) != 0) | ||
182 | Debug("%s\n", buf); | ||
183 | } | ||
184 | #endif | ||
185 | |||
186 | static inline int send_video_command(struct usb_device *udev, int index, void *buf, int buflen) | ||
187 | { | 178 | { |
188 | return usb_control_msg(udev, | 179 | return usb_control_msg(udev, |
189 | usb_sndctrlpipe(udev, 0), | 180 | usb_sndctrlpipe(udev, 0), |
@@ -196,7 +187,7 @@ static inline int send_video_command(struct usb_device *udev, int index, void *b | |||
196 | 187 | ||
197 | 188 | ||
198 | 189 | ||
199 | static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) | 190 | static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) |
200 | { | 191 | { |
201 | unsigned char buf[3]; | 192 | unsigned char buf[3]; |
202 | int ret, fps; | 193 | int ret, fps; |
@@ -229,34 +220,14 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra | |||
229 | if (pEntry->alternate == 0) | 220 | if (pEntry->alternate == 0) |
230 | return -EINVAL; | 221 | return -EINVAL; |
231 | 222 | ||
232 | if (pEntry->compressed) | ||
233 | return -ENOENT; /* Not supported. */ | ||
234 | |||
235 | memcpy(buf, pEntry->mode, 3); | 223 | memcpy(buf, pEntry->mode, 3); |
236 | ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3); | 224 | ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3); |
237 | if (ret < 0) { | 225 | if (ret < 0) { |
238 | Debug("Failed to send video command... %d\n", ret); | 226 | PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); |
239 | return ret; | 227 | return ret; |
240 | } | 228 | } |
241 | if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW) | 229 | if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW) |
242 | { | 230 | pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); |
243 | switch(pdev->type) { | ||
244 | case 645: | ||
245 | case 646: | ||
246 | /* pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ | ||
247 | break; | ||
248 | |||
249 | case 675: | ||
250 | case 680: | ||
251 | case 690: | ||
252 | case 720: | ||
253 | case 730: | ||
254 | case 740: | ||
255 | case 750: | ||
256 | /* pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ | ||
257 | break; | ||
258 | } | ||
259 | } | ||
260 | 231 | ||
261 | pdev->cmd_len = 3; | 232 | pdev->cmd_len = 3; |
262 | memcpy(pdev->cmd_buf, buf, 3); | 233 | memcpy(pdev->cmd_buf, buf, 3); |
@@ -283,7 +254,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra | |||
283 | } | 254 | } |
284 | 255 | ||
285 | 256 | ||
286 | static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) | 257 | static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) |
287 | { | 258 | { |
288 | unsigned char buf[13]; | 259 | unsigned char buf[13]; |
289 | const struct Timon_table_entry *pChoose; | 260 | const struct Timon_table_entry *pChoose; |
@@ -315,8 +286,8 @@ static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int fr | |||
315 | if (ret < 0) | 286 | if (ret < 0) |
316 | return ret; | 287 | return ret; |
317 | 288 | ||
318 | /* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) | 289 | if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) |
319 | pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ | 290 | pwc_dec23_init(pdev, pdev->type, buf); |
320 | 291 | ||
321 | pdev->cmd_len = 13; | 292 | pdev->cmd_len = 13; |
322 | memcpy(pdev->cmd_buf, buf, 13); | 293 | memcpy(pdev->cmd_buf, buf, 13); |
@@ -336,7 +307,7 @@ static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int fr | |||
336 | } | 307 | } |
337 | 308 | ||
338 | 309 | ||
339 | static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) | 310 | static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) |
340 | { | 311 | { |
341 | const struct Kiara_table_entry *pChoose = NULL; | 312 | const struct Kiara_table_entry *pChoose = NULL; |
342 | int fps, ret; | 313 | int fps, ret; |
@@ -350,21 +321,14 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr | |||
350 | fps = (frames / 5) - 1; | 321 | fps = (frames / 5) - 1; |
351 | 322 | ||
352 | /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ | 323 | /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ |
353 | if (size == PSZ_VGA && frames == 5 && snapshot) | 324 | if (size == PSZ_VGA && frames == 5 && snapshot && pdev->vpalette == VIDEO_PALETTE_RAW) |
354 | { | 325 | { |
355 | /* Only available in case the raw palette is selected or | 326 | /* Only available in case the raw palette is selected or |
356 | we have the decompressor available. This mode is | 327 | we have the decompressor available. This mode is |
357 | only available in compressed form | 328 | only available in compressed form |
358 | */ | 329 | */ |
359 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 330 | PWC_DEBUG_SIZE("Choosing VGA/5 BAYER mode.\n"); |
360 | { | 331 | pChoose = &RawEntry; |
361 | Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette); | ||
362 | pChoose = &RawEntry; | ||
363 | } | ||
364 | else | ||
365 | { | ||
366 | Info("VGA/5 BAYER mode _must_ have a decompressor available, or use RAW palette.\n"); | ||
367 | } | ||
368 | } | 332 | } |
369 | else | 333 | else |
370 | { | 334 | { |
@@ -372,6 +336,7 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr | |||
372 | if the preferred ratio is not available. | 336 | if the preferred ratio is not available. |
373 | Skip this step when using RAW modes. | 337 | Skip this step when using RAW modes. |
374 | */ | 338 | */ |
339 | snapshot = 0; | ||
375 | while (compression <= 3) { | 340 | while (compression <= 3) { |
376 | pChoose = &Kiara_table[size][fps][compression]; | 341 | pChoose = &Kiara_table[size][fps][compression]; |
377 | if (pChoose->alternate != 0) | 342 | if (pChoose->alternate != 0) |
@@ -382,7 +347,7 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr | |||
382 | if (pChoose == NULL || pChoose->alternate == 0) | 347 | if (pChoose == NULL || pChoose->alternate == 0) |
383 | return -ENOENT; /* Not supported. */ | 348 | return -ENOENT; /* Not supported. */ |
384 | 349 | ||
385 | Debug("Using alternate setting %d.\n", pChoose->alternate); | 350 | PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate); |
386 | 351 | ||
387 | /* usb_control_msg won't take staticly allocated arrays as argument?? */ | 352 | /* usb_control_msg won't take staticly allocated arrays as argument?? */ |
388 | memcpy(buf, pChoose->mode, 12); | 353 | memcpy(buf, pChoose->mode, 12); |
@@ -394,8 +359,8 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr | |||
394 | if (ret < 0) | 359 | if (ret < 0) |
395 | return ret; | 360 | return ret; |
396 | 361 | ||
397 | /* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) | 362 | if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) |
398 | pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ | 363 | pwc_dec23_init(pdev, pdev->type, buf); |
399 | 364 | ||
400 | pdev->cmd_len = 12; | 365 | pdev->cmd_len = 12; |
401 | memcpy(pdev->cmd_buf, buf, 12); | 366 | memcpy(pdev->cmd_buf, buf, 12); |
@@ -410,49 +375,13 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr | |||
410 | pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4; | 375 | pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4; |
411 | else | 376 | else |
412 | pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; | 377 | pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; |
378 | PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vsnapshot=%d, vbandlength=%d\n", | ||
379 | pdev->frame_size,pdev->vframes,pdev->vsize,pdev->vsnapshot,pdev->vbandlength); | ||
413 | return 0; | 380 | return 0; |
414 | } | 381 | } |
415 | 382 | ||
416 | 383 | ||
417 | 384 | ||
418 | static void pwc_set_image_buffer_size(struct pwc_device *pdev) | ||
419 | { | ||
420 | int i, factor = 0, filler = 0; | ||
421 | |||
422 | /* for PALETTE_YUV420P */ | ||
423 | switch(pdev->vpalette) | ||
424 | { | ||
425 | case VIDEO_PALETTE_YUV420P: | ||
426 | factor = 6; | ||
427 | filler = 128; | ||
428 | break; | ||
429 | case VIDEO_PALETTE_RAW: | ||
430 | factor = 6; /* can be uncompressed YUV420P */ | ||
431 | filler = 0; | ||
432 | break; | ||
433 | } | ||
434 | |||
435 | /* Set sizes in bytes */ | ||
436 | pdev->image.size = pdev->image.x * pdev->image.y * factor / 4; | ||
437 | pdev->view.size = pdev->view.x * pdev->view.y * factor / 4; | ||
438 | |||
439 | /* Align offset, or you'll get some very weird results in | ||
440 | YUV420 mode... x must be multiple of 4 (to get the Y's in | ||
441 | place), and y even (or you'll mixup U & V). This is less of a | ||
442 | problem for YUV420P. | ||
443 | */ | ||
444 | pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC; | ||
445 | pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE; | ||
446 | |||
447 | /* Fill buffers with gray or black */ | ||
448 | for (i = 0; i < MAX_IMAGES; i++) { | ||
449 | if (pdev->image_ptr[i] != NULL) | ||
450 | memset(pdev->image_ptr[i], filler, pdev->view.size); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | |||
455 | |||
456 | /** | 385 | /** |
457 | @pdev: device structure | 386 | @pdev: device structure |
458 | @width: viewport width | 387 | @width: viewport width |
@@ -465,50 +394,78 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame | |||
465 | { | 394 | { |
466 | int ret, size; | 395 | int ret, size; |
467 | 396 | ||
468 | Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); | 397 | PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); |
469 | size = pwc_decode_size(pdev, width, height); | 398 | size = pwc_decode_size(pdev, width, height); |
470 | if (size < 0) { | 399 | if (size < 0) { |
471 | Debug("Could not find suitable size.\n"); | 400 | PWC_DEBUG_MODULE("Could not find suitable size.\n"); |
472 | return -ERANGE; | 401 | return -ERANGE; |
473 | } | 402 | } |
474 | Debug("decode_size = %d.\n", size); | 403 | PWC_TRACE("decode_size = %d.\n", size); |
475 | 404 | ||
476 | ret = -EINVAL; | 405 | if (DEVICE_USE_CODEC1(pdev->type)) { |
477 | switch(pdev->type) { | ||
478 | case 645: | ||
479 | case 646: | ||
480 | ret = set_video_mode_Nala(pdev, size, frames); | 406 | ret = set_video_mode_Nala(pdev, size, frames); |
481 | break; | ||
482 | 407 | ||
483 | case 675: | 408 | } else if (DEVICE_USE_CODEC3(pdev->type)) { |
484 | case 680: | ||
485 | case 690: | ||
486 | ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot); | ||
487 | break; | ||
488 | |||
489 | case 720: | ||
490 | case 730: | ||
491 | case 740: | ||
492 | case 750: | ||
493 | ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot); | 409 | ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot); |
494 | break; | 410 | |
411 | } else { | ||
412 | ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot); | ||
495 | } | 413 | } |
496 | if (ret < 0) { | 414 | if (ret < 0) { |
497 | if (ret == -ENOENT) | 415 | PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); |
498 | Info("Video mode %s@%d fps is only supported with the decompressor module (pwcx).\n", size2name[size], frames); | ||
499 | else { | ||
500 | Err("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); | ||
501 | } | ||
502 | return ret; | 416 | return ret; |
503 | } | 417 | } |
504 | pdev->view.x = width; | 418 | pdev->view.x = width; |
505 | pdev->view.y = height; | 419 | pdev->view.y = height; |
506 | pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; | 420 | pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; |
507 | pwc_set_image_buffer_size(pdev); | 421 | pwc_set_image_buffer_size(pdev); |
508 | Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y); | 422 | PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y); |
509 | return 0; | 423 | return 0; |
510 | } | 424 | } |
511 | 425 | ||
426 | #define BLACK_Y 0 | ||
427 | #define BLACK_U 128 | ||
428 | #define BLACK_V 128 | ||
429 | |||
430 | static void pwc_set_image_buffer_size(struct pwc_device *pdev) | ||
431 | { | ||
432 | int i, factor = 0; | ||
433 | |||
434 | /* for PALETTE_YUV420P */ | ||
435 | switch(pdev->vpalette) | ||
436 | { | ||
437 | case VIDEO_PALETTE_YUV420P: | ||
438 | factor = 6; | ||
439 | break; | ||
440 | case VIDEO_PALETTE_RAW: | ||
441 | factor = 6; /* can be uncompressed YUV420P */ | ||
442 | break; | ||
443 | } | ||
444 | |||
445 | /* Set sizes in bytes */ | ||
446 | pdev->image.size = pdev->image.x * pdev->image.y * factor / 4; | ||
447 | pdev->view.size = pdev->view.x * pdev->view.y * factor / 4; | ||
448 | |||
449 | /* Align offset, or you'll get some very weird results in | ||
450 | YUV420 mode... x must be multiple of 4 (to get the Y's in | ||
451 | place), and y even (or you'll mixup U & V). This is less of a | ||
452 | problem for YUV420P. | ||
453 | */ | ||
454 | pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC; | ||
455 | pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE; | ||
456 | |||
457 | /* Fill buffers with black colors */ | ||
458 | for (i = 0; i < pwc_mbufs; i++) { | ||
459 | unsigned char *p = pdev->image_data + pdev->images[i].offset; | ||
460 | memset(p, BLACK_Y, pdev->view.x * pdev->view.y); | ||
461 | p += pdev->view.x * pdev->view.y; | ||
462 | memset(p, BLACK_U, pdev->view.x * pdev->view.y/4); | ||
463 | p += pdev->view.x * pdev->view.y/4; | ||
464 | memset(p, BLACK_V, pdev->view.x * pdev->view.y/4); | ||
465 | } | ||
466 | } | ||
467 | |||
468 | |||
512 | 469 | ||
513 | /* BRIGHTNESS */ | 470 | /* BRIGHTNESS */ |
514 | 471 | ||
@@ -520,7 +477,7 @@ int pwc_get_brightness(struct pwc_device *pdev) | |||
520 | ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); | 477 | ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); |
521 | if (ret < 0) | 478 | if (ret < 0) |
522 | return ret; | 479 | return ret; |
523 | return buf << 9; | 480 | return buf; |
524 | } | 481 | } |
525 | 482 | ||
526 | int pwc_set_brightness(struct pwc_device *pdev, int value) | 483 | int pwc_set_brightness(struct pwc_device *pdev, int value) |
@@ -545,7 +502,7 @@ int pwc_get_contrast(struct pwc_device *pdev) | |||
545 | ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1); | 502 | ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1); |
546 | if (ret < 0) | 503 | if (ret < 0) |
547 | return ret; | 504 | return ret; |
548 | return buf << 10; | 505 | return buf; |
549 | } | 506 | } |
550 | 507 | ||
551 | int pwc_set_contrast(struct pwc_device *pdev, int value) | 508 | int pwc_set_contrast(struct pwc_device *pdev, int value) |
@@ -570,7 +527,7 @@ int pwc_get_gamma(struct pwc_device *pdev) | |||
570 | ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1); | 527 | ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1); |
571 | if (ret < 0) | 528 | if (ret < 0) |
572 | return ret; | 529 | return ret; |
573 | return buf << 11; | 530 | return buf; |
574 | } | 531 | } |
575 | 532 | ||
576 | int pwc_set_gamma(struct pwc_device *pdev, int value) | 533 | int pwc_set_gamma(struct pwc_device *pdev, int value) |
@@ -588,37 +545,47 @@ int pwc_set_gamma(struct pwc_device *pdev, int value) | |||
588 | 545 | ||
589 | /* SATURATION */ | 546 | /* SATURATION */ |
590 | 547 | ||
591 | int pwc_get_saturation(struct pwc_device *pdev) | 548 | /* return a value between [-100 , 100] */ |
549 | int pwc_get_saturation(struct pwc_device *pdev, int *value) | ||
592 | { | 550 | { |
593 | char buf; | 551 | char buf; |
594 | int ret; | 552 | int ret, saturation_register; |
595 | 553 | ||
596 | if (pdev->type < 675) | 554 | if (pdev->type < 675) |
597 | return -1; | 555 | return -EINVAL; |
598 | ret = RecvControlMsg(GET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); | 556 | if (pdev->type < 730) |
557 | saturation_register = SATURATION_MODE_FORMATTER2; | ||
558 | else | ||
559 | saturation_register = SATURATION_MODE_FORMATTER1; | ||
560 | ret = RecvControlMsg(GET_CHROM_CTL, saturation_register, 1); | ||
599 | if (ret < 0) | 561 | if (ret < 0) |
600 | return ret; | 562 | return ret; |
601 | return 32768 + buf * 327; | 563 | *value = (signed)buf; |
564 | return 0; | ||
602 | } | 565 | } |
603 | 566 | ||
567 | /* @param value saturation color between [-100 , 100] */ | ||
604 | int pwc_set_saturation(struct pwc_device *pdev, int value) | 568 | int pwc_set_saturation(struct pwc_device *pdev, int value) |
605 | { | 569 | { |
606 | char buf; | 570 | char buf; |
571 | int saturation_register; | ||
607 | 572 | ||
608 | if (pdev->type < 675) | 573 | if (pdev->type < 675) |
609 | return -EINVAL; | 574 | return -EINVAL; |
610 | if (value < 0) | 575 | if (value < -100) |
611 | value = 0; | 576 | value = -100; |
612 | if (value > 0xffff) | 577 | if (value > 100) |
613 | value = 0xffff; | 578 | value = 100; |
614 | /* saturation ranges from -100 to +100 */ | 579 | if (pdev->type < 730) |
615 | buf = (value - 32768) / 327; | 580 | saturation_register = SATURATION_MODE_FORMATTER2; |
616 | return SendControlMsg(SET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); | 581 | else |
582 | saturation_register = SATURATION_MODE_FORMATTER1; | ||
583 | return SendControlMsg(SET_CHROM_CTL, saturation_register, 1); | ||
617 | } | 584 | } |
618 | 585 | ||
619 | /* AGC */ | 586 | /* AGC */ |
620 | 587 | ||
621 | static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value) | 588 | int pwc_set_agc(struct pwc_device *pdev, int mode, int value) |
622 | { | 589 | { |
623 | char buf; | 590 | char buf; |
624 | int ret; | 591 | int ret; |
@@ -643,7 +610,7 @@ static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value) | |||
643 | return 0; | 610 | return 0; |
644 | } | 611 | } |
645 | 612 | ||
646 | static inline int pwc_get_agc(struct pwc_device *pdev, int *value) | 613 | int pwc_get_agc(struct pwc_device *pdev, int *value) |
647 | { | 614 | { |
648 | unsigned char buf; | 615 | unsigned char buf; |
649 | int ret; | 616 | int ret; |
@@ -673,7 +640,7 @@ static inline int pwc_get_agc(struct pwc_device *pdev, int *value) | |||
673 | return 0; | 640 | return 0; |
674 | } | 641 | } |
675 | 642 | ||
676 | static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) | 643 | int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) |
677 | { | 644 | { |
678 | char buf[2]; | 645 | char buf[2]; |
679 | int speed, ret; | 646 | int speed, ret; |
@@ -691,23 +658,16 @@ static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int v | |||
691 | value = 0; | 658 | value = 0; |
692 | if (value > 0xffff) | 659 | if (value > 0xffff) |
693 | value = 0xffff; | 660 | value = 0xffff; |
694 | switch(pdev->type) { | 661 | |
695 | case 675: | 662 | if (DEVICE_USE_CODEC2(pdev->type)) { |
696 | case 680: | ||
697 | case 690: | ||
698 | /* speed ranges from 0x0 to 0x290 (656) */ | 663 | /* speed ranges from 0x0 to 0x290 (656) */ |
699 | speed = (value / 100); | 664 | speed = (value / 100); |
700 | buf[1] = speed >> 8; | 665 | buf[1] = speed >> 8; |
701 | buf[0] = speed & 0xff; | 666 | buf[0] = speed & 0xff; |
702 | break; | 667 | } else if (DEVICE_USE_CODEC3(pdev->type)) { |
703 | case 720: | ||
704 | case 730: | ||
705 | case 740: | ||
706 | case 750: | ||
707 | /* speed seems to range from 0x0 to 0xff */ | 668 | /* speed seems to range from 0x0 to 0xff */ |
708 | buf[1] = 0; | 669 | buf[1] = 0; |
709 | buf[0] = value >> 8; | 670 | buf[0] = value >> 8; |
710 | break; | ||
711 | } | 671 | } |
712 | 672 | ||
713 | ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2); | 673 | ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2); |
@@ -715,6 +675,25 @@ static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int v | |||
715 | return ret; | 675 | return ret; |
716 | } | 676 | } |
717 | 677 | ||
678 | /* This function is not exported to v4l1, so output values between 0 -> 256 */ | ||
679 | int pwc_get_shutter_speed(struct pwc_device *pdev, int *value) | ||
680 | { | ||
681 | unsigned char buf[2]; | ||
682 | int ret; | ||
683 | |||
684 | ret = RecvControlMsg(GET_STATUS_CTL, READ_SHUTTER_FORMATTER, 2); | ||
685 | if (ret < 0) | ||
686 | return ret; | ||
687 | *value = buf[0] + (buf[1] << 8); | ||
688 | if (DEVICE_USE_CODEC2(pdev->type)) { | ||
689 | /* speed ranges from 0x0 to 0x290 (656) */ | ||
690 | *value *= 256/656; | ||
691 | } else if (DEVICE_USE_CODEC3(pdev->type)) { | ||
692 | /* speed seems to range from 0x0 to 0xff */ | ||
693 | } | ||
694 | return 0; | ||
695 | } | ||
696 | |||
718 | 697 | ||
719 | /* POWER */ | 698 | /* POWER */ |
720 | 699 | ||
@@ -736,19 +715,19 @@ int pwc_camera_power(struct pwc_device *pdev, int power) | |||
736 | 715 | ||
737 | /* private calls */ | 716 | /* private calls */ |
738 | 717 | ||
739 | static inline int pwc_restore_user(struct pwc_device *pdev) | 718 | int pwc_restore_user(struct pwc_device *pdev) |
740 | { | 719 | { |
741 | char buf; /* dummy */ | 720 | char buf; /* dummy */ |
742 | return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0); | 721 | return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0); |
743 | } | 722 | } |
744 | 723 | ||
745 | static inline int pwc_save_user(struct pwc_device *pdev) | 724 | int pwc_save_user(struct pwc_device *pdev) |
746 | { | 725 | { |
747 | char buf; /* dummy */ | 726 | char buf; /* dummy */ |
748 | return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0); | 727 | return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0); |
749 | } | 728 | } |
750 | 729 | ||
751 | static inline int pwc_restore_factory(struct pwc_device *pdev) | 730 | int pwc_restore_factory(struct pwc_device *pdev) |
752 | { | 731 | { |
753 | char buf; /* dummy */ | 732 | char buf; /* dummy */ |
754 | return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0); | 733 | return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0); |
@@ -766,7 +745,7 @@ static inline int pwc_restore_factory(struct pwc_device *pdev) | |||
766 | * 03: manual | 745 | * 03: manual |
767 | * 04: auto | 746 | * 04: auto |
768 | */ | 747 | */ |
769 | static inline int pwc_set_awb(struct pwc_device *pdev, int mode) | 748 | int pwc_set_awb(struct pwc_device *pdev, int mode) |
770 | { | 749 | { |
771 | char buf; | 750 | char buf; |
772 | int ret; | 751 | int ret; |
@@ -786,7 +765,7 @@ static inline int pwc_set_awb(struct pwc_device *pdev, int mode) | |||
786 | return 0; | 765 | return 0; |
787 | } | 766 | } |
788 | 767 | ||
789 | static inline int pwc_get_awb(struct pwc_device *pdev) | 768 | int pwc_get_awb(struct pwc_device *pdev) |
790 | { | 769 | { |
791 | unsigned char buf; | 770 | unsigned char buf; |
792 | int ret; | 771 | int ret; |
@@ -798,7 +777,7 @@ static inline int pwc_get_awb(struct pwc_device *pdev) | |||
798 | return buf; | 777 | return buf; |
799 | } | 778 | } |
800 | 779 | ||
801 | static inline int pwc_set_red_gain(struct pwc_device *pdev, int value) | 780 | int pwc_set_red_gain(struct pwc_device *pdev, int value) |
802 | { | 781 | { |
803 | unsigned char buf; | 782 | unsigned char buf; |
804 | 783 | ||
@@ -811,7 +790,7 @@ static inline int pwc_set_red_gain(struct pwc_device *pdev, int value) | |||
811 | return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); | 790 | return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); |
812 | } | 791 | } |
813 | 792 | ||
814 | static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value) | 793 | int pwc_get_red_gain(struct pwc_device *pdev, int *value) |
815 | { | 794 | { |
816 | unsigned char buf; | 795 | unsigned char buf; |
817 | int ret; | 796 | int ret; |
@@ -824,7 +803,7 @@ static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value) | |||
824 | } | 803 | } |
825 | 804 | ||
826 | 805 | ||
827 | static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value) | 806 | int pwc_set_blue_gain(struct pwc_device *pdev, int value) |
828 | { | 807 | { |
829 | unsigned char buf; | 808 | unsigned char buf; |
830 | 809 | ||
@@ -837,7 +816,7 @@ static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value) | |||
837 | return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); | 816 | return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); |
838 | } | 817 | } |
839 | 818 | ||
840 | static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value) | 819 | int pwc_get_blue_gain(struct pwc_device *pdev, int *value) |
841 | { | 820 | { |
842 | unsigned char buf; | 821 | unsigned char buf; |
843 | int ret; | 822 | int ret; |
@@ -854,7 +833,7 @@ static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value) | |||
854 | internal red/blue gains, which may be different from the manual | 833 | internal red/blue gains, which may be different from the manual |
855 | gains set or read above. | 834 | gains set or read above. |
856 | */ | 835 | */ |
857 | static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value) | 836 | static int pwc_read_red_gain(struct pwc_device *pdev, int *value) |
858 | { | 837 | { |
859 | unsigned char buf; | 838 | unsigned char buf; |
860 | int ret; | 839 | int ret; |
@@ -866,7 +845,7 @@ static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value) | |||
866 | return 0; | 845 | return 0; |
867 | } | 846 | } |
868 | 847 | ||
869 | static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value) | 848 | static int pwc_read_blue_gain(struct pwc_device *pdev, int *value) |
870 | { | 849 | { |
871 | unsigned char buf; | 850 | unsigned char buf; |
872 | int ret; | 851 | int ret; |
@@ -879,7 +858,7 @@ static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value) | |||
879 | } | 858 | } |
880 | 859 | ||
881 | 860 | ||
882 | static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed) | 861 | static int pwc_set_wb_speed(struct pwc_device *pdev, int speed) |
883 | { | 862 | { |
884 | unsigned char buf; | 863 | unsigned char buf; |
885 | 864 | ||
@@ -888,7 +867,7 @@ static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed) | |||
888 | return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); | 867 | return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); |
889 | } | 868 | } |
890 | 869 | ||
891 | static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value) | 870 | static int pwc_get_wb_speed(struct pwc_device *pdev, int *value) |
892 | { | 871 | { |
893 | unsigned char buf; | 872 | unsigned char buf; |
894 | int ret; | 873 | int ret; |
@@ -901,7 +880,7 @@ static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value) | |||
901 | } | 880 | } |
902 | 881 | ||
903 | 882 | ||
904 | static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay) | 883 | static int pwc_set_wb_delay(struct pwc_device *pdev, int delay) |
905 | { | 884 | { |
906 | unsigned char buf; | 885 | unsigned char buf; |
907 | 886 | ||
@@ -910,7 +889,7 @@ static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay) | |||
910 | return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); | 889 | return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); |
911 | } | 890 | } |
912 | 891 | ||
913 | static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value) | 892 | static int pwc_get_wb_delay(struct pwc_device *pdev, int *value) |
914 | { | 893 | { |
915 | unsigned char buf; | 894 | unsigned char buf; |
916 | int ret; | 895 | int ret; |
@@ -965,7 +944,7 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value) | |||
965 | return 0; | 944 | return 0; |
966 | } | 945 | } |
967 | 946 | ||
968 | static inline int pwc_set_contour(struct pwc_device *pdev, int contour) | 947 | int pwc_set_contour(struct pwc_device *pdev, int contour) |
969 | { | 948 | { |
970 | unsigned char buf; | 949 | unsigned char buf; |
971 | int ret; | 950 | int ret; |
@@ -990,7 +969,7 @@ static inline int pwc_set_contour(struct pwc_device *pdev, int contour) | |||
990 | return 0; | 969 | return 0; |
991 | } | 970 | } |
992 | 971 | ||
993 | static inline int pwc_get_contour(struct pwc_device *pdev, int *contour) | 972 | int pwc_get_contour(struct pwc_device *pdev, int *contour) |
994 | { | 973 | { |
995 | unsigned char buf; | 974 | unsigned char buf; |
996 | int ret; | 975 | int ret; |
@@ -1012,7 +991,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour) | |||
1012 | } | 991 | } |
1013 | 992 | ||
1014 | 993 | ||
1015 | static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight) | 994 | int pwc_set_backlight(struct pwc_device *pdev, int backlight) |
1016 | { | 995 | { |
1017 | unsigned char buf; | 996 | unsigned char buf; |
1018 | 997 | ||
@@ -1023,7 +1002,7 @@ static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight) | |||
1023 | return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); | 1002 | return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); |
1024 | } | 1003 | } |
1025 | 1004 | ||
1026 | static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight) | 1005 | int pwc_get_backlight(struct pwc_device *pdev, int *backlight) |
1027 | { | 1006 | { |
1028 | int ret; | 1007 | int ret; |
1029 | unsigned char buf; | 1008 | unsigned char buf; |
@@ -1031,12 +1010,35 @@ static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight) | |||
1031 | ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); | 1010 | ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); |
1032 | if (ret < 0) | 1011 | if (ret < 0) |
1033 | return ret; | 1012 | return ret; |
1034 | *backlight = buf; | 1013 | *backlight = !!buf; |
1035 | return 0; | 1014 | return 0; |
1036 | } | 1015 | } |
1037 | 1016 | ||
1017 | int pwc_set_colour_mode(struct pwc_device *pdev, int colour) | ||
1018 | { | ||
1019 | unsigned char buf; | ||
1038 | 1020 | ||
1039 | static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker) | 1021 | if (colour) |
1022 | buf = 0xff; | ||
1023 | else | ||
1024 | buf = 0x0; | ||
1025 | return SendControlMsg(SET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1); | ||
1026 | } | ||
1027 | |||
1028 | int pwc_get_colour_mode(struct pwc_device *pdev, int *colour) | ||
1029 | { | ||
1030 | int ret; | ||
1031 | unsigned char buf; | ||
1032 | |||
1033 | ret = RecvControlMsg(GET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1); | ||
1034 | if (ret < 0) | ||
1035 | return ret; | ||
1036 | *colour = !!buf; | ||
1037 | return 0; | ||
1038 | } | ||
1039 | |||
1040 | |||
1041 | int pwc_set_flicker(struct pwc_device *pdev, int flicker) | ||
1040 | { | 1042 | { |
1041 | unsigned char buf; | 1043 | unsigned char buf; |
1042 | 1044 | ||
@@ -1047,7 +1049,7 @@ static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker) | |||
1047 | return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); | 1049 | return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); |
1048 | } | 1050 | } |
1049 | 1051 | ||
1050 | static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker) | 1052 | int pwc_get_flicker(struct pwc_device *pdev, int *flicker) |
1051 | { | 1053 | { |
1052 | int ret; | 1054 | int ret; |
1053 | unsigned char buf; | 1055 | unsigned char buf; |
@@ -1055,12 +1057,11 @@ static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker) | |||
1055 | ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); | 1057 | ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); |
1056 | if (ret < 0) | 1058 | if (ret < 0) |
1057 | return ret; | 1059 | return ret; |
1058 | *flicker = buf; | 1060 | *flicker = !!buf; |
1059 | return 0; | 1061 | return 0; |
1060 | } | 1062 | } |
1061 | 1063 | ||
1062 | 1064 | int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise) | |
1063 | static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise) | ||
1064 | { | 1065 | { |
1065 | unsigned char buf; | 1066 | unsigned char buf; |
1066 | 1067 | ||
@@ -1072,7 +1073,7 @@ static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise) | |||
1072 | return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); | 1073 | return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); |
1073 | } | 1074 | } |
1074 | 1075 | ||
1075 | static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) | 1076 | int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) |
1076 | { | 1077 | { |
1077 | int ret; | 1078 | int ret; |
1078 | unsigned char buf; | 1079 | unsigned char buf; |
@@ -1084,7 +1085,7 @@ static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) | |||
1084 | return 0; | 1085 | return 0; |
1085 | } | 1086 | } |
1086 | 1087 | ||
1087 | static int pwc_mpt_reset(struct pwc_device *pdev, int flags) | 1088 | static int _pwc_mpt_reset(struct pwc_device *pdev, int flags) |
1088 | { | 1089 | { |
1089 | unsigned char buf; | 1090 | unsigned char buf; |
1090 | 1091 | ||
@@ -1092,7 +1093,18 @@ static int pwc_mpt_reset(struct pwc_device *pdev, int flags) | |||
1092 | return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1); | 1093 | return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1); |
1093 | } | 1094 | } |
1094 | 1095 | ||
1095 | static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) | 1096 | int pwc_mpt_reset(struct pwc_device *pdev, int flags) |
1097 | { | ||
1098 | int ret; | ||
1099 | ret = _pwc_mpt_reset(pdev, flags); | ||
1100 | if (ret >= 0) { | ||
1101 | pdev->pan_angle = 0; | ||
1102 | pdev->tilt_angle = 0; | ||
1103 | } | ||
1104 | return ret; | ||
1105 | } | ||
1106 | |||
1107 | static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) | ||
1096 | { | 1108 | { |
1097 | unsigned char buf[4]; | 1109 | unsigned char buf[4]; |
1098 | 1110 | ||
@@ -1110,7 +1122,35 @@ static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) | |||
1110 | return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4); | 1122 | return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4); |
1111 | } | 1123 | } |
1112 | 1124 | ||
1113 | static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status) | 1125 | int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) |
1126 | { | ||
1127 | int ret; | ||
1128 | |||
1129 | /* check absolute ranges */ | ||
1130 | if (pan < pdev->angle_range.pan_min || | ||
1131 | pan > pdev->angle_range.pan_max || | ||
1132 | tilt < pdev->angle_range.tilt_min || | ||
1133 | tilt > pdev->angle_range.tilt_max) | ||
1134 | return -ERANGE; | ||
1135 | |||
1136 | /* go to relative range, check again */ | ||
1137 | pan -= pdev->pan_angle; | ||
1138 | tilt -= pdev->tilt_angle; | ||
1139 | /* angles are specified in degrees * 100, thus the limit = 36000 */ | ||
1140 | if (pan < -36000 || pan > 36000 || tilt < -36000 || tilt > 36000) | ||
1141 | return -ERANGE; | ||
1142 | |||
1143 | ret = _pwc_mpt_set_angle(pdev, pan, tilt); | ||
1144 | if (ret >= 0) { | ||
1145 | pdev->pan_angle += pan; | ||
1146 | pdev->tilt_angle += tilt; | ||
1147 | } | ||
1148 | if (ret == -EPIPE) /* stall -> out of range */ | ||
1149 | ret = -ERANGE; | ||
1150 | return ret; | ||
1151 | } | ||
1152 | |||
1153 | static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status) | ||
1114 | { | 1154 | { |
1115 | int ret; | 1155 | int ret; |
1116 | unsigned char buf[5]; | 1156 | unsigned char buf[5]; |
@@ -1151,6 +1191,26 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) | |||
1151 | /* End of Add-Ons */ | 1191 | /* End of Add-Ons */ |
1152 | /* ************************************************* */ | 1192 | /* ************************************************* */ |
1153 | 1193 | ||
1194 | /* Linux 2.5.something and 2.6 pass direct pointers to arguments of | ||
1195 | ioctl() calls. With 2.4, you have to do tedious copy_from_user() | ||
1196 | and copy_to_user() calls. With these macros we circumvent this, | ||
1197 | and let me maintain only one source file. The functionality is | ||
1198 | exactly the same otherwise. | ||
1199 | */ | ||
1200 | |||
1201 | |||
1202 | /* define local variable for arg */ | ||
1203 | #define ARG_DEF(ARG_type, ARG_name)\ | ||
1204 | ARG_type *ARG_name = arg; | ||
1205 | /* copy arg to local variable */ | ||
1206 | #define ARG_IN(ARG_name) /* nothing */ | ||
1207 | /* argument itself (referenced) */ | ||
1208 | #define ARGR(ARG_name) (*ARG_name) | ||
1209 | /* argument address */ | ||
1210 | #define ARGA(ARG_name) ARG_name | ||
1211 | /* copy local variable to arg */ | ||
1212 | #define ARG_OUT(ARG_name) /* nothing */ | ||
1213 | |||
1154 | 1214 | ||
1155 | int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | 1215 | int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) |
1156 | { | 1216 | { |
@@ -1180,206 +1240,243 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1180 | 1240 | ||
1181 | case VIDIOCPWCSCQUAL: | 1241 | case VIDIOCPWCSCQUAL: |
1182 | { | 1242 | { |
1183 | int *qual = arg; | 1243 | ARG_DEF(int, qual) |
1184 | 1244 | ||
1185 | if (*qual < 0 || *qual > 3) | 1245 | ARG_IN(qual) |
1246 | if (ARGR(qual) < 0 || ARGR(qual) > 3) | ||
1186 | ret = -EINVAL; | 1247 | ret = -EINVAL; |
1187 | else | 1248 | else |
1188 | ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot); | 1249 | ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); |
1189 | if (ret >= 0) | 1250 | if (ret >= 0) |
1190 | pdev->vcompression = *qual; | 1251 | pdev->vcompression = ARGR(qual); |
1191 | break; | 1252 | break; |
1192 | } | 1253 | } |
1193 | 1254 | ||
1194 | case VIDIOCPWCGCQUAL: | 1255 | case VIDIOCPWCGCQUAL: |
1195 | { | 1256 | { |
1196 | int *qual = arg; | 1257 | ARG_DEF(int, qual) |
1197 | *qual = pdev->vcompression; | 1258 | |
1259 | ARGR(qual) = pdev->vcompression; | ||
1260 | ARG_OUT(qual) | ||
1198 | break; | 1261 | break; |
1199 | } | 1262 | } |
1200 | 1263 | ||
1201 | case VIDIOCPWCPROBE: | 1264 | case VIDIOCPWCPROBE: |
1202 | { | 1265 | { |
1203 | struct pwc_probe *probe = arg; | 1266 | ARG_DEF(struct pwc_probe, probe) |
1204 | strcpy(probe->name, pdev->vdev->name); | 1267 | |
1205 | probe->type = pdev->type; | 1268 | strcpy(ARGR(probe).name, pdev->vdev->name); |
1269 | ARGR(probe).type = pdev->type; | ||
1270 | ARG_OUT(probe) | ||
1206 | break; | 1271 | break; |
1207 | } | 1272 | } |
1208 | 1273 | ||
1209 | case VIDIOCPWCGSERIAL: | 1274 | case VIDIOCPWCGSERIAL: |
1210 | { | 1275 | { |
1211 | struct pwc_serial *serial = arg; | 1276 | ARG_DEF(struct pwc_serial, serial) |
1212 | strcpy(serial->serial, pdev->serial); | 1277 | |
1278 | strcpy(ARGR(serial).serial, pdev->serial); | ||
1279 | ARG_OUT(serial) | ||
1213 | break; | 1280 | break; |
1214 | } | 1281 | } |
1215 | 1282 | ||
1216 | case VIDIOCPWCSAGC: | 1283 | case VIDIOCPWCSAGC: |
1217 | { | 1284 | { |
1218 | int *agc = arg; | 1285 | ARG_DEF(int, agc) |
1219 | if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc)) | 1286 | |
1287 | ARG_IN(agc) | ||
1288 | if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc))) | ||
1220 | ret = -EINVAL; | 1289 | ret = -EINVAL; |
1221 | break; | 1290 | break; |
1222 | } | 1291 | } |
1223 | 1292 | ||
1224 | case VIDIOCPWCGAGC: | 1293 | case VIDIOCPWCGAGC: |
1225 | { | 1294 | { |
1226 | int *agc = arg; | 1295 | ARG_DEF(int, agc) |
1227 | 1296 | ||
1228 | if (pwc_get_agc(pdev, agc)) | 1297 | if (pwc_get_agc(pdev, ARGA(agc))) |
1229 | ret = -EINVAL; | 1298 | ret = -EINVAL; |
1299 | ARG_OUT(agc) | ||
1230 | break; | 1300 | break; |
1231 | } | 1301 | } |
1232 | 1302 | ||
1233 | case VIDIOCPWCSSHUTTER: | 1303 | case VIDIOCPWCSSHUTTER: |
1234 | { | 1304 | { |
1235 | int *shutter_speed = arg; | 1305 | ARG_DEF(int, shutter_speed) |
1236 | ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed); | 1306 | |
1307 | ARG_IN(shutter_speed) | ||
1308 | ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed)); | ||
1237 | break; | 1309 | break; |
1238 | } | 1310 | } |
1239 | 1311 | ||
1240 | case VIDIOCPWCSAWB: | 1312 | case VIDIOCPWCSAWB: |
1241 | { | 1313 | { |
1242 | struct pwc_whitebalance *wb = arg; | 1314 | ARG_DEF(struct pwc_whitebalance, wb) |
1243 | 1315 | ||
1244 | ret = pwc_set_awb(pdev, wb->mode); | 1316 | ARG_IN(wb) |
1245 | if (ret >= 0 && wb->mode == PWC_WB_MANUAL) { | 1317 | ret = pwc_set_awb(pdev, ARGR(wb).mode); |
1246 | pwc_set_red_gain(pdev, wb->manual_red); | 1318 | if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) { |
1247 | pwc_set_blue_gain(pdev, wb->manual_blue); | 1319 | pwc_set_red_gain(pdev, ARGR(wb).manual_red); |
1320 | pwc_set_blue_gain(pdev, ARGR(wb).manual_blue); | ||
1248 | } | 1321 | } |
1249 | break; | 1322 | break; |
1250 | } | 1323 | } |
1251 | 1324 | ||
1252 | case VIDIOCPWCGAWB: | 1325 | case VIDIOCPWCGAWB: |
1253 | { | 1326 | { |
1254 | struct pwc_whitebalance *wb = arg; | 1327 | ARG_DEF(struct pwc_whitebalance, wb) |
1255 | 1328 | ||
1256 | memset(wb, 0, sizeof(struct pwc_whitebalance)); | 1329 | memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance)); |
1257 | wb->mode = pwc_get_awb(pdev); | 1330 | ARGR(wb).mode = pwc_get_awb(pdev); |
1258 | if (wb->mode < 0) | 1331 | if (ARGR(wb).mode < 0) |
1259 | ret = -EINVAL; | 1332 | ret = -EINVAL; |
1260 | else { | 1333 | else { |
1261 | if (wb->mode == PWC_WB_MANUAL) { | 1334 | if (ARGR(wb).mode == PWC_WB_MANUAL) { |
1262 | ret = pwc_get_red_gain(pdev, &wb->manual_red); | 1335 | ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red); |
1263 | if (ret < 0) | 1336 | if (ret < 0) |
1264 | break; | 1337 | break; |
1265 | ret = pwc_get_blue_gain(pdev, &wb->manual_blue); | 1338 | ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue); |
1266 | if (ret < 0) | 1339 | if (ret < 0) |
1267 | break; | 1340 | break; |
1268 | } | 1341 | } |
1269 | if (wb->mode == PWC_WB_AUTO) { | 1342 | if (ARGR(wb).mode == PWC_WB_AUTO) { |
1270 | ret = pwc_read_red_gain(pdev, &wb->read_red); | 1343 | ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red); |
1271 | if (ret < 0) | 1344 | if (ret < 0) |
1272 | break; | 1345 | break; |
1273 | ret = pwc_read_blue_gain(pdev, &wb->read_blue); | 1346 | ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue); |
1274 | if (ret < 0) | 1347 | if (ret < 0) |
1275 | break; | 1348 | break; |
1276 | } | 1349 | } |
1277 | } | 1350 | } |
1351 | ARG_OUT(wb) | ||
1278 | break; | 1352 | break; |
1279 | } | 1353 | } |
1280 | 1354 | ||
1281 | case VIDIOCPWCSAWBSPEED: | 1355 | case VIDIOCPWCSAWBSPEED: |
1282 | { | 1356 | { |
1283 | struct pwc_wb_speed *wbs = arg; | 1357 | ARG_DEF(struct pwc_wb_speed, wbs) |
1284 | 1358 | ||
1285 | if (wbs->control_speed > 0) { | 1359 | if (ARGR(wbs).control_speed > 0) { |
1286 | ret = pwc_set_wb_speed(pdev, wbs->control_speed); | 1360 | ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed); |
1287 | } | 1361 | } |
1288 | if (wbs->control_delay > 0) { | 1362 | if (ARGR(wbs).control_delay > 0) { |
1289 | ret = pwc_set_wb_delay(pdev, wbs->control_delay); | 1363 | ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay); |
1290 | } | 1364 | } |
1291 | break; | 1365 | break; |
1292 | } | 1366 | } |
1293 | 1367 | ||
1294 | case VIDIOCPWCGAWBSPEED: | 1368 | case VIDIOCPWCGAWBSPEED: |
1295 | { | 1369 | { |
1296 | struct pwc_wb_speed *wbs = arg; | 1370 | ARG_DEF(struct pwc_wb_speed, wbs) |
1297 | 1371 | ||
1298 | ret = pwc_get_wb_speed(pdev, &wbs->control_speed); | 1372 | ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed); |
1299 | if (ret < 0) | 1373 | if (ret < 0) |
1300 | break; | 1374 | break; |
1301 | ret = pwc_get_wb_delay(pdev, &wbs->control_delay); | 1375 | ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay); |
1302 | if (ret < 0) | 1376 | if (ret < 0) |
1303 | break; | 1377 | break; |
1378 | ARG_OUT(wbs) | ||
1304 | break; | 1379 | break; |
1305 | } | 1380 | } |
1306 | 1381 | ||
1307 | case VIDIOCPWCSLED: | 1382 | case VIDIOCPWCSLED: |
1308 | { | 1383 | { |
1309 | struct pwc_leds *leds = arg; | 1384 | ARG_DEF(struct pwc_leds, leds) |
1310 | ret = pwc_set_leds(pdev, leds->led_on, leds->led_off); | 1385 | |
1311 | break; | 1386 | ARG_IN(leds) |
1387 | ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off); | ||
1388 | break; | ||
1312 | } | 1389 | } |
1313 | 1390 | ||
1314 | 1391 | ||
1315 | case VIDIOCPWCGLED: | 1392 | case VIDIOCPWCGLED: |
1316 | { | 1393 | { |
1317 | struct pwc_leds *leds = arg; | 1394 | ARG_DEF(struct pwc_leds, leds) |
1318 | ret = pwc_get_leds(pdev, &leds->led_on, &leds->led_off); | 1395 | |
1396 | ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off); | ||
1397 | ARG_OUT(leds) | ||
1319 | break; | 1398 | break; |
1320 | } | 1399 | } |
1321 | 1400 | ||
1322 | case VIDIOCPWCSCONTOUR: | 1401 | case VIDIOCPWCSCONTOUR: |
1323 | { | 1402 | { |
1324 | int *contour = arg; | 1403 | ARG_DEF(int, contour) |
1325 | ret = pwc_set_contour(pdev, *contour); | 1404 | |
1405 | ARG_IN(contour) | ||
1406 | ret = pwc_set_contour(pdev, ARGR(contour)); | ||
1326 | break; | 1407 | break; |
1327 | } | 1408 | } |
1328 | 1409 | ||
1329 | case VIDIOCPWCGCONTOUR: | 1410 | case VIDIOCPWCGCONTOUR: |
1330 | { | 1411 | { |
1331 | int *contour = arg; | 1412 | ARG_DEF(int, contour) |
1332 | ret = pwc_get_contour(pdev, contour); | 1413 | |
1414 | ret = pwc_get_contour(pdev, ARGA(contour)); | ||
1415 | ARG_OUT(contour) | ||
1333 | break; | 1416 | break; |
1334 | } | 1417 | } |
1335 | 1418 | ||
1336 | case VIDIOCPWCSBACKLIGHT: | 1419 | case VIDIOCPWCSBACKLIGHT: |
1337 | { | 1420 | { |
1338 | int *backlight = arg; | 1421 | ARG_DEF(int, backlight) |
1339 | ret = pwc_set_backlight(pdev, *backlight); | 1422 | |
1423 | ARG_IN(backlight) | ||
1424 | ret = pwc_set_backlight(pdev, ARGR(backlight)); | ||
1340 | break; | 1425 | break; |
1341 | } | 1426 | } |
1342 | 1427 | ||
1343 | case VIDIOCPWCGBACKLIGHT: | 1428 | case VIDIOCPWCGBACKLIGHT: |
1344 | { | 1429 | { |
1345 | int *backlight = arg; | 1430 | ARG_DEF(int, backlight) |
1346 | ret = pwc_get_backlight(pdev, backlight); | 1431 | |
1432 | ret = pwc_get_backlight(pdev, ARGA(backlight)); | ||
1433 | ARG_OUT(backlight) | ||
1347 | break; | 1434 | break; |
1348 | } | 1435 | } |
1349 | 1436 | ||
1350 | case VIDIOCPWCSFLICKER: | 1437 | case VIDIOCPWCSFLICKER: |
1351 | { | 1438 | { |
1352 | int *flicker = arg; | 1439 | ARG_DEF(int, flicker) |
1353 | ret = pwc_set_flicker(pdev, *flicker); | 1440 | |
1441 | ARG_IN(flicker) | ||
1442 | ret = pwc_set_flicker(pdev, ARGR(flicker)); | ||
1354 | break; | 1443 | break; |
1355 | } | 1444 | } |
1356 | 1445 | ||
1357 | case VIDIOCPWCGFLICKER: | 1446 | case VIDIOCPWCGFLICKER: |
1358 | { | 1447 | { |
1359 | int *flicker = arg; | 1448 | ARG_DEF(int, flicker) |
1360 | ret = pwc_get_flicker(pdev, flicker); | 1449 | |
1450 | ret = pwc_get_flicker(pdev, ARGA(flicker)); | ||
1451 | ARG_OUT(flicker) | ||
1361 | break; | 1452 | break; |
1362 | } | 1453 | } |
1363 | 1454 | ||
1364 | case VIDIOCPWCSDYNNOISE: | 1455 | case VIDIOCPWCSDYNNOISE: |
1365 | { | 1456 | { |
1366 | int *dynnoise = arg; | 1457 | ARG_DEF(int, dynnoise) |
1367 | ret = pwc_set_dynamic_noise(pdev, *dynnoise); | 1458 | |
1459 | ARG_IN(dynnoise) | ||
1460 | ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise)); | ||
1368 | break; | 1461 | break; |
1369 | } | 1462 | } |
1370 | 1463 | ||
1371 | case VIDIOCPWCGDYNNOISE: | 1464 | case VIDIOCPWCGDYNNOISE: |
1372 | { | 1465 | { |
1373 | int *dynnoise = arg; | 1466 | ARG_DEF(int, dynnoise) |
1374 | ret = pwc_get_dynamic_noise(pdev, dynnoise); | 1467 | |
1468 | ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise)); | ||
1469 | ARG_OUT(dynnoise); | ||
1375 | break; | 1470 | break; |
1376 | } | 1471 | } |
1377 | 1472 | ||
1378 | case VIDIOCPWCGREALSIZE: | 1473 | case VIDIOCPWCGREALSIZE: |
1379 | { | 1474 | { |
1380 | struct pwc_imagesize *size = arg; | 1475 | ARG_DEF(struct pwc_imagesize, size) |
1381 | size->width = pdev->image.x; | 1476 | |
1382 | size->height = pdev->image.y; | 1477 | ARGR(size).width = pdev->image.x; |
1478 | ARGR(size).height = pdev->image.y; | ||
1479 | ARG_OUT(size) | ||
1383 | break; | 1480 | break; |
1384 | } | 1481 | } |
1385 | 1482 | ||
@@ -1387,14 +1484,10 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1387 | { | 1484 | { |
1388 | if (pdev->features & FEATURE_MOTOR_PANTILT) | 1485 | if (pdev->features & FEATURE_MOTOR_PANTILT) |
1389 | { | 1486 | { |
1390 | int *flags = arg; | 1487 | ARG_DEF(int, flags) |
1391 | 1488 | ||
1392 | ret = pwc_mpt_reset(pdev, *flags); | 1489 | ARG_IN(flags) |
1393 | if (ret >= 0) | 1490 | ret = pwc_mpt_reset(pdev, ARGR(flags)); |
1394 | { | ||
1395 | pdev->pan_angle = 0; | ||
1396 | pdev->tilt_angle = 0; | ||
1397 | } | ||
1398 | } | 1491 | } |
1399 | else | 1492 | else |
1400 | { | 1493 | { |
@@ -1407,8 +1500,10 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1407 | { | 1500 | { |
1408 | if (pdev->features & FEATURE_MOTOR_PANTILT) | 1501 | if (pdev->features & FEATURE_MOTOR_PANTILT) |
1409 | { | 1502 | { |
1410 | struct pwc_mpt_range *range = arg; | 1503 | ARG_DEF(struct pwc_mpt_range, range) |
1411 | *range = pdev->angle_range; | 1504 | |
1505 | ARGR(range) = pdev->angle_range; | ||
1506 | ARG_OUT(range) | ||
1412 | } | 1507 | } |
1413 | else | 1508 | else |
1414 | { | 1509 | { |
@@ -1423,48 +1518,23 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1423 | 1518 | ||
1424 | if (pdev->features & FEATURE_MOTOR_PANTILT) | 1519 | if (pdev->features & FEATURE_MOTOR_PANTILT) |
1425 | { | 1520 | { |
1426 | struct pwc_mpt_angles *angles = arg; | 1521 | ARG_DEF(struct pwc_mpt_angles, angles) |
1522 | |||
1523 | ARG_IN(angles) | ||
1427 | /* The camera can only set relative angles, so | 1524 | /* The camera can only set relative angles, so |
1428 | do some calculations when getting an absolute angle . | 1525 | do some calculations when getting an absolute angle . |
1429 | */ | 1526 | */ |
1430 | if (angles->absolute) | 1527 | if (ARGR(angles).absolute) |
1431 | { | 1528 | { |
1432 | new_pan = angles->pan; | 1529 | new_pan = ARGR(angles).pan; |
1433 | new_tilt = angles->tilt; | 1530 | new_tilt = ARGR(angles).tilt; |
1434 | } | 1531 | } |
1435 | else | 1532 | else |
1436 | { | 1533 | { |
1437 | new_pan = pdev->pan_angle + angles->pan; | 1534 | new_pan = pdev->pan_angle + ARGR(angles).pan; |
1438 | new_tilt = pdev->tilt_angle + angles->tilt; | 1535 | new_tilt = pdev->tilt_angle + ARGR(angles).tilt; |
1439 | } | ||
1440 | /* check absolute ranges */ | ||
1441 | if (new_pan < pdev->angle_range.pan_min || | ||
1442 | new_pan > pdev->angle_range.pan_max || | ||
1443 | new_tilt < pdev->angle_range.tilt_min || | ||
1444 | new_tilt > pdev->angle_range.tilt_max) | ||
1445 | { | ||
1446 | ret = -ERANGE; | ||
1447 | } | ||
1448 | else | ||
1449 | { | ||
1450 | /* go to relative range, check again */ | ||
1451 | new_pan -= pdev->pan_angle; | ||
1452 | new_tilt -= pdev->tilt_angle; | ||
1453 | /* angles are specified in degrees * 100, thus the limit = 36000 */ | ||
1454 | if (new_pan < -36000 || new_pan > 36000 || new_tilt < -36000 || new_tilt > 36000) | ||
1455 | ret = -ERANGE; | ||
1456 | } | ||
1457 | if (ret == 0) /* no errors so far */ | ||
1458 | { | ||
1459 | ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt); | ||
1460 | if (ret >= 0) | ||
1461 | { | ||
1462 | pdev->pan_angle += new_pan; | ||
1463 | pdev->tilt_angle += new_tilt; | ||
1464 | } | ||
1465 | if (ret == -EPIPE) /* stall -> out of range */ | ||
1466 | ret = -ERANGE; | ||
1467 | } | 1536 | } |
1537 | ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt); | ||
1468 | } | 1538 | } |
1469 | else | 1539 | else |
1470 | { | 1540 | { |
@@ -1478,11 +1548,12 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1478 | 1548 | ||
1479 | if (pdev->features & FEATURE_MOTOR_PANTILT) | 1549 | if (pdev->features & FEATURE_MOTOR_PANTILT) |
1480 | { | 1550 | { |
1481 | struct pwc_mpt_angles *angles = arg; | 1551 | ARG_DEF(struct pwc_mpt_angles, angles) |
1482 | 1552 | ||
1483 | angles->absolute = 1; | 1553 | ARGR(angles).absolute = 1; |
1484 | angles->pan = pdev->pan_angle; | 1554 | ARGR(angles).pan = pdev->pan_angle; |
1485 | angles->tilt = pdev->tilt_angle; | 1555 | ARGR(angles).tilt = pdev->tilt_angle; |
1556 | ARG_OUT(angles) | ||
1486 | } | 1557 | } |
1487 | else | 1558 | else |
1488 | { | 1559 | { |
@@ -1495,8 +1566,10 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1495 | { | 1566 | { |
1496 | if (pdev->features & FEATURE_MOTOR_PANTILT) | 1567 | if (pdev->features & FEATURE_MOTOR_PANTILT) |
1497 | { | 1568 | { |
1498 | struct pwc_mpt_status *status = arg; | 1569 | ARG_DEF(struct pwc_mpt_status, status) |
1499 | ret = pwc_mpt_get_status(pdev, status); | 1570 | |
1571 | ret = pwc_mpt_get_status(pdev, ARGA(status)); | ||
1572 | ARG_OUT(status) | ||
1500 | } | 1573 | } |
1501 | else | 1574 | else |
1502 | { | 1575 | { |
@@ -1507,22 +1580,24 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1507 | 1580 | ||
1508 | case VIDIOCPWCGVIDCMD: | 1581 | case VIDIOCPWCGVIDCMD: |
1509 | { | 1582 | { |
1510 | struct pwc_video_command *cmd = arg; | 1583 | ARG_DEF(struct pwc_video_command, cmd); |
1511 | 1584 | ||
1512 | cmd->type = pdev->type; | 1585 | ARGR(cmd).type = pdev->type; |
1513 | cmd->release = pdev->release; | 1586 | ARGR(cmd).release = pdev->release; |
1514 | cmd->command_len = pdev->cmd_len; | 1587 | ARGR(cmd).command_len = pdev->cmd_len; |
1515 | memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len); | 1588 | memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len); |
1516 | cmd->bandlength = pdev->vbandlength; | 1589 | ARGR(cmd).bandlength = pdev->vbandlength; |
1517 | cmd->frame_size = pdev->frame_size; | 1590 | ARGR(cmd).frame_size = pdev->frame_size; |
1591 | ARG_OUT(cmd) | ||
1518 | break; | 1592 | break; |
1519 | } | 1593 | } |
1520 | /* | 1594 | /* |
1521 | case VIDIOCPWCGVIDTABLE: | 1595 | case VIDIOCPWCGVIDTABLE: |
1522 | { | 1596 | { |
1523 | struct pwc_table_init_buffer *table = arg; | 1597 | ARG_DEF(struct pwc_table_init_buffer, table); |
1524 | table->len = pdev->cmd_len; | 1598 | ARGR(table).len = pdev->cmd_len; |
1525 | memcpy(&table->buffer, pdev->decompress_data, pdev->decompressor->table_size); | 1599 | memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size); |
1600 | ARG_OUT(table) | ||
1526 | break; | 1601 | break; |
1527 | } | 1602 | } |
1528 | */ | 1603 | */ |
@@ -1538,4 +1613,4 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1538 | } | 1613 | } |
1539 | 1614 | ||
1540 | 1615 | ||
1541 | 1616 | /* vim: set cinoptions= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ | |
diff --git a/drivers/media/video/pwc/pwc-dec1.c b/drivers/media/video/pwc/pwc-dec1.c new file mode 100644 index 000000000000..c29593f589eb --- /dev/null +++ b/drivers/media/video/pwc/pwc-dec1.c | |||
@@ -0,0 +1,50 @@ | |||
1 | /* Linux driver for Philips webcam | ||
2 | Decompression for chipset version 1 | ||
3 | (C) 2004-2006 Luc Saillard (luc@saillard.org) | ||
4 | |||
5 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | ||
6 | driver and thus may have bugs that are not present in the original version. | ||
7 | Please send bug reports and support requests to <luc@saillard.org>. | ||
8 | The decompression routines have been implemented by reverse-engineering the | ||
9 | Nemosoft binary pwcx module. Caveat emptor. | ||
10 | |||
11 | This program is free software; you can redistribute it and/or modify | ||
12 | it under the terms of the GNU General Public License as published by | ||
13 | the Free Software Foundation; either version 2 of the License, or | ||
14 | (at your option) any later version. | ||
15 | |||
16 | This program is distributed in the hope that it will be useful, | ||
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | GNU General Public License for more details. | ||
20 | |||
21 | You should have received a copy of the GNU General Public License | ||
22 | along with this program; if not, write to the Free Software | ||
23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | |||
27 | |||
28 | #include "pwc-dec1.h" | ||
29 | |||
30 | |||
31 | void pwc_dec1_init(int type, int release, void *buffer, void *table) | ||
32 | { | ||
33 | |||
34 | } | ||
35 | |||
36 | void pwc_dec1_exit(void) | ||
37 | { | ||
38 | |||
39 | |||
40 | |||
41 | } | ||
42 | |||
43 | int pwc_dec1_alloc(struct pwc_device *pwc) | ||
44 | { | ||
45 | pwc->decompress_data = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL); | ||
46 | if (pwc->decompress_data == NULL) | ||
47 | return -ENOMEM; | ||
48 | return 0; | ||
49 | } | ||
50 | |||
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/video/pwc/pwc-dec1.h new file mode 100644 index 000000000000..8b62ddcc5c7e --- /dev/null +++ b/drivers/media/video/pwc/pwc-dec1.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* Linux driver for Philips webcam | ||
2 | (C) 2004-2006 Luc Saillard (luc@saillard.org) | ||
3 | |||
4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | ||
5 | driver and thus may have bugs that are not present in the original version. | ||
6 | Please send bug reports and support requests to <luc@saillard.org>. | ||
7 | The decompression routines have been implemented by reverse-engineering the | ||
8 | Nemosoft binary pwcx module. Caveat emptor. | ||
9 | |||
10 | This program is free software; you can redistribute it and/or modify | ||
11 | it under the terms of the GNU General Public License as published by | ||
12 | the Free Software Foundation; either version 2 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software | ||
22 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | |||
25 | |||
26 | |||
27 | #ifndef PWC_DEC1_H | ||
28 | #define PWC_DEC1_H | ||
29 | |||
30 | #include "pwc.h" | ||
31 | |||
32 | struct pwc_dec1_private | ||
33 | { | ||
34 | int version; | ||
35 | |||
36 | }; | ||
37 | |||
38 | int pwc_dec1_alloc(struct pwc_device *pwc); | ||
39 | void pwc_dec1_init(int type, int release, void *buffer, void *private_data); | ||
40 | void pwc_dec1_exit(void); | ||
41 | |||
42 | #endif | ||
43 | |||
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c new file mode 100644 index 000000000000..9e2d91f26bfe --- /dev/null +++ b/drivers/media/video/pwc/pwc-dec23.c | |||
@@ -0,0 +1,941 @@ | |||
1 | /* Linux driver for Philips webcam | ||
2 | Decompression for chipset version 2 et 3 | ||
3 | (C) 2004-2006 Luc Saillard (luc@saillard.org) | ||
4 | |||
5 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | ||
6 | driver and thus may have bugs that are not present in the original version. | ||
7 | Please send bug reports and support requests to <luc@saillard.org>. | ||
8 | The decompression routines have been implemented by reverse-engineering the | ||
9 | Nemosoft binary pwcx module. Caveat emptor. | ||
10 | |||
11 | This program is free software; you can redistribute it and/or modify | ||
12 | it under the terms of the GNU General Public License as published by | ||
13 | the Free Software Foundation; either version 2 of the License, or | ||
14 | (at your option) any later version. | ||
15 | |||
16 | This program is distributed in the hope that it will be useful, | ||
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | GNU General Public License for more details. | ||
20 | |||
21 | You should have received a copy of the GNU General Public License | ||
22 | along with this program; if not, write to the Free Software | ||
23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | |||
25 | */ | ||
26 | |||
27 | #include "pwc-timon.h" | ||
28 | #include "pwc-kiara.h" | ||
29 | #include "pwc-dec23.h" | ||
30 | #include <media/pwc-ioctl.h> | ||
31 | |||
32 | #include <linux/string.h> | ||
33 | |||
34 | /* | ||
35 | * USE_LOOKUP_TABLE_TO_CLAMP | ||
36 | * 0: use a C version of this tests: { a<0?0:(a>255?255:a) } | ||
37 | * 1: use a faster lookup table for cpu with a big cache (intel) | ||
38 | */ | ||
39 | #define USE_LOOKUP_TABLE_TO_CLAMP 1 | ||
40 | /* | ||
41 | * UNROLL_LOOP_FOR_COPYING_BLOCK | ||
42 | * 0: use a loop for a smaller code (but little slower) | ||
43 | * 1: when unrolling the loop, gcc produces some faster code (perhaps only | ||
44 | * valid for intel processor class). Activating this option, automaticaly | ||
45 | * activate USE_LOOKUP_TABLE_TO_CLAMP | ||
46 | */ | ||
47 | #define UNROLL_LOOP_FOR_COPY 1 | ||
48 | #if UNROLL_LOOP_FOR_COPY | ||
49 | # undef USE_LOOKUP_TABLE_TO_CLAMP | ||
50 | # define USE_LOOKUP_TABLE_TO_CLAMP 1 | ||
51 | #endif | ||
52 | |||
53 | /* | ||
54 | * ENABLE_BAYER_DECODER | ||
55 | * 0: bayer decoder is not build (save some space) | ||
56 | * 1: bayer decoder is build and can be used | ||
57 | */ | ||
58 | #define ENABLE_BAYER_DECODER 0 | ||
59 | |||
60 | static void build_subblock_pattern(struct pwc_dec23_private *pdec) | ||
61 | { | ||
62 | static const unsigned int initial_values[12] = { | ||
63 | -0x526500, -0x221200, 0x221200, 0x526500, | ||
64 | -0x3de200, 0x3de200, | ||
65 | -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480, | ||
66 | -0x12c200, 0x12c200 | ||
67 | |||
68 | }; | ||
69 | static const unsigned int values_derivated[12] = { | ||
70 | 0xa4ca, 0x4424, -0x4424, -0xa4ca, | ||
71 | 0x7bc4, -0x7bc4, | ||
72 | 0xdb69, 0x5aba, -0x5aba, -0xdb69, | ||
73 | 0x2584, -0x2584 | ||
74 | }; | ||
75 | unsigned int temp_values[12]; | ||
76 | int i, j; | ||
77 | |||
78 | memcpy(temp_values, initial_values, sizeof(initial_values)); | ||
79 | for (i = 0; i < 256; i++) { | ||
80 | for (j = 0; j < 12; j++) { | ||
81 | pdec->table_subblock[i][j] = temp_values[j]; | ||
82 | temp_values[j] += values_derivated[j]; | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | |||
87 | static void build_bit_powermask_table(struct pwc_dec23_private *pdec) | ||
88 | { | ||
89 | unsigned char *p; | ||
90 | unsigned int bit, byte, mask, val; | ||
91 | unsigned int bitpower = 1; | ||
92 | |||
93 | for (bit = 0; bit < 8; bit++) { | ||
94 | mask = bitpower - 1; | ||
95 | p = pdec->table_bitpowermask[bit]; | ||
96 | for (byte = 0; byte < 256; byte++) { | ||
97 | val = (byte & mask); | ||
98 | if (byte & bitpower) | ||
99 | val = -val; | ||
100 | *p++ = val; | ||
101 | } | ||
102 | bitpower<<=1; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | |||
107 | static void build_table_color(const unsigned int romtable[16][8], | ||
108 | unsigned char p0004[16][1024], | ||
109 | unsigned char p8004[16][256]) | ||
110 | { | ||
111 | int compression_mode, j, k, bit, pw; | ||
112 | unsigned char *p0, *p8; | ||
113 | const unsigned int *r; | ||
114 | |||
115 | /* We have 16 compressions tables */ | ||
116 | for (compression_mode = 0; compression_mode < 16; compression_mode++) { | ||
117 | p0 = p0004[compression_mode]; | ||
118 | p8 = p8004[compression_mode]; | ||
119 | r = romtable[compression_mode]; | ||
120 | |||
121 | for (j = 0; j < 8; j++, r++, p0 += 128) { | ||
122 | |||
123 | for (k = 0; k < 16; k++) { | ||
124 | if (k == 0) | ||
125 | bit = 1; | ||
126 | else if (k >= 1 && k < 3) | ||
127 | bit = (r[0] >> 15) & 7; | ||
128 | else if (k >= 3 && k < 6) | ||
129 | bit = (r[0] >> 12) & 7; | ||
130 | else if (k >= 6 && k < 10) | ||
131 | bit = (r[0] >> 9) & 7; | ||
132 | else if (k >= 10 && k < 13) | ||
133 | bit = (r[0] >> 6) & 7; | ||
134 | else if (k >= 13 && k < 15) | ||
135 | bit = (r[0] >> 3) & 7; | ||
136 | else | ||
137 | bit = (r[0]) & 7; | ||
138 | if (k == 0) | ||
139 | *p8++ = 8; | ||
140 | else | ||
141 | *p8++ = j - bit; | ||
142 | *p8++ = bit; | ||
143 | |||
144 | pw = 1 << bit; | ||
145 | p0[k + 0x00] = (1 * pw) + 0x80; | ||
146 | p0[k + 0x10] = (2 * pw) + 0x80; | ||
147 | p0[k + 0x20] = (3 * pw) + 0x80; | ||
148 | p0[k + 0x30] = (4 * pw) + 0x80; | ||
149 | p0[k + 0x40] = (-1 * pw) + 0x80; | ||
150 | p0[k + 0x50] = (-2 * pw) + 0x80; | ||
151 | p0[k + 0x60] = (-3 * pw) + 0x80; | ||
152 | p0[k + 0x70] = (-4 * pw) + 0x80; | ||
153 | } /* end of for (k=0; k<16; k++, p8++) */ | ||
154 | } /* end of for (j=0; j<8; j++ , table++) */ | ||
155 | } /* end of foreach compression_mode */ | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * | ||
160 | */ | ||
161 | static void fill_table_dc00_d800(struct pwc_dec23_private *pdec) | ||
162 | { | ||
163 | #define SCALEBITS 15 | ||
164 | #define ONE_HALF (1UL << (SCALEBITS - 1)) | ||
165 | int i; | ||
166 | unsigned int offset1 = ONE_HALF; | ||
167 | unsigned int offset2 = 0x0000; | ||
168 | |||
169 | for (i=0; i<256; i++) { | ||
170 | pdec->table_dc00[i] = offset1 & ~(ONE_HALF); | ||
171 | pdec->table_d800[i] = offset2; | ||
172 | |||
173 | offset1 += 0x7bc4; | ||
174 | offset2 += 0x7bc4; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | /* | ||
179 | * To decode the stream: | ||
180 | * if look_bits(2) == 0: # op == 2 in the lookup table | ||
181 | * skip_bits(2) | ||
182 | * end of the stream | ||
183 | * elif look_bits(3) == 7: # op == 1 in the lookup table | ||
184 | * skip_bits(3) | ||
185 | * yyyy = get_bits(4) | ||
186 | * xxxx = get_bits(8) | ||
187 | * else: # op == 0 in the lookup table | ||
188 | * skip_bits(x) | ||
189 | * | ||
190 | * For speedup processing, we build a lookup table and we takes the first 6 bits. | ||
191 | * | ||
192 | * struct { | ||
193 | * unsigned char op; // operation to execute | ||
194 | * unsigned char bits; // bits use to perform operation | ||
195 | * unsigned char offset1; // offset to add to access in the table_0004 % 16 | ||
196 | * unsigned char offset2; // offset to add to access in the table_0004 | ||
197 | * } | ||
198 | * | ||
199 | * How to build this table ? | ||
200 | * op == 2 when (i%4)==0 | ||
201 | * op == 1 when (i%8)==7 | ||
202 | * op == 0 otherwise | ||
203 | * | ||
204 | */ | ||
205 | static const unsigned char hash_table_ops[64*4] = { | ||
206 | 0x02, 0x00, 0x00, 0x00, | ||
207 | 0x00, 0x03, 0x01, 0x00, | ||
208 | 0x00, 0x04, 0x01, 0x10, | ||
209 | 0x00, 0x06, 0x01, 0x30, | ||
210 | 0x02, 0x00, 0x00, 0x00, | ||
211 | 0x00, 0x03, 0x01, 0x40, | ||
212 | 0x00, 0x05, 0x01, 0x20, | ||
213 | 0x01, 0x00, 0x00, 0x00, | ||
214 | 0x02, 0x00, 0x00, 0x00, | ||
215 | 0x00, 0x03, 0x01, 0x00, | ||
216 | 0x00, 0x04, 0x01, 0x50, | ||
217 | 0x00, 0x05, 0x02, 0x00, | ||
218 | 0x02, 0x00, 0x00, 0x00, | ||
219 | 0x00, 0x03, 0x01, 0x40, | ||
220 | 0x00, 0x05, 0x03, 0x00, | ||
221 | 0x01, 0x00, 0x00, 0x00, | ||
222 | 0x02, 0x00, 0x00, 0x00, | ||
223 | 0x00, 0x03, 0x01, 0x00, | ||
224 | 0x00, 0x04, 0x01, 0x10, | ||
225 | 0x00, 0x06, 0x02, 0x10, | ||
226 | 0x02, 0x00, 0x00, 0x00, | ||
227 | 0x00, 0x03, 0x01, 0x40, | ||
228 | 0x00, 0x05, 0x01, 0x60, | ||
229 | 0x01, 0x00, 0x00, 0x00, | ||
230 | 0x02, 0x00, 0x00, 0x00, | ||
231 | 0x00, 0x03, 0x01, 0x00, | ||
232 | 0x00, 0x04, 0x01, 0x50, | ||
233 | 0x00, 0x05, 0x02, 0x40, | ||
234 | 0x02, 0x00, 0x00, 0x00, | ||
235 | 0x00, 0x03, 0x01, 0x40, | ||
236 | 0x00, 0x05, 0x03, 0x40, | ||
237 | 0x01, 0x00, 0x00, 0x00, | ||
238 | 0x02, 0x00, 0x00, 0x00, | ||
239 | 0x00, 0x03, 0x01, 0x00, | ||
240 | 0x00, 0x04, 0x01, 0x10, | ||
241 | 0x00, 0x06, 0x01, 0x70, | ||
242 | 0x02, 0x00, 0x00, 0x00, | ||
243 | 0x00, 0x03, 0x01, 0x40, | ||
244 | 0x00, 0x05, 0x01, 0x20, | ||
245 | 0x01, 0x00, 0x00, 0x00, | ||
246 | 0x02, 0x00, 0x00, 0x00, | ||
247 | 0x00, 0x03, 0x01, 0x00, | ||
248 | 0x00, 0x04, 0x01, 0x50, | ||
249 | 0x00, 0x05, 0x02, 0x00, | ||
250 | 0x02, 0x00, 0x00, 0x00, | ||
251 | 0x00, 0x03, 0x01, 0x40, | ||
252 | 0x00, 0x05, 0x03, 0x00, | ||
253 | 0x01, 0x00, 0x00, 0x00, | ||
254 | 0x02, 0x00, 0x00, 0x00, | ||
255 | 0x00, 0x03, 0x01, 0x00, | ||
256 | 0x00, 0x04, 0x01, 0x10, | ||
257 | 0x00, 0x06, 0x02, 0x50, | ||
258 | 0x02, 0x00, 0x00, 0x00, | ||
259 | 0x00, 0x03, 0x01, 0x40, | ||
260 | 0x00, 0x05, 0x01, 0x60, | ||
261 | 0x01, 0x00, 0x00, 0x00, | ||
262 | 0x02, 0x00, 0x00, 0x00, | ||
263 | 0x00, 0x03, 0x01, 0x00, | ||
264 | 0x00, 0x04, 0x01, 0x50, | ||
265 | 0x00, 0x05, 0x02, 0x40, | ||
266 | 0x02, 0x00, 0x00, 0x00, | ||
267 | 0x00, 0x03, 0x01, 0x40, | ||
268 | 0x00, 0x05, 0x03, 0x40, | ||
269 | 0x01, 0x00, 0x00, 0x00 | ||
270 | }; | ||
271 | |||
272 | /* | ||
273 | * | ||
274 | */ | ||
275 | static const unsigned int MulIdx[16][16] = { | ||
276 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, | ||
277 | {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,}, | ||
278 | {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,}, | ||
279 | {4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,}, | ||
280 | {6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,}, | ||
281 | {4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,}, | ||
282 | {1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,}, | ||
283 | {0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,}, | ||
284 | {0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,}, | ||
285 | {1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,}, | ||
286 | {7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,}, | ||
287 | {4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,}, | ||
288 | {7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,}, | ||
289 | {1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,}, | ||
290 | {1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,}, | ||
291 | {10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10} | ||
292 | }; | ||
293 | |||
294 | #if USE_LOOKUP_TABLE_TO_CLAMP | ||
295 | #define MAX_OUTER_CROP_VALUE (512) | ||
296 | static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE]; | ||
297 | #define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)]) | ||
298 | #else | ||
299 | #define CLAMP(x) ((x)>255?255:((x)<0?0:x)) | ||
300 | #endif | ||
301 | |||
302 | |||
303 | /* If the type or the command change, we rebuild the lookup table */ | ||
304 | int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd) | ||
305 | { | ||
306 | int flags, version, shift, i; | ||
307 | struct pwc_dec23_private *pdec; | ||
308 | |||
309 | if (pwc->decompress_data == NULL) { | ||
310 | pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); | ||
311 | if (pdec == NULL) | ||
312 | return -ENOMEM; | ||
313 | pwc->decompress_data = pdec; | ||
314 | } | ||
315 | pdec = pwc->decompress_data; | ||
316 | |||
317 | if (DEVICE_USE_CODEC3(type)) { | ||
318 | flags = cmd[2] & 0x18; | ||
319 | if (flags == 8) | ||
320 | pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */ | ||
321 | else if (flags == 0x10) | ||
322 | pdec->nbits = 8; | ||
323 | else | ||
324 | pdec->nbits = 6; | ||
325 | |||
326 | version = cmd[2] >> 5; | ||
327 | build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1); | ||
328 | build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2); | ||
329 | |||
330 | } else { | ||
331 | |||
332 | flags = cmd[2] & 6; | ||
333 | if (flags == 2) | ||
334 | pdec->nbits = 7; | ||
335 | else if (flags == 4) | ||
336 | pdec->nbits = 8; | ||
337 | else | ||
338 | pdec->nbits = 6; | ||
339 | |||
340 | version = cmd[2] >> 3; | ||
341 | build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1); | ||
342 | build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2); | ||
343 | } | ||
344 | |||
345 | /* Informations can be coded on a variable number of bits but never less than 8 */ | ||
346 | shift = 8 - pdec->nbits; | ||
347 | pdec->scalebits = SCALEBITS - shift; | ||
348 | pdec->nbitsmask = 0xFF >> shift; | ||
349 | |||
350 | fill_table_dc00_d800(pdec); | ||
351 | build_subblock_pattern(pdec); | ||
352 | build_bit_powermask_table(pdec); | ||
353 | |||
354 | #if USE_LOOKUP_TABLE_TO_CLAMP | ||
355 | /* Build the static table to clamp value [0-255] */ | ||
356 | for (i=0;i<MAX_OUTER_CROP_VALUE;i++) | ||
357 | pwc_crop_table[i] = 0; | ||
358 | for (i=0; i<256; i++) | ||
359 | pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i; | ||
360 | for (i=0; i<MAX_OUTER_CROP_VALUE; i++) | ||
361 | pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255; | ||
362 | #endif | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * Copy the 4x4 image block to Y plane buffer | ||
369 | */ | ||
370 | static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) | ||
371 | { | ||
372 | #if UNROLL_LOOP_FOR_COPY | ||
373 | const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE; | ||
374 | const int *c = src; | ||
375 | unsigned char *d = dst; | ||
376 | |||
377 | *d++ = cm[c[0] >> scalebits]; | ||
378 | *d++ = cm[c[1] >> scalebits]; | ||
379 | *d++ = cm[c[2] >> scalebits]; | ||
380 | *d++ = cm[c[3] >> scalebits]; | ||
381 | |||
382 | d = dst + bytes_per_line; | ||
383 | *d++ = cm[c[4] >> scalebits]; | ||
384 | *d++ = cm[c[5] >> scalebits]; | ||
385 | *d++ = cm[c[6] >> scalebits]; | ||
386 | *d++ = cm[c[7] >> scalebits]; | ||
387 | |||
388 | d = dst + bytes_per_line*2; | ||
389 | *d++ = cm[c[8] >> scalebits]; | ||
390 | *d++ = cm[c[9] >> scalebits]; | ||
391 | *d++ = cm[c[10] >> scalebits]; | ||
392 | *d++ = cm[c[11] >> scalebits]; | ||
393 | |||
394 | d = dst + bytes_per_line*3; | ||
395 | *d++ = cm[c[12] >> scalebits]; | ||
396 | *d++ = cm[c[13] >> scalebits]; | ||
397 | *d++ = cm[c[14] >> scalebits]; | ||
398 | *d++ = cm[c[15] >> scalebits]; | ||
399 | #else | ||
400 | int i; | ||
401 | const int *c = src; | ||
402 | unsigned char *d = dst; | ||
403 | for (i = 0; i < 4; i++, c++) | ||
404 | *d++ = CLAMP((*c) >> scalebits); | ||
405 | |||
406 | d = dst + bytes_per_line; | ||
407 | for (i = 0; i < 4; i++, c++) | ||
408 | *d++ = CLAMP((*c) >> scalebits); | ||
409 | |||
410 | d = dst + bytes_per_line*2; | ||
411 | for (i = 0; i < 4; i++, c++) | ||
412 | *d++ = CLAMP((*c) >> scalebits); | ||
413 | |||
414 | d = dst + bytes_per_line*3; | ||
415 | for (i = 0; i < 4; i++, c++) | ||
416 | *d++ = CLAMP((*c) >> scalebits); | ||
417 | #endif | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * Copy the 4x4 image block to a CrCb plane buffer | ||
422 | * | ||
423 | */ | ||
424 | static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) | ||
425 | { | ||
426 | #if UNROLL_LOOP_FOR_COPY | ||
427 | /* Unroll all loops */ | ||
428 | const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE; | ||
429 | const int *c = src; | ||
430 | unsigned char *d = dst; | ||
431 | |||
432 | *d++ = cm[c[0] >> scalebits]; | ||
433 | *d++ = cm[c[4] >> scalebits]; | ||
434 | *d++ = cm[c[1] >> scalebits]; | ||
435 | *d++ = cm[c[5] >> scalebits]; | ||
436 | *d++ = cm[c[2] >> scalebits]; | ||
437 | *d++ = cm[c[6] >> scalebits]; | ||
438 | *d++ = cm[c[3] >> scalebits]; | ||
439 | *d++ = cm[c[7] >> scalebits]; | ||
440 | |||
441 | d = dst + bytes_per_line; | ||
442 | *d++ = cm[c[12] >> scalebits]; | ||
443 | *d++ = cm[c[8] >> scalebits]; | ||
444 | *d++ = cm[c[13] >> scalebits]; | ||
445 | *d++ = cm[c[9] >> scalebits]; | ||
446 | *d++ = cm[c[14] >> scalebits]; | ||
447 | *d++ = cm[c[10] >> scalebits]; | ||
448 | *d++ = cm[c[15] >> scalebits]; | ||
449 | *d++ = cm[c[11] >> scalebits]; | ||
450 | #else | ||
451 | int i; | ||
452 | const int *c1 = src; | ||
453 | const int *c2 = src + 4; | ||
454 | unsigned char *d = dst; | ||
455 | |||
456 | for (i = 0; i < 4; i++, c1++, c2++) { | ||
457 | *d++ = CLAMP((*c1) >> scalebits); | ||
458 | *d++ = CLAMP((*c2) >> scalebits); | ||
459 | } | ||
460 | c1 = src + 12; | ||
461 | d = dst + bytes_per_line; | ||
462 | for (i = 0; i < 4; i++, c1++, c2++) { | ||
463 | *d++ = CLAMP((*c1) >> scalebits); | ||
464 | *d++ = CLAMP((*c2) >> scalebits); | ||
465 | } | ||
466 | #endif | ||
467 | } | ||
468 | |||
469 | #if ENABLE_BAYER_DECODER | ||
470 | /* | ||
471 | * Format: 8x2 pixels | ||
472 | * . G . G . G . G . G . G . G | ||
473 | * . . . . . . . . . . . . . . | ||
474 | * . G . G . G . G . G . G . G | ||
475 | * . . . . . . . . . . . . . . | ||
476 | * or | ||
477 | * . . . . . . . . . . . . . . | ||
478 | * G . G . G . G . G . G . G . | ||
479 | * . . . . . . . . . . . . . . | ||
480 | * G . G . G . G . G . G . G . | ||
481 | */ | ||
482 | static void copy_image_block_Green(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) | ||
483 | { | ||
484 | #if UNROLL_LOOP_FOR_COPY | ||
485 | /* Unroll all loops */ | ||
486 | const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE; | ||
487 | unsigned char *d = dst; | ||
488 | const int *c = src; | ||
489 | |||
490 | d[0] = cm[c[0] >> scalebits]; | ||
491 | d[2] = cm[c[1] >> scalebits]; | ||
492 | d[4] = cm[c[2] >> scalebits]; | ||
493 | d[6] = cm[c[3] >> scalebits]; | ||
494 | d[8] = cm[c[4] >> scalebits]; | ||
495 | d[10] = cm[c[5] >> scalebits]; | ||
496 | d[12] = cm[c[6] >> scalebits]; | ||
497 | d[14] = cm[c[7] >> scalebits]; | ||
498 | |||
499 | d = dst + bytes_per_line; | ||
500 | d[0] = cm[c[8] >> scalebits]; | ||
501 | d[2] = cm[c[9] >> scalebits]; | ||
502 | d[4] = cm[c[10] >> scalebits]; | ||
503 | d[6] = cm[c[11] >> scalebits]; | ||
504 | d[8] = cm[c[12] >> scalebits]; | ||
505 | d[10] = cm[c[13] >> scalebits]; | ||
506 | d[12] = cm[c[14] >> scalebits]; | ||
507 | d[14] = cm[c[15] >> scalebits]; | ||
508 | #else | ||
509 | int i; | ||
510 | unsigned char *d; | ||
511 | const int *c = src; | ||
512 | |||
513 | d = dst; | ||
514 | for (i = 0; i < 8; i++, c++) | ||
515 | d[i*2] = CLAMP((*c) >> scalebits); | ||
516 | |||
517 | d = dst + bytes_per_line; | ||
518 | for (i = 0; i < 8; i++, c++) | ||
519 | d[i*2] = CLAMP((*c) >> scalebits); | ||
520 | #endif | ||
521 | } | ||
522 | #endif | ||
523 | |||
524 | #if ENABLE_BAYER_DECODER | ||
525 | /* | ||
526 | * Format: 4x4 pixels | ||
527 | * R . R . R . R | ||
528 | * . B . B . B . | ||
529 | * R . R . R . R | ||
530 | * . B . B . B . | ||
531 | */ | ||
532 | static void copy_image_block_RedBlue(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) | ||
533 | { | ||
534 | #if UNROLL_LOOP_FOR_COPY | ||
535 | /* Unroll all loops */ | ||
536 | const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE; | ||
537 | unsigned char *d = dst; | ||
538 | const int *c = src; | ||
539 | |||
540 | d[0] = cm[c[0] >> scalebits]; | ||
541 | d[2] = cm[c[1] >> scalebits]; | ||
542 | d[4] = cm[c[2] >> scalebits]; | ||
543 | d[6] = cm[c[3] >> scalebits]; | ||
544 | |||
545 | d = dst + bytes_per_line; | ||
546 | d[1] = cm[c[4] >> scalebits]; | ||
547 | d[3] = cm[c[5] >> scalebits]; | ||
548 | d[5] = cm[c[6] >> scalebits]; | ||
549 | d[7] = cm[c[7] >> scalebits]; | ||
550 | |||
551 | d = dst + bytes_per_line*2; | ||
552 | d[0] = cm[c[8] >> scalebits]; | ||
553 | d[2] = cm[c[9] >> scalebits]; | ||
554 | d[4] = cm[c[10] >> scalebits]; | ||
555 | d[6] = cm[c[11] >> scalebits]; | ||
556 | |||
557 | d = dst + bytes_per_line*3; | ||
558 | d[1] = cm[c[12] >> scalebits]; | ||
559 | d[3] = cm[c[13] >> scalebits]; | ||
560 | d[5] = cm[c[14] >> scalebits]; | ||
561 | d[7] = cm[c[15] >> scalebits]; | ||
562 | #else | ||
563 | int i; | ||
564 | unsigned char *d; | ||
565 | const int *c = src; | ||
566 | |||
567 | d = dst; | ||
568 | for (i = 0; i < 4; i++, c++) | ||
569 | d[i*2] = CLAMP((*c) >> scalebits); | ||
570 | |||
571 | d = dst + bytes_per_line; | ||
572 | for (i = 0; i < 4; i++, c++) | ||
573 | d[i*2+1] = CLAMP((*c) >> scalebits); | ||
574 | |||
575 | d = dst + bytes_per_line*2; | ||
576 | for (i = 0; i < 4; i++, c++) | ||
577 | d[i*2] = CLAMP((*c) >> scalebits); | ||
578 | |||
579 | d = dst + bytes_per_line*3; | ||
580 | for (i = 0; i < 4; i++, c++) | ||
581 | d[i*2+1] = CLAMP((*c) >> scalebits); | ||
582 | #endif | ||
583 | } | ||
584 | #endif | ||
585 | |||
586 | /* | ||
587 | * To manage the stream, we keep bits in a 32 bits register. | ||
588 | * fill_nbits(n): fill the reservoir with at least n bits | ||
589 | * skip_bits(n): discard n bits from the reservoir | ||
590 | * get_bits(n): fill the reservoir, returns the first n bits and discard the | ||
591 | * bits from the reservoir. | ||
592 | * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir | ||
593 | * contains at least n bits. bits returned is discarded. | ||
594 | */ | ||
595 | #define fill_nbits(pdec, nbits_wanted) do { \ | ||
596 | while (pdec->nbits_in_reservoir<(nbits_wanted)) \ | ||
597 | { \ | ||
598 | pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \ | ||
599 | pdec->nbits_in_reservoir += 8; \ | ||
600 | } \ | ||
601 | } while(0); | ||
602 | |||
603 | #define skip_nbits(pdec, nbits_to_skip) do { \ | ||
604 | pdec->reservoir >>= (nbits_to_skip); \ | ||
605 | pdec->nbits_in_reservoir -= (nbits_to_skip); \ | ||
606 | } while(0); | ||
607 | |||
608 | #define get_nbits(pdec, nbits_wanted, result) do { \ | ||
609 | fill_nbits(pdec, nbits_wanted); \ | ||
610 | result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \ | ||
611 | skip_nbits(pdec, nbits_wanted); \ | ||
612 | } while(0); | ||
613 | |||
614 | #define __get_nbits(pdec, nbits_wanted, result) do { \ | ||
615 | result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \ | ||
616 | skip_nbits(pdec, nbits_wanted); \ | ||
617 | } while(0); | ||
618 | |||
619 | #define look_nbits(pdec, nbits_wanted) \ | ||
620 | ((pdec->reservoir) & ((1U<<(nbits_wanted))-1)) | ||
621 | |||
622 | /* | ||
623 | * Decode a 4x4 pixel block | ||
624 | */ | ||
625 | static void decode_block(struct pwc_dec23_private *pdec, | ||
626 | const unsigned char *ptable0004, | ||
627 | const unsigned char *ptable8004) | ||
628 | { | ||
629 | unsigned int primary_color; | ||
630 | unsigned int channel_v, offset1, op; | ||
631 | int i; | ||
632 | |||
633 | fill_nbits(pdec, 16); | ||
634 | __get_nbits(pdec, pdec->nbits, primary_color); | ||
635 | |||
636 | if (look_nbits(pdec,2) == 0) { | ||
637 | skip_nbits(pdec, 2); | ||
638 | /* Very simple, the color is the same for all pixels of the square */ | ||
639 | for (i = 0; i < 16; i++) | ||
640 | pdec->temp_colors[i] = pdec->table_dc00[primary_color]; | ||
641 | |||
642 | return; | ||
643 | } | ||
644 | |||
645 | /* This block is encoded with small pattern */ | ||
646 | for (i = 0; i < 16; i++) | ||
647 | pdec->temp_colors[i] = pdec->table_d800[primary_color]; | ||
648 | |||
649 | __get_nbits(pdec, 3, channel_v); | ||
650 | channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2); | ||
651 | |||
652 | ptable0004 += (channel_v * 128); | ||
653 | ptable8004 += (channel_v * 32); | ||
654 | |||
655 | offset1 = 0; | ||
656 | do | ||
657 | { | ||
658 | unsigned int htable_idx, rows = 0; | ||
659 | const unsigned int *block; | ||
660 | |||
661 | /* [ zzzz y x x ] | ||
662 | * xx == 00 :=> end of the block def, remove the two bits from the stream | ||
663 | * yxx == 111 | ||
664 | * yxx == any other value | ||
665 | * | ||
666 | */ | ||
667 | fill_nbits(pdec, 16); | ||
668 | htable_idx = look_nbits(pdec, 6); | ||
669 | op = hash_table_ops[htable_idx * 4]; | ||
670 | |||
671 | if (op == 2) { | ||
672 | skip_nbits(pdec, 2); | ||
673 | |||
674 | } else if (op == 1) { | ||
675 | /* 15bits [ xxxx xxxx yyyy 111 ] | ||
676 | * yyy => offset in the table8004 | ||
677 | * xxx => offset in the tabled004 (tree) | ||
678 | */ | ||
679 | unsigned int mask, shift; | ||
680 | unsigned int nbits, col1; | ||
681 | unsigned int yyyy; | ||
682 | |||
683 | skip_nbits(pdec, 3); | ||
684 | /* offset1 += yyyy */ | ||
685 | __get_nbits(pdec, 4, yyyy); | ||
686 | offset1 += 1 + yyyy; | ||
687 | offset1 &= 0x0F; | ||
688 | nbits = ptable8004[offset1 * 2]; | ||
689 | |||
690 | /* col1 = xxxx xxxx */ | ||
691 | __get_nbits(pdec, nbits+1, col1); | ||
692 | |||
693 | /* Bit mask table */ | ||
694 | mask = pdec->table_bitpowermask[nbits][col1]; | ||
695 | shift = ptable8004[offset1 * 2 + 1]; | ||
696 | rows = ((mask << shift) + 0x80) & 0xFF; | ||
697 | |||
698 | block = pdec->table_subblock[rows]; | ||
699 | for (i = 0; i < 16; i++) | ||
700 | pdec->temp_colors[i] += block[MulIdx[offset1][i]]; | ||
701 | |||
702 | } else { | ||
703 | /* op == 0 | ||
704 | * offset1 is coded on 3 bits | ||
705 | */ | ||
706 | unsigned int shift; | ||
707 | |||
708 | offset1 += hash_table_ops [htable_idx * 4 + 2]; | ||
709 | offset1 &= 0x0F; | ||
710 | |||
711 | rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]]; | ||
712 | block = pdec->table_subblock[rows]; | ||
713 | for (i = 0; i < 16; i++) | ||
714 | pdec->temp_colors[i] += block[MulIdx[offset1][i]]; | ||
715 | |||
716 | shift = hash_table_ops[htable_idx * 4 + 1]; | ||
717 | skip_nbits(pdec, shift); | ||
718 | } | ||
719 | |||
720 | } while (op != 2); | ||
721 | |||
722 | } | ||
723 | |||
724 | static void DecompressBand23(struct pwc_dec23_private *pdec, | ||
725 | const unsigned char *rawyuv, | ||
726 | unsigned char *planar_y, | ||
727 | unsigned char *planar_u, | ||
728 | unsigned char *planar_v, | ||
729 | unsigned int compressed_image_width, | ||
730 | unsigned int real_image_width) | ||
731 | { | ||
732 | int compression_index, nblocks; | ||
733 | const unsigned char *ptable0004; | ||
734 | const unsigned char *ptable8004; | ||
735 | |||
736 | pdec->reservoir = 0; | ||
737 | pdec->nbits_in_reservoir = 0; | ||
738 | pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */ | ||
739 | |||
740 | get_nbits(pdec, 4, compression_index); | ||
741 | |||
742 | /* pass 1: uncompress Y component */ | ||
743 | nblocks = compressed_image_width / 4; | ||
744 | |||
745 | ptable0004 = pdec->table_0004_pass1[compression_index]; | ||
746 | ptable8004 = pdec->table_8004_pass1[compression_index]; | ||
747 | |||
748 | /* Each block decode a square of 4x4 */ | ||
749 | while (nblocks) { | ||
750 | decode_block(pdec, ptable0004, ptable8004); | ||
751 | copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits); | ||
752 | planar_y += 4; | ||
753 | nblocks--; | ||
754 | } | ||
755 | |||
756 | /* pass 2: uncompress UV component */ | ||
757 | nblocks = compressed_image_width / 8; | ||
758 | |||
759 | ptable0004 = pdec->table_0004_pass2[compression_index]; | ||
760 | ptable8004 = pdec->table_8004_pass2[compression_index]; | ||
761 | |||
762 | /* Each block decode a square of 4x4 */ | ||
763 | while (nblocks) { | ||
764 | decode_block(pdec, ptable0004, ptable8004); | ||
765 | copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits); | ||
766 | |||
767 | decode_block(pdec, ptable0004, ptable8004); | ||
768 | copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits); | ||
769 | |||
770 | planar_v += 8; | ||
771 | planar_u += 8; | ||
772 | nblocks -= 2; | ||
773 | } | ||
774 | |||
775 | } | ||
776 | |||
777 | #if ENABLE_BAYER_DECODER | ||
778 | /* | ||
779 | * Size need to be a multiple of 8 in width | ||
780 | * | ||
781 | * Return a block of four line encoded like this: | ||
782 | * | ||
783 | * G R G R G R G R G R G R G R G R | ||
784 | * B G B G B G B G B G B G B G B G | ||
785 | * G R G R G R G R G R G R G R G R | ||
786 | * B G B G B G B G B G B G B G B G | ||
787 | * | ||
788 | */ | ||
789 | static void DecompressBandBayer(struct pwc_dec23_private *pdec, | ||
790 | const unsigned char *rawyuv, | ||
791 | unsigned char *rgbbayer, | ||
792 | unsigned int compressed_image_width, | ||
793 | unsigned int real_image_width) | ||
794 | { | ||
795 | int compression_index, nblocks; | ||
796 | const unsigned char *ptable0004; | ||
797 | const unsigned char *ptable8004; | ||
798 | unsigned char *dest; | ||
799 | |||
800 | pdec->reservoir = 0; | ||
801 | pdec->nbits_in_reservoir = 0; | ||
802 | pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */ | ||
803 | |||
804 | get_nbits(pdec, 4, compression_index); | ||
805 | |||
806 | /* pass 1: uncompress RB component */ | ||
807 | nblocks = compressed_image_width / 4; | ||
808 | |||
809 | ptable0004 = pdec->table_0004_pass1[compression_index]; | ||
810 | ptable8004 = pdec->table_8004_pass1[compression_index]; | ||
811 | dest = rgbbayer; | ||
812 | |||
813 | /* Each block decode a square of 4x4 */ | ||
814 | while (nblocks) { | ||
815 | decode_block(pdec, ptable0004, ptable8004); | ||
816 | copy_image_block_RedBlue(pdec->temp_colors, rgbbayer, real_image_width, pdec->scalebits); | ||
817 | dest += 8; | ||
818 | nblocks--; | ||
819 | } | ||
820 | |||
821 | /* pass 2: uncompress G component */ | ||
822 | nblocks = compressed_image_width / 8; | ||
823 | |||
824 | ptable0004 = pdec->table_0004_pass2[compression_index]; | ||
825 | ptable8004 = pdec->table_8004_pass2[compression_index]; | ||
826 | |||
827 | /* Each block decode a square of 4x4 */ | ||
828 | while (nblocks) { | ||
829 | decode_block(pdec, ptable0004, ptable8004); | ||
830 | copy_image_block_Green(pdec->temp_colors, rgbbayer+1, real_image_width, pdec->scalebits); | ||
831 | |||
832 | decode_block(pdec, ptable0004, ptable8004); | ||
833 | copy_image_block_Green(pdec->temp_colors, rgbbayer+real_image_width, real_image_width, pdec->scalebits); | ||
834 | |||
835 | rgbbayer += 16; | ||
836 | nblocks -= 2; | ||
837 | } | ||
838 | } | ||
839 | #endif | ||
840 | |||
841 | |||
842 | /** | ||
843 | * | ||
844 | * Uncompress a pwc23 buffer. | ||
845 | * | ||
846 | * pwc.view: size of the image wanted | ||
847 | * pwc.image: size of the image returned by the camera | ||
848 | * pwc.offset: (x,y) to displayer image in the view | ||
849 | * | ||
850 | * src: raw data | ||
851 | * dst: image output | ||
852 | * flags: PWCX_FLAG_PLANAR or PWCX_FLAG_BAYER | ||
853 | */ | ||
854 | void pwc_dec23_decompress(const struct pwc_device *pwc, | ||
855 | const void *src, | ||
856 | void *dst, | ||
857 | int flags) | ||
858 | { | ||
859 | int bandlines_left, stride, bytes_per_block; | ||
860 | |||
861 | bandlines_left = pwc->image.y / 4; | ||
862 | bytes_per_block = pwc->view.x * 4; | ||
863 | |||
864 | if (flags & PWCX_FLAG_BAYER) { | ||
865 | #if ENABLE_BAYER_DECODER | ||
866 | /* RGB Bayer format */ | ||
867 | unsigned char *rgbout; | ||
868 | |||
869 | stride = pwc->view.x * pwc->offset.y; | ||
870 | rgbout = dst + stride + pwc->offset.x; | ||
871 | |||
872 | |||
873 | while (bandlines_left--) { | ||
874 | |||
875 | DecompressBandBayer(pwc->decompress_data, | ||
876 | src, | ||
877 | rgbout, | ||
878 | pwc->image.x, pwc->view.x); | ||
879 | |||
880 | src += pwc->vbandlength; | ||
881 | rgbout += bytes_per_block; | ||
882 | |||
883 | } | ||
884 | #else | ||
885 | memset(dst, 0, pwc->view.x * pwc->view.y); | ||
886 | #endif | ||
887 | |||
888 | } else { | ||
889 | /* YUV420P image format */ | ||
890 | unsigned char *pout_planar_y; | ||
891 | unsigned char *pout_planar_u; | ||
892 | unsigned char *pout_planar_v; | ||
893 | unsigned int plane_size; | ||
894 | |||
895 | plane_size = pwc->view.x * pwc->view.y; | ||
896 | |||
897 | /* offset in Y plane */ | ||
898 | stride = pwc->view.x * pwc->offset.y; | ||
899 | pout_planar_y = dst + stride + pwc->offset.x; | ||
900 | |||
901 | /* offsets in U/V planes */ | ||
902 | stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2; | ||
903 | pout_planar_u = dst + plane_size + stride; | ||
904 | pout_planar_v = dst + plane_size + plane_size / 4 + stride; | ||
905 | |||
906 | while (bandlines_left--) { | ||
907 | |||
908 | DecompressBand23(pwc->decompress_data, | ||
909 | src, | ||
910 | pout_planar_y, pout_planar_u, pout_planar_v, | ||
911 | pwc->image.x, pwc->view.x); | ||
912 | src += pwc->vbandlength; | ||
913 | pout_planar_y += bytes_per_block; | ||
914 | pout_planar_u += pwc->view.x; | ||
915 | pout_planar_v += pwc->view.x; | ||
916 | |||
917 | } | ||
918 | |||
919 | } | ||
920 | |||
921 | } | ||
922 | |||
923 | void pwc_dec23_exit(void) | ||
924 | { | ||
925 | /* Do nothing */ | ||
926 | |||
927 | } | ||
928 | |||
929 | /** | ||
930 | * Allocate a private structure used by lookup table. | ||
931 | * You must call kfree() to free the memory allocated. | ||
932 | */ | ||
933 | int pwc_dec23_alloc(struct pwc_device *pwc) | ||
934 | { | ||
935 | pwc->decompress_data = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); | ||
936 | if (pwc->decompress_data == NULL) | ||
937 | return -ENOMEM; | ||
938 | return 0; | ||
939 | } | ||
940 | |||
941 | /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ | ||
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/video/pwc/pwc-dec23.h new file mode 100644 index 000000000000..1c55298ad153 --- /dev/null +++ b/drivers/media/video/pwc/pwc-dec23.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* Linux driver for Philips webcam | ||
2 | (C) 2004-2006 Luc Saillard (luc@saillard.org) | ||
3 | |||
4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | ||
5 | driver and thus may have bugs that are not present in the original version. | ||
6 | Please send bug reports and support requests to <luc@saillard.org>. | ||
7 | The decompression routines have been implemented by reverse-engineering the | ||
8 | Nemosoft binary pwcx module. Caveat emptor. | ||
9 | |||
10 | This program is free software; you can redistribute it and/or modify | ||
11 | it under the terms of the GNU General Public License as published by | ||
12 | the Free Software Foundation; either version 2 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software | ||
22 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | |||
25 | #ifndef PWC_DEC23_H | ||
26 | #define PWC_DEC23_H | ||
27 | |||
28 | #include "pwc.h" | ||
29 | |||
30 | struct pwc_dec23_private | ||
31 | { | ||
32 | unsigned int scalebits; | ||
33 | unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */ | ||
34 | |||
35 | unsigned int reservoir; | ||
36 | unsigned int nbits_in_reservoir; | ||
37 | const unsigned char *stream; | ||
38 | int temp_colors[16]; | ||
39 | |||
40 | unsigned char table_0004_pass1[16][1024]; | ||
41 | unsigned char table_0004_pass2[16][1024]; | ||
42 | unsigned char table_8004_pass1[16][256]; | ||
43 | unsigned char table_8004_pass2[16][256]; | ||
44 | unsigned int table_subblock[256][12]; | ||
45 | |||
46 | unsigned char table_bitpowermask[8][256]; | ||
47 | unsigned int table_d800[256]; | ||
48 | unsigned int table_dc00[256]; | ||
49 | |||
50 | }; | ||
51 | |||
52 | |||
53 | int pwc_dec23_alloc(struct pwc_device *pwc); | ||
54 | int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd); | ||
55 | void pwc_dec23_exit(void); | ||
56 | void pwc_dec23_decompress(const struct pwc_device *pwc, | ||
57 | const void *src, | ||
58 | void *dst, | ||
59 | int flags); | ||
60 | |||
61 | |||
62 | |||
63 | #endif | ||
64 | |||
65 | |||
66 | /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ | ||
67 | |||
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 41418294a32b..47d0d83a0264 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Linux driver for Philips webcam | 1 | /* Linux driver for Philips webcam |
2 | USB and Video4Linux interface part. | 2 | USB and Video4Linux interface part. |
3 | (C) 1999-2004 Nemosoft Unv. | 3 | (C) 1999-2004 Nemosoft Unv. |
4 | (C) 2004 Luc Saillard (luc@saillard.org) | 4 | (C) 2004-2006 Luc Saillard (luc@saillard.org) |
5 | 5 | ||
6 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | 6 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx |
7 | driver and thus may have bugs that are not present in the original version. | 7 | driver and thus may have bugs that are not present in the original version. |
@@ -62,18 +62,21 @@ | |||
62 | #include <linux/poll.h> | 62 | #include <linux/poll.h> |
63 | #include <linux/slab.h> | 63 | #include <linux/slab.h> |
64 | #include <linux/vmalloc.h> | 64 | #include <linux/vmalloc.h> |
65 | #include <linux/version.h> | ||
65 | #include <asm/io.h> | 66 | #include <asm/io.h> |
67 | #include <linux/moduleparam.h> | ||
66 | 68 | ||
67 | #include "pwc.h" | 69 | #include "pwc.h" |
68 | #include "pwc-ioctl.h" | ||
69 | #include "pwc-kiara.h" | 70 | #include "pwc-kiara.h" |
70 | #include "pwc-timon.h" | 71 | #include "pwc-timon.h" |
72 | #include "pwc-dec23.h" | ||
73 | #include "pwc-dec1.h" | ||
71 | #include "pwc-uncompress.h" | 74 | #include "pwc-uncompress.h" |
72 | 75 | ||
73 | /* Function prototypes and driver templates */ | 76 | /* Function prototypes and driver templates */ |
74 | 77 | ||
75 | /* hotplug device table support */ | 78 | /* hotplug device table support */ |
76 | static struct usb_device_id pwc_device_table [] = { | 79 | static const struct usb_device_id pwc_device_table [] = { |
77 | { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */ | 80 | { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */ |
78 | { USB_DEVICE(0x0471, 0x0303) }, | 81 | { USB_DEVICE(0x0471, 0x0303) }, |
79 | { USB_DEVICE(0x0471, 0x0304) }, | 82 | { USB_DEVICE(0x0471, 0x0304) }, |
@@ -81,9 +84,10 @@ static struct usb_device_id pwc_device_table [] = { | |||
81 | { USB_DEVICE(0x0471, 0x0308) }, | 84 | { USB_DEVICE(0x0471, 0x0308) }, |
82 | { USB_DEVICE(0x0471, 0x030C) }, | 85 | { USB_DEVICE(0x0471, 0x030C) }, |
83 | { USB_DEVICE(0x0471, 0x0310) }, | 86 | { USB_DEVICE(0x0471, 0x0310) }, |
84 | { USB_DEVICE(0x0471, 0x0311) }, | 87 | { USB_DEVICE(0x0471, 0x0311) }, /* Philips ToUcam PRO II */ |
85 | { USB_DEVICE(0x0471, 0x0312) }, | 88 | { USB_DEVICE(0x0471, 0x0312) }, |
86 | { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */ | 89 | { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */ |
90 | { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */ | ||
87 | { USB_DEVICE(0x069A, 0x0001) }, /* Askey */ | 91 | { USB_DEVICE(0x069A, 0x0001) }, /* Askey */ |
88 | { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */ | 92 | { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */ |
89 | { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */ | 93 | { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */ |
@@ -94,8 +98,9 @@ static struct usb_device_id pwc_device_table [] = { | |||
94 | { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */ | 98 | { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */ |
95 | { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */ | 99 | { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */ |
96 | { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */ | 100 | { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */ |
97 | { USB_DEVICE(0x055D, 0x9000) }, /* Samsung */ | 101 | { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */ |
98 | { USB_DEVICE(0x055D, 0x9001) }, | 102 | { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */ |
103 | { USB_DEVICE(0x055D, 0x9002) }, /* Samsung SNC-35E (Ver3.0) */ | ||
99 | { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */ | 104 | { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */ |
100 | { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */ | 105 | { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */ |
101 | { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */ | 106 | { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */ |
@@ -122,11 +127,13 @@ static struct usb_driver pwc_driver = { | |||
122 | static int default_size = PSZ_QCIF; | 127 | static int default_size = PSZ_QCIF; |
123 | static int default_fps = 10; | 128 | static int default_fps = 10; |
124 | static int default_fbufs = 3; /* Default number of frame buffers */ | 129 | static int default_fbufs = 3; /* Default number of frame buffers */ |
125 | static int default_mbufs = 2; /* Default number of mmap() buffers */ | 130 | int pwc_mbufs = 2; /* Default number of mmap() buffers */ |
126 | int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX; | 131 | #if CONFIG_PWC_DEBUG |
132 | int pwc_trace = PWC_DEBUG_LEVEL; | ||
133 | #endif | ||
127 | static int power_save = 0; | 134 | static int power_save = 0; |
128 | static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */ | 135 | static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */ |
129 | static int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */ | 136 | static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */ |
130 | static struct { | 137 | static struct { |
131 | int type; | 138 | int type; |
132 | char serial_number[30]; | 139 | char serial_number[30]; |
@@ -138,7 +145,7 @@ static struct { | |||
138 | 145 | ||
139 | static int pwc_video_open(struct inode *inode, struct file *file); | 146 | static int pwc_video_open(struct inode *inode, struct file *file); |
140 | static int pwc_video_close(struct inode *inode, struct file *file); | 147 | static int pwc_video_close(struct inode *inode, struct file *file); |
141 | static ssize_t pwc_video_read(struct file *file, char __user * buf, | 148 | static ssize_t pwc_video_read(struct file *file, char __user *buf, |
142 | size_t count, loff_t *ppos); | 149 | size_t count, loff_t *ppos); |
143 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); | 150 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); |
144 | static int pwc_video_ioctl(struct inode *inode, struct file *file, | 151 | static int pwc_video_ioctl(struct inode *inode, struct file *file, |
@@ -153,7 +160,6 @@ static struct file_operations pwc_fops = { | |||
153 | .poll = pwc_video_poll, | 160 | .poll = pwc_video_poll, |
154 | .mmap = pwc_video_mmap, | 161 | .mmap = pwc_video_mmap, |
155 | .ioctl = pwc_video_ioctl, | 162 | .ioctl = pwc_video_ioctl, |
156 | .compat_ioctl = v4l_compat_ioctl32, | ||
157 | .llseek = no_llseek, | 163 | .llseek = no_llseek, |
158 | }; | 164 | }; |
159 | static struct video_device pwc_template = { | 165 | static struct video_device pwc_template = { |
@@ -203,52 +209,44 @@ static struct video_device pwc_template = { | |||
203 | /* Here we want the physical address of the memory. | 209 | /* Here we want the physical address of the memory. |
204 | * This is used when initializing the contents of the area. | 210 | * This is used when initializing the contents of the area. |
205 | */ | 211 | */ |
206 | static inline unsigned long kvirt_to_pa(unsigned long adr) | ||
207 | { | ||
208 | unsigned long kva, ret; | ||
209 | 212 | ||
210 | kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); | ||
211 | kva |= adr & (PAGE_SIZE-1); /* restore the offset */ | ||
212 | ret = __pa(kva); | ||
213 | return ret; | ||
214 | } | ||
215 | 213 | ||
216 | static void * rvmalloc(unsigned long size) | 214 | |
215 | static void *pwc_rvmalloc(unsigned long size) | ||
217 | { | 216 | { |
218 | void * mem; | 217 | void * mem; |
219 | unsigned long adr; | 218 | unsigned long adr; |
220 | 219 | ||
221 | size=PAGE_ALIGN(size); | ||
222 | mem=vmalloc_32(size); | 220 | mem=vmalloc_32(size); |
223 | if (mem) | 221 | if (!mem) |
224 | { | 222 | return NULL; |
225 | memset(mem, 0, size); /* Clear the ram out, no junk to the user */ | 223 | |
226 | adr=(unsigned long) mem; | 224 | memset(mem, 0, size); /* Clear the ram out, no junk to the user */ |
227 | while (size > 0) | 225 | adr=(unsigned long) mem; |
228 | { | 226 | while (size > 0) |
229 | SetPageReserved(vmalloc_to_page((void *)adr)); | 227 | { |
230 | adr+=PAGE_SIZE; | 228 | SetPageReserved(vmalloc_to_page((void *)adr)); |
231 | size-=PAGE_SIZE; | 229 | adr += PAGE_SIZE; |
232 | } | 230 | size -= PAGE_SIZE; |
233 | } | 231 | } |
234 | return mem; | 232 | return mem; |
235 | } | 233 | } |
236 | 234 | ||
237 | static void rvfree(void * mem, unsigned long size) | 235 | static void pwc_rvfree(void * mem, unsigned long size) |
238 | { | 236 | { |
239 | unsigned long adr; | 237 | unsigned long adr; |
240 | 238 | ||
241 | if (mem) | 239 | if (!mem) |
242 | { | 240 | return; |
243 | adr=(unsigned long) mem; | 241 | |
244 | while ((long) size > 0) | 242 | adr=(unsigned long) mem; |
245 | { | 243 | while ((long) size > 0) |
246 | ClearPageReserved(vmalloc_to_page((void *)adr)); | 244 | { |
247 | adr+=PAGE_SIZE; | 245 | ClearPageReserved(vmalloc_to_page((void *)adr)); |
248 | size-=PAGE_SIZE; | 246 | adr += PAGE_SIZE; |
249 | } | 247 | size -= PAGE_SIZE; |
250 | vfree(mem); | 248 | } |
251 | } | 249 | vfree(mem); |
252 | } | 250 | } |
253 | 251 | ||
254 | 252 | ||
@@ -256,100 +254,83 @@ static void rvfree(void * mem, unsigned long size) | |||
256 | 254 | ||
257 | static int pwc_allocate_buffers(struct pwc_device *pdev) | 255 | static int pwc_allocate_buffers(struct pwc_device *pdev) |
258 | { | 256 | { |
259 | int i; | 257 | int i, err; |
260 | void *kbuf; | 258 | void *kbuf; |
261 | 259 | ||
262 | Trace(TRACE_MEMORY, ">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev); | 260 | PWC_DEBUG_MEMORY(">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev); |
263 | 261 | ||
264 | if (pdev == NULL) | 262 | if (pdev == NULL) |
265 | return -ENXIO; | 263 | return -ENXIO; |
266 | 264 | ||
267 | #ifdef PWC_MAGIC | 265 | /* Allocate Isochronuous pipe buffers */ |
268 | if (pdev->magic != PWC_MAGIC) { | ||
269 | Err("allocate_buffers(): magic failed.\n"); | ||
270 | return -ENXIO; | ||
271 | } | ||
272 | #endif | ||
273 | /* Allocate Isochronous pipe buffers */ | ||
274 | for (i = 0; i < MAX_ISO_BUFS; i++) { | 266 | for (i = 0; i < MAX_ISO_BUFS; i++) { |
275 | if (pdev->sbuf[i].data == NULL) { | 267 | if (pdev->sbuf[i].data == NULL) { |
276 | kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL); | 268 | kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL); |
277 | if (kbuf == NULL) { | 269 | if (kbuf == NULL) { |
278 | Err("Failed to allocate iso buffer %d.\n", i); | 270 | PWC_ERROR("Failed to allocate iso buffer %d.\n", i); |
279 | return -ENOMEM; | 271 | return -ENOMEM; |
280 | } | 272 | } |
281 | Trace(TRACE_MEMORY, "Allocated iso buffer at %p.\n", kbuf); | 273 | PWC_DEBUG_MEMORY("Allocated iso buffer at %p.\n", kbuf); |
282 | pdev->sbuf[i].data = kbuf; | 274 | pdev->sbuf[i].data = kbuf; |
283 | memset(kbuf, 0, ISO_BUFFER_SIZE); | ||
284 | } | 275 | } |
285 | } | 276 | } |
286 | 277 | ||
287 | /* Allocate frame buffer structure */ | 278 | /* Allocate frame buffer structure */ |
288 | if (pdev->fbuf == NULL) { | 279 | if (pdev->fbuf == NULL) { |
289 | kbuf = kmalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL); | 280 | kbuf = kzalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL); |
290 | if (kbuf == NULL) { | 281 | if (kbuf == NULL) { |
291 | Err("Failed to allocate frame buffer structure.\n"); | 282 | PWC_ERROR("Failed to allocate frame buffer structure.\n"); |
292 | return -ENOMEM; | 283 | return -ENOMEM; |
293 | } | 284 | } |
294 | Trace(TRACE_MEMORY, "Allocated frame buffer structure at %p.\n", kbuf); | 285 | PWC_DEBUG_MEMORY("Allocated frame buffer structure at %p.\n", kbuf); |
295 | pdev->fbuf = kbuf; | 286 | pdev->fbuf = kbuf; |
296 | memset(kbuf, 0, default_fbufs * sizeof(struct pwc_frame_buf)); | ||
297 | } | 287 | } |
288 | |||
298 | /* create frame buffers, and make circular ring */ | 289 | /* create frame buffers, and make circular ring */ |
299 | for (i = 0; i < default_fbufs; i++) { | 290 | for (i = 0; i < default_fbufs; i++) { |
300 | if (pdev->fbuf[i].data == NULL) { | 291 | if (pdev->fbuf[i].data == NULL) { |
301 | kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ | 292 | kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ |
302 | if (kbuf == NULL) { | 293 | if (kbuf == NULL) { |
303 | Err("Failed to allocate frame buffer %d.\n", i); | 294 | PWC_ERROR("Failed to allocate frame buffer %d.\n", i); |
304 | return -ENOMEM; | 295 | return -ENOMEM; |
305 | } | 296 | } |
306 | Trace(TRACE_MEMORY, "Allocated frame buffer %d at %p.\n", i, kbuf); | 297 | PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf); |
307 | pdev->fbuf[i].data = kbuf; | 298 | pdev->fbuf[i].data = kbuf; |
308 | memset(kbuf, 128, PWC_FRAME_SIZE); | 299 | memset(kbuf, 0, PWC_FRAME_SIZE); |
309 | } | 300 | } |
310 | } | 301 | } |
311 | 302 | ||
312 | /* Allocate decompressor table space */ | 303 | /* Allocate decompressor table space */ |
313 | kbuf = NULL; | 304 | if (DEVICE_USE_CODEC1(pdev->type)) |
314 | switch (pdev->type) | 305 | err = pwc_dec1_alloc(pdev); |
315 | { | 306 | else |
316 | case 675: | 307 | err = pwc_dec23_alloc(pdev); |
317 | case 680: | 308 | |
318 | case 690: | 309 | if (err) { |
319 | case 720: | 310 | PWC_ERROR("Failed to allocate decompress table.\n"); |
320 | case 730: | 311 | return err; |
321 | case 740: | 312 | } |
322 | case 750: | ||
323 | #if 0 | ||
324 | Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private)); | ||
325 | kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */ | ||
326 | break; | ||
327 | case 645: | ||
328 | case 646: | ||
329 | /* TODO & FIXME */ | ||
330 | kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); | ||
331 | break; | ||
332 | #endif | ||
333 | ; | ||
334 | } | ||
335 | pdev->decompress_data = kbuf; | ||
336 | 313 | ||
337 | /* Allocate image buffer; double buffer for mmap() */ | 314 | /* Allocate image buffer; double buffer for mmap() */ |
338 | kbuf = rvmalloc(default_mbufs * pdev->len_per_image); | 315 | kbuf = pwc_rvmalloc(pwc_mbufs * pdev->len_per_image); |
339 | if (kbuf == NULL) { | 316 | if (kbuf == NULL) { |
340 | Err("Failed to allocate image buffer(s). needed (%d)\n",default_mbufs * pdev->len_per_image); | 317 | PWC_ERROR("Failed to allocate image buffer(s). needed (%d)\n", |
318 | pwc_mbufs * pdev->len_per_image); | ||
341 | return -ENOMEM; | 319 | return -ENOMEM; |
342 | } | 320 | } |
343 | Trace(TRACE_MEMORY, "Allocated image buffer at %p.\n", kbuf); | 321 | PWC_DEBUG_MEMORY("Allocated image buffer at %p.\n", kbuf); |
344 | pdev->image_data = kbuf; | 322 | pdev->image_data = kbuf; |
345 | for (i = 0; i < default_mbufs; i++) | 323 | for (i = 0; i < pwc_mbufs; i++) { |
346 | pdev->image_ptr[i] = kbuf + i * pdev->len_per_image; | 324 | pdev->images[i].offset = i * pdev->len_per_image; |
347 | for (; i < MAX_IMAGES; i++) | 325 | pdev->images[i].vma_use_count = 0; |
348 | pdev->image_ptr[i] = NULL; | 326 | } |
327 | for (; i < MAX_IMAGES; i++) { | ||
328 | pdev->images[i].offset = 0; | ||
329 | } | ||
349 | 330 | ||
350 | kbuf = NULL; | 331 | kbuf = NULL; |
351 | 332 | ||
352 | Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n"); | 333 | PWC_DEBUG_MEMORY("<< pwc_allocate_buffers()\n"); |
353 | return 0; | 334 | return 0; |
354 | } | 335 | } |
355 | 336 | ||
@@ -357,21 +338,14 @@ static void pwc_free_buffers(struct pwc_device *pdev) | |||
357 | { | 338 | { |
358 | int i; | 339 | int i; |
359 | 340 | ||
360 | Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", pdev); | 341 | PWC_DEBUG_MEMORY("Entering free_buffers(%p).\n", pdev); |
361 | 342 | ||
362 | if (pdev == NULL) | 343 | if (pdev == NULL) |
363 | return; | 344 | return; |
364 | #ifdef PWC_MAGIC | ||
365 | if (pdev->magic != PWC_MAGIC) { | ||
366 | Err("free_buffers(): magic failed.\n"); | ||
367 | return; | ||
368 | } | ||
369 | #endif | ||
370 | |||
371 | /* Release Iso-pipe buffers */ | 345 | /* Release Iso-pipe buffers */ |
372 | for (i = 0; i < MAX_ISO_BUFS; i++) | 346 | for (i = 0; i < MAX_ISO_BUFS; i++) |
373 | if (pdev->sbuf[i].data != NULL) { | 347 | if (pdev->sbuf[i].data != NULL) { |
374 | Trace(TRACE_MEMORY, "Freeing ISO buffer at %p.\n", pdev->sbuf[i].data); | 348 | PWC_DEBUG_MEMORY("Freeing ISO buffer at %p.\n", pdev->sbuf[i].data); |
375 | kfree(pdev->sbuf[i].data); | 349 | kfree(pdev->sbuf[i].data); |
376 | pdev->sbuf[i].data = NULL; | 350 | pdev->sbuf[i].data = NULL; |
377 | } | 351 | } |
@@ -380,7 +354,7 @@ static void pwc_free_buffers(struct pwc_device *pdev) | |||
380 | if (pdev->fbuf != NULL) { | 354 | if (pdev->fbuf != NULL) { |
381 | for (i = 0; i < default_fbufs; i++) { | 355 | for (i = 0; i < default_fbufs; i++) { |
382 | if (pdev->fbuf[i].data != NULL) { | 356 | if (pdev->fbuf[i].data != NULL) { |
383 | Trace(TRACE_MEMORY, "Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data); | 357 | PWC_DEBUG_MEMORY("Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data); |
384 | vfree(pdev->fbuf[i].data); | 358 | vfree(pdev->fbuf[i].data); |
385 | pdev->fbuf[i].data = NULL; | 359 | pdev->fbuf[i].data = NULL; |
386 | } | 360 | } |
@@ -391,20 +365,19 @@ static void pwc_free_buffers(struct pwc_device *pdev) | |||
391 | 365 | ||
392 | /* Intermediate decompression buffer & tables */ | 366 | /* Intermediate decompression buffer & tables */ |
393 | if (pdev->decompress_data != NULL) { | 367 | if (pdev->decompress_data != NULL) { |
394 | Trace(TRACE_MEMORY, "Freeing decompression buffer at %p.\n", pdev->decompress_data); | 368 | PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n", pdev->decompress_data); |
395 | kfree(pdev->decompress_data); | 369 | kfree(pdev->decompress_data); |
396 | pdev->decompress_data = NULL; | 370 | pdev->decompress_data = NULL; |
397 | } | 371 | } |
398 | pdev->decompressor = NULL; | ||
399 | 372 | ||
400 | /* Release image buffers */ | 373 | /* Release image buffers */ |
401 | if (pdev->image_data != NULL) { | 374 | if (pdev->image_data != NULL) { |
402 | Trace(TRACE_MEMORY, "Freeing image buffer at %p.\n", pdev->image_data); | 375 | PWC_DEBUG_MEMORY("Freeing image buffer at %p.\n", pdev->image_data); |
403 | rvfree(pdev->image_data, default_mbufs * pdev->len_per_image); | 376 | pwc_rvfree(pdev->image_data, pwc_mbufs * pdev->len_per_image); |
404 | } | 377 | } |
405 | pdev->image_data = NULL; | 378 | pdev->image_data = NULL; |
406 | 379 | ||
407 | Trace(TRACE_MEMORY, "Leaving free_buffers().\n"); | 380 | PWC_DEBUG_MEMORY("Leaving free_buffers().\n"); |
408 | } | 381 | } |
409 | 382 | ||
410 | /* The frame & image buffer mess. | 383 | /* The frame & image buffer mess. |
@@ -464,7 +437,7 @@ static void pwc_free_buffers(struct pwc_device *pdev) | |||
464 | /** | 437 | /** |
465 | \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first. | 438 | \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first. |
466 | */ | 439 | */ |
467 | static inline int pwc_next_fill_frame(struct pwc_device *pdev) | 440 | static int pwc_next_fill_frame(struct pwc_device *pdev) |
468 | { | 441 | { |
469 | int ret; | 442 | int ret; |
470 | unsigned long flags; | 443 | unsigned long flags; |
@@ -489,23 +462,17 @@ static inline int pwc_next_fill_frame(struct pwc_device *pdev) | |||
489 | } | 462 | } |
490 | else { | 463 | else { |
491 | /* Hmm. Take it from the full list */ | 464 | /* Hmm. Take it from the full list */ |
492 | #if PWC_DEBUG | ||
493 | /* sanity check */ | 465 | /* sanity check */ |
494 | if (pdev->full_frames == NULL) { | 466 | if (pdev->full_frames == NULL) { |
495 | Err("Neither empty or full frames available!\n"); | 467 | PWC_ERROR("Neither empty or full frames available!\n"); |
496 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | 468 | spin_unlock_irqrestore(&pdev->ptrlock, flags); |
497 | return -EINVAL; | 469 | return -EINVAL; |
498 | } | 470 | } |
499 | #endif | ||
500 | pdev->fill_frame = pdev->full_frames; | 471 | pdev->fill_frame = pdev->full_frames; |
501 | pdev->full_frames = pdev->full_frames->next; | 472 | pdev->full_frames = pdev->full_frames->next; |
502 | ret = 1; | 473 | ret = 1; |
503 | } | 474 | } |
504 | pdev->fill_frame->next = NULL; | 475 | pdev->fill_frame->next = NULL; |
505 | #if PWC_DEBUG | ||
506 | Trace(TRACE_SEQUENCE, "Assigning sequence number %d.\n", pdev->sequence); | ||
507 | pdev->fill_frame->sequence = pdev->sequence++; | ||
508 | #endif | ||
509 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | 476 | spin_unlock_irqrestore(&pdev->ptrlock, flags); |
510 | return ret; | 477 | return ret; |
511 | } | 478 | } |
@@ -521,6 +488,8 @@ static void pwc_reset_buffers(struct pwc_device *pdev) | |||
521 | int i; | 488 | int i; |
522 | unsigned long flags; | 489 | unsigned long flags; |
523 | 490 | ||
491 | PWC_DEBUG_MEMORY(">> %s __enter__\n", __FUNCTION__); | ||
492 | |||
524 | spin_lock_irqsave(&pdev->ptrlock, flags); | 493 | spin_lock_irqsave(&pdev->ptrlock, flags); |
525 | pdev->full_frames = NULL; | 494 | pdev->full_frames = NULL; |
526 | pdev->full_frames_tail = NULL; | 495 | pdev->full_frames_tail = NULL; |
@@ -540,13 +509,15 @@ static void pwc_reset_buffers(struct pwc_device *pdev) | |||
540 | pdev->image_read_pos = 0; | 509 | pdev->image_read_pos = 0; |
541 | pdev->fill_image = 0; | 510 | pdev->fill_image = 0; |
542 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | 511 | spin_unlock_irqrestore(&pdev->ptrlock, flags); |
512 | |||
513 | PWC_DEBUG_MEMORY("<< %s __leaving__\n", __FUNCTION__); | ||
543 | } | 514 | } |
544 | 515 | ||
545 | 516 | ||
546 | /** | 517 | /** |
547 | \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers. | 518 | \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers. |
548 | */ | 519 | */ |
549 | static int pwc_handle_frame(struct pwc_device *pdev) | 520 | int pwc_handle_frame(struct pwc_device *pdev) |
550 | { | 521 | { |
551 | int ret = 0; | 522 | int ret = 0; |
552 | unsigned long flags; | 523 | unsigned long flags; |
@@ -556,41 +527,40 @@ static int pwc_handle_frame(struct pwc_device *pdev) | |||
556 | we can release the lock after this without problems */ | 527 | we can release the lock after this without problems */ |
557 | if (pdev->read_frame != NULL) { | 528 | if (pdev->read_frame != NULL) { |
558 | /* This can't theoretically happen */ | 529 | /* This can't theoretically happen */ |
559 | Err("Huh? Read frame still in use?\n"); | 530 | PWC_ERROR("Huh? Read frame still in use?\n"); |
531 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | ||
532 | return ret; | ||
533 | } | ||
534 | |||
535 | |||
536 | if (pdev->full_frames == NULL) { | ||
537 | PWC_ERROR("Woops. No frames ready.\n"); | ||
560 | } | 538 | } |
561 | else { | 539 | else { |
562 | if (pdev->full_frames == NULL) { | 540 | pdev->read_frame = pdev->full_frames; |
563 | Err("Woops. No frames ready.\n"); | 541 | pdev->full_frames = pdev->full_frames->next; |
542 | pdev->read_frame->next = NULL; | ||
543 | } | ||
544 | |||
545 | if (pdev->read_frame != NULL) { | ||
546 | /* Decompression is a lenghty process, so it's outside of the lock. | ||
547 | This gives the isoc_handler the opportunity to fill more frames | ||
548 | in the mean time. | ||
549 | */ | ||
550 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | ||
551 | ret = pwc_decompress(pdev); | ||
552 | spin_lock_irqsave(&pdev->ptrlock, flags); | ||
553 | |||
554 | /* We're done with read_buffer, tack it to the end of the empty buffer list */ | ||
555 | if (pdev->empty_frames == NULL) { | ||
556 | pdev->empty_frames = pdev->read_frame; | ||
557 | pdev->empty_frames_tail = pdev->empty_frames; | ||
564 | } | 558 | } |
565 | else { | 559 | else { |
566 | pdev->read_frame = pdev->full_frames; | 560 | pdev->empty_frames_tail->next = pdev->read_frame; |
567 | pdev->full_frames = pdev->full_frames->next; | 561 | pdev->empty_frames_tail = pdev->read_frame; |
568 | pdev->read_frame->next = NULL; | ||
569 | } | ||
570 | |||
571 | if (pdev->read_frame != NULL) { | ||
572 | #if PWC_DEBUG | ||
573 | Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence); | ||
574 | #endif | ||
575 | /* Decompression is a lenghty process, so it's outside of the lock. | ||
576 | This gives the isoc_handler the opportunity to fill more frames | ||
577 | in the mean time. | ||
578 | */ | ||
579 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | ||
580 | ret = pwc_decompress(pdev); | ||
581 | spin_lock_irqsave(&pdev->ptrlock, flags); | ||
582 | |||
583 | /* We're done with read_buffer, tack it to the end of the empty buffer list */ | ||
584 | if (pdev->empty_frames == NULL) { | ||
585 | pdev->empty_frames = pdev->read_frame; | ||
586 | pdev->empty_frames_tail = pdev->empty_frames; | ||
587 | } | ||
588 | else { | ||
589 | pdev->empty_frames_tail->next = pdev->read_frame; | ||
590 | pdev->empty_frames_tail = pdev->read_frame; | ||
591 | } | ||
592 | pdev->read_frame = NULL; | ||
593 | } | 562 | } |
563 | pdev->read_frame = NULL; | ||
594 | } | 564 | } |
595 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | 565 | spin_unlock_irqrestore(&pdev->ptrlock, flags); |
596 | return ret; | 566 | return ret; |
@@ -599,12 +569,114 @@ static int pwc_handle_frame(struct pwc_device *pdev) | |||
599 | /** | 569 | /** |
600 | \brief Advance pointers of image buffer (after each user request) | 570 | \brief Advance pointers of image buffer (after each user request) |
601 | */ | 571 | */ |
602 | static inline void pwc_next_image(struct pwc_device *pdev) | 572 | void pwc_next_image(struct pwc_device *pdev) |
603 | { | 573 | { |
604 | pdev->image_used[pdev->fill_image] = 0; | 574 | pdev->image_used[pdev->fill_image] = 0; |
605 | pdev->fill_image = (pdev->fill_image + 1) % default_mbufs; | 575 | pdev->fill_image = (pdev->fill_image + 1) % pwc_mbufs; |
606 | } | 576 | } |
607 | 577 | ||
578 | /** | ||
579 | * Print debug information when a frame is discarded because all of our buffer | ||
580 | * is full | ||
581 | */ | ||
582 | static void pwc_frame_dumped(struct pwc_device *pdev) | ||
583 | { | ||
584 | pdev->vframes_dumped++; | ||
585 | if (pdev->vframe_count < FRAME_LOWMARK) | ||
586 | return; | ||
587 | |||
588 | if (pdev->vframes_dumped < 20) | ||
589 | PWC_DEBUG_FLOW("Dumping frame %d\n", pdev->vframe_count); | ||
590 | else if (pdev->vframes_dumped == 20) | ||
591 | PWC_DEBUG_FLOW("Dumping frame %d (last message)\n", | ||
592 | pdev->vframe_count); | ||
593 | } | ||
594 | |||
595 | static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf) | ||
596 | { | ||
597 | int awake = 0; | ||
598 | |||
599 | /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus | ||
600 | frames on the USB wire after an exposure change. This conditition is | ||
601 | however detected in the cam and a bit is set in the header. | ||
602 | */ | ||
603 | if (pdev->type == 730) { | ||
604 | unsigned char *ptr = (unsigned char *)fbuf->data; | ||
605 | |||
606 | if (ptr[1] == 1 && ptr[0] & 0x10) { | ||
607 | PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n"); | ||
608 | pdev->drop_frames += 2; | ||
609 | pdev->vframes_error++; | ||
610 | } | ||
611 | if ((ptr[0] ^ pdev->vmirror) & 0x01) { | ||
612 | if (ptr[0] & 0x01) { | ||
613 | pdev->snapshot_button_status = 1; | ||
614 | PWC_TRACE("Snapshot button pressed.\n"); | ||
615 | } | ||
616 | else { | ||
617 | PWC_TRACE("Snapshot button released.\n"); | ||
618 | } | ||
619 | } | ||
620 | if ((ptr[0] ^ pdev->vmirror) & 0x02) { | ||
621 | if (ptr[0] & 0x02) | ||
622 | PWC_TRACE("Image is mirrored.\n"); | ||
623 | else | ||
624 | PWC_TRACE("Image is normal.\n"); | ||
625 | } | ||
626 | pdev->vmirror = ptr[0] & 0x03; | ||
627 | /* Sometimes the trailer of the 730 is still sent as a 4 byte packet | ||
628 | after a short frame; this condition is filtered out specifically. A 4 byte | ||
629 | frame doesn't make sense anyway. | ||
630 | So we get either this sequence: | ||
631 | drop_bit set -> 4 byte frame -> short frame -> good frame | ||
632 | Or this one: | ||
633 | drop_bit set -> short frame -> good frame | ||
634 | So we drop either 3 or 2 frames in all! | ||
635 | */ | ||
636 | if (fbuf->filled == 4) | ||
637 | pdev->drop_frames++; | ||
638 | } | ||
639 | else if (pdev->type == 740 || pdev->type == 720) { | ||
640 | unsigned char *ptr = (unsigned char *)fbuf->data; | ||
641 | if ((ptr[0] ^ pdev->vmirror) & 0x01) { | ||
642 | if (ptr[0] & 0x01) { | ||
643 | pdev->snapshot_button_status = 1; | ||
644 | PWC_TRACE("Snapshot button pressed.\n"); | ||
645 | } | ||
646 | else | ||
647 | PWC_TRACE("Snapshot button released.\n"); | ||
648 | } | ||
649 | pdev->vmirror = ptr[0] & 0x03; | ||
650 | } | ||
651 | |||
652 | /* In case we were instructed to drop the frame, do so silently. | ||
653 | The buffer pointers are not updated either (but the counters are reset below). | ||
654 | */ | ||
655 | if (pdev->drop_frames > 0) | ||
656 | pdev->drop_frames--; | ||
657 | else { | ||
658 | /* Check for underflow first */ | ||
659 | if (fbuf->filled < pdev->frame_total_size) { | ||
660 | PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);" | ||
661 | " discarded.\n", fbuf->filled); | ||
662 | pdev->vframes_error++; | ||
663 | } | ||
664 | else { | ||
665 | /* Send only once per EOF */ | ||
666 | awake = 1; /* delay wake_ups */ | ||
667 | |||
668 | /* Find our next frame to fill. This will always succeed, since we | ||
669 | * nick a frame from either empty or full list, but if we had to | ||
670 | * take it from the full list, it means a frame got dropped. | ||
671 | */ | ||
672 | if (pwc_next_fill_frame(pdev)) | ||
673 | pwc_frame_dumped(pdev); | ||
674 | |||
675 | } | ||
676 | } /* !drop_frames */ | ||
677 | pdev->vframe_count++; | ||
678 | return awake; | ||
679 | } | ||
608 | 680 | ||
609 | /* This gets called for the Isochronous pipe (video). This is done in | 681 | /* This gets called for the Isochronous pipe (video). This is done in |
610 | * interrupt time, so it has to be fast, not crash, and not stall. Neat. | 682 | * interrupt time, so it has to be fast, not crash, and not stall. Neat. |
@@ -620,17 +692,12 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) | |||
620 | awake = 0; | 692 | awake = 0; |
621 | pdev = (struct pwc_device *)urb->context; | 693 | pdev = (struct pwc_device *)urb->context; |
622 | if (pdev == NULL) { | 694 | if (pdev == NULL) { |
623 | Err("isoc_handler() called with NULL device?!\n"); | 695 | PWC_ERROR("isoc_handler() called with NULL device?!\n"); |
624 | return; | ||
625 | } | ||
626 | #ifdef PWC_MAGIC | ||
627 | if (pdev->magic != PWC_MAGIC) { | ||
628 | Err("isoc_handler() called with bad magic!\n"); | ||
629 | return; | 696 | return; |
630 | } | 697 | } |
631 | #endif | 698 | |
632 | if (urb->status == -ENOENT || urb->status == -ECONNRESET) { | 699 | if (urb->status == -ENOENT || urb->status == -ECONNRESET) { |
633 | Trace(TRACE_OPEN, "pwc_isoc_handler(): URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); | 700 | PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); |
634 | return; | 701 | return; |
635 | } | 702 | } |
636 | if (urb->status != -EINPROGRESS && urb->status != 0) { | 703 | if (urb->status != -EINPROGRESS && urb->status != 0) { |
@@ -645,13 +712,13 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) | |||
645 | case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break; | 712 | case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break; |
646 | case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break; | 713 | case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break; |
647 | } | 714 | } |
648 | Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg); | 715 | PWC_DEBUG_FLOW("pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg); |
649 | /* Give up after a number of contiguous errors on the USB bus. | 716 | /* Give up after a number of contiguous errors on the USB bus. |
650 | Appearantly something is wrong so we simulate an unplug event. | 717 | Appearantly something is wrong so we simulate an unplug event. |
651 | */ | 718 | */ |
652 | if (++pdev->visoc_errors > MAX_ISOC_ERRORS) | 719 | if (++pdev->visoc_errors > MAX_ISOC_ERRORS) |
653 | { | 720 | { |
654 | Info("Too many ISOC errors, bailing out.\n"); | 721 | PWC_INFO("Too many ISOC errors, bailing out.\n"); |
655 | pdev->error_status = EIO; | 722 | pdev->error_status = EIO; |
656 | awake = 1; | 723 | awake = 1; |
657 | wake_up_interruptible(&pdev->frameq); | 724 | wake_up_interruptible(&pdev->frameq); |
@@ -661,7 +728,7 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) | |||
661 | 728 | ||
662 | fbuf = pdev->fill_frame; | 729 | fbuf = pdev->fill_frame; |
663 | if (fbuf == NULL) { | 730 | if (fbuf == NULL) { |
664 | Err("pwc_isoc_handler without valid fill frame.\n"); | 731 | PWC_ERROR("pwc_isoc_handler without valid fill frame.\n"); |
665 | awake = 1; | 732 | awake = 1; |
666 | goto handler_end; | 733 | goto handler_end; |
667 | } | 734 | } |
@@ -688,7 +755,7 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) | |||
688 | 755 | ||
689 | /* ...copy data to frame buffer, if possible */ | 756 | /* ...copy data to frame buffer, if possible */ |
690 | if (flen + fbuf->filled > pdev->frame_total_size) { | 757 | if (flen + fbuf->filled > pdev->frame_total_size) { |
691 | Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size); | 758 | PWC_DEBUG_FLOW("Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size); |
692 | pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */ | 759 | pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */ |
693 | pdev->vframes_error++; | 760 | pdev->vframes_error++; |
694 | } | 761 | } |
@@ -704,96 +771,28 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) | |||
704 | /* Shorter packet... We probably have the end of an image-frame; | 771 | /* Shorter packet... We probably have the end of an image-frame; |
705 | wake up read() process and let select()/poll() do something. | 772 | wake up read() process and let select()/poll() do something. |
706 | Decompression is done in user time over there. | 773 | Decompression is done in user time over there. |
707 | */ | 774 | */ |
708 | if (pdev->vsync == 2) { | 775 | if (pdev->vsync == 2) { |
709 | /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus | 776 | if (pwc_rcv_short_packet(pdev, fbuf)) { |
710 | frames on the USB wire after an exposure change. This conditition is | 777 | awake = 1; |
711 | however detected in the cam and a bit is set in the header. | 778 | fbuf = pdev->fill_frame; |
712 | */ | ||
713 | if (pdev->type == 730) { | ||
714 | unsigned char *ptr = (unsigned char *)fbuf->data; | ||
715 | |||
716 | if (ptr[1] == 1 && ptr[0] & 0x10) { | ||
717 | #if PWC_DEBUG | ||
718 | Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence); | ||
719 | #endif | ||
720 | pdev->drop_frames += 2; | ||
721 | pdev->vframes_error++; | ||
722 | } | ||
723 | if ((ptr[0] ^ pdev->vmirror) & 0x01) { | ||
724 | if (ptr[0] & 0x01) | ||
725 | Info("Snapshot button pressed.\n"); | ||
726 | else | ||
727 | Info("Snapshot button released.\n"); | ||
728 | } | ||
729 | if ((ptr[0] ^ pdev->vmirror) & 0x02) { | ||
730 | if (ptr[0] & 0x02) | ||
731 | Info("Image is mirrored.\n"); | ||
732 | else | ||
733 | Info("Image is normal.\n"); | ||
734 | } | ||
735 | pdev->vmirror = ptr[0] & 0x03; | ||
736 | /* Sometimes the trailer of the 730 is still sent as a 4 byte packet | ||
737 | after a short frame; this condition is filtered out specifically. A 4 byte | ||
738 | frame doesn't make sense anyway. | ||
739 | So we get either this sequence: | ||
740 | drop_bit set -> 4 byte frame -> short frame -> good frame | ||
741 | Or this one: | ||
742 | drop_bit set -> short frame -> good frame | ||
743 | So we drop either 3 or 2 frames in all! | ||
744 | */ | ||
745 | if (fbuf->filled == 4) | ||
746 | pdev->drop_frames++; | ||
747 | } | 779 | } |
748 | |||
749 | /* In case we were instructed to drop the frame, do so silently. | ||
750 | The buffer pointers are not updated either (but the counters are reset below). | ||
751 | */ | ||
752 | if (pdev->drop_frames > 0) | ||
753 | pdev->drop_frames--; | ||
754 | else { | ||
755 | /* Check for underflow first */ | ||
756 | if (fbuf->filled < pdev->frame_total_size) { | ||
757 | Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled); | ||
758 | pdev->vframes_error++; | ||
759 | } | ||
760 | else { | ||
761 | /* Send only once per EOF */ | ||
762 | awake = 1; /* delay wake_ups */ | ||
763 | |||
764 | /* Find our next frame to fill. This will always succeed, since we | ||
765 | * nick a frame from either empty or full list, but if we had to | ||
766 | * take it from the full list, it means a frame got dropped. | ||
767 | */ | ||
768 | if (pwc_next_fill_frame(pdev)) { | ||
769 | pdev->vframes_dumped++; | ||
770 | if ((pdev->vframe_count > FRAME_LOWMARK) && (pwc_trace & TRACE_FLOW)) { | ||
771 | if (pdev->vframes_dumped < 20) | ||
772 | Trace(TRACE_FLOW, "Dumping frame %d.\n", pdev->vframe_count); | ||
773 | if (pdev->vframes_dumped == 20) | ||
774 | Trace(TRACE_FLOW, "Dumping frame %d (last message).\n", pdev->vframe_count); | ||
775 | } | ||
776 | } | ||
777 | fbuf = pdev->fill_frame; | ||
778 | } | ||
779 | } /* !drop_frames */ | ||
780 | pdev->vframe_count++; | ||
781 | } | 780 | } |
782 | fbuf->filled = 0; | 781 | fbuf->filled = 0; |
783 | fillptr = fbuf->data; | 782 | fillptr = fbuf->data; |
784 | pdev->vsync = 1; | 783 | pdev->vsync = 1; |
785 | } /* .. flen < last_packet_size */ | 784 | } |
785 | |||
786 | pdev->vlast_packet_size = flen; | 786 | pdev->vlast_packet_size = flen; |
787 | } /* ..status == 0 */ | 787 | } /* ..status == 0 */ |
788 | #if PWC_DEBUG | ||
789 | /* This is normally not interesting to the user, unless you are really debugging something */ | ||
790 | else { | 788 | else { |
789 | /* This is normally not interesting to the user, unless | ||
790 | * you are really debugging something */ | ||
791 | static int iso_error = 0; | 791 | static int iso_error = 0; |
792 | iso_error++; | 792 | iso_error++; |
793 | if (iso_error < 20) | 793 | if (iso_error < 20) |
794 | Trace(TRACE_FLOW, "Iso frame %d of USB has error %d\n", i, fst); | 794 | PWC_DEBUG_FLOW("Iso frame %d of USB has error %d\n", i, fst); |
795 | } | 795 | } |
796 | #endif | ||
797 | } | 796 | } |
798 | 797 | ||
799 | handler_end: | 798 | handler_end: |
@@ -803,11 +802,11 @@ handler_end: | |||
803 | urb->dev = pdev->udev; | 802 | urb->dev = pdev->udev; |
804 | i = usb_submit_urb(urb, GFP_ATOMIC); | 803 | i = usb_submit_urb(urb, GFP_ATOMIC); |
805 | if (i != 0) | 804 | if (i != 0) |
806 | Err("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); | 805 | PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); |
807 | } | 806 | } |
808 | 807 | ||
809 | 808 | ||
810 | static int pwc_isoc_init(struct pwc_device *pdev) | 809 | int pwc_isoc_init(struct pwc_device *pdev) |
811 | { | 810 | { |
812 | struct usb_device *udev; | 811 | struct usb_device *udev; |
813 | struct urb *urb; | 812 | struct urb *urb; |
@@ -826,7 +825,6 @@ static int pwc_isoc_init(struct pwc_device *pdev) | |||
826 | /* Get the current alternate interface, adjust packet size */ | 825 | /* Get the current alternate interface, adjust packet size */ |
827 | if (!udev->actconfig) | 826 | if (!udev->actconfig) |
828 | return -EFAULT; | 827 | return -EFAULT; |
829 | |||
830 | intf = usb_ifnum_to_if(udev, 0); | 828 | intf = usb_ifnum_to_if(udev, 0); |
831 | if (intf) | 829 | if (intf) |
832 | idesc = usb_altnum_to_altsetting(intf, pdev->valternate); | 830 | idesc = usb_altnum_to_altsetting(intf, pdev->valternate); |
@@ -836,20 +834,21 @@ static int pwc_isoc_init(struct pwc_device *pdev) | |||
836 | 834 | ||
837 | /* Search video endpoint */ | 835 | /* Search video endpoint */ |
838 | pdev->vmax_packet_size = -1; | 836 | pdev->vmax_packet_size = -1; |
839 | for (i = 0; i < idesc->desc.bNumEndpoints; i++) | 837 | for (i = 0; i < idesc->desc.bNumEndpoints; i++) { |
840 | if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) { | 838 | if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) { |
841 | pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize); | 839 | pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize); |
842 | break; | 840 | break; |
843 | } | 841 | } |
842 | } | ||
844 | 843 | ||
845 | if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) { | 844 | if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) { |
846 | Err("Failed to find packet size for video endpoint in current alternate setting.\n"); | 845 | PWC_ERROR("Failed to find packet size for video endpoint in current alternate setting.\n"); |
847 | return -ENFILE; /* Odd error, that should be noticeable */ | 846 | return -ENFILE; /* Odd error, that should be noticeable */ |
848 | } | 847 | } |
849 | 848 | ||
850 | /* Set alternate interface */ | 849 | /* Set alternate interface */ |
851 | ret = 0; | 850 | ret = 0; |
852 | Trace(TRACE_OPEN, "Setting alternate interface %d\n", pdev->valternate); | 851 | PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate); |
853 | ret = usb_set_interface(pdev->udev, 0, pdev->valternate); | 852 | ret = usb_set_interface(pdev->udev, 0, pdev->valternate); |
854 | if (ret < 0) | 853 | if (ret < 0) |
855 | return ret; | 854 | return ret; |
@@ -857,12 +856,12 @@ static int pwc_isoc_init(struct pwc_device *pdev) | |||
857 | for (i = 0; i < MAX_ISO_BUFS; i++) { | 856 | for (i = 0; i < MAX_ISO_BUFS; i++) { |
858 | urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); | 857 | urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); |
859 | if (urb == NULL) { | 858 | if (urb == NULL) { |
860 | Err("Failed to allocate urb %d\n", i); | 859 | PWC_ERROR("Failed to allocate urb %d\n", i); |
861 | ret = -ENOMEM; | 860 | ret = -ENOMEM; |
862 | break; | 861 | break; |
863 | } | 862 | } |
864 | pdev->sbuf[i].urb = urb; | 863 | pdev->sbuf[i].urb = urb; |
865 | Trace(TRACE_MEMORY, "Allocated URB at 0x%p\n", urb); | 864 | PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb); |
866 | } | 865 | } |
867 | if (ret) { | 866 | if (ret) { |
868 | /* De-allocate in reverse order */ | 867 | /* De-allocate in reverse order */ |
@@ -899,24 +898,26 @@ static int pwc_isoc_init(struct pwc_device *pdev) | |||
899 | for (i = 0; i < MAX_ISO_BUFS; i++) { | 898 | for (i = 0; i < MAX_ISO_BUFS; i++) { |
900 | ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); | 899 | ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); |
901 | if (ret) | 900 | if (ret) |
902 | Err("isoc_init() submit_urb %d failed with error %d\n", i, ret); | 901 | PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); |
903 | else | 902 | else |
904 | Trace(TRACE_MEMORY, "URB 0x%p submitted.\n", pdev->sbuf[i].urb); | 903 | PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb); |
905 | } | 904 | } |
906 | 905 | ||
907 | /* All is done... */ | 906 | /* All is done... */ |
908 | pdev->iso_init = 1; | 907 | pdev->iso_init = 1; |
909 | Trace(TRACE_OPEN, "<< pwc_isoc_init()\n"); | 908 | PWC_DEBUG_OPEN("<< pwc_isoc_init()\n"); |
910 | return 0; | 909 | return 0; |
911 | } | 910 | } |
912 | 911 | ||
913 | static void pwc_isoc_cleanup(struct pwc_device *pdev) | 912 | void pwc_isoc_cleanup(struct pwc_device *pdev) |
914 | { | 913 | { |
915 | int i; | 914 | int i; |
916 | 915 | ||
917 | Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n"); | 916 | PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n"); |
918 | if (pdev == NULL) | 917 | if (pdev == NULL) |
919 | return; | 918 | return; |
919 | if (pdev->iso_init == 0) | ||
920 | return; | ||
920 | 921 | ||
921 | /* Unlinking ISOC buffers one by one */ | 922 | /* Unlinking ISOC buffers one by one */ |
922 | for (i = 0; i < MAX_ISO_BUFS; i++) { | 923 | for (i = 0; i < MAX_ISO_BUFS; i++) { |
@@ -925,10 +926,10 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev) | |||
925 | urb = pdev->sbuf[i].urb; | 926 | urb = pdev->sbuf[i].urb; |
926 | if (urb != 0) { | 927 | if (urb != 0) { |
927 | if (pdev->iso_init) { | 928 | if (pdev->iso_init) { |
928 | Trace(TRACE_MEMORY, "Unlinking URB %p\n", urb); | 929 | PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb); |
929 | usb_kill_urb(urb); | 930 | usb_kill_urb(urb); |
930 | } | 931 | } |
931 | Trace(TRACE_MEMORY, "Freeing URB\n"); | 932 | PWC_DEBUG_MEMORY("Freeing URB\n"); |
932 | usb_free_urb(urb); | 933 | usb_free_urb(urb); |
933 | pdev->sbuf[i].urb = NULL; | 934 | pdev->sbuf[i].urb = NULL; |
934 | } | 935 | } |
@@ -938,12 +939,12 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev) | |||
938 | is signalled by EPIPE) | 939 | is signalled by EPIPE) |
939 | */ | 940 | */ |
940 | if (pdev->error_status && pdev->error_status != EPIPE) { | 941 | if (pdev->error_status && pdev->error_status != EPIPE) { |
941 | Trace(TRACE_OPEN, "Setting alternate interface 0.\n"); | 942 | PWC_DEBUG_OPEN("Setting alternate interface 0.\n"); |
942 | usb_set_interface(pdev->udev, 0, 0); | 943 | usb_set_interface(pdev->udev, 0, 0); |
943 | } | 944 | } |
944 | 945 | ||
945 | pdev->iso_init = 0; | 946 | pdev->iso_init = 0; |
946 | Trace(TRACE_OPEN, "<< pwc_isoc_cleanup()\n"); | 947 | PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); |
947 | } | 948 | } |
948 | 949 | ||
949 | int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot) | 950 | int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot) |
@@ -957,18 +958,18 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f | |||
957 | /* Try to set video mode... */ | 958 | /* Try to set video mode... */ |
958 | start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot); | 959 | start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot); |
959 | if (ret) { | 960 | if (ret) { |
960 | Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n"); | 961 | PWC_DEBUG_FLOW("pwc_set_video_mode attempt 1 failed.\n"); |
961 | /* That failed... restore old mode (we know that worked) */ | 962 | /* That failed... restore old mode (we know that worked) */ |
962 | start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | 963 | start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); |
963 | if (start) { | 964 | if (start) { |
964 | Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n"); | 965 | PWC_DEBUG_FLOW("pwc_set_video_mode attempt 2 failed.\n"); |
965 | } | 966 | } |
966 | } | 967 | } |
967 | if (start == 0) | 968 | if (start == 0) |
968 | { | 969 | { |
969 | if (pwc_isoc_init(pdev) < 0) | 970 | if (pwc_isoc_init(pdev) < 0) |
970 | { | 971 | { |
971 | Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n"); | 972 | PWC_WARNING("Failed to restart ISOC transfers in pwc_try_video_mode.\n"); |
972 | ret = -EAGAIN; /* let's try again, who knows if it works a second time */ | 973 | ret = -EAGAIN; /* let's try again, who knows if it works a second time */ |
973 | } | 974 | } |
974 | } | 975 | } |
@@ -976,54 +977,129 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f | |||
976 | return ret; /* Return original error code */ | 977 | return ret; /* Return original error code */ |
977 | } | 978 | } |
978 | 979 | ||
980 | /********* | ||
981 | * sysfs | ||
982 | *********/ | ||
983 | static struct pwc_device *cd_to_pwc(struct class_device *cd) | ||
984 | { | ||
985 | struct video_device *vdev = to_video_device(cd); | ||
986 | return video_get_drvdata(vdev); | ||
987 | } | ||
988 | |||
989 | static ssize_t show_pan_tilt(struct class_device *class_dev, char *buf) | ||
990 | { | ||
991 | struct pwc_device *pdev = cd_to_pwc(class_dev); | ||
992 | return sprintf(buf, "%d %d\n", pdev->pan_angle, pdev->tilt_angle); | ||
993 | } | ||
994 | |||
995 | static ssize_t store_pan_tilt(struct class_device *class_dev, const char *buf, | ||
996 | size_t count) | ||
997 | { | ||
998 | struct pwc_device *pdev = cd_to_pwc(class_dev); | ||
999 | int pan, tilt; | ||
1000 | int ret = -EINVAL; | ||
1001 | |||
1002 | if (strncmp(buf, "reset", 5) == 0) | ||
1003 | ret = pwc_mpt_reset(pdev, 0x3); | ||
1004 | |||
1005 | else if (sscanf(buf, "%d %d", &pan, &tilt) > 0) | ||
1006 | ret = pwc_mpt_set_angle(pdev, pan, tilt); | ||
1007 | |||
1008 | if (ret < 0) | ||
1009 | return ret; | ||
1010 | return strlen(buf); | ||
1011 | } | ||
1012 | static CLASS_DEVICE_ATTR(pan_tilt, S_IRUGO | S_IWUSR, show_pan_tilt, | ||
1013 | store_pan_tilt); | ||
1014 | |||
1015 | static ssize_t show_snapshot_button_status(struct class_device *class_dev, char *buf) | ||
1016 | { | ||
1017 | struct pwc_device *pdev = cd_to_pwc(class_dev); | ||
1018 | int status = pdev->snapshot_button_status; | ||
1019 | pdev->snapshot_button_status = 0; | ||
1020 | return sprintf(buf, "%d\n", status); | ||
1021 | } | ||
1022 | |||
1023 | static CLASS_DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status, | ||
1024 | NULL); | ||
1025 | |||
1026 | static void pwc_create_sysfs_files(struct video_device *vdev) | ||
1027 | { | ||
1028 | struct pwc_device *pdev = video_get_drvdata(vdev); | ||
1029 | if (pdev->features & FEATURE_MOTOR_PANTILT) | ||
1030 | video_device_create_file(vdev, &class_device_attr_pan_tilt); | ||
1031 | video_device_create_file(vdev, &class_device_attr_button); | ||
1032 | } | ||
1033 | |||
1034 | static void pwc_remove_sysfs_files(struct video_device *vdev) | ||
1035 | { | ||
1036 | struct pwc_device *pdev = video_get_drvdata(vdev); | ||
1037 | if (pdev->features & FEATURE_MOTOR_PANTILT) | ||
1038 | video_device_remove_file(vdev, &class_device_attr_pan_tilt); | ||
1039 | video_device_remove_file(vdev, &class_device_attr_button); | ||
1040 | } | ||
1041 | |||
1042 | #if CONFIG_PWC_DEBUG | ||
1043 | static const char *pwc_sensor_type_to_string(unsigned int sensor_type) | ||
1044 | { | ||
1045 | switch(sensor_type) { | ||
1046 | case 0x00: | ||
1047 | return "Hyundai CMOS sensor"; | ||
1048 | case 0x20: | ||
1049 | return "Sony CCD sensor + TDA8787"; | ||
1050 | case 0x2E: | ||
1051 | return "Sony CCD sensor + Exas 98L59"; | ||
1052 | case 0x2F: | ||
1053 | return "Sony CCD sensor + ADI 9804"; | ||
1054 | case 0x30: | ||
1055 | return "Sharp CCD sensor + TDA8787"; | ||
1056 | case 0x3E: | ||
1057 | return "Sharp CCD sensor + Exas 98L59"; | ||
1058 | case 0x3F: | ||
1059 | return "Sharp CCD sensor + ADI 9804"; | ||
1060 | case 0x40: | ||
1061 | return "UPA 1021 sensor"; | ||
1062 | case 0x100: | ||
1063 | return "VGA sensor"; | ||
1064 | case 0x101: | ||
1065 | return "PAL MR sensor"; | ||
1066 | default: | ||
1067 | return "unknown type of sensor"; | ||
1068 | } | ||
1069 | } | ||
1070 | #endif | ||
979 | 1071 | ||
980 | /***************************************************************************/ | 1072 | /***************************************************************************/ |
981 | /* Video4Linux functions */ | 1073 | /* Video4Linux functions */ |
982 | 1074 | ||
983 | static int pwc_video_open(struct inode *inode, struct file *file) | 1075 | static int pwc_video_open(struct inode *inode, struct file *file) |
984 | { | 1076 | { |
985 | int i; | 1077 | int i, ret; |
986 | struct video_device *vdev = video_devdata(file); | 1078 | struct video_device *vdev = video_devdata(file); |
987 | struct pwc_device *pdev; | 1079 | struct pwc_device *pdev; |
988 | 1080 | ||
989 | Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev); | 1081 | PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev); |
990 | 1082 | ||
991 | pdev = (struct pwc_device *)vdev->priv; | 1083 | pdev = (struct pwc_device *)vdev->priv; |
992 | if (pdev == NULL) | 1084 | if (pdev == NULL) |
993 | BUG(); | 1085 | BUG(); |
994 | if (pdev->vopen) | 1086 | if (pdev->vopen) { |
1087 | PWC_DEBUG_OPEN("I'm busy, someone is using the device.\n"); | ||
995 | return -EBUSY; | 1088 | return -EBUSY; |
1089 | } | ||
996 | 1090 | ||
997 | down(&pdev->modlock); | 1091 | down(&pdev->modlock); |
998 | if (!pdev->usb_init) { | 1092 | if (!pdev->usb_init) { |
999 | Trace(TRACE_OPEN, "Doing first time initialization.\n"); | 1093 | PWC_DEBUG_OPEN("Doing first time initialization.\n"); |
1000 | pdev->usb_init = 1; | 1094 | pdev->usb_init = 1; |
1001 | 1095 | ||
1002 | if (pwc_trace & TRACE_OPEN) | 1096 | /* Query sensor type */ |
1097 | ret = pwc_get_cmos_sensor(pdev, &i); | ||
1098 | if (ret >= 0) | ||
1003 | { | 1099 | { |
1004 | /* Query sensor type */ | 1100 | PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n", |
1005 | const char *sensor_type = NULL; | 1101 | pdev->vdev->name, |
1006 | int ret; | 1102 | pwc_sensor_type_to_string(i), i); |
1007 | |||
1008 | ret = pwc_get_cmos_sensor(pdev, &i); | ||
1009 | if (ret >= 0) | ||
1010 | { | ||
1011 | switch(i) { | ||
1012 | case 0x00: sensor_type = "Hyundai CMOS sensor"; break; | ||
1013 | case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break; | ||
1014 | case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break; | ||
1015 | case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break; | ||
1016 | case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break; | ||
1017 | case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break; | ||
1018 | case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break; | ||
1019 | case 0x40: sensor_type = "UPA 1021 sensor"; break; | ||
1020 | case 0x100: sensor_type = "VGA sensor"; break; | ||
1021 | case 0x101: sensor_type = "PAL MR sensor"; break; | ||
1022 | default: sensor_type = "unknown type of sensor"; break; | ||
1023 | } | ||
1024 | } | ||
1025 | if (sensor_type != NULL) | ||
1026 | Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev->name, sensor_type, i); | ||
1027 | } | 1103 | } |
1028 | } | 1104 | } |
1029 | 1105 | ||
@@ -1031,34 +1107,32 @@ static int pwc_video_open(struct inode *inode, struct file *file) | |||
1031 | if (power_save) { | 1107 | if (power_save) { |
1032 | i = pwc_camera_power(pdev, 1); | 1108 | i = pwc_camera_power(pdev, 1); |
1033 | if (i < 0) | 1109 | if (i < 0) |
1034 | Info("Failed to restore power to the camera! (%d)\n", i); | 1110 | PWC_DEBUG_OPEN("Failed to restore power to the camera! (%d)\n", i); |
1035 | } | 1111 | } |
1036 | /* Set LED on/off time */ | 1112 | /* Set LED on/off time */ |
1037 | if (pwc_set_leds(pdev, led_on, led_off) < 0) | 1113 | if (pwc_set_leds(pdev, led_on, led_off) < 0) |
1038 | Info("Failed to set LED on/off time.\n"); | 1114 | PWC_DEBUG_OPEN("Failed to set LED on/off time.\n"); |
1039 | 1115 | ||
1040 | pwc_construct(pdev); /* set min/max sizes correct */ | 1116 | pwc_construct(pdev); /* set min/max sizes correct */ |
1041 | 1117 | ||
1042 | /* So far, so good. Allocate memory. */ | 1118 | /* So far, so good. Allocate memory. */ |
1043 | i = pwc_allocate_buffers(pdev); | 1119 | i = pwc_allocate_buffers(pdev); |
1044 | if (i < 0) { | 1120 | if (i < 0) { |
1045 | Trace(TRACE_OPEN, "Failed to allocate buffer memory.\n"); | 1121 | PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n"); |
1122 | pwc_free_buffers(pdev); | ||
1046 | up(&pdev->modlock); | 1123 | up(&pdev->modlock); |
1047 | return i; | 1124 | return i; |
1048 | } | 1125 | } |
1049 | 1126 | ||
1050 | /* Reset buffers & parameters */ | 1127 | /* Reset buffers & parameters */ |
1051 | pwc_reset_buffers(pdev); | 1128 | pwc_reset_buffers(pdev); |
1052 | for (i = 0; i < default_mbufs; i++) | 1129 | for (i = 0; i < pwc_mbufs; i++) |
1053 | pdev->image_used[i] = 0; | 1130 | pdev->image_used[i] = 0; |
1054 | pdev->vframe_count = 0; | 1131 | pdev->vframe_count = 0; |
1055 | pdev->vframes_dumped = 0; | 1132 | pdev->vframes_dumped = 0; |
1056 | pdev->vframes_error = 0; | 1133 | pdev->vframes_error = 0; |
1057 | pdev->visoc_errors = 0; | 1134 | pdev->visoc_errors = 0; |
1058 | pdev->error_status = 0; | 1135 | pdev->error_status = 0; |
1059 | #if PWC_DEBUG | ||
1060 | pdev->sequence = 0; | ||
1061 | #endif | ||
1062 | pwc_construct(pdev); /* set min/max sizes correct */ | 1136 | pwc_construct(pdev); /* set min/max sizes correct */ |
1063 | 1137 | ||
1064 | /* Set some defaults */ | 1138 | /* Set some defaults */ |
@@ -1070,29 +1144,44 @@ static int pwc_video_open(struct inode *inode, struct file *file) | |||
1070 | */ | 1144 | */ |
1071 | i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0); | 1145 | i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0); |
1072 | if (i) { | 1146 | if (i) { |
1073 | Trace(TRACE_OPEN, "First attempt at set_video_mode failed.\n"); | 1147 | unsigned int default_resolution; |
1074 | if (pdev->type == 730 || pdev->type == 740 || pdev->type == 750) | 1148 | PWC_DEBUG_OPEN("First attempt at set_video_mode failed.\n"); |
1075 | i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QSIF].x, pwc_image_sizes[PSZ_QSIF].y, 10, pdev->vcompression, 0); | 1149 | if (pdev->type>= 730) |
1150 | default_resolution = PSZ_QSIF; | ||
1076 | else | 1151 | else |
1077 | i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QCIF].x, pwc_image_sizes[PSZ_QCIF].y, 10, pdev->vcompression, 0); | 1152 | default_resolution = PSZ_QCIF; |
1153 | |||
1154 | i = pwc_set_video_mode(pdev, | ||
1155 | pwc_image_sizes[default_resolution].x, | ||
1156 | pwc_image_sizes[default_resolution].y, | ||
1157 | 10, | ||
1158 | pdev->vcompression, | ||
1159 | 0); | ||
1078 | } | 1160 | } |
1079 | if (i) { | 1161 | if (i) { |
1080 | Trace(TRACE_OPEN, "Second attempt at set_video_mode failed.\n"); | 1162 | PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n"); |
1163 | pwc_free_buffers(pdev); | ||
1081 | up(&pdev->modlock); | 1164 | up(&pdev->modlock); |
1082 | return i; | 1165 | return i; |
1083 | } | 1166 | } |
1084 | 1167 | ||
1085 | i = pwc_isoc_init(pdev); | 1168 | i = pwc_isoc_init(pdev); |
1086 | if (i) { | 1169 | if (i) { |
1087 | Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i); | 1170 | PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i); |
1171 | pwc_isoc_cleanup(pdev); | ||
1172 | pwc_free_buffers(pdev); | ||
1088 | up(&pdev->modlock); | 1173 | up(&pdev->modlock); |
1089 | return i; | 1174 | return i; |
1090 | } | 1175 | } |
1091 | 1176 | ||
1177 | /* Initialize the webcam to sane value */ | ||
1178 | pwc_set_brightness(pdev, 0x7fff); | ||
1179 | pwc_set_agc(pdev, 1, 0); | ||
1180 | |||
1092 | pdev->vopen++; | 1181 | pdev->vopen++; |
1093 | file->private_data = vdev; | 1182 | file->private_data = vdev; |
1094 | up(&pdev->modlock); | 1183 | up(&pdev->modlock); |
1095 | Trace(TRACE_OPEN, "<< video_open() returns 0.\n"); | 1184 | PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); |
1096 | return 0; | 1185 | return 0; |
1097 | } | 1186 | } |
1098 | 1187 | ||
@@ -1103,35 +1192,23 @@ static int pwc_video_close(struct inode *inode, struct file *file) | |||
1103 | struct pwc_device *pdev; | 1192 | struct pwc_device *pdev; |
1104 | int i; | 1193 | int i; |
1105 | 1194 | ||
1106 | Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev); | 1195 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); |
1107 | 1196 | ||
1108 | pdev = (struct pwc_device *)vdev->priv; | 1197 | pdev = (struct pwc_device *)vdev->priv; |
1109 | if (pdev->vopen == 0) | 1198 | if (pdev->vopen == 0) |
1110 | Info("video_close() called on closed device?\n"); | 1199 | PWC_DEBUG_MODULE("video_close() called on closed device?\n"); |
1111 | 1200 | ||
1112 | /* Dump statistics, but only if a reasonable amount of frames were | 1201 | /* Dump statistics, but only if a reasonable amount of frames were |
1113 | processed (to prevent endless log-entries in case of snap-shot | 1202 | processed (to prevent endless log-entries in case of snap-shot |
1114 | programs) | 1203 | programs) |
1115 | */ | 1204 | */ |
1116 | if (pdev->vframe_count > 20) | 1205 | if (pdev->vframe_count > 20) |
1117 | Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error); | 1206 | PWC_DEBUG_MODULE("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error); |
1118 | 1207 | ||
1119 | switch (pdev->type) | 1208 | if (DEVICE_USE_CODEC1(pdev->type)) |
1120 | { | 1209 | pwc_dec1_exit(); |
1121 | case 675: | 1210 | else |
1122 | case 680: | 1211 | pwc_dec23_exit(); |
1123 | case 690: | ||
1124 | case 720: | ||
1125 | case 730: | ||
1126 | case 740: | ||
1127 | case 750: | ||
1128 | /* pwc_dec23_exit(); *//* Timon & Kiara */ | ||
1129 | break; | ||
1130 | case 645: | ||
1131 | case 646: | ||
1132 | /* pwc_dec1_exit(); */ | ||
1133 | break; | ||
1134 | } | ||
1135 | 1212 | ||
1136 | pwc_isoc_cleanup(pdev); | 1213 | pwc_isoc_cleanup(pdev); |
1137 | pwc_free_buffers(pdev); | 1214 | pwc_free_buffers(pdev); |
@@ -1140,15 +1217,15 @@ static int pwc_video_close(struct inode *inode, struct file *file) | |||
1140 | if (pdev->error_status != EPIPE) { | 1217 | if (pdev->error_status != EPIPE) { |
1141 | /* Turn LEDs off */ | 1218 | /* Turn LEDs off */ |
1142 | if (pwc_set_leds(pdev, 0, 0) < 0) | 1219 | if (pwc_set_leds(pdev, 0, 0) < 0) |
1143 | Info("Failed to set LED on/off time.\n"); | 1220 | PWC_DEBUG_MODULE("Failed to set LED on/off time.\n"); |
1144 | if (power_save) { | 1221 | if (power_save) { |
1145 | i = pwc_camera_power(pdev, 0); | 1222 | i = pwc_camera_power(pdev, 0); |
1146 | if (i < 0) | 1223 | if (i < 0) |
1147 | Err("Failed to power down camera (%d)\n", i); | 1224 | PWC_ERROR("Failed to power down camera (%d)\n", i); |
1148 | } | 1225 | } |
1149 | } | 1226 | } |
1150 | pdev->vopen = 0; | 1227 | pdev->vopen--; |
1151 | Trace(TRACE_OPEN, "<< video_close()\n"); | 1228 | PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); |
1152 | return 0; | 1229 | return 0; |
1153 | } | 1230 | } |
1154 | 1231 | ||
@@ -1164,7 +1241,7 @@ static int pwc_video_close(struct inode *inode, struct file *file) | |||
1164 | device is tricky anyhow. | 1241 | device is tricky anyhow. |
1165 | */ | 1242 | */ |
1166 | 1243 | ||
1167 | static ssize_t pwc_video_read(struct file *file, char __user * buf, | 1244 | static ssize_t pwc_video_read(struct file *file, char __user *buf, |
1168 | size_t count, loff_t *ppos) | 1245 | size_t count, loff_t *ppos) |
1169 | { | 1246 | { |
1170 | struct video_device *vdev = file->private_data; | 1247 | struct video_device *vdev = file->private_data; |
@@ -1172,8 +1249,10 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf, | |||
1172 | int noblock = file->f_flags & O_NONBLOCK; | 1249 | int noblock = file->f_flags & O_NONBLOCK; |
1173 | DECLARE_WAITQUEUE(wait, current); | 1250 | DECLARE_WAITQUEUE(wait, current); |
1174 | int bytes_to_read; | 1251 | int bytes_to_read; |
1252 | void *image_buffer_addr; | ||
1175 | 1253 | ||
1176 | Trace(TRACE_READ, "video_read(0x%p, %p, %zu) called.\n", vdev, buf, count); | 1254 | PWC_DEBUG_READ("pwc_video_read(vdev=0x%p, buf=%p, count=%zd) called.\n", |
1255 | vdev, buf, count); | ||
1177 | if (vdev == NULL) | 1256 | if (vdev == NULL) |
1178 | return -EFAULT; | 1257 | return -EFAULT; |
1179 | pdev = vdev->priv; | 1258 | pdev = vdev->priv; |
@@ -1214,16 +1293,19 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf, | |||
1214 | return -EFAULT; | 1293 | return -EFAULT; |
1215 | } | 1294 | } |
1216 | 1295 | ||
1217 | Trace(TRACE_READ, "Copying data to user space.\n"); | 1296 | PWC_DEBUG_READ("Copying data to user space.\n"); |
1218 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 1297 | if (pdev->vpalette == VIDEO_PALETTE_RAW) |
1219 | bytes_to_read = pdev->frame_size; | 1298 | bytes_to_read = pdev->frame_size + sizeof(struct pwc_raw_frame); |
1220 | else | 1299 | else |
1221 | bytes_to_read = pdev->view.size; | 1300 | bytes_to_read = pdev->view.size; |
1222 | 1301 | ||
1223 | /* copy bytes to user space; we allow for partial reads */ | 1302 | /* copy bytes to user space; we allow for partial reads */ |
1224 | if (count + pdev->image_read_pos > bytes_to_read) | 1303 | if (count + pdev->image_read_pos > bytes_to_read) |
1225 | count = bytes_to_read - pdev->image_read_pos; | 1304 | count = bytes_to_read - pdev->image_read_pos; |
1226 | if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count)) | 1305 | image_buffer_addr = pdev->image_data; |
1306 | image_buffer_addr += pdev->images[pdev->fill_image].offset; | ||
1307 | image_buffer_addr += pdev->image_read_pos; | ||
1308 | if (copy_to_user(buf, image_buffer_addr, count)) | ||
1227 | return -EFAULT; | 1309 | return -EFAULT; |
1228 | pdev->image_read_pos += count; | 1310 | pdev->image_read_pos += count; |
1229 | if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */ | 1311 | if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */ |
@@ -1253,370 +1335,56 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) | |||
1253 | return 0; | 1335 | return 0; |
1254 | } | 1336 | } |
1255 | 1337 | ||
1256 | static int pwc_video_do_ioctl(struct inode *inode, struct file *file, | ||
1257 | unsigned int cmd, void *arg) | ||
1258 | { | ||
1259 | struct video_device *vdev = file->private_data; | ||
1260 | struct pwc_device *pdev; | ||
1261 | DECLARE_WAITQUEUE(wait, current); | ||
1262 | |||
1263 | if (vdev == NULL) | ||
1264 | return -EFAULT; | ||
1265 | pdev = vdev->priv; | ||
1266 | if (pdev == NULL) | ||
1267 | return -EFAULT; | ||
1268 | |||
1269 | switch (cmd) { | ||
1270 | /* Query cabapilities */ | ||
1271 | case VIDIOCGCAP: | ||
1272 | { | ||
1273 | struct video_capability *caps = arg; | ||
1274 | |||
1275 | strcpy(caps->name, vdev->name); | ||
1276 | caps->type = VID_TYPE_CAPTURE; | ||
1277 | caps->channels = 1; | ||
1278 | caps->audios = 1; | ||
1279 | caps->minwidth = pdev->view_min.x; | ||
1280 | caps->minheight = pdev->view_min.y; | ||
1281 | caps->maxwidth = pdev->view_max.x; | ||
1282 | caps->maxheight = pdev->view_max.y; | ||
1283 | break; | ||
1284 | } | ||
1285 | |||
1286 | /* Channel functions (simulate 1 channel) */ | ||
1287 | case VIDIOCGCHAN: | ||
1288 | { | ||
1289 | struct video_channel *v = arg; | ||
1290 | |||
1291 | if (v->channel != 0) | ||
1292 | return -EINVAL; | ||
1293 | v->flags = 0; | ||
1294 | v->tuners = 0; | ||
1295 | v->type = VIDEO_TYPE_CAMERA; | ||
1296 | strcpy(v->name, "Webcam"); | ||
1297 | return 0; | ||
1298 | } | ||
1299 | |||
1300 | case VIDIOCSCHAN: | ||
1301 | { | ||
1302 | /* The spec says the argument is an integer, but | ||
1303 | the bttv driver uses a video_channel arg, which | ||
1304 | makes sense becasue it also has the norm flag. | ||
1305 | */ | ||
1306 | struct video_channel *v = arg; | ||
1307 | if (v->channel != 0) | ||
1308 | return -EINVAL; | ||
1309 | return 0; | ||
1310 | } | ||
1311 | |||
1312 | |||
1313 | /* Picture functions; contrast etc. */ | ||
1314 | case VIDIOCGPICT: | ||
1315 | { | ||
1316 | struct video_picture *p = arg; | ||
1317 | int val; | ||
1318 | |||
1319 | val = pwc_get_brightness(pdev); | ||
1320 | if (val >= 0) | ||
1321 | p->brightness = val; | ||
1322 | else | ||
1323 | p->brightness = 0xffff; | ||
1324 | val = pwc_get_contrast(pdev); | ||
1325 | if (val >= 0) | ||
1326 | p->contrast = val; | ||
1327 | else | ||
1328 | p->contrast = 0xffff; | ||
1329 | /* Gamma, Whiteness, what's the difference? :) */ | ||
1330 | val = pwc_get_gamma(pdev); | ||
1331 | if (val >= 0) | ||
1332 | p->whiteness = val; | ||
1333 | else | ||
1334 | p->whiteness = 0xffff; | ||
1335 | val = pwc_get_saturation(pdev); | ||
1336 | if (val >= 0) | ||
1337 | p->colour = val; | ||
1338 | else | ||
1339 | p->colour = 0xffff; | ||
1340 | p->depth = 24; | ||
1341 | p->palette = pdev->vpalette; | ||
1342 | p->hue = 0xFFFF; /* N/A */ | ||
1343 | break; | ||
1344 | } | ||
1345 | |||
1346 | case VIDIOCSPICT: | ||
1347 | { | ||
1348 | struct video_picture *p = arg; | ||
1349 | /* | ||
1350 | * FIXME: Suppose we are mid read | ||
1351 | ANSWER: No problem: the firmware of the camera | ||
1352 | can handle brightness/contrast/etc | ||
1353 | changes at _any_ time, and the palette | ||
1354 | is used exactly once in the uncompress | ||
1355 | routine. | ||
1356 | */ | ||
1357 | pwc_set_brightness(pdev, p->brightness); | ||
1358 | pwc_set_contrast(pdev, p->contrast); | ||
1359 | pwc_set_gamma(pdev, p->whiteness); | ||
1360 | pwc_set_saturation(pdev, p->colour); | ||
1361 | if (p->palette && p->palette != pdev->vpalette) { | ||
1362 | switch (p->palette) { | ||
1363 | case VIDEO_PALETTE_YUV420P: | ||
1364 | case VIDEO_PALETTE_RAW: | ||
1365 | pdev->vpalette = p->palette; | ||
1366 | return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | ||
1367 | break; | ||
1368 | default: | ||
1369 | return -EINVAL; | ||
1370 | break; | ||
1371 | } | ||
1372 | } | ||
1373 | break; | ||
1374 | } | ||
1375 | |||
1376 | /* Window/size parameters */ | ||
1377 | case VIDIOCGWIN: | ||
1378 | { | ||
1379 | struct video_window *vw = arg; | ||
1380 | |||
1381 | vw->x = 0; | ||
1382 | vw->y = 0; | ||
1383 | vw->width = pdev->view.x; | ||
1384 | vw->height = pdev->view.y; | ||
1385 | vw->chromakey = 0; | ||
1386 | vw->flags = (pdev->vframes << PWC_FPS_SHIFT) | | ||
1387 | (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0); | ||
1388 | break; | ||
1389 | } | ||
1390 | |||
1391 | case VIDIOCSWIN: | ||
1392 | { | ||
1393 | struct video_window *vw = arg; | ||
1394 | int fps, snapshot, ret; | ||
1395 | |||
1396 | fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT; | ||
1397 | snapshot = vw->flags & PWC_FPS_SNAPSHOT; | ||
1398 | if (fps == 0) | ||
1399 | fps = pdev->vframes; | ||
1400 | if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot) | ||
1401 | return 0; | ||
1402 | ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot); | ||
1403 | if (ret) | ||
1404 | return ret; | ||
1405 | break; | ||
1406 | } | ||
1407 | |||
1408 | /* We don't have overlay support (yet) */ | ||
1409 | case VIDIOCGFBUF: | ||
1410 | { | ||
1411 | struct video_buffer *vb = arg; | ||
1412 | |||
1413 | memset(vb,0,sizeof(*vb)); | ||
1414 | break; | ||
1415 | } | ||
1416 | |||
1417 | /* mmap() functions */ | ||
1418 | case VIDIOCGMBUF: | ||
1419 | { | ||
1420 | /* Tell the user program how much memory is needed for a mmap() */ | ||
1421 | struct video_mbuf *vm = arg; | ||
1422 | int i; | ||
1423 | |||
1424 | memset(vm, 0, sizeof(*vm)); | ||
1425 | vm->size = default_mbufs * pdev->len_per_image; | ||
1426 | vm->frames = default_mbufs; /* double buffering should be enough for most applications */ | ||
1427 | for (i = 0; i < default_mbufs; i++) | ||
1428 | vm->offsets[i] = i * pdev->len_per_image; | ||
1429 | break; | ||
1430 | } | ||
1431 | |||
1432 | case VIDIOCMCAPTURE: | ||
1433 | { | ||
1434 | /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */ | ||
1435 | struct video_mmap *vm = arg; | ||
1436 | |||
1437 | Trace(TRACE_READ, "VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format); | ||
1438 | if (vm->frame < 0 || vm->frame >= default_mbufs) | ||
1439 | return -EINVAL; | ||
1440 | |||
1441 | /* xawtv is nasty. It probes the available palettes | ||
1442 | by setting a very small image size and trying | ||
1443 | various palettes... The driver doesn't support | ||
1444 | such small images, so I'm working around it. | ||
1445 | */ | ||
1446 | if (vm->format) | ||
1447 | { | ||
1448 | switch (vm->format) | ||
1449 | { | ||
1450 | case VIDEO_PALETTE_YUV420P: | ||
1451 | case VIDEO_PALETTE_RAW: | ||
1452 | break; | ||
1453 | default: | ||
1454 | return -EINVAL; | ||
1455 | break; | ||
1456 | } | ||
1457 | } | ||
1458 | |||
1459 | if ((vm->width != pdev->view.x || vm->height != pdev->view.y) && | ||
1460 | (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) { | ||
1461 | int ret; | ||
1462 | |||
1463 | Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n"); | ||
1464 | ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | ||
1465 | if (ret) | ||
1466 | return ret; | ||
1467 | } /* ... size mismatch */ | ||
1468 | |||
1469 | /* FIXME: should we lock here? */ | ||
1470 | if (pdev->image_used[vm->frame]) | ||
1471 | return -EBUSY; /* buffer wasn't available. Bummer */ | ||
1472 | pdev->image_used[vm->frame] = 1; | ||
1473 | |||
1474 | /* Okay, we're done here. In the SYNC call we wait until a | ||
1475 | frame comes available, then expand image into the given | ||
1476 | buffer. | ||
1477 | In contrast to the CPiA cam the Philips cams deliver a | ||
1478 | constant stream, almost like a grabber card. Also, | ||
1479 | we have separate buffers for the rawdata and the image, | ||
1480 | meaning we can nearly always expand into the requested buffer. | ||
1481 | */ | ||
1482 | Trace(TRACE_READ, "VIDIOCMCAPTURE done.\n"); | ||
1483 | break; | ||
1484 | } | ||
1485 | |||
1486 | case VIDIOCSYNC: | ||
1487 | { | ||
1488 | /* The doc says: "Whenever a buffer is used it should | ||
1489 | call VIDIOCSYNC to free this frame up and continue." | ||
1490 | |||
1491 | The only odd thing about this whole procedure is | ||
1492 | that MCAPTURE flags the buffer as "in use", and | ||
1493 | SYNC immediately unmarks it, while it isn't | ||
1494 | after SYNC that you know that the buffer actually | ||
1495 | got filled! So you better not start a CAPTURE in | ||
1496 | the same frame immediately (use double buffering). | ||
1497 | This is not a problem for this cam, since it has | ||
1498 | extra intermediate buffers, but a hardware | ||
1499 | grabber card will then overwrite the buffer | ||
1500 | you're working on. | ||
1501 | */ | ||
1502 | int *mbuf = arg; | ||
1503 | int ret; | ||
1504 | |||
1505 | Trace(TRACE_READ, "VIDIOCSYNC called (%d).\n", *mbuf); | ||
1506 | |||
1507 | /* bounds check */ | ||
1508 | if (*mbuf < 0 || *mbuf >= default_mbufs) | ||
1509 | return -EINVAL; | ||
1510 | /* check if this buffer was requested anyway */ | ||
1511 | if (pdev->image_used[*mbuf] == 0) | ||
1512 | return -EINVAL; | ||
1513 | |||
1514 | /* Add ourselves to the frame wait-queue. | ||
1515 | |||
1516 | FIXME: needs auditing for safety. | ||
1517 | QUESTION: In what respect? I think that using the | ||
1518 | frameq is safe now. | ||
1519 | */ | ||
1520 | add_wait_queue(&pdev->frameq, &wait); | ||
1521 | while (pdev->full_frames == NULL) { | ||
1522 | if (pdev->error_status) { | ||
1523 | remove_wait_queue(&pdev->frameq, &wait); | ||
1524 | set_current_state(TASK_RUNNING); | ||
1525 | return -pdev->error_status; | ||
1526 | } | ||
1527 | |||
1528 | if (signal_pending(current)) { | ||
1529 | remove_wait_queue(&pdev->frameq, &wait); | ||
1530 | set_current_state(TASK_RUNNING); | ||
1531 | return -ERESTARTSYS; | ||
1532 | } | ||
1533 | schedule(); | ||
1534 | set_current_state(TASK_INTERRUPTIBLE); | ||
1535 | } | ||
1536 | remove_wait_queue(&pdev->frameq, &wait); | ||
1537 | set_current_state(TASK_RUNNING); | ||
1538 | |||
1539 | /* The frame is ready. Expand in the image buffer | ||
1540 | requested by the user. I don't care if you | ||
1541 | mmap() 5 buffers and request data in this order: | ||
1542 | buffer 4 2 3 0 1 2 3 0 4 3 1 . . . | ||
1543 | Grabber hardware may not be so forgiving. | ||
1544 | */ | ||
1545 | Trace(TRACE_READ, "VIDIOCSYNC: frame ready.\n"); | ||
1546 | pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */ | ||
1547 | /* Decompress, etc */ | ||
1548 | ret = pwc_handle_frame(pdev); | ||
1549 | pdev->image_used[*mbuf] = 0; | ||
1550 | if (ret) | ||
1551 | return -EFAULT; | ||
1552 | break; | ||
1553 | } | ||
1554 | |||
1555 | case VIDIOCGAUDIO: | ||
1556 | { | ||
1557 | struct video_audio *v = arg; | ||
1558 | |||
1559 | strcpy(v->name, "Microphone"); | ||
1560 | v->audio = -1; /* unknown audio minor */ | ||
1561 | v->flags = 0; | ||
1562 | v->mode = VIDEO_SOUND_MONO; | ||
1563 | v->volume = 0; | ||
1564 | v->bass = 0; | ||
1565 | v->treble = 0; | ||
1566 | v->balance = 0x8000; | ||
1567 | v->step = 1; | ||
1568 | break; | ||
1569 | } | ||
1570 | |||
1571 | case VIDIOCSAUDIO: | ||
1572 | { | ||
1573 | /* Dummy: nothing can be set */ | ||
1574 | break; | ||
1575 | } | ||
1576 | |||
1577 | case VIDIOCGUNIT: | ||
1578 | { | ||
1579 | struct video_unit *vu = arg; | ||
1580 | |||
1581 | vu->video = pdev->vdev->minor & 0x3F; | ||
1582 | vu->audio = -1; /* not known yet */ | ||
1583 | vu->vbi = -1; | ||
1584 | vu->radio = -1; | ||
1585 | vu->teletext = -1; | ||
1586 | break; | ||
1587 | } | ||
1588 | default: | ||
1589 | return pwc_ioctl(pdev, cmd, arg); | ||
1590 | } /* ..switch */ | ||
1591 | return 0; | ||
1592 | } | ||
1593 | |||
1594 | static int pwc_video_ioctl(struct inode *inode, struct file *file, | 1338 | static int pwc_video_ioctl(struct inode *inode, struct file *file, |
1595 | unsigned int cmd, unsigned long arg) | 1339 | unsigned int cmd, unsigned long arg) |
1596 | { | 1340 | { |
1597 | return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl); | 1341 | return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl); |
1598 | } | 1342 | } |
1599 | 1343 | ||
1600 | |||
1601 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) | 1344 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) |
1602 | { | 1345 | { |
1603 | struct video_device *vdev = file->private_data; | 1346 | struct video_device *vdev = file->private_data; |
1604 | struct pwc_device *pdev; | 1347 | struct pwc_device *pdev; |
1605 | unsigned long start = vma->vm_start; | 1348 | unsigned long start; |
1606 | unsigned long size = vma->vm_end-vma->vm_start; | 1349 | unsigned long size; |
1607 | unsigned long page, pos; | 1350 | unsigned long page, pos = 0; |
1351 | int index; | ||
1608 | 1352 | ||
1609 | Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size); | 1353 | PWC_DEBUG_MEMORY(">> %s\n", __FUNCTION__); |
1610 | pdev = vdev->priv; | 1354 | pdev = vdev->priv; |
1355 | size = vma->vm_end - vma->vm_start; | ||
1356 | start = vma->vm_start; | ||
1611 | 1357 | ||
1612 | vma->vm_flags |= VM_IO; | 1358 | /* Find the idx buffer for this mapping */ |
1359 | for (index = 0; index < pwc_mbufs; index++) { | ||
1360 | pos = pdev->images[index].offset; | ||
1361 | if ((pos>>PAGE_SHIFT) == vma->vm_pgoff) | ||
1362 | break; | ||
1363 | } | ||
1364 | if (index == MAX_IMAGES) | ||
1365 | return -EINVAL; | ||
1366 | if (index == 0) { | ||
1367 | /* | ||
1368 | * Special case for v4l1. In v4l1, we map only one big buffer, | ||
1369 | * but in v4l2 each buffer is mapped | ||
1370 | */ | ||
1371 | unsigned long total_size; | ||
1372 | total_size = pwc_mbufs * pdev->len_per_image; | ||
1373 | if (size != pdev->len_per_image && size != total_size) { | ||
1374 | PWC_ERROR("Wrong size (%lu) needed to be len_per_image=%d or total_size=%lu\n", | ||
1375 | size, pdev->len_per_image, total_size); | ||
1376 | return -EINVAL; | ||
1377 | } | ||
1378 | } else if (size > pdev->len_per_image) | ||
1379 | return -EINVAL; | ||
1613 | 1380 | ||
1614 | pos = (unsigned long)pdev->image_data; | 1381 | vma->vm_flags |= VM_IO; /* from 2.6.9-acX */ |
1382 | |||
1383 | pos += (unsigned long)pdev->image_data; | ||
1615 | while (size > 0) { | 1384 | while (size > 0) { |
1616 | page = vmalloc_to_pfn((void *)pos); | 1385 | page = vmalloc_to_pfn((void *)pos); |
1617 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) | 1386 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) |
1618 | return -EAGAIN; | 1387 | return -EAGAIN; |
1619 | |||
1620 | start += PAGE_SIZE; | 1388 | start += PAGE_SIZE; |
1621 | pos += PAGE_SIZE; | 1389 | pos += PAGE_SIZE; |
1622 | if (size > PAGE_SIZE) | 1390 | if (size > PAGE_SIZE) |
@@ -1624,7 +1392,6 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) | |||
1624 | else | 1392 | else |
1625 | size = 0; | 1393 | size = 0; |
1626 | } | 1394 | } |
1627 | |||
1628 | return 0; | 1395 | return 0; |
1629 | } | 1396 | } |
1630 | 1397 | ||
@@ -1645,10 +1412,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1645 | int video_nr = -1; /* default: use next available device */ | 1412 | int video_nr = -1; /* default: use next available device */ |
1646 | char serial_number[30], *name; | 1413 | char serial_number[30], *name; |
1647 | 1414 | ||
1415 | vendor_id = le16_to_cpu(udev->descriptor.idVendor); | ||
1416 | product_id = le16_to_cpu(udev->descriptor.idProduct); | ||
1417 | |||
1648 | /* Check if we can handle this device */ | 1418 | /* Check if we can handle this device */ |
1649 | Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", | 1419 | PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n", |
1650 | le16_to_cpu(udev->descriptor.idVendor), | 1420 | vendor_id, product_id, |
1651 | le16_to_cpu(udev->descriptor.idProduct), | ||
1652 | intf->altsetting->desc.bInterfaceNumber); | 1421 | intf->altsetting->desc.bInterfaceNumber); |
1653 | 1422 | ||
1654 | /* the interfaces are probed one by one. We are only interested in the | 1423 | /* the interfaces are probed one by one. We are only interested in the |
@@ -1658,61 +1427,63 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1658 | if (intf->altsetting->desc.bInterfaceNumber > 0) | 1427 | if (intf->altsetting->desc.bInterfaceNumber > 0) |
1659 | return -ENODEV; | 1428 | return -ENODEV; |
1660 | 1429 | ||
1661 | vendor_id = le16_to_cpu(udev->descriptor.idVendor); | ||
1662 | product_id = le16_to_cpu(udev->descriptor.idProduct); | ||
1663 | |||
1664 | if (vendor_id == 0x0471) { | 1430 | if (vendor_id == 0x0471) { |
1665 | switch (product_id) { | 1431 | switch (product_id) { |
1666 | case 0x0302: | 1432 | case 0x0302: |
1667 | Info("Philips PCA645VC USB webcam detected.\n"); | 1433 | PWC_INFO("Philips PCA645VC USB webcam detected.\n"); |
1668 | name = "Philips 645 webcam"; | 1434 | name = "Philips 645 webcam"; |
1669 | type_id = 645; | 1435 | type_id = 645; |
1670 | break; | 1436 | break; |
1671 | case 0x0303: | 1437 | case 0x0303: |
1672 | Info("Philips PCA646VC USB webcam detected.\n"); | 1438 | PWC_INFO("Philips PCA646VC USB webcam detected.\n"); |
1673 | name = "Philips 646 webcam"; | 1439 | name = "Philips 646 webcam"; |
1674 | type_id = 646; | 1440 | type_id = 646; |
1675 | break; | 1441 | break; |
1676 | case 0x0304: | 1442 | case 0x0304: |
1677 | Info("Askey VC010 type 2 USB webcam detected.\n"); | 1443 | PWC_INFO("Askey VC010 type 2 USB webcam detected.\n"); |
1678 | name = "Askey VC010 webcam"; | 1444 | name = "Askey VC010 webcam"; |
1679 | type_id = 646; | 1445 | type_id = 646; |
1680 | break; | 1446 | break; |
1681 | case 0x0307: | 1447 | case 0x0307: |
1682 | Info("Philips PCVC675K (Vesta) USB webcam detected.\n"); | 1448 | PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n"); |
1683 | name = "Philips 675 webcam"; | 1449 | name = "Philips 675 webcam"; |
1684 | type_id = 675; | 1450 | type_id = 675; |
1685 | break; | 1451 | break; |
1686 | case 0x0308: | 1452 | case 0x0308: |
1687 | Info("Philips PCVC680K (Vesta Pro) USB webcam detected.\n"); | 1453 | PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n"); |
1688 | name = "Philips 680 webcam"; | 1454 | name = "Philips 680 webcam"; |
1689 | type_id = 680; | 1455 | type_id = 680; |
1690 | break; | 1456 | break; |
1691 | case 0x030C: | 1457 | case 0x030C: |
1692 | Info("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n"); | 1458 | PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n"); |
1693 | name = "Philips 690 webcam"; | 1459 | name = "Philips 690 webcam"; |
1694 | type_id = 690; | 1460 | type_id = 690; |
1695 | break; | 1461 | break; |
1696 | case 0x0310: | 1462 | case 0x0310: |
1697 | Info("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n"); | 1463 | PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n"); |
1698 | name = "Philips 730 webcam"; | 1464 | name = "Philips 730 webcam"; |
1699 | type_id = 730; | 1465 | type_id = 730; |
1700 | break; | 1466 | break; |
1701 | case 0x0311: | 1467 | case 0x0311: |
1702 | Info("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n"); | 1468 | PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n"); |
1703 | name = "Philips 740 webcam"; | 1469 | name = "Philips 740 webcam"; |
1704 | type_id = 740; | 1470 | type_id = 740; |
1705 | break; | 1471 | break; |
1706 | case 0x0312: | 1472 | case 0x0312: |
1707 | Info("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n"); | 1473 | PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n"); |
1708 | name = "Philips 750 webcam"; | 1474 | name = "Philips 750 webcam"; |
1709 | type_id = 750; | 1475 | type_id = 750; |
1710 | break; | 1476 | break; |
1711 | case 0x0313: | 1477 | case 0x0313: |
1712 | Info("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n"); | 1478 | PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n"); |
1713 | name = "Philips 720K/40 webcam"; | 1479 | name = "Philips 720K/40 webcam"; |
1714 | type_id = 720; | 1480 | type_id = 720; |
1715 | break; | 1481 | break; |
1482 | case 0x0329: | ||
1483 | PWC_INFO("Philips SPC 900NC USB webcam detected.\n"); | ||
1484 | name = "Philips SPC 900NC webcam"; | ||
1485 | type_id = 720; | ||
1486 | break; | ||
1716 | default: | 1487 | default: |
1717 | return -ENODEV; | 1488 | return -ENODEV; |
1718 | break; | 1489 | break; |
@@ -1721,7 +1492,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1721 | else if (vendor_id == 0x069A) { | 1492 | else if (vendor_id == 0x069A) { |
1722 | switch(product_id) { | 1493 | switch(product_id) { |
1723 | case 0x0001: | 1494 | case 0x0001: |
1724 | Info("Askey VC010 type 1 USB webcam detected.\n"); | 1495 | PWC_INFO("Askey VC010 type 1 USB webcam detected.\n"); |
1725 | name = "Askey VC010 webcam"; | 1496 | name = "Askey VC010 webcam"; |
1726 | type_id = 645; | 1497 | type_id = 645; |
1727 | break; | 1498 | break; |
@@ -1733,32 +1504,33 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1733 | else if (vendor_id == 0x046d) { | 1504 | else if (vendor_id == 0x046d) { |
1734 | switch(product_id) { | 1505 | switch(product_id) { |
1735 | case 0x08b0: | 1506 | case 0x08b0: |
1736 | Info("Logitech QuickCam Pro 3000 USB webcam detected.\n"); | 1507 | PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n"); |
1737 | name = "Logitech QuickCam Pro 3000"; | 1508 | name = "Logitech QuickCam Pro 3000"; |
1738 | type_id = 740; /* CCD sensor */ | 1509 | type_id = 740; /* CCD sensor */ |
1739 | break; | 1510 | break; |
1740 | case 0x08b1: | 1511 | case 0x08b1: |
1741 | Info("Logitech QuickCam Notebook Pro USB webcam detected.\n"); | 1512 | PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n"); |
1742 | name = "Logitech QuickCam Notebook Pro"; | 1513 | name = "Logitech QuickCam Notebook Pro"; |
1743 | type_id = 740; /* CCD sensor */ | 1514 | type_id = 740; /* CCD sensor */ |
1744 | break; | 1515 | break; |
1745 | case 0x08b2: | 1516 | case 0x08b2: |
1746 | Info("Logitech QuickCam 4000 Pro USB webcam detected.\n"); | 1517 | PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n"); |
1747 | name = "Logitech QuickCam Pro 4000"; | 1518 | name = "Logitech QuickCam Pro 4000"; |
1748 | type_id = 740; /* CCD sensor */ | 1519 | type_id = 740; /* CCD sensor */ |
1749 | break; | 1520 | break; |
1750 | case 0x08b3: | 1521 | case 0x08b3: |
1751 | Info("Logitech QuickCam Zoom USB webcam detected.\n"); | 1522 | PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n"); |
1752 | name = "Logitech QuickCam Zoom"; | 1523 | name = "Logitech QuickCam Zoom"; |
1753 | type_id = 740; /* CCD sensor */ | 1524 | type_id = 740; /* CCD sensor */ |
1754 | break; | 1525 | break; |
1755 | case 0x08B4: | 1526 | case 0x08B4: |
1756 | Info("Logitech QuickCam Zoom (new model) USB webcam detected.\n"); | 1527 | PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n"); |
1757 | name = "Logitech QuickCam Zoom"; | 1528 | name = "Logitech QuickCam Zoom"; |
1758 | type_id = 740; /* CCD sensor */ | 1529 | type_id = 740; /* CCD sensor */ |
1530 | power_save = 1; | ||
1759 | break; | 1531 | break; |
1760 | case 0x08b5: | 1532 | case 0x08b5: |
1761 | Info("Logitech QuickCam Orbit/Sphere USB webcam detected.\n"); | 1533 | PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n"); |
1762 | name = "Logitech QuickCam Orbit"; | 1534 | name = "Logitech QuickCam Orbit"; |
1763 | type_id = 740; /* CCD sensor */ | 1535 | type_id = 740; /* CCD sensor */ |
1764 | features |= FEATURE_MOTOR_PANTILT; | 1536 | features |= FEATURE_MOTOR_PANTILT; |
@@ -1766,7 +1538,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1766 | case 0x08b6: | 1538 | case 0x08b6: |
1767 | case 0x08b7: | 1539 | case 0x08b7: |
1768 | case 0x08b8: | 1540 | case 0x08b8: |
1769 | Info("Logitech QuickCam detected (reserved ID).\n"); | 1541 | PWC_INFO("Logitech QuickCam detected (reserved ID).\n"); |
1770 | name = "Logitech QuickCam (res.)"; | 1542 | name = "Logitech QuickCam (res.)"; |
1771 | type_id = 730; /* Assuming CMOS */ | 1543 | type_id = 730; /* Assuming CMOS */ |
1772 | break; | 1544 | break; |
@@ -1782,15 +1554,20 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1782 | */ | 1554 | */ |
1783 | switch(product_id) { | 1555 | switch(product_id) { |
1784 | case 0x9000: | 1556 | case 0x9000: |
1785 | Info("Samsung MPC-C10 USB webcam detected.\n"); | 1557 | PWC_INFO("Samsung MPC-C10 USB webcam detected.\n"); |
1786 | name = "Samsung MPC-C10"; | 1558 | name = "Samsung MPC-C10"; |
1787 | type_id = 675; | 1559 | type_id = 675; |
1788 | break; | 1560 | break; |
1789 | case 0x9001: | 1561 | case 0x9001: |
1790 | Info("Samsung MPC-C30 USB webcam detected.\n"); | 1562 | PWC_INFO("Samsung MPC-C30 USB webcam detected.\n"); |
1791 | name = "Samsung MPC-C30"; | 1563 | name = "Samsung MPC-C30"; |
1792 | type_id = 675; | 1564 | type_id = 675; |
1793 | break; | 1565 | break; |
1566 | case 0x9002: | ||
1567 | PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n"); | ||
1568 | name = "Samsung MPC-C30"; | ||
1569 | type_id = 740; | ||
1570 | break; | ||
1794 | default: | 1571 | default: |
1795 | return -ENODEV; | 1572 | return -ENODEV; |
1796 | break; | 1573 | break; |
@@ -1799,12 +1576,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1799 | else if (vendor_id == 0x041e) { | 1576 | else if (vendor_id == 0x041e) { |
1800 | switch(product_id) { | 1577 | switch(product_id) { |
1801 | case 0x400c: | 1578 | case 0x400c: |
1802 | Info("Creative Labs Webcam 5 detected.\n"); | 1579 | PWC_INFO("Creative Labs Webcam 5 detected.\n"); |
1803 | name = "Creative Labs Webcam 5"; | 1580 | name = "Creative Labs Webcam 5"; |
1804 | type_id = 730; | 1581 | type_id = 730; |
1805 | break; | 1582 | break; |
1806 | case 0x4011: | 1583 | case 0x4011: |
1807 | Info("Creative Labs Webcam Pro Ex detected.\n"); | 1584 | PWC_INFO("Creative Labs Webcam Pro Ex detected.\n"); |
1808 | name = "Creative Labs Webcam Pro Ex"; | 1585 | name = "Creative Labs Webcam Pro Ex"; |
1809 | type_id = 740; | 1586 | type_id = 740; |
1810 | break; | 1587 | break; |
@@ -1816,7 +1593,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1816 | else if (vendor_id == 0x04cc) { | 1593 | else if (vendor_id == 0x04cc) { |
1817 | switch(product_id) { | 1594 | switch(product_id) { |
1818 | case 0x8116: | 1595 | case 0x8116: |
1819 | Info("Sotec Afina Eye USB webcam detected.\n"); | 1596 | PWC_INFO("Sotec Afina Eye USB webcam detected.\n"); |
1820 | name = "Sotec Afina Eye"; | 1597 | name = "Sotec Afina Eye"; |
1821 | type_id = 730; | 1598 | type_id = 730; |
1822 | break; | 1599 | break; |
@@ -1829,7 +1606,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1829 | switch(product_id) { | 1606 | switch(product_id) { |
1830 | case 0x8116: | 1607 | case 0x8116: |
1831 | /* This is essentially the same cam as the Sotec Afina Eye */ | 1608 | /* This is essentially the same cam as the Sotec Afina Eye */ |
1832 | Info("AME Co. Afina Eye USB webcam detected.\n"); | 1609 | PWC_INFO("AME Co. Afina Eye USB webcam detected.\n"); |
1833 | name = "AME Co. Afina Eye"; | 1610 | name = "AME Co. Afina Eye"; |
1834 | type_id = 750; | 1611 | type_id = 750; |
1835 | break; | 1612 | break; |
@@ -1842,12 +1619,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1842 | else if (vendor_id == 0x0d81) { | 1619 | else if (vendor_id == 0x0d81) { |
1843 | switch(product_id) { | 1620 | switch(product_id) { |
1844 | case 0x1900: | 1621 | case 0x1900: |
1845 | Info("Visionite VCS-UC300 USB webcam detected.\n"); | 1622 | PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n"); |
1846 | name = "Visionite VCS-UC300"; | 1623 | name = "Visionite VCS-UC300"; |
1847 | type_id = 740; /* CCD sensor */ | 1624 | type_id = 740; /* CCD sensor */ |
1848 | break; | 1625 | break; |
1849 | case 0x1910: | 1626 | case 0x1910: |
1850 | Info("Visionite VCS-UM100 USB webcam detected.\n"); | 1627 | PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n"); |
1851 | name = "Visionite VCS-UM100"; | 1628 | name = "Visionite VCS-UM100"; |
1852 | type_id = 730; /* CMOS sensor */ | 1629 | type_id = 730; /* CMOS sensor */ |
1853 | break; | 1630 | break; |
@@ -1861,15 +1638,15 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1861 | 1638 | ||
1862 | memset(serial_number, 0, 30); | 1639 | memset(serial_number, 0, 30); |
1863 | usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); | 1640 | usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); |
1864 | Trace(TRACE_PROBE, "Device serial number is %s\n", serial_number); | 1641 | PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number); |
1865 | 1642 | ||
1866 | if (udev->descriptor.bNumConfigurations > 1) | 1643 | if (udev->descriptor.bNumConfigurations > 1) |
1867 | Info("Warning: more than 1 configuration available.\n"); | 1644 | PWC_WARNING("Warning: more than 1 configuration available.\n"); |
1868 | 1645 | ||
1869 | /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ | 1646 | /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ |
1870 | pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL); | 1647 | pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL); |
1871 | if (pdev == NULL) { | 1648 | if (pdev == NULL) { |
1872 | Err("Oops, could not allocate memory for pwc_device.\n"); | 1649 | PWC_ERROR("Oops, could not allocate memory for pwc_device.\n"); |
1873 | return -ENOMEM; | 1650 | return -ENOMEM; |
1874 | } | 1651 | } |
1875 | pdev->type = type_id; | 1652 | pdev->type = type_id; |
@@ -1900,17 +1677,18 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1900 | pdev->vdev = video_device_alloc(); | 1677 | pdev->vdev = video_device_alloc(); |
1901 | if (pdev->vdev == 0) | 1678 | if (pdev->vdev == 0) |
1902 | { | 1679 | { |
1903 | Err("Err, cannot allocate video_device struture. Failing probe."); | 1680 | PWC_ERROR("Err, cannot allocate video_device struture. Failing probe."); |
1904 | kfree(pdev); | 1681 | kfree(pdev); |
1905 | return -ENOMEM; | 1682 | return -ENOMEM; |
1906 | } | 1683 | } |
1907 | memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); | 1684 | memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); |
1685 | pdev->vdev->dev = &(udev->dev); | ||
1908 | strcpy(pdev->vdev->name, name); | 1686 | strcpy(pdev->vdev->name, name); |
1909 | pdev->vdev->owner = THIS_MODULE; | 1687 | pdev->vdev->owner = THIS_MODULE; |
1910 | video_set_drvdata(pdev->vdev, pdev); | 1688 | video_set_drvdata(pdev->vdev, pdev); |
1911 | 1689 | ||
1912 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); | 1690 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); |
1913 | Trace(TRACE_PROBE, "Release: %04x\n", pdev->release); | 1691 | PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); |
1914 | 1692 | ||
1915 | /* Now search device_hint[] table for a match, so we can hint a node number. */ | 1693 | /* Now search device_hint[] table for a match, so we can hint a node number. */ |
1916 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) { | 1694 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) { |
@@ -1918,10 +1696,10 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1918 | (device_hint[hint].pdev == NULL)) { | 1696 | (device_hint[hint].pdev == NULL)) { |
1919 | /* so far, so good... try serial number */ | 1697 | /* so far, so good... try serial number */ |
1920 | if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) { | 1698 | if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) { |
1921 | /* match! */ | 1699 | /* match! */ |
1922 | video_nr = device_hint[hint].device_node; | 1700 | video_nr = device_hint[hint].device_node; |
1923 | Trace(TRACE_PROBE, "Found hint, will try to register as /dev/video%d\n", video_nr); | 1701 | PWC_DEBUG_PROBE("Found hint, will try to register as /dev/video%d\n", video_nr); |
1924 | break; | 1702 | break; |
1925 | } | 1703 | } |
1926 | } | 1704 | } |
1927 | } | 1705 | } |
@@ -1929,21 +1707,27 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1929 | pdev->vdev->release = video_device_release; | 1707 | pdev->vdev->release = video_device_release; |
1930 | i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); | 1708 | i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); |
1931 | if (i < 0) { | 1709 | if (i < 0) { |
1932 | Err("Failed to register as video device (%d).\n", i); | 1710 | PWC_ERROR("Failed to register as video device (%d).\n", i); |
1933 | video_device_release(pdev->vdev); /* Drip... drip... drip... */ | 1711 | video_device_release(pdev->vdev); /* Drip... drip... drip... */ |
1934 | kfree(pdev); /* Oops, no memory leaks please */ | 1712 | kfree(pdev); /* Oops, no memory leaks please */ |
1935 | return -EIO; | 1713 | return -EIO; |
1936 | } | 1714 | } |
1937 | else { | 1715 | else { |
1938 | Info("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F); | 1716 | PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F); |
1939 | } | 1717 | } |
1940 | 1718 | ||
1941 | /* occupy slot */ | 1719 | /* occupy slot */ |
1942 | if (hint < MAX_DEV_HINTS) | 1720 | if (hint < MAX_DEV_HINTS) |
1943 | device_hint[hint].pdev = pdev; | 1721 | device_hint[hint].pdev = pdev; |
1944 | 1722 | ||
1945 | Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev); | 1723 | PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); |
1946 | usb_set_intfdata (intf, pdev); | 1724 | usb_set_intfdata (intf, pdev); |
1725 | pwc_create_sysfs_files(pdev->vdev); | ||
1726 | |||
1727 | /* Set the leds off */ | ||
1728 | pwc_set_leds(pdev, 0, 0); | ||
1729 | pwc_camera_power(pdev, 0); | ||
1730 | |||
1947 | return 0; | 1731 | return 0; |
1948 | } | 1732 | } |
1949 | 1733 | ||
@@ -1957,27 +1741,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
1957 | pdev = usb_get_intfdata (intf); | 1741 | pdev = usb_get_intfdata (intf); |
1958 | usb_set_intfdata (intf, NULL); | 1742 | usb_set_intfdata (intf, NULL); |
1959 | if (pdev == NULL) { | 1743 | if (pdev == NULL) { |
1960 | Err("pwc_disconnect() Called without private pointer.\n"); | 1744 | PWC_ERROR("pwc_disconnect() Called without private pointer.\n"); |
1961 | goto disconnect_out; | 1745 | goto disconnect_out; |
1962 | } | 1746 | } |
1963 | if (pdev->udev == NULL) { | 1747 | if (pdev->udev == NULL) { |
1964 | Err("pwc_disconnect() already called for %p\n", pdev); | 1748 | PWC_ERROR("pwc_disconnect() already called for %p\n", pdev); |
1965 | goto disconnect_out; | 1749 | goto disconnect_out; |
1966 | } | 1750 | } |
1967 | if (pdev->udev != interface_to_usbdev(intf)) { | 1751 | if (pdev->udev != interface_to_usbdev(intf)) { |
1968 | Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n"); | 1752 | PWC_ERROR("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n"); |
1969 | goto disconnect_out; | ||
1970 | } | ||
1971 | #ifdef PWC_MAGIC | ||
1972 | if (pdev->magic != PWC_MAGIC) { | ||
1973 | Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n"); | ||
1974 | goto disconnect_out; | 1753 | goto disconnect_out; |
1975 | } | 1754 | } |
1976 | #endif | ||
1977 | 1755 | ||
1978 | /* We got unplugged; this is signalled by an EPIPE error code */ | 1756 | /* We got unplugged; this is signalled by an EPIPE error code */ |
1979 | if (pdev->vopen) { | 1757 | if (pdev->vopen) { |
1980 | Info("Disconnected while webcam is in use!\n"); | 1758 | PWC_INFO("Disconnected while webcam is in use!\n"); |
1981 | pdev->error_status = EPIPE; | 1759 | pdev->error_status = EPIPE; |
1982 | } | 1760 | } |
1983 | 1761 | ||
@@ -1987,7 +1765,8 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
1987 | while (pdev->vopen) | 1765 | while (pdev->vopen) |
1988 | schedule(); | 1766 | schedule(); |
1989 | /* Device is now closed, so we can safely unregister it */ | 1767 | /* Device is now closed, so we can safely unregister it */ |
1990 | Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n"); | 1768 | PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); |
1769 | pwc_remove_sysfs_files(pdev->vdev); | ||
1991 | video_unregister_device(pdev->vdev); | 1770 | video_unregister_device(pdev->vdev); |
1992 | 1771 | ||
1993 | /* Free memory (don't set pdev to 0 just yet) */ | 1772 | /* Free memory (don't set pdev to 0 just yet) */ |
@@ -2021,58 +1800,64 @@ static int pwc_atoi(const char *s) | |||
2021 | * Initialization code & module stuff | 1800 | * Initialization code & module stuff |
2022 | */ | 1801 | */ |
2023 | 1802 | ||
2024 | static char size[10]; | 1803 | static char *size; |
2025 | static int fps = 0; | 1804 | static int fps; |
2026 | static int fbufs = 0; | 1805 | static int fbufs; |
2027 | static int mbufs = 0; | 1806 | static int mbufs; |
2028 | static int trace = -1; | ||
2029 | static int compression = -1; | 1807 | static int compression = -1; |
2030 | static int leds[2] = { -1, -1 }; | 1808 | static int leds[2] = { -1, -1 }; |
2031 | static char *dev_hint[MAX_DEV_HINTS] = { }; | 1809 | static int leds_nargs; |
1810 | static char *dev_hint[MAX_DEV_HINTS]; | ||
1811 | static int dev_hint_nargs; | ||
1812 | |||
1813 | module_param(size, charp, 0444); | ||
1814 | module_param(fps, int, 0444); | ||
1815 | module_param(fbufs, int, 0444); | ||
1816 | module_param(mbufs, int, 0444); | ||
1817 | #if CONFIG_PWC_DEBUG | ||
1818 | module_param_named(trace, pwc_trace, int, 0644); | ||
1819 | #endif | ||
1820 | module_param(power_save, int, 0444); | ||
1821 | module_param(compression, int, 0444); | ||
1822 | module_param_array(leds, int, &leds_nargs, 0444); | ||
1823 | module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); | ||
2032 | 1824 | ||
2033 | module_param_string(size, size, sizeof(size), 0); | ||
2034 | MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); | 1825 | MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); |
2035 | module_param(fps, int, 0000); | ||
2036 | MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); | 1826 | MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); |
2037 | module_param(fbufs, int, 0000); | ||
2038 | MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); | 1827 | MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); |
2039 | module_param(mbufs, int, 0000); | ||
2040 | MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); | 1828 | MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); |
2041 | module_param(trace, int, 0000); | ||
2042 | MODULE_PARM_DESC(trace, "For debugging purposes"); | 1829 | MODULE_PARM_DESC(trace, "For debugging purposes"); |
2043 | module_param(power_save, bool, 0000); | ||
2044 | MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); | 1830 | MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); |
2045 | module_param(compression, int, 0000); | ||
2046 | MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); | 1831 | MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); |
2047 | module_param_array(leds, int, NULL, 0000); | ||
2048 | MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); | 1832 | MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); |
2049 | module_param_array(dev_hint, charp, NULL, 0000); | ||
2050 | MODULE_PARM_DESC(dev_hint, "Device node hints"); | 1833 | MODULE_PARM_DESC(dev_hint, "Device node hints"); |
2051 | 1834 | ||
2052 | MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); | 1835 | MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); |
2053 | MODULE_AUTHOR("Luc Saillard <luc@saillard.org>"); | 1836 | MODULE_AUTHOR("Luc Saillard <luc@saillard.org>"); |
2054 | MODULE_LICENSE("GPL"); | 1837 | MODULE_LICENSE("GPL"); |
1838 | MODULE_ALIAS("pwcx"); | ||
1839 | MODULE_VERSION( PWC_VERSION ); | ||
2055 | 1840 | ||
2056 | static int __init usb_pwc_init(void) | 1841 | static int __init usb_pwc_init(void) |
2057 | { | 1842 | { |
2058 | int i, sz; | 1843 | int i, sz; |
2059 | char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" }; | 1844 | char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" }; |
2060 | 1845 | ||
2061 | Info("Philips webcam module version " PWC_VERSION " loaded.\n"); | 1846 | PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n"); |
2062 | Info("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); | 1847 | PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); |
2063 | Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); | 1848 | PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); |
2064 | Info("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); | 1849 | PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); |
2065 | 1850 | ||
2066 | if (fps) { | 1851 | if (fps) { |
2067 | if (fps < 4 || fps > 30) { | 1852 | if (fps < 4 || fps > 30) { |
2068 | Err("Framerate out of bounds (4-30).\n"); | 1853 | PWC_ERROR("Framerate out of bounds (4-30).\n"); |
2069 | return -EINVAL; | 1854 | return -EINVAL; |
2070 | } | 1855 | } |
2071 | default_fps = fps; | 1856 | default_fps = fps; |
2072 | Info("Default framerate set to %d.\n", default_fps); | 1857 | PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps); |
2073 | } | 1858 | } |
2074 | 1859 | ||
2075 | if (size[0]) { | 1860 | if (size) { |
2076 | /* string; try matching with array */ | 1861 | /* string; try matching with array */ |
2077 | for (sz = 0; sz < PSZ_MAX; sz++) { | 1862 | for (sz = 0; sz < PSZ_MAX; sz++) { |
2078 | if (!strcmp(sizenames[sz], size)) { /* Found! */ | 1863 | if (!strcmp(sizenames[sz], size)) { /* Found! */ |
@@ -2081,41 +1866,42 @@ static int __init usb_pwc_init(void) | |||
2081 | } | 1866 | } |
2082 | } | 1867 | } |
2083 | if (sz == PSZ_MAX) { | 1868 | if (sz == PSZ_MAX) { |
2084 | Err("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n"); | 1869 | PWC_ERROR("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n"); |
2085 | return -EINVAL; | 1870 | return -EINVAL; |
2086 | } | 1871 | } |
2087 | Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y); | 1872 | PWC_DEBUG_MODULE("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y); |
2088 | } | 1873 | } |
2089 | if (mbufs) { | 1874 | if (mbufs) { |
2090 | if (mbufs < 1 || mbufs > MAX_IMAGES) { | 1875 | if (mbufs < 1 || mbufs > MAX_IMAGES) { |
2091 | Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES); | 1876 | PWC_ERROR("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES); |
2092 | return -EINVAL; | 1877 | return -EINVAL; |
2093 | } | 1878 | } |
2094 | default_mbufs = mbufs; | 1879 | pwc_mbufs = mbufs; |
2095 | Info("Number of image buffers set to %d.\n", default_mbufs); | 1880 | PWC_DEBUG_MODULE("Number of image buffers set to %d.\n", pwc_mbufs); |
2096 | } | 1881 | } |
2097 | if (fbufs) { | 1882 | if (fbufs) { |
2098 | if (fbufs < 2 || fbufs > MAX_FRAMES) { | 1883 | if (fbufs < 2 || fbufs > MAX_FRAMES) { |
2099 | Err("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES); | 1884 | PWC_ERROR("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES); |
2100 | return -EINVAL; | 1885 | return -EINVAL; |
2101 | } | 1886 | } |
2102 | default_fbufs = fbufs; | 1887 | default_fbufs = fbufs; |
2103 | Info("Number of frame buffers set to %d.\n", default_fbufs); | 1888 | PWC_DEBUG_MODULE("Number of frame buffers set to %d.\n", default_fbufs); |
2104 | } | 1889 | } |
2105 | if (trace >= 0) { | 1890 | #if CONFIG_PWC_DEBUG |
2106 | Info("Trace options: 0x%04x\n", trace); | 1891 | if (pwc_trace >= 0) { |
2107 | pwc_trace = trace; | 1892 | PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace); |
2108 | } | 1893 | } |
1894 | #endif | ||
2109 | if (compression >= 0) { | 1895 | if (compression >= 0) { |
2110 | if (compression > 3) { | 1896 | if (compression > 3) { |
2111 | Err("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n"); | 1897 | PWC_ERROR("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n"); |
2112 | return -EINVAL; | 1898 | return -EINVAL; |
2113 | } | 1899 | } |
2114 | pwc_preferred_compression = compression; | 1900 | pwc_preferred_compression = compression; |
2115 | Info("Preferred compression set to %d.\n", pwc_preferred_compression); | 1901 | PWC_DEBUG_MODULE("Preferred compression set to %d.\n", pwc_preferred_compression); |
2116 | } | 1902 | } |
2117 | if (power_save) | 1903 | if (power_save) |
2118 | Info("Enabling power save on open/close.\n"); | 1904 | PWC_DEBUG_MODULE("Enabling power save on open/close.\n"); |
2119 | if (leds[0] >= 0) | 1905 | if (leds[0] >= 0) |
2120 | led_on = leds[0]; | 1906 | led_on = leds[0]; |
2121 | if (leds[1] >= 0) | 1907 | if (leds[1] >= 0) |
@@ -2146,14 +1932,14 @@ static int __init usb_pwc_init(void) | |||
2146 | dot++; | 1932 | dot++; |
2147 | /* Few sanity checks */ | 1933 | /* Few sanity checks */ |
2148 | if (*dot != '\0' && dot > colon) { | 1934 | if (*dot != '\0' && dot > colon) { |
2149 | Err("Malformed camera hint: the colon must be after the dot.\n"); | 1935 | PWC_ERROR("Malformed camera hint: the colon must be after the dot.\n"); |
2150 | return -EINVAL; | 1936 | return -EINVAL; |
2151 | } | 1937 | } |
2152 | 1938 | ||
2153 | if (*colon == '\0') { | 1939 | if (*colon == '\0') { |
2154 | /* No colon */ | 1940 | /* No colon */ |
2155 | if (*dot != '\0') { | 1941 | if (*dot != '\0') { |
2156 | Err("Malformed camera hint: no colon + device node given.\n"); | 1942 | PWC_ERROR("Malformed camera hint: no colon + device node given.\n"); |
2157 | return -EINVAL; | 1943 | return -EINVAL; |
2158 | } | 1944 | } |
2159 | else { | 1945 | else { |
@@ -2178,28 +1964,27 @@ static int __init usb_pwc_init(void) | |||
2178 | device_hint[i].serial_number[k] = '\0'; | 1964 | device_hint[i].serial_number[k] = '\0'; |
2179 | } | 1965 | } |
2180 | } | 1966 | } |
2181 | #if PWC_DEBUG | 1967 | PWC_TRACE("device_hint[%d]:\n", i); |
2182 | Debug("device_hint[%d]:\n", i); | 1968 | PWC_TRACE(" type : %d\n", device_hint[i].type); |
2183 | Debug(" type : %d\n", device_hint[i].type); | 1969 | PWC_TRACE(" serial# : %s\n", device_hint[i].serial_number); |
2184 | Debug(" serial# : %s\n", device_hint[i].serial_number); | 1970 | PWC_TRACE(" node : %d\n", device_hint[i].device_node); |
2185 | Debug(" node : %d\n", device_hint[i].device_node); | ||
2186 | #endif | ||
2187 | } | 1971 | } |
2188 | else | 1972 | else |
2189 | device_hint[i].type = 0; /* not filled */ | 1973 | device_hint[i].type = 0; /* not filled */ |
2190 | } /* ..for MAX_DEV_HINTS */ | 1974 | } /* ..for MAX_DEV_HINTS */ |
2191 | 1975 | ||
2192 | Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver); | 1976 | PWC_DEBUG_PROBE("Registering driver at address 0x%p.\n", &pwc_driver); |
2193 | return usb_register(&pwc_driver); | 1977 | return usb_register(&pwc_driver); |
2194 | } | 1978 | } |
2195 | 1979 | ||
2196 | static void __exit usb_pwc_exit(void) | 1980 | static void __exit usb_pwc_exit(void) |
2197 | { | 1981 | { |
2198 | Trace(TRACE_MODULE, "Deregistering driver.\n"); | 1982 | PWC_DEBUG_MODULE("Deregistering driver.\n"); |
2199 | usb_deregister(&pwc_driver); | 1983 | usb_deregister(&pwc_driver); |
2200 | Info("Philips webcam module removed.\n"); | 1984 | PWC_INFO("Philips webcam module removed.\n"); |
2201 | } | 1985 | } |
2202 | 1986 | ||
2203 | module_init(usb_pwc_init); | 1987 | module_init(usb_pwc_init); |
2204 | module_exit(usb_pwc_exit); | 1988 | module_exit(usb_pwc_exit); |
2205 | 1989 | ||
1990 | /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ | ||
diff --git a/drivers/media/video/pwc/pwc-kiara.c b/drivers/media/video/pwc/pwc-kiara.c index 4c96037f7be5..fec39cc5a9f1 100644 --- a/drivers/media/video/pwc/pwc-kiara.c +++ b/drivers/media/video/pwc/pwc-kiara.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* Linux driver for Philips webcam | 1 | /* Linux driver for Philips webcam |
2 | (C) 2004 Luc Saillard (luc@saillard.org) | 2 | (C) 2004-2006 Luc Saillard (luc@saillard.org) |
3 | 3 | ||
4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | 4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx |
5 | driver and thus may have bugs that are not present in the original version. | 5 | driver and thus may have bugs that are not present in the original version. |
@@ -316,3 +316,576 @@ const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] = | |||
316 | }, | 316 | }, |
317 | }; | 317 | }; |
318 | 318 | ||
319 | |||
320 | /* | ||
321 | * Rom table for kiara chips | ||
322 | * | ||
323 | * 32 roms tables (one for each resolution ?) | ||
324 | * 2 tables per roms (one for each passes) (Y, and U&V) | ||
325 | * 128 bytes per passes | ||
326 | */ | ||
327 | |||
328 | const unsigned int KiaraRomTable [8][2][16][8] = | ||
329 | { | ||
330 | { /* version 0 */ | ||
331 | { /* version 0, passes 0 */ | ||
332 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
333 | 0x00000000,0x00000000,0x00000001,0x00000001}, | ||
334 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
335 | 0x00000009,0x00000009,0x00000009,0x00000009}, | ||
336 | {0x00000000,0x00000000,0x00000009,0x00000049, | ||
337 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
338 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
339 | 0x00000049,0x00000249,0x0000024a,0x00000049}, | ||
340 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
341 | 0x00000249,0x00000249,0x0000024a,0x0000024a}, | ||
342 | {0x00000000,0x00000000,0x00000049,0x00000249, | ||
343 | 0x00000249,0x0000124a,0x0000024a,0x0000024a}, | ||
344 | {0x00000000,0x00000000,0x00000049,0x00000249, | ||
345 | 0x0000124a,0x00009252,0x00001252,0x00001252}, | ||
346 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
347 | 0x00009252,0x00009292,0x00009292,0x00009292}, | ||
348 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
349 | 0x00009292,0x00009292,0x00009493,0x000124db}, | ||
350 | {0x00000000,0x00000000,0x00000249,0x0000924a, | ||
351 | 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, | ||
352 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
353 | 0x0000a493,0x000124db,0x000124db,0x000126dc}, | ||
354 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
355 | 0x000124db,0x000126dc,0x000136e4,0x000126dc}, | ||
356 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
357 | 0x000124db,0x000136e4,0x000136e4,0x000136e4}, | ||
358 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
359 | 0x000126dc,0x0001b724,0x0001b92d,0x0001b925}, | ||
360 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
361 | 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d}, | ||
362 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
363 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
364 | }, | ||
365 | { /* version 0, passes 1 */ | ||
366 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
367 | 0x00000000,0x00000000,0x00000000,0x00000000}, | ||
368 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
369 | 0x00000000,0x00000000,0x00000000,0x00000000}, | ||
370 | {0x00000000,0x00000000,0x00000001,0x00000009, | ||
371 | 0x00000009,0x00000009,0x00000009,0x00000001}, | ||
372 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
373 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
374 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
375 | 0x00000049,0x00000049,0x0000024a,0x0000024a}, | ||
376 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
377 | 0x00000249,0x00000249,0x0000024a,0x0000024a}, | ||
378 | {0x00000000,0x00000000,0x00000049,0x00000249, | ||
379 | 0x00000249,0x00000249,0x0000024a,0x00001252}, | ||
380 | {0x00000000,0x00000000,0x00000049,0x00001249, | ||
381 | 0x0000124a,0x0000124a,0x00001252,0x00009292}, | ||
382 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
383 | 0x00009252,0x00009252,0x00009292,0x00009493}, | ||
384 | {0x00000000,0x00000000,0x00000249,0x0000924a, | ||
385 | 0x00009292,0x00009292,0x00009292,0x00009493}, | ||
386 | {0x00000000,0x00000000,0x00000249,0x00009292, | ||
387 | 0x00009492,0x00009493,0x0000a49b,0x00009493}, | ||
388 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
389 | 0x0000a493,0x000124db,0x000126dc,0x000126dc}, | ||
390 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
391 | 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, | ||
392 | {0x00000000,0x00000000,0x00009252,0x00009493, | ||
393 | 0x000126dc,0x000126dc,0x000136e4,0x000136e4}, | ||
394 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
395 | 0x000136e4,0x000136e4,0x0001b725,0x0001b724}, | ||
396 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
397 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
398 | } | ||
399 | }, | ||
400 | { /* version 1 */ | ||
401 | { /* version 1, passes 0 */ | ||
402 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
403 | 0x00000000,0x00000000,0x00000000,0x00000001}, | ||
404 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
405 | 0x00000009,0x00000009,0x00000009,0x00000009}, | ||
406 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
407 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
408 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
409 | 0x00000049,0x00000249,0x0000024a,0x0000024a}, | ||
410 | {0x00000000,0x00000000,0x00000049,0x00000249, | ||
411 | 0x00000249,0x00000249,0x0000024a,0x00001252}, | ||
412 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
413 | 0x00000249,0x0000124a,0x00001252,0x00001252}, | ||
414 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
415 | 0x0000124a,0x0000124a,0x00009292,0x00009292}, | ||
416 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
417 | 0x0000124a,0x00009252,0x00009292,0x00009292}, | ||
418 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
419 | 0x00009252,0x00009292,0x00009292,0x00009292}, | ||
420 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
421 | 0x00009252,0x00009292,0x00009493,0x00009493}, | ||
422 | {0x00000000,0x00000000,0x00000249,0x0000924a, | ||
423 | 0x00009252,0x00009493,0x00009493,0x00009493}, | ||
424 | {0x00000000,0x00000000,0x00000249,0x0000924a, | ||
425 | 0x00009292,0x00009493,0x00009493,0x00009493}, | ||
426 | {0x00000000,0x00000000,0x00000249,0x00009252, | ||
427 | 0x00009492,0x00009493,0x0000a49b,0x0000a49b}, | ||
428 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
429 | 0x00009492,0x000124db,0x000124db,0x000124db}, | ||
430 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
431 | 0x0000a493,0x000126dc,0x000126dc,0x000126dc}, | ||
432 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
433 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
434 | }, | ||
435 | { /* version 1, passes 1 */ | ||
436 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
437 | 0x00000000,0x00000000,0x00000000,0x00000000}, | ||
438 | {0x00000000,0x00000000,0x00000049,0x00000009, | ||
439 | 0x00000049,0x00000009,0x00000001,0x00000000}, | ||
440 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
441 | 0x00000049,0x00000049,0x00000049,0x00000000}, | ||
442 | {0x00000000,0x00000000,0x00000249,0x00000049, | ||
443 | 0x00000249,0x00000049,0x0000024a,0x00000001}, | ||
444 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
445 | 0x00000249,0x00000249,0x0000024a,0x00000001}, | ||
446 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
447 | 0x00000249,0x00000249,0x0000024a,0x00000001}, | ||
448 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
449 | 0x00000249,0x00000249,0x0000024a,0x00000009}, | ||
450 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
451 | 0x0000124a,0x0000124a,0x0000024a,0x00000009}, | ||
452 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
453 | 0x0000124a,0x0000124a,0x0000024a,0x00000009}, | ||
454 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
455 | 0x0000124a,0x00009252,0x00001252,0x00000049}, | ||
456 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
457 | 0x0000124a,0x00009292,0x00001252,0x00000049}, | ||
458 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
459 | 0x0000124a,0x00009292,0x00001252,0x00000049}, | ||
460 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
461 | 0x00009252,0x00009292,0x00001252,0x0000024a}, | ||
462 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
463 | 0x00009292,0x00009292,0x00001252,0x0000024a}, | ||
464 | {0x00000000,0x00000000,0x0000924a,0x0000924a, | ||
465 | 0x00009492,0x00009493,0x00009292,0x00001252}, | ||
466 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
467 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
468 | } | ||
469 | }, | ||
470 | { /* version 2 */ | ||
471 | { /* version 2, passes 0 */ | ||
472 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
473 | 0x00000049,0x00000049,0x0000024a,0x0000024a}, | ||
474 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
475 | 0x00000249,0x0000124a,0x00001252,0x00009292}, | ||
476 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
477 | 0x0000124a,0x00009252,0x00009292,0x00009292}, | ||
478 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
479 | 0x0000124a,0x00009292,0x00009493,0x00009493}, | ||
480 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
481 | 0x00009252,0x00009493,0x00009493,0x0000a49b}, | ||
482 | {0x00000000,0x00000000,0x00000249,0x0000924a, | ||
483 | 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, | ||
484 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
485 | 0x00009292,0x00009493,0x0000a49b,0x000124db}, | ||
486 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
487 | 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, | ||
488 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
489 | 0x00009492,0x000124db,0x000124db,0x000126dc}, | ||
490 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
491 | 0x0000a493,0x000124db,0x000126dc,0x000126dc}, | ||
492 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
493 | 0x0000a493,0x000124db,0x000126dc,0x000136e4}, | ||
494 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
495 | 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, | ||
496 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
497 | 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, | ||
498 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
499 | 0x000124db,0x000136e4,0x000136e4,0x0001b724}, | ||
500 | {0x00000000,0x00000000,0x00009252,0x000124db, | ||
501 | 0x000126dc,0x0001b724,0x0001b725,0x0001b925}, | ||
502 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
503 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
504 | }, | ||
505 | { /* version 2, passes 1 */ | ||
506 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
507 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
508 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
509 | 0x00000249,0x00000249,0x0000024a,0x00000049}, | ||
510 | {0x00000000,0x00000000,0x00001249,0x00000249, | ||
511 | 0x0000124a,0x0000124a,0x00001252,0x00000049}, | ||
512 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
513 | 0x0000124a,0x0000124a,0x00009292,0x0000024a}, | ||
514 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
515 | 0x00009252,0x00009292,0x00009292,0x0000024a}, | ||
516 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
517 | 0x00009252,0x00009292,0x0000a49b,0x0000024a}, | ||
518 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
519 | 0x00009292,0x00009493,0x0000a49b,0x00001252}, | ||
520 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
521 | 0x00009292,0x00009493,0x0000a49b,0x00001252}, | ||
522 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
523 | 0x00009492,0x0000a49b,0x0000a49b,0x00001252}, | ||
524 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
525 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
526 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
527 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
528 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
529 | 0x0000a493,0x0000a49b,0x0000a49b,0x00009292}, | ||
530 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
531 | 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, | ||
532 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
533 | 0x0000a493,0x000124db,0x0000a49b,0x00009493}, | ||
534 | {0x00000000,0x00000000,0x00009252,0x0000a49b, | ||
535 | 0x0001249b,0x000126dc,0x000124db,0x0000a49b}, | ||
536 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
537 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
538 | } | ||
539 | }, | ||
540 | { /* version 3 */ | ||
541 | { /* version 3, passes 0 */ | ||
542 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
543 | 0x0000124a,0x0000124a,0x00009292,0x00009292}, | ||
544 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
545 | 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, | ||
546 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
547 | 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, | ||
548 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
549 | 0x00009492,0x000124db,0x000126dc,0x000126dc}, | ||
550 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
551 | 0x0000a493,0x000124db,0x000126dc,0x000126dc}, | ||
552 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
553 | 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, | ||
554 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
555 | 0x0000a493,0x000126dc,0x000136e4,0x0001b724}, | ||
556 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
557 | 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, | ||
558 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
559 | 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, | ||
560 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
561 | 0x0001249b,0x000136e4,0x0001b725,0x0001b724}, | ||
562 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
563 | 0x000124db,0x000136e4,0x0001b725,0x0001b925}, | ||
564 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
565 | 0x000126dc,0x000136e4,0x0001b92d,0x0001b925}, | ||
566 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
567 | 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, | ||
568 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
569 | 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, | ||
570 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
571 | 0x000136e4,0x0001b925,0x00025bb6,0x00024b77}, | ||
572 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
573 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
574 | }, | ||
575 | { /* version 3, passes 1 */ | ||
576 | {0x00000000,0x00000000,0x00001249,0x00000249, | ||
577 | 0x0000124a,0x0000124a,0x00001252,0x00001252}, | ||
578 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
579 | 0x00009252,0x00009292,0x00009292,0x00001252}, | ||
580 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
581 | 0x00009492,0x00009493,0x0000a49b,0x00001252}, | ||
582 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
583 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
584 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
585 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
586 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
587 | 0x0000a493,0x0000a49b,0x000126dc,0x00009292}, | ||
588 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
589 | 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, | ||
590 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
591 | 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, | ||
592 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
593 | 0x0000a493,0x000124db,0x000126dc,0x00009493}, | ||
594 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
595 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
596 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
597 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
598 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
599 | 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, | ||
600 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
601 | 0x000124db,0x000136e4,0x000126dc,0x000124db}, | ||
602 | {0x00000000,0x00000000,0x00009492,0x0000a49b, | ||
603 | 0x000136e4,0x000136e4,0x000126dc,0x000124db}, | ||
604 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
605 | 0x0001b724,0x0001b724,0x000136e4,0x000126dc}, | ||
606 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
607 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
608 | } | ||
609 | }, | ||
610 | { /* version 4 */ | ||
611 | { /* version 4, passes 0 */ | ||
612 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
613 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
614 | {0x00000000,0x00000000,0x00000249,0x00000049, | ||
615 | 0x00000249,0x00000249,0x0000024a,0x00000049}, | ||
616 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
617 | 0x0000124a,0x00009252,0x00001252,0x0000024a}, | ||
618 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
619 | 0x00009252,0x00009292,0x00009493,0x00001252}, | ||
620 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
621 | 0x00009292,0x00009493,0x00009493,0x00001252}, | ||
622 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
623 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
624 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
625 | 0x0000a493,0x000124db,0x000124db,0x00009493}, | ||
626 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
627 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
628 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
629 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
630 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
631 | 0x0001249b,0x000126dc,0x000126dc,0x000124db}, | ||
632 | {0x00000000,0x00000000,0x00009252,0x00009493, | ||
633 | 0x000124db,0x000136e4,0x000136e4,0x000126dc}, | ||
634 | {0x00000000,0x00000000,0x00009252,0x0000a49b, | ||
635 | 0x000124db,0x000136e4,0x000136e4,0x000126dc}, | ||
636 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
637 | 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, | ||
638 | {0x00000000,0x00000000,0x00009492,0x0000a49b, | ||
639 | 0x000126dc,0x0001b724,0x0001b725,0x0001b724}, | ||
640 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
641 | 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, | ||
642 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
643 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
644 | }, | ||
645 | { /* version 4, passes 1 */ | ||
646 | {0x00000000,0x00000000,0x00000249,0x00000049, | ||
647 | 0x00000009,0x00000009,0x00000009,0x00000009}, | ||
648 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
649 | 0x00000049,0x00000049,0x00000009,0x00000009}, | ||
650 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
651 | 0x0000124a,0x00000249,0x00000049,0x00000049}, | ||
652 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
653 | 0x0000124a,0x0000124a,0x00000049,0x00000049}, | ||
654 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
655 | 0x00009252,0x0000124a,0x0000024a,0x0000024a}, | ||
656 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
657 | 0x00009252,0x0000124a,0x0000024a,0x0000024a}, | ||
658 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
659 | 0x00009492,0x00009252,0x00001252,0x00001252}, | ||
660 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
661 | 0x0000a493,0x00009292,0x00009292,0x00001252}, | ||
662 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
663 | 0x0000a493,0x00009292,0x00009292,0x00009292}, | ||
664 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
665 | 0x0000a493,0x00009493,0x00009493,0x00009292}, | ||
666 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
667 | 0x0000a493,0x0000a49b,0x00009493,0x00009493}, | ||
668 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
669 | 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, | ||
670 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
671 | 0x0001249b,0x000124db,0x0000a49b,0x0000a49b}, | ||
672 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
673 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
674 | {0x00000000,0x00000000,0x00009252,0x000124db, | ||
675 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
676 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
677 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
678 | } | ||
679 | }, | ||
680 | { /* version 5 */ | ||
681 | { /* version 5, passes 0 */ | ||
682 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
683 | 0x00000249,0x00000249,0x00001252,0x00001252}, | ||
684 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
685 | 0x00009252,0x00009292,0x00009292,0x00001252}, | ||
686 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
687 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
688 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
689 | 0x0000a493,0x0000a49b,0x000124db,0x00009493}, | ||
690 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
691 | 0x0000a493,0x000124db,0x000126dc,0x00009493}, | ||
692 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
693 | 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, | ||
694 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
695 | 0x0001249b,0x000126dc,0x000136e4,0x000124db}, | ||
696 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
697 | 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, | ||
698 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
699 | 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, | ||
700 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
701 | 0x000126dc,0x0001b724,0x0001b725,0x000136e4}, | ||
702 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
703 | 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, | ||
704 | {0x00000000,0x00000000,0x00009492,0x0000a49b, | ||
705 | 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, | ||
706 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
707 | 0x000136e4,0x0001b925,0x0001c96e,0x0001b925}, | ||
708 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
709 | 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, | ||
710 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
711 | 0x0001c924,0x0002496d,0x00025bb6,0x00024b77}, | ||
712 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
713 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
714 | }, | ||
715 | { /* version 5, passes 1 */ | ||
716 | {0x00000000,0x00000000,0x00001249,0x00000249, | ||
717 | 0x00000249,0x00000249,0x0000024a,0x0000024a}, | ||
718 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
719 | 0x0000124a,0x0000124a,0x0000024a,0x0000024a}, | ||
720 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
721 | 0x00009252,0x00009252,0x0000024a,0x0000024a}, | ||
722 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
723 | 0x00009492,0x0000a49b,0x00001252,0x00001252}, | ||
724 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
725 | 0x0000a493,0x0000a49b,0x00001252,0x00001252}, | ||
726 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
727 | 0x0000a493,0x0000a49b,0x00009292,0x00001252}, | ||
728 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
729 | 0x0000a493,0x0000a49b,0x00009292,0x00009292}, | ||
730 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
731 | 0x0000a493,0x0000a49b,0x00009493,0x00009292}, | ||
732 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
733 | 0x0001249b,0x000124db,0x00009493,0x00009292}, | ||
734 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
735 | 0x0001249b,0x000124db,0x00009493,0x00009493}, | ||
736 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
737 | 0x000124db,0x000124db,0x0000a49b,0x00009493}, | ||
738 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
739 | 0x000126dc,0x000126dc,0x0000a49b,0x00009493}, | ||
740 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
741 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
742 | {0x00000000,0x00000000,0x00009292,0x000124db, | ||
743 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
744 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
745 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
746 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
747 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
748 | } | ||
749 | }, | ||
750 | { /* version 6 */ | ||
751 | { /* version 6, passes 0 */ | ||
752 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
753 | 0x00009252,0x00009292,0x00009493,0x00009493}, | ||
754 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
755 | 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, | ||
756 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
757 | 0x0000a493,0x000124db,0x000124db,0x0000a49b}, | ||
758 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
759 | 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, | ||
760 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
761 | 0x0001249b,0x000126dc,0x000136e4,0x000124db}, | ||
762 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
763 | 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, | ||
764 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
765 | 0x000126dc,0x0001b724,0x0001b725,0x000126dc}, | ||
766 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
767 | 0x000136e4,0x0001b724,0x0001b92d,0x000136e4}, | ||
768 | {0x00000000,0x00000000,0x00009492,0x0000a49b, | ||
769 | 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, | ||
770 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
771 | 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, | ||
772 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
773 | 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, | ||
774 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
775 | 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, | ||
776 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
777 | 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d}, | ||
778 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
779 | 0x0001b724,0x0001c92d,0x00024b76,0x0002496e}, | ||
780 | {0x00000000,0x00000000,0x00012492,0x000126db, | ||
781 | 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf}, | ||
782 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
783 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
784 | }, | ||
785 | { /* version 6, passes 1 */ | ||
786 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
787 | 0x0000124a,0x0000124a,0x00001252,0x00001252}, | ||
788 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
789 | 0x00009492,0x00009252,0x00001252,0x00001252}, | ||
790 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
791 | 0x0000a493,0x00009292,0x00001252,0x00001252}, | ||
792 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
793 | 0x0000a493,0x0000a49b,0x00009292,0x00009292}, | ||
794 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
795 | 0x0000a493,0x0000a49b,0x00009292,0x00009292}, | ||
796 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
797 | 0x0001249b,0x0000a49b,0x00009493,0x00009292}, | ||
798 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
799 | 0x000124db,0x000124db,0x00009493,0x00009493}, | ||
800 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
801 | 0x000124db,0x000124db,0x0000a49b,0x00009493}, | ||
802 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
803 | 0x000126dc,0x000124db,0x0000a49b,0x00009493}, | ||
804 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
805 | 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b}, | ||
806 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
807 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
808 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
809 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
810 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
811 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
812 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
813 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
814 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
815 | 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, | ||
816 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
817 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
818 | } | ||
819 | }, | ||
820 | { /* version 7 */ | ||
821 | { /* version 7, passes 0 */ | ||
822 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
823 | 0x00009252,0x00009292,0x00009493,0x00009493}, | ||
824 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
825 | 0x0000a493,0x000124db,0x000126dc,0x00009493}, | ||
826 | {0x00000000,0x00000000,0x00001249,0x0000a49b, | ||
827 | 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, | ||
828 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
829 | 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, | ||
830 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
831 | 0x000126dc,0x000136e4,0x0001b725,0x000124db}, | ||
832 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
833 | 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, | ||
834 | {0x00000000,0x00000000,0x00009292,0x000124db, | ||
835 | 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, | ||
836 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
837 | 0x000136e4,0x0001b724,0x0001c96e,0x000136e4}, | ||
838 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
839 | 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, | ||
840 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
841 | 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, | ||
842 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
843 | 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925}, | ||
844 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
845 | 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, | ||
846 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
847 | 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, | ||
848 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
849 | 0x0001b924,0x0001c92d,0x00024b76,0x0002496e}, | ||
850 | {0x00000000,0x00000000,0x00012492,0x000136db, | ||
851 | 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf}, | ||
852 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
853 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
854 | }, | ||
855 | { /* version 7, passes 1 */ | ||
856 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
857 | 0x0000124a,0x0000124a,0x00001252,0x00001252}, | ||
858 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
859 | 0x00009492,0x00009292,0x00001252,0x00001252}, | ||
860 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
861 | 0x0000a493,0x0000a49b,0x00001252,0x00001252}, | ||
862 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
863 | 0x0000a493,0x0000a49b,0x00009292,0x00009292}, | ||
864 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
865 | 0x0000a493,0x0000a49b,0x00009292,0x00009292}, | ||
866 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
867 | 0x000126dc,0x0000a49b,0x00009493,0x00009292}, | ||
868 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
869 | 0x000126dc,0x000124db,0x00009493,0x00009493}, | ||
870 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
871 | 0x000136e4,0x000124db,0x0000a49b,0x00009493}, | ||
872 | {0x00000000,0x00000000,0x0000924a,0x000136db, | ||
873 | 0x0001b724,0x000124db,0x0000a49b,0x00009493}, | ||
874 | {0x00000000,0x00000000,0x0000924a,0x000136db, | ||
875 | 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b}, | ||
876 | {0x00000000,0x00000000,0x00009292,0x000136db, | ||
877 | 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, | ||
878 | {0x00000000,0x00000000,0x00009492,0x000136db, | ||
879 | 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, | ||
880 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
881 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
882 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
883 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
884 | {0x00000000,0x00000000,0x00012492,0x0001b6db, | ||
885 | 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, | ||
886 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
887 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
888 | } | ||
889 | } | ||
890 | }; | ||
891 | |||
diff --git a/drivers/media/video/pwc/pwc-kiara.h b/drivers/media/video/pwc/pwc-kiara.h index 12929abbb1f0..0bdb22547d86 100644 --- a/drivers/media/video/pwc/pwc-kiara.h +++ b/drivers/media/video/pwc/pwc-kiara.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* Linux driver for Philips webcam | 1 | /* Linux driver for Philips webcam |
2 | (C) 2004 Luc Saillard (luc@saillard.org) | 2 | (C) 2004-2006 Luc Saillard (luc@saillard.org) |
3 | 3 | ||
4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | 4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx |
5 | driver and thus may have bugs that are not present in the original version. | 5 | driver and thus may have bugs that are not present in the original version. |
@@ -27,7 +27,7 @@ | |||
27 | #ifndef PWC_KIARA_H | 27 | #ifndef PWC_KIARA_H |
28 | #define PWC_KIARA_H | 28 | #define PWC_KIARA_H |
29 | 29 | ||
30 | #include "pwc-ioctl.h" | 30 | #include <media/pwc-ioctl.h> |
31 | 31 | ||
32 | struct Kiara_table_entry | 32 | struct Kiara_table_entry |
33 | { | 33 | { |
@@ -37,8 +37,8 @@ struct Kiara_table_entry | |||
37 | unsigned char mode[12]; /* precomputed mode settings for cam */ | 37 | unsigned char mode[12]; /* precomputed mode settings for cam */ |
38 | }; | 38 | }; |
39 | 39 | ||
40 | const extern struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4]; | 40 | extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4]; |
41 | const extern unsigned int KiaraRomTable[8][2][16][8]; | 41 | extern const unsigned int KiaraRomTable[8][2][16][8]; |
42 | 42 | ||
43 | #endif | 43 | #endif |
44 | 44 | ||
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c index 58fe79747992..589c687439da 100644 --- a/drivers/media/video/pwc/pwc-misc.c +++ b/drivers/media/video/pwc/pwc-misc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Linux driver for Philips webcam | 1 | /* Linux driver for Philips webcam |
2 | Various miscellaneous functions and tables. | 2 | Various miscellaneous functions and tables. |
3 | (C) 1999-2003 Nemosoft Unv. | 3 | (C) 1999-2003 Nemosoft Unv. |
4 | (C) 2004 Luc Saillard (luc@saillard.org) | 4 | (C) 2004-2006 Luc Saillard (luc@saillard.org) |
5 | 5 | ||
6 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | 6 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx |
7 | driver and thus may have bugs that are not present in the original version. | 7 | driver and thus may have bugs that are not present in the original version. |
@@ -24,18 +24,17 @@ | |||
24 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 24 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/slab.h> | ||
28 | 27 | ||
29 | #include "pwc.h" | 28 | #include "pwc.h" |
30 | 29 | ||
31 | struct pwc_coord pwc_image_sizes[PSZ_MAX] = | 30 | const struct pwc_coord pwc_image_sizes[PSZ_MAX] = |
32 | { | 31 | { |
33 | { 128, 96, 0 }, | 32 | { 128, 96, 0 }, /* sqcif */ |
34 | { 160, 120, 0 }, | 33 | { 160, 120, 0 }, /* qsif */ |
35 | { 176, 144, 0 }, | 34 | { 176, 144, 0 }, /* qcif */ |
36 | { 320, 240, 0 }, | 35 | { 320, 240, 0 }, /* sif */ |
37 | { 352, 288, 0 }, | 36 | { 352, 288, 0 }, /* cif */ |
38 | { 640, 480, 0 }, | 37 | { 640, 480, 0 }, /* vga */ |
39 | }; | 38 | }; |
40 | 39 | ||
41 | /* x,y -> PSZ_ */ | 40 | /* x,y -> PSZ_ */ |
@@ -52,7 +51,7 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height) | |||
52 | { | 51 | { |
53 | if (width > pdev->abs_max.x || height > pdev->abs_max.y) | 52 | if (width > pdev->abs_max.x || height > pdev->abs_max.y) |
54 | { | 53 | { |
55 | Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n"); | 54 | PWC_DEBUG_SIZE("VIDEO_PALETTE_RAW: going beyond abs_max.\n"); |
56 | return -1; | 55 | return -1; |
57 | } | 56 | } |
58 | } | 57 | } |
@@ -60,7 +59,7 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height) | |||
60 | { | 59 | { |
61 | if (width > pdev->view_max.x || height > pdev->view_max.y) | 60 | if (width > pdev->view_max.x || height > pdev->view_max.y) |
62 | { | 61 | { |
63 | Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n"); | 62 | PWC_DEBUG_SIZE("VIDEO_PALETTE_not RAW: going beyond view_max.\n"); |
64 | return -1; | 63 | return -1; |
65 | } | 64 | } |
66 | } | 65 | } |
@@ -81,9 +80,8 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height) | |||
81 | /* initialize variables depending on type and decompressor*/ | 80 | /* initialize variables depending on type and decompressor*/ |
82 | void pwc_construct(struct pwc_device *pdev) | 81 | void pwc_construct(struct pwc_device *pdev) |
83 | { | 82 | { |
84 | switch(pdev->type) { | 83 | if (DEVICE_USE_CODEC1(pdev->type)) { |
85 | case 645: | 84 | |
86 | case 646: | ||
87 | pdev->view_min.x = 128; | 85 | pdev->view_min.x = 128; |
88 | pdev->view_min.y = 96; | 86 | pdev->view_min.y = 96; |
89 | pdev->view_max.x = 352; | 87 | pdev->view_max.x = 352; |
@@ -95,10 +93,23 @@ void pwc_construct(struct pwc_device *pdev) | |||
95 | pdev->vendpoint = 4; | 93 | pdev->vendpoint = 4; |
96 | pdev->frame_header_size = 0; | 94 | pdev->frame_header_size = 0; |
97 | pdev->frame_trailer_size = 0; | 95 | pdev->frame_trailer_size = 0; |
98 | break; | 96 | |
99 | case 675: | 97 | } else if (DEVICE_USE_CODEC3(pdev->type)) { |
100 | case 680: | 98 | |
101 | case 690: | 99 | pdev->view_min.x = 160; |
100 | pdev->view_min.y = 120; | ||
101 | pdev->view_max.x = 640; | ||
102 | pdev->view_max.y = 480; | ||
103 | pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA; | ||
104 | pdev->abs_max.x = 640; | ||
105 | pdev->abs_max.y = 480; | ||
106 | pdev->vcinterface = 3; | ||
107 | pdev->vendpoint = 5; | ||
108 | pdev->frame_header_size = TOUCAM_HEADER_SIZE; | ||
109 | pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE; | ||
110 | |||
111 | } else /* if (DEVICE_USE_CODEC2(pdev->type)) */ { | ||
112 | |||
102 | pdev->view_min.x = 128; | 113 | pdev->view_min.x = 128; |
103 | pdev->view_min.y = 96; | 114 | pdev->view_min.y = 96; |
104 | /* Anthill bug #38: PWC always reports max size, even without PWCX */ | 115 | /* Anthill bug #38: PWC always reports max size, even without PWCX */ |
@@ -111,30 +122,12 @@ void pwc_construct(struct pwc_device *pdev) | |||
111 | pdev->vendpoint = 4; | 122 | pdev->vendpoint = 4; |
112 | pdev->frame_header_size = 0; | 123 | pdev->frame_header_size = 0; |
113 | pdev->frame_trailer_size = 0; | 124 | pdev->frame_trailer_size = 0; |
114 | break; | ||
115 | case 720: | ||
116 | case 730: | ||
117 | case 740: | ||
118 | case 750: | ||
119 | pdev->view_min.x = 160; | ||
120 | pdev->view_min.y = 120; | ||
121 | pdev->view_max.x = 640; | ||
122 | pdev->view_max.y = 480; | ||
123 | pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA; | ||
124 | pdev->abs_max.x = 640; | ||
125 | pdev->abs_max.y = 480; | ||
126 | pdev->vcinterface = 3; | ||
127 | pdev->vendpoint = 5; | ||
128 | pdev->frame_header_size = TOUCAM_HEADER_SIZE; | ||
129 | pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE; | ||
130 | break; | ||
131 | } | 125 | } |
132 | Debug("type = %d\n",pdev->type); | ||
133 | pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */ | 126 | pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */ |
134 | pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; | 127 | pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; |
135 | pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; | 128 | pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; |
136 | /* length of image, in YUV format; always allocate enough memory. */ | 129 | /* length of image, in YUV format; always allocate enough memory. */ |
137 | pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2; | 130 | pdev->len_per_image = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2); |
138 | } | 131 | } |
139 | 132 | ||
140 | 133 | ||
diff --git a/drivers/media/video/pwc/pwc-timon.c b/drivers/media/video/pwc/pwc-timon.c index 175250d089cf..be65bdcd195b 100644 --- a/drivers/media/video/pwc/pwc-timon.c +++ b/drivers/media/video/pwc/pwc-timon.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* Linux driver for Philips webcam | 1 | /* Linux driver for Philips webcam |
2 | (C) 2004 Luc Saillard (luc@saillard.org) | 2 | (C) 2004-2006 Luc Saillard (luc@saillard.org) |
3 | 3 | ||
4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | 4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx |
5 | driver and thus may have bugs that are not present in the original version. | 5 | driver and thus may have bugs that are not present in the original version. |
@@ -314,3 +314,1133 @@ const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] = | |||
314 | }, | 314 | }, |
315 | }; | 315 | }; |
316 | 316 | ||
317 | /* | ||
318 | * 16 versions: | ||
319 | * 2 tables (one for Y, and one for U&V) | ||
320 | * 16 levels of details per tables | ||
321 | * 8 blocs | ||
322 | */ | ||
323 | |||
324 | const unsigned int TimonRomTable [16][2][16][8] = | ||
325 | { | ||
326 | { /* version 0 */ | ||
327 | { /* version 0, passes 0 */ | ||
328 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
329 | 0x00000000,0x00000000,0x00000000,0x00000001}, | ||
330 | {0x00000000,0x00000000,0x00000001,0x00000001, | ||
331 | 0x00000001,0x00000001,0x00000001,0x00000001}, | ||
332 | {0x00000000,0x00000000,0x00000001,0x00000001, | ||
333 | 0x00000001,0x00000009,0x00000009,0x00000009}, | ||
334 | {0x00000000,0x00000000,0x00000009,0x00000001, | ||
335 | 0x00000009,0x00000009,0x00000009,0x00000009}, | ||
336 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
337 | 0x00000009,0x00000009,0x00000049,0x00000009}, | ||
338 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
339 | 0x00000009,0x00000049,0x00000049,0x00000049}, | ||
340 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
341 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
342 | {0x00000000,0x00000000,0x00000009,0x00000049, | ||
343 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
344 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
345 | 0x00000049,0x00000049,0x0000024a,0x0000024a}, | ||
346 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
347 | 0x00000049,0x00000249,0x0000024a,0x0000024a}, | ||
348 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
349 | 0x00000249,0x00000249,0x0000024a,0x0000024a}, | ||
350 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
351 | 0x00000249,0x00000249,0x00001252,0x0000024a}, | ||
352 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
353 | 0x00000249,0x0000124a,0x00001252,0x0000024a}, | ||
354 | {0x00000000,0x00000000,0x00000049,0x00000249, | ||
355 | 0x00000249,0x0000124a,0x00001252,0x0000024a}, | ||
356 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
357 | 0x0000124a,0x00009252,0x00009292,0x00001252}, | ||
358 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
359 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
360 | }, | ||
361 | { /* version 0, passes 1 */ | ||
362 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
363 | 0x00000000,0x00000000,0x00000000,0x00000000}, | ||
364 | {0x00000000,0x00000000,0x00000001,0x00000001, | ||
365 | 0x00000001,0x00000001,0x00000000,0x00000000}, | ||
366 | {0x00000000,0x00000000,0x00000009,0x00000001, | ||
367 | 0x00000001,0x00000009,0x00000000,0x00000000}, | ||
368 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
369 | 0x00000009,0x00000009,0x00000000,0x00000000}, | ||
370 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
371 | 0x00000009,0x00000009,0x00000001,0x00000000}, | ||
372 | {0x00000000,0x00000000,0x00000049,0x00000009, | ||
373 | 0x00000009,0x00000049,0x00000001,0x00000001}, | ||
374 | {0x00000000,0x00000000,0x00000049,0x00000009, | ||
375 | 0x00000009,0x00000049,0x00000001,0x00000001}, | ||
376 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
377 | 0x00000049,0x00000049,0x00000009,0x00000001}, | ||
378 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
379 | 0x00000049,0x00000049,0x00000009,0x00000001}, | ||
380 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
381 | 0x00000049,0x00000049,0x00000009,0x00000001}, | ||
382 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
383 | 0x00000049,0x00000049,0x00000009,0x00000009}, | ||
384 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
385 | 0x00000049,0x00000249,0x00000049,0x00000009}, | ||
386 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
387 | 0x00000049,0x00000249,0x00000049,0x00000009}, | ||
388 | {0x00000000,0x00000000,0x00000249,0x00000049, | ||
389 | 0x00000249,0x00000249,0x00000049,0x00000009}, | ||
390 | {0x00000000,0x00000000,0x00001249,0x00000249, | ||
391 | 0x0000124a,0x0000124a,0x0000024a,0x00000049}, | ||
392 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
393 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
394 | } | ||
395 | }, | ||
396 | { /* version 1 */ | ||
397 | { /* version 1, passes 0 */ | ||
398 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
399 | 0x00000000,0x00000000,0x00000000,0x00000001}, | ||
400 | {0x00000000,0x00000000,0x00000001,0x00000001, | ||
401 | 0x00000001,0x00000009,0x00000009,0x00000009}, | ||
402 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
403 | 0x00000009,0x00000009,0x00000009,0x00000009}, | ||
404 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
405 | 0x00000009,0x00000049,0x00000049,0x00000049}, | ||
406 | {0x00000000,0x00000000,0x00000009,0x00000049, | ||
407 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
408 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
409 | 0x00000049,0x00000249,0x0000024a,0x0000024a}, | ||
410 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
411 | 0x00000249,0x00000249,0x0000024a,0x0000024a}, | ||
412 | {0x00000000,0x00000000,0x00000049,0x00000249, | ||
413 | 0x00000249,0x00000249,0x0000024a,0x00001252}, | ||
414 | {0x00000000,0x00000000,0x00000049,0x00000249, | ||
415 | 0x00000249,0x0000124a,0x00001252,0x00001252}, | ||
416 | {0x00000000,0x00000000,0x00000049,0x00000249, | ||
417 | 0x0000124a,0x0000124a,0x00001252,0x00001252}, | ||
418 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
419 | 0x0000124a,0x0000124a,0x00009292,0x00009292}, | ||
420 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
421 | 0x0000124a,0x00009252,0x00009292,0x00009292}, | ||
422 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
423 | 0x00009252,0x00009252,0x00009292,0x00009292}, | ||
424 | {0x00000000,0x00000000,0x00000249,0x0000924a, | ||
425 | 0x00009292,0x00009493,0x00009493,0x00009493}, | ||
426 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
427 | 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b}, | ||
428 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
429 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
430 | }, | ||
431 | { /* version 1, passes 1 */ | ||
432 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
433 | 0x00000000,0x00000000,0x00000000,0x00000000}, | ||
434 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
435 | 0x00000009,0x00000001,0x00000001,0x00000000}, | ||
436 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
437 | 0x00000009,0x00000009,0x00000001,0x00000000}, | ||
438 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
439 | 0x00000049,0x00000009,0x00000001,0x00000000}, | ||
440 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
441 | 0x00000049,0x00000049,0x00000001,0x00000001}, | ||
442 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
443 | 0x00000049,0x00000049,0x00000009,0x00000001}, | ||
444 | {0x00000000,0x00000000,0x00000249,0x00000049, | ||
445 | 0x00000049,0x00000249,0x00000009,0x00000001}, | ||
446 | {0x00000000,0x00000000,0x00000249,0x00000049, | ||
447 | 0x00000249,0x00000249,0x00000009,0x00000009}, | ||
448 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
449 | 0x00000249,0x00000249,0x00000049,0x00000009}, | ||
450 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
451 | 0x00000249,0x0000124a,0x00000049,0x00000009}, | ||
452 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
453 | 0x00000249,0x0000124a,0x00000049,0x00000009}, | ||
454 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
455 | 0x00000249,0x0000124a,0x0000024a,0x00000049}, | ||
456 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
457 | 0x0000124a,0x0000124a,0x0000024a,0x00000049}, | ||
458 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
459 | 0x0000124a,0x0000124a,0x0000024a,0x00000049}, | ||
460 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
461 | 0x00009252,0x00009252,0x00001252,0x0000024a}, | ||
462 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
463 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
464 | } | ||
465 | }, | ||
466 | { /* version 2 */ | ||
467 | { /* version 2, passes 0 */ | ||
468 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
469 | 0x00000000,0x00000000,0x00000000,0x00000001}, | ||
470 | {0x00000000,0x00000000,0x00000009,0x00000009, | ||
471 | 0x00000009,0x00000009,0x00000009,0x00000009}, | ||
472 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
473 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
474 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
475 | 0x00000049,0x00000249,0x0000024a,0x0000024a}, | ||
476 | {0x00000000,0x00000000,0x00000049,0x00000249, | ||
477 | 0x00000249,0x00000249,0x0000024a,0x00001252}, | ||
478 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
479 | 0x00000249,0x0000124a,0x00001252,0x00001252}, | ||
480 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
481 | 0x0000124a,0x0000124a,0x00009292,0x00009292}, | ||
482 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
483 | 0x0000124a,0x00009252,0x00009292,0x00009292}, | ||
484 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
485 | 0x00009252,0x00009292,0x00009292,0x00009292}, | ||
486 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
487 | 0x00009252,0x00009292,0x00009493,0x00009493}, | ||
488 | {0x00000000,0x00000000,0x00000249,0x0000924a, | ||
489 | 0x00009252,0x00009493,0x00009493,0x00009493}, | ||
490 | {0x00000000,0x00000000,0x00000249,0x0000924a, | ||
491 | 0x00009292,0x00009493,0x00009493,0x00009493}, | ||
492 | {0x00000000,0x00000000,0x00000249,0x00009252, | ||
493 | 0x00009492,0x00009493,0x0000a49b,0x0000a49b}, | ||
494 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
495 | 0x00009492,0x000124db,0x000124db,0x000124db}, | ||
496 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
497 | 0x0000a493,0x000126dc,0x000126dc,0x000126dc}, | ||
498 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
499 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
500 | }, | ||
501 | { /* version 2, passes 1 */ | ||
502 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
503 | 0x00000000,0x00000000,0x00000000,0x00000000}, | ||
504 | {0x00000000,0x00000000,0x00000049,0x00000009, | ||
505 | 0x00000049,0x00000009,0x00000001,0x00000000}, | ||
506 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
507 | 0x00000049,0x00000049,0x00000049,0x00000000}, | ||
508 | {0x00000000,0x00000000,0x00000249,0x00000049, | ||
509 | 0x00000249,0x00000049,0x0000024a,0x00000001}, | ||
510 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
511 | 0x00000249,0x00000249,0x0000024a,0x00000001}, | ||
512 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
513 | 0x00000249,0x00000249,0x0000024a,0x00000001}, | ||
514 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
515 | 0x00000249,0x00000249,0x0000024a,0x00000009}, | ||
516 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
517 | 0x0000124a,0x0000124a,0x0000024a,0x00000009}, | ||
518 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
519 | 0x0000124a,0x0000124a,0x0000024a,0x00000009}, | ||
520 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
521 | 0x0000124a,0x00009252,0x00001252,0x00000049}, | ||
522 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
523 | 0x0000124a,0x00009292,0x00001252,0x00000049}, | ||
524 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
525 | 0x0000124a,0x00009292,0x00001252,0x00000049}, | ||
526 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
527 | 0x00009252,0x00009292,0x00001252,0x0000024a}, | ||
528 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
529 | 0x00009292,0x00009292,0x00001252,0x0000024a}, | ||
530 | {0x00000000,0x00000000,0x0000924a,0x0000924a, | ||
531 | 0x00009492,0x00009493,0x00009292,0x00001252}, | ||
532 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
533 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
534 | } | ||
535 | }, | ||
536 | { /* version 3 */ | ||
537 | { /* version 3, passes 0 */ | ||
538 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
539 | 0x00000000,0x00000000,0x00000000,0x00000001}, | ||
540 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
541 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
542 | {0x00000000,0x00000000,0x00000049,0x00000249, | ||
543 | 0x00000249,0x00000249,0x00001252,0x0000024a}, | ||
544 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
545 | 0x00000249,0x0000124a,0x00001252,0x00001252}, | ||
546 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
547 | 0x0000124a,0x00009252,0x00009292,0x00009292}, | ||
548 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
549 | 0x0000124a,0x00009292,0x00009292,0x00009493}, | ||
550 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
551 | 0x00009252,0x00009292,0x00009493,0x00009493}, | ||
552 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
553 | 0x00009292,0x00009493,0x00009493,0x00009493}, | ||
554 | {0x00000000,0x00000000,0x00000249,0x00009252, | ||
555 | 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, | ||
556 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
557 | 0x00009292,0x0000a49b,0x0000a49b,0x0000a49b}, | ||
558 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
559 | 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b}, | ||
560 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
561 | 0x00009492,0x0000a49b,0x000124db,0x000124db}, | ||
562 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
563 | 0x0000a493,0x0000a49b,0x000124db,0x000124db}, | ||
564 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
565 | 0x0001249b,0x000126dc,0x000136e4,0x000126dc}, | ||
566 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
567 | 0x000124db,0x000136e4,0x0001b725,0x000136e4}, | ||
568 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
569 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
570 | }, | ||
571 | { /* version 3, passes 1 */ | ||
572 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
573 | 0x00000000,0x00000000,0x00000000,0x00000000}, | ||
574 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
575 | 0x00000049,0x00000049,0x00000001,0x00000000}, | ||
576 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
577 | 0x00000249,0x00000249,0x00000049,0x00000001}, | ||
578 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
579 | 0x00000249,0x0000124a,0x00001252,0x00000001}, | ||
580 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
581 | 0x0000124a,0x0000124a,0x00001252,0x00000009}, | ||
582 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
583 | 0x0000124a,0x00009252,0x00009292,0x00000009}, | ||
584 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
585 | 0x0000124a,0x00009252,0x00009292,0x00000049}, | ||
586 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
587 | 0x00009252,0x00009252,0x00009292,0x00000049}, | ||
588 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
589 | 0x00009252,0x00009493,0x00009292,0x0000024a}, | ||
590 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
591 | 0x00009252,0x00009493,0x00009292,0x0000024a}, | ||
592 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
593 | 0x00009252,0x00009493,0x00009493,0x00001252}, | ||
594 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
595 | 0x00009292,0x00009493,0x00009493,0x00001252}, | ||
596 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
597 | 0x00009492,0x00009493,0x00009493,0x00009292}, | ||
598 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
599 | 0x00009492,0x0000a49b,0x00009493,0x00009292}, | ||
600 | {0x00000000,0x00000000,0x0000924a,0x00009292, | ||
601 | 0x0000a493,0x000124db,0x0000a49b,0x00009493}, | ||
602 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
603 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
604 | } | ||
605 | }, | ||
606 | { /* version 4 */ | ||
607 | { /* version 4, passes 0 */ | ||
608 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
609 | 0x00000049,0x00000049,0x0000024a,0x0000024a}, | ||
610 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
611 | 0x00000249,0x0000124a,0x00001252,0x00009292}, | ||
612 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
613 | 0x0000124a,0x00009252,0x00009292,0x00009292}, | ||
614 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
615 | 0x0000124a,0x00009292,0x00009493,0x00009493}, | ||
616 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
617 | 0x00009252,0x00009493,0x00009493,0x0000a49b}, | ||
618 | {0x00000000,0x00000000,0x00000249,0x0000924a, | ||
619 | 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, | ||
620 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
621 | 0x00009292,0x00009493,0x0000a49b,0x000124db}, | ||
622 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
623 | 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, | ||
624 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
625 | 0x00009492,0x000124db,0x000124db,0x000126dc}, | ||
626 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
627 | 0x0000a493,0x000124db,0x000126dc,0x000126dc}, | ||
628 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
629 | 0x0000a493,0x000124db,0x000126dc,0x000136e4}, | ||
630 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
631 | 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, | ||
632 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
633 | 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, | ||
634 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
635 | 0x000124db,0x000136e4,0x000136e4,0x0001b724}, | ||
636 | {0x00000000,0x00000000,0x00009252,0x000124db, | ||
637 | 0x000126dc,0x0001b724,0x0001b725,0x0001b925}, | ||
638 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
639 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
640 | }, | ||
641 | { /* version 4, passes 1 */ | ||
642 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
643 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
644 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
645 | 0x00000249,0x00000249,0x0000024a,0x00000049}, | ||
646 | {0x00000000,0x00000000,0x00001249,0x00000249, | ||
647 | 0x0000124a,0x0000124a,0x00001252,0x00000049}, | ||
648 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
649 | 0x0000124a,0x0000124a,0x00009292,0x0000024a}, | ||
650 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
651 | 0x00009252,0x00009292,0x00009292,0x0000024a}, | ||
652 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
653 | 0x00009252,0x00009292,0x0000a49b,0x0000024a}, | ||
654 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
655 | 0x00009292,0x00009493,0x0000a49b,0x00001252}, | ||
656 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
657 | 0x00009292,0x00009493,0x0000a49b,0x00001252}, | ||
658 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
659 | 0x00009492,0x0000a49b,0x0000a49b,0x00001252}, | ||
660 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
661 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
662 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
663 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
664 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
665 | 0x0000a493,0x0000a49b,0x0000a49b,0x00009292}, | ||
666 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
667 | 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, | ||
668 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
669 | 0x0000a493,0x000124db,0x0000a49b,0x00009493}, | ||
670 | {0x00000000,0x00000000,0x00009252,0x0000a49b, | ||
671 | 0x0001249b,0x000126dc,0x000124db,0x0000a49b}, | ||
672 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
673 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
674 | } | ||
675 | }, | ||
676 | { /* version 5 */ | ||
677 | { /* version 5, passes 0 */ | ||
678 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
679 | 0x00000249,0x0000124a,0x00001252,0x00009292}, | ||
680 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
681 | 0x0000124a,0x00009292,0x00009292,0x00009493}, | ||
682 | {0x00000000,0x00000000,0x00000249,0x0000924a, | ||
683 | 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, | ||
684 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
685 | 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, | ||
686 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
687 | 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, | ||
688 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
689 | 0x00009492,0x0000a49b,0x000124db,0x000124db}, | ||
690 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
691 | 0x0000a493,0x000124db,0x000124db,0x000126dc}, | ||
692 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
693 | 0x0000a493,0x000124db,0x000126dc,0x000126dc}, | ||
694 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
695 | 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, | ||
696 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
697 | 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, | ||
698 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
699 | 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, | ||
700 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
701 | 0x0001249b,0x000126dc,0x0001b725,0x0001b724}, | ||
702 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
703 | 0x000124db,0x000126dc,0x0001b725,0x0001b724}, | ||
704 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
705 | 0x000126dc,0x000136e4,0x0001b92d,0x0001b925}, | ||
706 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
707 | 0x000136e4,0x0001b724,0x0001c96e,0x0001c92d}, | ||
708 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
709 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
710 | }, | ||
711 | { /* version 5, passes 1 */ | ||
712 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
713 | 0x0000124a,0x00000249,0x0000024a,0x0000024a}, | ||
714 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
715 | 0x0000124a,0x0000124a,0x00001252,0x0000024a}, | ||
716 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
717 | 0x00009292,0x00009493,0x00009493,0x0000024a}, | ||
718 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
719 | 0x00009292,0x00009493,0x00009493,0x00001252}, | ||
720 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
721 | 0x00009292,0x00009493,0x0000a49b,0x00001252}, | ||
722 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
723 | 0x00009492,0x00009493,0x000124db,0x00001252}, | ||
724 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
725 | 0x00009492,0x00009493,0x000124db,0x00009292}, | ||
726 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
727 | 0x00009492,0x0000a49b,0x000124db,0x00009292}, | ||
728 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
729 | 0x0000a493,0x0000a49b,0x000124db,0x00009292}, | ||
730 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
731 | 0x0000a493,0x000124db,0x000124db,0x00009493}, | ||
732 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
733 | 0x0000a493,0x000124db,0x000124db,0x00009493}, | ||
734 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
735 | 0x0000a493,0x000124db,0x000124db,0x00009493}, | ||
736 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
737 | 0x0000a493,0x000124db,0x000124db,0x0000a49b}, | ||
738 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
739 | 0x000124db,0x000126dc,0x000124db,0x0000a49b}, | ||
740 | {0x00000000,0x00000000,0x00009252,0x000124db, | ||
741 | 0x000126dc,0x000136e4,0x000126dc,0x000124db}, | ||
742 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
743 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
744 | } | ||
745 | }, | ||
746 | { /* version 6 */ | ||
747 | { /* version 6, passes 0 */ | ||
748 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
749 | 0x0000124a,0x0000124a,0x00009292,0x00009292}, | ||
750 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
751 | 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, | ||
752 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
753 | 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, | ||
754 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
755 | 0x00009492,0x000124db,0x000126dc,0x000126dc}, | ||
756 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
757 | 0x0000a493,0x000124db,0x000126dc,0x000126dc}, | ||
758 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
759 | 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, | ||
760 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
761 | 0x0000a493,0x000126dc,0x000136e4,0x0001b724}, | ||
762 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
763 | 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, | ||
764 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
765 | 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, | ||
766 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
767 | 0x0001249b,0x000136e4,0x0001b725,0x0001b724}, | ||
768 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
769 | 0x000124db,0x000136e4,0x0001b725,0x0001b925}, | ||
770 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
771 | 0x000126dc,0x000136e4,0x0001b92d,0x0001b925}, | ||
772 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
773 | 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, | ||
774 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
775 | 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, | ||
776 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
777 | 0x000136e4,0x0001b925,0x00025bb6,0x00024b77}, | ||
778 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
779 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
780 | }, | ||
781 | { /* version 6, passes 1 */ | ||
782 | {0x00000000,0x00000000,0x00001249,0x00000249, | ||
783 | 0x0000124a,0x0000124a,0x00001252,0x00001252}, | ||
784 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
785 | 0x00009252,0x00009292,0x00009292,0x00001252}, | ||
786 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
787 | 0x00009492,0x00009493,0x0000a49b,0x00001252}, | ||
788 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
789 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
790 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
791 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
792 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
793 | 0x0000a493,0x0000a49b,0x000126dc,0x00009292}, | ||
794 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
795 | 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, | ||
796 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
797 | 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, | ||
798 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
799 | 0x0000a493,0x000124db,0x000126dc,0x00009493}, | ||
800 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
801 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
802 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
803 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
804 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
805 | 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, | ||
806 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
807 | 0x000124db,0x000136e4,0x000126dc,0x000124db}, | ||
808 | {0x00000000,0x00000000,0x00009492,0x0000a49b, | ||
809 | 0x000136e4,0x000136e4,0x000126dc,0x000124db}, | ||
810 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
811 | 0x0001b724,0x0001b724,0x000136e4,0x000126dc}, | ||
812 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
813 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
814 | } | ||
815 | }, | ||
816 | { /* version 7 */ | ||
817 | { /* version 7, passes 0 */ | ||
818 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
819 | 0x00009292,0x00009493,0x0000a49b,0x000124db}, | ||
820 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
821 | 0x0000a493,0x0000a49b,0x000124db,0x000126dc}, | ||
822 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
823 | 0x0000a493,0x000124db,0x000126dc,0x000136e4}, | ||
824 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
825 | 0x0000a493,0x000124db,0x000136e4,0x000136e4}, | ||
826 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
827 | 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, | ||
828 | {0x00000000,0x00000000,0x00001249,0x0000a49b, | ||
829 | 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, | ||
830 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
831 | 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, | ||
832 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
833 | 0x000124db,0x000136e4,0x0001b725,0x0001b724}, | ||
834 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
835 | 0x000126dc,0x000136e4,0x0001b725,0x0001b925}, | ||
836 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
837 | 0x000126dc,0x0001b724,0x0001b92d,0x0001b925}, | ||
838 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
839 | 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, | ||
840 | {0x00000000,0x00000000,0x00009292,0x000124db, | ||
841 | 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, | ||
842 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
843 | 0x000136e4,0x0001b724,0x0001c96e,0x0002496e}, | ||
844 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
845 | 0x000136e4,0x0001b925,0x0001c96e,0x0002496e}, | ||
846 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
847 | 0x0001b724,0x0002496d,0x00025bb6,0x00025bbf}, | ||
848 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
849 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
850 | }, | ||
851 | { /* version 7, passes 1 */ | ||
852 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
853 | 0x00009252,0x00009292,0x00009292,0x00009292}, | ||
854 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
855 | 0x00009492,0x00009493,0x00009493,0x00009292}, | ||
856 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
857 | 0x0000a493,0x0000a49b,0x0000a49b,0x00009292}, | ||
858 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
859 | 0x0000a493,0x0000a49b,0x000124db,0x00009493}, | ||
860 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
861 | 0x0000a493,0x000124db,0x000124db,0x00009493}, | ||
862 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
863 | 0x0000a493,0x000124db,0x000136e4,0x00009493}, | ||
864 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
865 | 0x0000a493,0x000124db,0x000136e4,0x0000a49b}, | ||
866 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
867 | 0x0001249b,0x000124db,0x000136e4,0x0000a49b}, | ||
868 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
869 | 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, | ||
870 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
871 | 0x0001249b,0x000126dc,0x000136e4,0x000124db}, | ||
872 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
873 | 0x000126dc,0x000136e4,0x000136e4,0x000124db}, | ||
874 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
875 | 0x000126dc,0x000136e4,0x000136e4,0x000124db}, | ||
876 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
877 | 0x000136e4,0x000136e4,0x000136e4,0x000126dc}, | ||
878 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
879 | 0x000136e4,0x0001b724,0x000136e4,0x000126dc}, | ||
880 | {0x00000000,0x00000000,0x00012492,0x000126db, | ||
881 | 0x0001b724,0x0001b925,0x0001b725,0x000136e4}, | ||
882 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
883 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
884 | } | ||
885 | }, | ||
886 | { /* version 8 */ | ||
887 | { /* version 8, passes 0 */ | ||
888 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
889 | 0x00009292,0x00009493,0x0000a49b,0x000124db}, | ||
890 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
891 | 0x0000a493,0x000124db,0x000126dc,0x000126dc}, | ||
892 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
893 | 0x0000a493,0x000124db,0x000126dc,0x000136e4}, | ||
894 | {0x00000000,0x00000000,0x00001249,0x0000a49b, | ||
895 | 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, | ||
896 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
897 | 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, | ||
898 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
899 | 0x000124db,0x000136e4,0x0001b725,0x0001b724}, | ||
900 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
901 | 0x000126dc,0x000136e4,0x0001b725,0x0001b925}, | ||
902 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
903 | 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, | ||
904 | {0x00000000,0x00000000,0x00009252,0x000124db, | ||
905 | 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, | ||
906 | {0x00000000,0x00000000,0x00009292,0x000124db, | ||
907 | 0x000126dc,0x0001b925,0x0001c96e,0x0001c92d}, | ||
908 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
909 | 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d}, | ||
910 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
911 | 0x000136e4,0x0001b925,0x00024b76,0x00024b77}, | ||
912 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
913 | 0x000136e4,0x0001b925,0x00024b76,0x00025bbf}, | ||
914 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
915 | 0x000136e4,0x0001c92d,0x00024b76,0x00025bbf}, | ||
916 | {0x00000000,0x00000000,0x00012492,0x000136db, | ||
917 | 0x0001b724,0x00024b6d,0x0002ddb6,0x0002efff}, | ||
918 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
919 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
920 | }, | ||
921 | { /* version 8, passes 1 */ | ||
922 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
923 | 0x00009252,0x00009493,0x00009493,0x00009493}, | ||
924 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
925 | 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, | ||
926 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
927 | 0x0000a493,0x0000a49b,0x000124db,0x00009493}, | ||
928 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
929 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
930 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
931 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
932 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
933 | 0x0000a493,0x000124db,0x000136e4,0x000124db}, | ||
934 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
935 | 0x0001249b,0x000126dc,0x000136e4,0x000124db}, | ||
936 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
937 | 0x000126dc,0x000126dc,0x000136e4,0x000126dc}, | ||
938 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
939 | 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, | ||
940 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
941 | 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, | ||
942 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
943 | 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, | ||
944 | {0x00000000,0x00000000,0x00009292,0x000124db, | ||
945 | 0x000136e4,0x0001b724,0x0001b725,0x000136e4}, | ||
946 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
947 | 0x000136e4,0x0001b925,0x0001b725,0x0001b724}, | ||
948 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
949 | 0x000136e4,0x0001b925,0x0001b725,0x0001b724}, | ||
950 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
951 | 0x0001b724,0x0002496d,0x0001b92d,0x0001b925}, | ||
952 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
953 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
954 | } | ||
955 | }, | ||
956 | { /* version 9 */ | ||
957 | { /* version 9, passes 0 */ | ||
958 | {0x00000000,0x00000000,0x00000049,0x00000049, | ||
959 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
960 | {0x00000000,0x00000000,0x00000249,0x00000049, | ||
961 | 0x00000249,0x00000249,0x0000024a,0x00000049}, | ||
962 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
963 | 0x0000124a,0x00009252,0x00001252,0x0000024a}, | ||
964 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
965 | 0x00009252,0x00009292,0x00009493,0x00001252}, | ||
966 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
967 | 0x00009292,0x00009493,0x00009493,0x00001252}, | ||
968 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
969 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
970 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
971 | 0x0000a493,0x000124db,0x000124db,0x00009493}, | ||
972 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
973 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
974 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
975 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
976 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
977 | 0x0001249b,0x000126dc,0x000126dc,0x000124db}, | ||
978 | {0x00000000,0x00000000,0x00009252,0x00009493, | ||
979 | 0x000124db,0x000136e4,0x000136e4,0x000126dc}, | ||
980 | {0x00000000,0x00000000,0x00009252,0x0000a49b, | ||
981 | 0x000124db,0x000136e4,0x000136e4,0x000126dc}, | ||
982 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
983 | 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, | ||
984 | {0x00000000,0x00000000,0x00009492,0x0000a49b, | ||
985 | 0x000126dc,0x0001b724,0x0001b725,0x0001b724}, | ||
986 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
987 | 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, | ||
988 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
989 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
990 | }, | ||
991 | { /* version 9, passes 1 */ | ||
992 | {0x00000000,0x00000000,0x00000249,0x00000049, | ||
993 | 0x00000009,0x00000009,0x00000009,0x00000009}, | ||
994 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
995 | 0x00000049,0x00000049,0x00000009,0x00000009}, | ||
996 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
997 | 0x0000124a,0x00000249,0x00000049,0x00000049}, | ||
998 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
999 | 0x0000124a,0x0000124a,0x00000049,0x00000049}, | ||
1000 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1001 | 0x00009252,0x0000124a,0x0000024a,0x0000024a}, | ||
1002 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
1003 | 0x00009252,0x0000124a,0x0000024a,0x0000024a}, | ||
1004 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
1005 | 0x00009492,0x00009252,0x00001252,0x00001252}, | ||
1006 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
1007 | 0x0000a493,0x00009292,0x00009292,0x00001252}, | ||
1008 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1009 | 0x0000a493,0x00009292,0x00009292,0x00009292}, | ||
1010 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1011 | 0x0000a493,0x00009493,0x00009493,0x00009292}, | ||
1012 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1013 | 0x0000a493,0x0000a49b,0x00009493,0x00009493}, | ||
1014 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1015 | 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, | ||
1016 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1017 | 0x0001249b,0x000124db,0x0000a49b,0x0000a49b}, | ||
1018 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1019 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
1020 | {0x00000000,0x00000000,0x00009252,0x000124db, | ||
1021 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
1022 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1023 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1024 | } | ||
1025 | }, | ||
1026 | { /* version 10 */ | ||
1027 | { /* version 10, passes 0 */ | ||
1028 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
1029 | 0x00000249,0x00000249,0x0000024a,0x0000024a}, | ||
1030 | {0x00000000,0x00000000,0x00000249,0x00001249, | ||
1031 | 0x00009252,0x00009292,0x00009292,0x0000024a}, | ||
1032 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1033 | 0x00009252,0x00009292,0x00009292,0x00001252}, | ||
1034 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
1035 | 0x00009492,0x00009493,0x0000a49b,0x00009292}, | ||
1036 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
1037 | 0x00009492,0x000124db,0x000124db,0x00009292}, | ||
1038 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
1039 | 0x0000a493,0x000124db,0x000124db,0x00009493}, | ||
1040 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
1041 | 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, | ||
1042 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1043 | 0x0000a493,0x000124db,0x000126dc,0x000124db}, | ||
1044 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1045 | 0x0001249b,0x000126dc,0x000126dc,0x000124db}, | ||
1046 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1047 | 0x000124db,0x000126dc,0x000136e4,0x000126dc}, | ||
1048 | {0x00000000,0x00000000,0x00009252,0x0000a49b, | ||
1049 | 0x000124db,0x000136e4,0x000136e4,0x000136e4}, | ||
1050 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
1051 | 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, | ||
1052 | {0x00000000,0x00000000,0x00009492,0x0000a49b, | ||
1053 | 0x000126dc,0x0001b724,0x0001b92d,0x0001b724}, | ||
1054 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1055 | 0x000126dc,0x0001b925,0x0001b92d,0x0001b925}, | ||
1056 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
1057 | 0x000136e4,0x0002496d,0x0001c96e,0x0001c92d}, | ||
1058 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1059 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1060 | }, | ||
1061 | { /* version 10, passes 1 */ | ||
1062 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
1063 | 0x00000049,0x00000049,0x00000049,0x00000049}, | ||
1064 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1065 | 0x0000124a,0x00000249,0x00000049,0x00000049}, | ||
1066 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1067 | 0x0000124a,0x00009252,0x0000024a,0x00000049}, | ||
1068 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1069 | 0x00009252,0x00009493,0x0000024a,0x0000024a}, | ||
1070 | {0x00000000,0x00000000,0x00001249,0x00009252, | ||
1071 | 0x00009492,0x00009493,0x00001252,0x0000024a}, | ||
1072 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
1073 | 0x00009492,0x00009493,0x00001252,0x00001252}, | ||
1074 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1075 | 0x00009492,0x00009493,0x00009292,0x00001252}, | ||
1076 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1077 | 0x0000a493,0x00009493,0x00009292,0x00009292}, | ||
1078 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1079 | 0x0000a493,0x0000a49b,0x00009493,0x00009292}, | ||
1080 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1081 | 0x0000a493,0x0000a49b,0x00009493,0x00009292}, | ||
1082 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1083 | 0x0000a493,0x000124db,0x0000a49b,0x00009493}, | ||
1084 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1085 | 0x0000a493,0x000124db,0x0000a49b,0x00009493}, | ||
1086 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1087 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
1088 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1089 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
1090 | {0x00000000,0x00000000,0x00009252,0x000126db, | ||
1091 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
1092 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1093 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1094 | } | ||
1095 | }, | ||
1096 | { /* version 11 */ | ||
1097 | { /* version 11, passes 0 */ | ||
1098 | {0x00000000,0x00000000,0x00000249,0x00000249, | ||
1099 | 0x00000249,0x00000249,0x00001252,0x00001252}, | ||
1100 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1101 | 0x00009252,0x00009292,0x00009292,0x00001252}, | ||
1102 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
1103 | 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, | ||
1104 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
1105 | 0x0000a493,0x0000a49b,0x000124db,0x00009493}, | ||
1106 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
1107 | 0x0000a493,0x000124db,0x000126dc,0x00009493}, | ||
1108 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1109 | 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, | ||
1110 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1111 | 0x0001249b,0x000126dc,0x000136e4,0x000124db}, | ||
1112 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1113 | 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, | ||
1114 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
1115 | 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, | ||
1116 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
1117 | 0x000126dc,0x0001b724,0x0001b725,0x000136e4}, | ||
1118 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
1119 | 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, | ||
1120 | {0x00000000,0x00000000,0x00009492,0x0000a49b, | ||
1121 | 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, | ||
1122 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1123 | 0x000136e4,0x0001b925,0x0001c96e,0x0001b925}, | ||
1124 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1125 | 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, | ||
1126 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
1127 | 0x0001c924,0x0002496d,0x00025bb6,0x00024b77}, | ||
1128 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1129 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1130 | }, | ||
1131 | { /* version 11, passes 1 */ | ||
1132 | {0x00000000,0x00000000,0x00001249,0x00000249, | ||
1133 | 0x00000249,0x00000249,0x0000024a,0x0000024a}, | ||
1134 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1135 | 0x0000124a,0x0000124a,0x0000024a,0x0000024a}, | ||
1136 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
1137 | 0x00009252,0x00009252,0x0000024a,0x0000024a}, | ||
1138 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
1139 | 0x00009492,0x0000a49b,0x00001252,0x00001252}, | ||
1140 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1141 | 0x0000a493,0x0000a49b,0x00001252,0x00001252}, | ||
1142 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1143 | 0x0000a493,0x0000a49b,0x00009292,0x00001252}, | ||
1144 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1145 | 0x0000a493,0x0000a49b,0x00009292,0x00009292}, | ||
1146 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1147 | 0x0000a493,0x0000a49b,0x00009493,0x00009292}, | ||
1148 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1149 | 0x0001249b,0x000124db,0x00009493,0x00009292}, | ||
1150 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1151 | 0x0001249b,0x000124db,0x00009493,0x00009493}, | ||
1152 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1153 | 0x000124db,0x000124db,0x0000a49b,0x00009493}, | ||
1154 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1155 | 0x000126dc,0x000126dc,0x0000a49b,0x00009493}, | ||
1156 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1157 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
1158 | {0x00000000,0x00000000,0x00009292,0x000124db, | ||
1159 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
1160 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
1161 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
1162 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1163 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1164 | } | ||
1165 | }, | ||
1166 | { /* version 12 */ | ||
1167 | { /* version 12, passes 0 */ | ||
1168 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1169 | 0x00009252,0x00009292,0x00009493,0x00009493}, | ||
1170 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
1171 | 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, | ||
1172 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
1173 | 0x0000a493,0x000124db,0x000124db,0x0000a49b}, | ||
1174 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1175 | 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, | ||
1176 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1177 | 0x0001249b,0x000126dc,0x000136e4,0x000124db}, | ||
1178 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1179 | 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, | ||
1180 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
1181 | 0x000126dc,0x0001b724,0x0001b725,0x000126dc}, | ||
1182 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
1183 | 0x000136e4,0x0001b724,0x0001b92d,0x000136e4}, | ||
1184 | {0x00000000,0x00000000,0x00009492,0x0000a49b, | ||
1185 | 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, | ||
1186 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1187 | 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, | ||
1188 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1189 | 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, | ||
1190 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1191 | 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, | ||
1192 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
1193 | 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d}, | ||
1194 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
1195 | 0x0001b724,0x0001c92d,0x00024b76,0x0002496e}, | ||
1196 | {0x00000000,0x00000000,0x00012492,0x000126db, | ||
1197 | 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf}, | ||
1198 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1199 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1200 | }, | ||
1201 | { /* version 12, passes 1 */ | ||
1202 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1203 | 0x0000124a,0x0000124a,0x00001252,0x00001252}, | ||
1204 | {0x00000000,0x00000000,0x00001249,0x00009292, | ||
1205 | 0x00009492,0x00009252,0x00001252,0x00001252}, | ||
1206 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1207 | 0x0000a493,0x00009292,0x00001252,0x00001252}, | ||
1208 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1209 | 0x0000a493,0x0000a49b,0x00009292,0x00009292}, | ||
1210 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1211 | 0x0000a493,0x0000a49b,0x00009292,0x00009292}, | ||
1212 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1213 | 0x0001249b,0x0000a49b,0x00009493,0x00009292}, | ||
1214 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1215 | 0x000124db,0x000124db,0x00009493,0x00009493}, | ||
1216 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1217 | 0x000124db,0x000124db,0x0000a49b,0x00009493}, | ||
1218 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1219 | 0x000126dc,0x000124db,0x0000a49b,0x00009493}, | ||
1220 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1221 | 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b}, | ||
1222 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1223 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
1224 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
1225 | 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, | ||
1226 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
1227 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
1228 | {0x00000000,0x00000000,0x00009492,0x000126db, | ||
1229 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
1230 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1231 | 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, | ||
1232 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1233 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1234 | } | ||
1235 | }, | ||
1236 | { /* version 13 */ | ||
1237 | { /* version 13, passes 0 */ | ||
1238 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1239 | 0x00009252,0x00009292,0x00009493,0x00009493}, | ||
1240 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
1241 | 0x0000a493,0x000124db,0x000126dc,0x00009493}, | ||
1242 | {0x00000000,0x00000000,0x00001249,0x0000a49b, | ||
1243 | 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, | ||
1244 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1245 | 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, | ||
1246 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1247 | 0x000126dc,0x000136e4,0x0001b725,0x000124db}, | ||
1248 | {0x00000000,0x00000000,0x00009292,0x0000a49b, | ||
1249 | 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, | ||
1250 | {0x00000000,0x00000000,0x00009292,0x000124db, | ||
1251 | 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, | ||
1252 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1253 | 0x000136e4,0x0001b724,0x0001c96e,0x000136e4}, | ||
1254 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1255 | 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, | ||
1256 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
1257 | 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, | ||
1258 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
1259 | 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925}, | ||
1260 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
1261 | 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, | ||
1262 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
1263 | 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, | ||
1264 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
1265 | 0x0001b924,0x0001c92d,0x00024b76,0x0002496e}, | ||
1266 | {0x00000000,0x00000000,0x00012492,0x000136db, | ||
1267 | 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf}, | ||
1268 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1269 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1270 | }, | ||
1271 | { /* version 13, passes 1 */ | ||
1272 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1273 | 0x0000124a,0x0000124a,0x00001252,0x00001252}, | ||
1274 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1275 | 0x00009492,0x00009292,0x00001252,0x00001252}, | ||
1276 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1277 | 0x0000a493,0x0000a49b,0x00001252,0x00001252}, | ||
1278 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1279 | 0x0000a493,0x0000a49b,0x00009292,0x00009292}, | ||
1280 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1281 | 0x0000a493,0x0000a49b,0x00009292,0x00009292}, | ||
1282 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1283 | 0x000126dc,0x0000a49b,0x00009493,0x00009292}, | ||
1284 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1285 | 0x000126dc,0x000124db,0x00009493,0x00009493}, | ||
1286 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1287 | 0x000136e4,0x000124db,0x0000a49b,0x00009493}, | ||
1288 | {0x00000000,0x00000000,0x0000924a,0x000136db, | ||
1289 | 0x0001b724,0x000124db,0x0000a49b,0x00009493}, | ||
1290 | {0x00000000,0x00000000,0x0000924a,0x000136db, | ||
1291 | 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b}, | ||
1292 | {0x00000000,0x00000000,0x00009292,0x000136db, | ||
1293 | 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, | ||
1294 | {0x00000000,0x00000000,0x00009492,0x000136db, | ||
1295 | 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, | ||
1296 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1297 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
1298 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1299 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
1300 | {0x00000000,0x00000000,0x00012492,0x0001b6db, | ||
1301 | 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, | ||
1302 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1303 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1304 | } | ||
1305 | }, | ||
1306 | { /* version 14 */ | ||
1307 | { /* version 14, passes 0 */ | ||
1308 | {0x00000000,0x00000000,0x00001249,0x0000924a, | ||
1309 | 0x00009292,0x00009493,0x00009493,0x00009493}, | ||
1310 | {0x00000000,0x00000000,0x00001249,0x0000a49b, | ||
1311 | 0x0000a493,0x000124db,0x000126dc,0x00009493}, | ||
1312 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1313 | 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, | ||
1314 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1315 | 0x000126dc,0x000136e4,0x0001b725,0x000124db}, | ||
1316 | {0x00000000,0x00000000,0x00009292,0x000124db, | ||
1317 | 0x000126dc,0x0001b724,0x0001b92d,0x000126dc}, | ||
1318 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1319 | 0x000136e4,0x0001b724,0x0001b92d,0x000126dc}, | ||
1320 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1321 | 0x000136e4,0x0001c92d,0x0001c96e,0x000136e4}, | ||
1322 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1323 | 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724}, | ||
1324 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
1325 | 0x0001b724,0x0001c92d,0x00024b76,0x0001b925}, | ||
1326 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
1327 | 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, | ||
1328 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
1329 | 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, | ||
1330 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1331 | 0x0001b724,0x0001c92d,0x00024b76,0x0002496e}, | ||
1332 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1333 | 0x0001b924,0x0002496d,0x00024b76,0x00024b77}, | ||
1334 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1335 | 0x0001b924,0x00024b6d,0x0002ddb6,0x00025bbf}, | ||
1336 | {0x00000000,0x00000000,0x00012492,0x0001b6db, | ||
1337 | 0x00024924,0x0002db6d,0x00036db6,0x0002efff}, | ||
1338 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1339 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1340 | }, | ||
1341 | { /* version 14, passes 1 */ | ||
1342 | {0x00000000,0x00000000,0x00001249,0x00001249, | ||
1343 | 0x0000124a,0x0000124a,0x00001252,0x00001252}, | ||
1344 | {0x00000000,0x00000000,0x0000924a,0x00009493, | ||
1345 | 0x0000a493,0x00009292,0x00001252,0x00001252}, | ||
1346 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1347 | 0x0000a493,0x0000a49b,0x00001252,0x00001252}, | ||
1348 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1349 | 0x0001249b,0x000136e4,0x00009292,0x00009292}, | ||
1350 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1351 | 0x0001249b,0x000136e4,0x00009292,0x00009292}, | ||
1352 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1353 | 0x000136e4,0x000136e4,0x00009493,0x00009292}, | ||
1354 | {0x00000000,0x00000000,0x00009492,0x000136db, | ||
1355 | 0x0001b724,0x000136e4,0x00009493,0x00009493}, | ||
1356 | {0x00000000,0x00000000,0x00009492,0x000136db, | ||
1357 | 0x0001b724,0x000136e4,0x0000a49b,0x00009493}, | ||
1358 | {0x00000000,0x00000000,0x00009492,0x000136db, | ||
1359 | 0x0001b724,0x000136e4,0x0000a49b,0x00009493}, | ||
1360 | {0x00000000,0x00000000,0x00009492,0x000136db, | ||
1361 | 0x0001b724,0x000136e4,0x0000a49b,0x0000a49b}, | ||
1362 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1363 | 0x0001b724,0x000136e4,0x000124db,0x0000a49b}, | ||
1364 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1365 | 0x0001b724,0x000136e4,0x000124db,0x0000a49b}, | ||
1366 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1367 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
1368 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1369 | 0x0001b724,0x000136e4,0x000126dc,0x000124db}, | ||
1370 | {0x00000000,0x00000000,0x00012492,0x0001b6db, | ||
1371 | 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, | ||
1372 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1373 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1374 | } | ||
1375 | }, | ||
1376 | { /* version 15 */ | ||
1377 | { /* version 15, passes 0 */ | ||
1378 | {0x00000000,0x00000000,0x00001249,0x00009493, | ||
1379 | 0x0000a493,0x0000a49b,0x000124db,0x000124db}, | ||
1380 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1381 | 0x0001249b,0x000126dc,0x000136e4,0x000124db}, | ||
1382 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1383 | 0x000126dc,0x0001b724,0x0001b725,0x000126dc}, | ||
1384 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1385 | 0x000136e4,0x0001b724,0x0001b92d,0x000126dc}, | ||
1386 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1387 | 0x000136e4,0x0001b925,0x0001c96e,0x000136e4}, | ||
1388 | {0x00000000,0x00000000,0x00009492,0x000124db, | ||
1389 | 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724}, | ||
1390 | {0x00000000,0x00000000,0x0000a492,0x000124db, | ||
1391 | 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724}, | ||
1392 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
1393 | 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925}, | ||
1394 | {0x00000000,0x00000000,0x0000a492,0x000126db, | ||
1395 | 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, | ||
1396 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1397 | 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, | ||
1398 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1399 | 0x0001b924,0x0002496d,0x00024b76,0x0002496e}, | ||
1400 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1401 | 0x0001c924,0x0002496d,0x00025bb6,0x00024b77}, | ||
1402 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1403 | 0x0001c924,0x00024b6d,0x00025bb6,0x00024b77}, | ||
1404 | {0x00000000,0x00000000,0x00012492,0x000136db, | ||
1405 | 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf}, | ||
1406 | {0x00000000,0x00000000,0x00012492,0x0001b6db, | ||
1407 | 0x00024924,0x0002db6d,0x00036db6,0x0002efff}, | ||
1408 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1409 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1410 | }, | ||
1411 | { /* version 15, passes 1 */ | ||
1412 | {0x00000000,0x00000000,0x0000924a,0x0000924a, | ||
1413 | 0x00009292,0x00009292,0x00009292,0x00009292}, | ||
1414 | {0x00000000,0x00000000,0x0000924a,0x0000a49b, | ||
1415 | 0x0000a493,0x000124db,0x00009292,0x00009292}, | ||
1416 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1417 | 0x000124db,0x0001b724,0x00009493,0x00009493}, | ||
1418 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1419 | 0x000126dc,0x0001b724,0x00009493,0x00009493}, | ||
1420 | {0x00000000,0x00000000,0x0000924a,0x000124db, | ||
1421 | 0x000136e4,0x0001b724,0x0000a49b,0x0000a49b}, | ||
1422 | {0x00000000,0x00000000,0x00009292,0x000136db, | ||
1423 | 0x0001b724,0x0001b724,0x0000a49b,0x0000a49b}, | ||
1424 | {0x00000000,0x00000000,0x00009492,0x000136db, | ||
1425 | 0x0001c924,0x0001b724,0x000124db,0x000124db}, | ||
1426 | {0x00000000,0x00000000,0x00009492,0x000136db, | ||
1427 | 0x0001c924,0x0001b724,0x000124db,0x000124db}, | ||
1428 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1429 | 0x0001c924,0x0001b724,0x000126dc,0x000126dc}, | ||
1430 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1431 | 0x0001c924,0x0001b925,0x000126dc,0x000126dc}, | ||
1432 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1433 | 0x0001c924,0x0001b925,0x000136e4,0x000136e4}, | ||
1434 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1435 | 0x0001c924,0x0001b925,0x000136e4,0x000136e4}, | ||
1436 | {0x00000000,0x00000000,0x0000a492,0x000136db, | ||
1437 | 0x0001c924,0x0001b925,0x0001b725,0x0001b724}, | ||
1438 | {0x00000000,0x00000000,0x00012492,0x000136db, | ||
1439 | 0x0001c924,0x0001b925,0x0001b725,0x0001b724}, | ||
1440 | {0x00000000,0x00000000,0x00012492,0x0001b6db, | ||
1441 | 0x00024924,0x0002496d,0x0001b92d,0x0001b925}, | ||
1442 | {0x00000000,0x00000000,0x00000000,0x00000000, | ||
1443 | 0x00000000,0x00000000,0x00000000,0x00000000} | ||
1444 | } | ||
1445 | } | ||
1446 | }; | ||
diff --git a/drivers/media/video/pwc/pwc-timon.h b/drivers/media/video/pwc/pwc-timon.h index a86b3782a081..eef9e2cd4320 100644 --- a/drivers/media/video/pwc/pwc-timon.h +++ b/drivers/media/video/pwc/pwc-timon.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* Linux driver for Philips webcam | 1 | /* Linux driver for Philips webcam |
2 | (C) 2004 Luc Saillard (luc@saillard.org) | 2 | (C) 2004-2006 Luc Saillard (luc@saillard.org) |
3 | 3 | ||
4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | 4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx |
5 | driver and thus may have bugs that are not present in the original version. | 5 | driver and thus may have bugs that are not present in the original version. |
@@ -42,7 +42,7 @@ | |||
42 | #ifndef PWC_TIMON_H | 42 | #ifndef PWC_TIMON_H |
43 | #define PWC_TIMON_H | 43 | #define PWC_TIMON_H |
44 | 44 | ||
45 | #include "pwc-ioctl.h" | 45 | #include <media/pwc-ioctl.h> |
46 | 46 | ||
47 | struct Timon_table_entry | 47 | struct Timon_table_entry |
48 | { | 48 | { |
@@ -52,8 +52,8 @@ struct Timon_table_entry | |||
52 | unsigned char mode[13]; /* precomputed mode settings for cam */ | 52 | unsigned char mode[13]; /* precomputed mode settings for cam */ |
53 | }; | 53 | }; |
54 | 54 | ||
55 | const extern struct Timon_table_entry Timon_table[PSZ_MAX][6][4]; | 55 | extern const struct Timon_table_entry Timon_table[PSZ_MAX][6][4]; |
56 | const extern unsigned int TimonRomTable [16][2][16][8]; | 56 | extern const unsigned int TimonRomTable [16][2][16][8]; |
57 | 57 | ||
58 | 58 | ||
59 | #endif | 59 | #endif |
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c index b37a89a163f9..5d82028ef942 100644 --- a/drivers/media/video/pwc/pwc-uncompress.c +++ b/drivers/media/video/pwc/pwc-uncompress.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Linux driver for Philips webcam | 1 | /* Linux driver for Philips webcam |
2 | Decompression frontend. | 2 | Decompression frontend. |
3 | (C) 1999-2003 Nemosoft Unv. | 3 | (C) 1999-2003 Nemosoft Unv. |
4 | (C) 2004 Luc Saillard (luc@saillard.org) | 4 | (C) 2004-2006 Luc Saillard (luc@saillard.org) |
5 | 5 | ||
6 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | 6 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx |
7 | driver and thus may have bugs that are not present in the original version. | 7 | driver and thus may have bugs that are not present in the original version. |
@@ -22,6 +22,8 @@ | |||
22 | You should have received a copy of the GNU General Public License | 22 | You should have received a copy of the GNU General Public License |
23 | along with this program; if not, write to the Free Software | 23 | along with this program; if not, write to the Free Software |
24 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 24 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
25 | |||
26 | vim: set ts=8: | ||
25 | */ | 27 | */ |
26 | 28 | ||
27 | #include <asm/current.h> | 29 | #include <asm/current.h> |
@@ -29,6 +31,8 @@ | |||
29 | 31 | ||
30 | #include "pwc.h" | 32 | #include "pwc.h" |
31 | #include "pwc-uncompress.h" | 33 | #include "pwc-uncompress.h" |
34 | #include "pwc-dec1.h" | ||
35 | #include "pwc-dec23.h" | ||
32 | 36 | ||
33 | int pwc_decompress(struct pwc_device *pdev) | 37 | int pwc_decompress(struct pwc_device *pdev) |
34 | { | 38 | { |
@@ -40,107 +44,95 @@ int pwc_decompress(struct pwc_device *pdev) | |||
40 | 44 | ||
41 | if (pdev == NULL) | 45 | if (pdev == NULL) |
42 | return -EFAULT; | 46 | return -EFAULT; |
43 | #if defined(__KERNEL__) && defined(PWC_MAGIC) | ||
44 | if (pdev->magic != PWC_MAGIC) { | ||
45 | Err("pwc_decompress(): magic failed.\n"); | ||
46 | return -EFAULT; | ||
47 | } | ||
48 | #endif | ||
49 | 47 | ||
50 | fbuf = pdev->read_frame; | 48 | fbuf = pdev->read_frame; |
51 | if (fbuf == NULL) | 49 | if (fbuf == NULL) |
52 | return -EFAULT; | 50 | return -EFAULT; |
53 | image = pdev->image_ptr[pdev->fill_image]; | 51 | image = pdev->image_data; |
54 | if (!image) | 52 | image += pdev->images[pdev->fill_image].offset; |
55 | return -EFAULT; | ||
56 | 53 | ||
57 | yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ | 54 | yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ |
58 | 55 | ||
59 | /* Raw format; that's easy... */ | 56 | /* Raw format; that's easy... */ |
60 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | 57 | if (pdev->vpalette == VIDEO_PALETTE_RAW) |
61 | { | 58 | { |
62 | memcpy(image, yuv, pdev->frame_size); | 59 | struct pwc_raw_frame *raw_frame = image; |
60 | raw_frame->type = cpu_to_le16(pdev->type); | ||
61 | raw_frame->vbandlength = cpu_to_le16(pdev->vbandlength); | ||
62 | /* cmd_buf is always 4 bytes, but sometimes, only the | ||
63 | * first 3 bytes is filled (Nala case). We can | ||
64 | * determine this using the type of the webcam */ | ||
65 | memcpy(raw_frame->cmd, pdev->cmd_buf, 4); | ||
66 | memcpy(raw_frame+1, yuv, pdev->frame_size); | ||
63 | return 0; | 67 | return 0; |
64 | } | 68 | } |
65 | 69 | ||
66 | if (pdev->vbandlength == 0) { | 70 | if (pdev->vbandlength == 0) { |
67 | /* Uncompressed mode. We copy the data into the output buffer, | 71 | /* Uncompressed mode. |
68 | using the viewport size (which may be larger than the image | 72 | * We copy the data into the output buffer, using the viewport |
69 | size). Unfortunately we have to do a bit of byte stuffing | 73 | * size (which may be larger than the image size). |
70 | to get the desired output format/size. | 74 | * Unfortunately we have to do a bit of byte stuffing to get |
75 | * the desired output format/size. | ||
76 | * | ||
77 | * We do some byte shuffling here to go from the | ||
78 | * native format to YUV420P. | ||
71 | */ | 79 | */ |
72 | /* | 80 | src = (u16 *)yuv; |
73 | * We do some byte shuffling here to go from the | 81 | n = pdev->view.x * pdev->view.y; |
74 | * native format to YUV420P. | 82 | |
75 | */ | 83 | /* offset in Y plane */ |
76 | src = (u16 *)yuv; | 84 | stride = pdev->view.x * pdev->offset.y + pdev->offset.x; |
77 | n = pdev->view.x * pdev->view.y; | 85 | dsty = (u16 *)(image + stride); |
78 | 86 | ||
79 | /* offset in Y plane */ | 87 | /* offsets in U/V planes */ |
80 | stride = pdev->view.x * pdev->offset.y + pdev->offset.x; | 88 | stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; |
81 | dsty = (u16 *)(image + stride); | 89 | dstu = (u16 *)(image + n + stride); |
82 | 90 | dstv = (u16 *)(image + n + n / 4 + stride); | |
83 | /* offsets in U/V planes */ | 91 | |
84 | stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; | 92 | /* increment after each line */ |
85 | dstu = (u16 *)(image + n + stride); | 93 | stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ |
86 | dstv = (u16 *)(image + n + n / 4 + stride); | 94 | |
87 | 95 | for (line = 0; line < pdev->image.y; line++) { | |
88 | /* increment after each line */ | 96 | for (col = 0; col < pdev->image.x; col += 4) { |
89 | stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ | 97 | *dsty++ = *src++; |
90 | 98 | *dsty++ = *src++; | |
91 | for (line = 0; line < pdev->image.y; line++) { | ||
92 | for (col = 0; col < pdev->image.x; col += 4) { | ||
93 | *dsty++ = *src++; | ||
94 | *dsty++ = *src++; | ||
95 | if (line & 1) | ||
96 | *dstv++ = *src++; | ||
97 | else | ||
98 | *dstu++ = *src++; | ||
99 | } | ||
100 | dsty += stride; | ||
101 | if (line & 1) | 99 | if (line & 1) |
102 | dstv += (stride >> 1); | 100 | *dstv++ = *src++; |
103 | else | 101 | else |
104 | dstu += (stride >> 1); | 102 | *dstu++ = *src++; |
105 | } | 103 | } |
104 | dsty += stride; | ||
105 | if (line & 1) | ||
106 | dstv += (stride >> 1); | ||
107 | else | ||
108 | dstu += (stride >> 1); | ||
109 | } | ||
110 | |||
111 | return 0; | ||
106 | } | 112 | } |
107 | else { | 113 | |
108 | /* Compressed; the decompressor routines will write the data | 114 | /* |
109 | in planar format immediately. | 115 | * Compressed; |
110 | */ | 116 | * the decompressor routines will write the data in planar format |
111 | int flags; | 117 | * immediately. |
112 | 118 | */ | |
113 | flags = PWCX_FLAG_PLANAR; | 119 | if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) { |
114 | if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) | 120 | PWC_ERROR("Mode Bayer is not supported for now\n"); |
115 | { | 121 | /* flags |= PWCX_FLAG_BAYER; */ |
116 | printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n"); | 122 | return -ENXIO; /* No such device or address: missing decompressor */ |
117 | flags |= PWCX_FLAG_BAYER; | 123 | } |
118 | return -ENXIO; /* No such device or address: missing decompressor */ | 124 | |
119 | } | 125 | if (DEVICE_USE_CODEC1(pdev->type)) { |
120 | 126 | ||
121 | #if 0 | 127 | /* TODO & FIXME */ |
122 | switch (pdev->type) | 128 | PWC_ERROR("This chipset is not supported for now\n"); |
123 | { | 129 | return -ENXIO; /* No such device or address: missing decompressor */ |
124 | case 675: | 130 | |
125 | case 680: | 131 | } else { |
126 | case 690: | 132 | pwc_dec23_decompress(pdev, yuv, image, PWCX_FLAG_PLANAR); |
127 | case 720: | ||
128 | case 730: | ||
129 | case 740: | ||
130 | case 750: | ||
131 | pwc_dec23_decompress(&pdev->image, &pdev->view, | ||
132 | &pdev->offset, yuv, image, flags, | ||
133 | pdev->decompress_data, pdev->vbandlength); | ||
134 | break; | ||
135 | case 645: | ||
136 | case 646: | ||
137 | /* TODO & FIXME */ | ||
138 | return -ENXIO; /* Missing decompressor */ | ||
139 | break; | ||
140 | } | ||
141 | #endif | ||
142 | } | 133 | } |
143 | return 0; | 134 | return 0; |
144 | } | 135 | } |
145 | 136 | ||
146 | 137 | ||
138 | /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ | ||
diff --git a/drivers/media/video/pwc/pwc-uncompress.h b/drivers/media/video/pwc/pwc-uncompress.h index f75e1b6cbe19..041227f65246 100644 --- a/drivers/media/video/pwc/pwc-uncompress.h +++ b/drivers/media/video/pwc/pwc-uncompress.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* (C) 1999-2003 Nemosoft Unv. | 1 | /* (C) 1999-2003 Nemosoft Unv. |
2 | (C) 2004 Luc Saillard (luc@saillard.org) | 2 | (C) 2004-2006 Luc Saillard (luc@saillard.org) |
3 | 3 | ||
4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | 4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx |
5 | driver and thus may have bugs that are not present in the original version. | 5 | driver and thus may have bugs that are not present in the original version. |
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #include <linux/config.h> | 33 | #include <linux/config.h> |
34 | 34 | ||
35 | #include "pwc-ioctl.h" | 35 | #include <media/pwc-ioctl.h> |
36 | 36 | ||
37 | /* from pwc-dec.h */ | 37 | /* from pwc-dec.h */ |
38 | #define PWCX_FLAG_PLANAR 0x0001 | 38 | #define PWCX_FLAG_PLANAR 0x0001 |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c new file mode 100644 index 000000000000..b7eb3ce3b968 --- /dev/null +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -0,0 +1,1202 @@ | |||
1 | /* Linux driver for Philips webcam | ||
2 | USB and Video4Linux interface part. | ||
3 | (C) 1999-2004 Nemosoft Unv. | ||
4 | (C) 2004-2006 Luc Saillard (luc@saillard.org) | ||
5 | |||
6 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | ||
7 | driver and thus may have bugs that are not present in the original version. | ||
8 | Please send bug reports and support requests to <luc@saillard.org>. | ||
9 | The decompression routines have been implemented by reverse-engineering the | ||
10 | Nemosoft binary pwcx module. Caveat emptor. | ||
11 | |||
12 | This program is free software; you can redistribute it and/or modify | ||
13 | it under the terms of the GNU General Public License as published by | ||
14 | the Free Software Foundation; either version 2 of the License, or | ||
15 | (at your option) any later version. | ||
16 | |||
17 | This program is distributed in the hope that it will be useful, | ||
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | GNU General Public License for more details. | ||
21 | |||
22 | You should have received a copy of the GNU General Public License | ||
23 | along with this program; if not, write to the Free Software | ||
24 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | |||
26 | */ | ||
27 | |||
28 | #include <linux/errno.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/poll.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/vmalloc.h> | ||
35 | #include <asm/io.h> | ||
36 | |||
37 | #include "pwc.h" | ||
38 | |||
39 | static struct v4l2_queryctrl pwc_controls[] = { | ||
40 | { | ||
41 | .id = V4L2_CID_BRIGHTNESS, | ||
42 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
43 | .name = "Brightness", | ||
44 | .minimum = 0, | ||
45 | .maximum = 128, | ||
46 | .step = 1, | ||
47 | .default_value = 64, | ||
48 | }, | ||
49 | { | ||
50 | .id = V4L2_CID_CONTRAST, | ||
51 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
52 | .name = "Contrast", | ||
53 | .minimum = 0, | ||
54 | .maximum = 64, | ||
55 | .step = 1, | ||
56 | .default_value = 0, | ||
57 | }, | ||
58 | { | ||
59 | .id = V4L2_CID_SATURATION, | ||
60 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
61 | .name = "Saturation", | ||
62 | .minimum = -100, | ||
63 | .maximum = 100, | ||
64 | .step = 1, | ||
65 | .default_value = 0, | ||
66 | }, | ||
67 | { | ||
68 | .id = V4L2_CID_GAMMA, | ||
69 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
70 | .name = "Gamma", | ||
71 | .minimum = 0, | ||
72 | .maximum = 32, | ||
73 | .step = 1, | ||
74 | .default_value = 0, | ||
75 | }, | ||
76 | { | ||
77 | .id = V4L2_CID_RED_BALANCE, | ||
78 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
79 | .name = "Red Gain", | ||
80 | .minimum = 0, | ||
81 | .maximum = 256, | ||
82 | .step = 1, | ||
83 | .default_value = 0, | ||
84 | }, | ||
85 | { | ||
86 | .id = V4L2_CID_BLUE_BALANCE, | ||
87 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
88 | .name = "Blue Gain", | ||
89 | .minimum = 0, | ||
90 | .maximum = 256, | ||
91 | .step = 1, | ||
92 | .default_value = 0, | ||
93 | }, | ||
94 | { | ||
95 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
96 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
97 | .name = "Auto White Balance", | ||
98 | .minimum = 0, | ||
99 | .maximum = 1, | ||
100 | .step = 1, | ||
101 | .default_value = 0, | ||
102 | }, | ||
103 | { | ||
104 | .id = V4L2_CID_EXPOSURE, | ||
105 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
106 | .name = "Shutter Speed (Exposure)", | ||
107 | .minimum = 0, | ||
108 | .maximum = 256, | ||
109 | .step = 1, | ||
110 | .default_value = 200, | ||
111 | }, | ||
112 | { | ||
113 | .id = V4L2_CID_AUTOGAIN, | ||
114 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
115 | .name = "Auto Gain Enabled", | ||
116 | .minimum = 0, | ||
117 | .maximum = 1, | ||
118 | .step = 1, | ||
119 | .default_value = 1, | ||
120 | }, | ||
121 | { | ||
122 | .id = V4L2_CID_GAIN, | ||
123 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
124 | .name = "Gain Level", | ||
125 | .minimum = 0, | ||
126 | .maximum = 256, | ||
127 | .step = 1, | ||
128 | .default_value = 0, | ||
129 | }, | ||
130 | { | ||
131 | .id = V4L2_CID_PRIVATE_SAVE_USER, | ||
132 | .type = V4L2_CTRL_TYPE_BUTTON, | ||
133 | .name = "Save User Settings", | ||
134 | .minimum = 0, | ||
135 | .maximum = 0, | ||
136 | .step = 0, | ||
137 | .default_value = 0, | ||
138 | }, | ||
139 | { | ||
140 | .id = V4L2_CID_PRIVATE_RESTORE_USER, | ||
141 | .type = V4L2_CTRL_TYPE_BUTTON, | ||
142 | .name = "Restore User Settings", | ||
143 | .minimum = 0, | ||
144 | .maximum = 0, | ||
145 | .step = 0, | ||
146 | .default_value = 0, | ||
147 | }, | ||
148 | { | ||
149 | .id = V4L2_CID_PRIVATE_RESTORE_FACTORY, | ||
150 | .type = V4L2_CTRL_TYPE_BUTTON, | ||
151 | .name = "Restore Factory Settings", | ||
152 | .minimum = 0, | ||
153 | .maximum = 0, | ||
154 | .step = 0, | ||
155 | .default_value = 0, | ||
156 | }, | ||
157 | { | ||
158 | .id = V4L2_CID_PRIVATE_COLOUR_MODE, | ||
159 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
160 | .name = "Colour mode", | ||
161 | .minimum = 0, | ||
162 | .maximum = 1, | ||
163 | .step = 1, | ||
164 | .default_value = 0, | ||
165 | }, | ||
166 | { | ||
167 | .id = V4L2_CID_PRIVATE_AUTOCONTOUR, | ||
168 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
169 | .name = "Auto contour", | ||
170 | .minimum = 0, | ||
171 | .maximum = 1, | ||
172 | .step = 1, | ||
173 | .default_value = 0, | ||
174 | }, | ||
175 | { | ||
176 | .id = V4L2_CID_PRIVATE_CONTOUR, | ||
177 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
178 | .name = "Contour", | ||
179 | .minimum = 0, | ||
180 | .maximum = 63, | ||
181 | .step = 1, | ||
182 | .default_value = 0, | ||
183 | }, | ||
184 | { | ||
185 | .id = V4L2_CID_PRIVATE_BACKLIGHT, | ||
186 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
187 | .name = "Backlight compensation", | ||
188 | .minimum = 0, | ||
189 | .maximum = 1, | ||
190 | .step = 1, | ||
191 | .default_value = 0, | ||
192 | }, | ||
193 | { | ||
194 | .id = V4L2_CID_PRIVATE_FLICKERLESS, | ||
195 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
196 | .name = "Flickerless", | ||
197 | .minimum = 0, | ||
198 | .maximum = 1, | ||
199 | .step = 1, | ||
200 | .default_value = 0, | ||
201 | }, | ||
202 | { | ||
203 | .id = V4L2_CID_PRIVATE_NOISE_REDUCTION, | ||
204 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
205 | .name = "Noise reduction", | ||
206 | .minimum = 0, | ||
207 | .maximum = 3, | ||
208 | .step = 1, | ||
209 | .default_value = 0, | ||
210 | }, | ||
211 | }; | ||
212 | |||
213 | |||
214 | static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f) | ||
215 | { | ||
216 | memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); | ||
217 | f->fmt.pix.width = pdev->view.x; | ||
218 | f->fmt.pix.height = pdev->view.y; | ||
219 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
220 | if (pdev->vpalette == VIDEO_PALETTE_YUV420P) { | ||
221 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; | ||
222 | f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2; | ||
223 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
224 | } else { | ||
225 | /* vbandlength contains 4 lines ... */ | ||
226 | f->fmt.pix.bytesperline = pdev->vbandlength/4; | ||
227 | f->fmt.pix.sizeimage = pdev->frame_size + sizeof(struct pwc_raw_frame); | ||
228 | if (DEVICE_USE_CODEC1(pdev->type)) | ||
229 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC1; | ||
230 | else | ||
231 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC2; | ||
232 | } | ||
233 | PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() " | ||
234 | "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n", | ||
235 | f->fmt.pix.width, | ||
236 | f->fmt.pix.height, | ||
237 | f->fmt.pix.bytesperline, | ||
238 | f->fmt.pix.sizeimage, | ||
239 | (f->fmt.pix.pixelformat)&255, | ||
240 | (f->fmt.pix.pixelformat>>8)&255, | ||
241 | (f->fmt.pix.pixelformat>>16)&255, | ||
242 | (f->fmt.pix.pixelformat>>24)&255); | ||
243 | } | ||
244 | |||
245 | /* ioctl(VIDIOC_TRY_FMT) */ | ||
246 | static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f) | ||
247 | { | ||
248 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
249 | PWC_DEBUG_IOCTL("Bad video type must be V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | |||
253 | switch (f->fmt.pix.pixelformat) { | ||
254 | case V4L2_PIX_FMT_YUV420: | ||
255 | break; | ||
256 | case V4L2_PIX_FMT_PWC1: | ||
257 | if (DEVICE_USE_CODEC23(pdev->type)) { | ||
258 | PWC_DEBUG_IOCTL("codec1 is only supported for old pwc webcam\n"); | ||
259 | return -EINVAL; | ||
260 | } | ||
261 | break; | ||
262 | case V4L2_PIX_FMT_PWC2: | ||
263 | if (DEVICE_USE_CODEC1(pdev->type)) { | ||
264 | PWC_DEBUG_IOCTL("codec23 is only supported for new pwc webcam\n"); | ||
265 | return -EINVAL; | ||
266 | } | ||
267 | break; | ||
268 | default: | ||
269 | PWC_DEBUG_IOCTL("Unsupported pixel format\n"); | ||
270 | return -EINVAL; | ||
271 | |||
272 | } | ||
273 | |||
274 | if (f->fmt.pix.width > pdev->view_max.x) | ||
275 | f->fmt.pix.width = pdev->view_max.x; | ||
276 | else if (f->fmt.pix.width < pdev->view_min.x) | ||
277 | f->fmt.pix.width = pdev->view_min.x; | ||
278 | |||
279 | if (f->fmt.pix.height > pdev->view_max.y) | ||
280 | f->fmt.pix.height = pdev->view_max.y; | ||
281 | else if (f->fmt.pix.height < pdev->view_min.y) | ||
282 | f->fmt.pix.height = pdev->view_min.y; | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | /* ioctl(VIDIOC_SET_FMT) */ | ||
288 | static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) | ||
289 | { | ||
290 | int ret, fps, snapshot, compression, pixelformat; | ||
291 | |||
292 | ret = pwc_vidioc_try_fmt(pdev, f); | ||
293 | if (ret<0) | ||
294 | return ret; | ||
295 | |||
296 | pixelformat = f->fmt.pix.pixelformat; | ||
297 | compression = pdev->vcompression; | ||
298 | snapshot = 0; | ||
299 | fps = pdev->vframes; | ||
300 | if (f->fmt.pix.priv) { | ||
301 | compression = (f->fmt.pix.priv & PWC_QLT_MASK) >> PWC_QLT_SHIFT; | ||
302 | snapshot = !!(f->fmt.pix.priv & PWC_FPS_SNAPSHOT); | ||
303 | fps = (f->fmt.pix.priv & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT; | ||
304 | if (fps == 0) | ||
305 | fps = pdev->vframes; | ||
306 | } | ||
307 | |||
308 | if (pixelformat == V4L2_PIX_FMT_YUV420) | ||
309 | pdev->vpalette = VIDEO_PALETTE_YUV420P; | ||
310 | else | ||
311 | pdev->vpalette = VIDEO_PALETTE_RAW; | ||
312 | |||
313 | PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d " | ||
314 | "compression=%d snapshot=%d format=%c%c%c%c\n", | ||
315 | f->fmt.pix.width, f->fmt.pix.height, fps, | ||
316 | compression, snapshot, | ||
317 | (pixelformat)&255, | ||
318 | (pixelformat>>8)&255, | ||
319 | (pixelformat>>16)&255, | ||
320 | (pixelformat>>24)&255); | ||
321 | |||
322 | ret = pwc_try_video_mode(pdev, | ||
323 | f->fmt.pix.width, | ||
324 | f->fmt.pix.height, | ||
325 | fps, | ||
326 | compression, | ||
327 | snapshot); | ||
328 | |||
329 | PWC_DEBUG_IOCTL("pwc_try_video_mode(), return=%d\n", ret); | ||
330 | |||
331 | if (ret) | ||
332 | return ret; | ||
333 | |||
334 | pwc_vidioc_fill_fmt(pdev, f); | ||
335 | |||
336 | return 0; | ||
337 | |||
338 | } | ||
339 | |||
340 | int pwc_video_do_ioctl(struct inode *inode, struct file *file, | ||
341 | unsigned int cmd, void *arg) | ||
342 | { | ||
343 | struct video_device *vdev = video_devdata(file); | ||
344 | struct pwc_device *pdev; | ||
345 | DECLARE_WAITQUEUE(wait, current); | ||
346 | |||
347 | if (vdev == NULL) | ||
348 | return -EFAULT; | ||
349 | pdev = vdev->priv; | ||
350 | if (pdev == NULL) | ||
351 | return -EFAULT; | ||
352 | |||
353 | #if CONFIG_PWC_DEBUG | ||
354 | if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) | ||
355 | v4l_printk_ioctl(cmd); | ||
356 | #endif | ||
357 | |||
358 | |||
359 | switch (cmd) { | ||
360 | /* Query cabapilities */ | ||
361 | case VIDIOCGCAP: | ||
362 | { | ||
363 | struct video_capability *caps = arg; | ||
364 | |||
365 | strcpy(caps->name, vdev->name); | ||
366 | caps->type = VID_TYPE_CAPTURE; | ||
367 | caps->channels = 1; | ||
368 | caps->audios = 1; | ||
369 | caps->minwidth = pdev->view_min.x; | ||
370 | caps->minheight = pdev->view_min.y; | ||
371 | caps->maxwidth = pdev->view_max.x; | ||
372 | caps->maxheight = pdev->view_max.y; | ||
373 | break; | ||
374 | } | ||
375 | |||
376 | /* Channel functions (simulate 1 channel) */ | ||
377 | case VIDIOCGCHAN: | ||
378 | { | ||
379 | struct video_channel *v = arg; | ||
380 | |||
381 | if (v->channel != 0) | ||
382 | return -EINVAL; | ||
383 | v->flags = 0; | ||
384 | v->tuners = 0; | ||
385 | v->type = VIDEO_TYPE_CAMERA; | ||
386 | strcpy(v->name, "Webcam"); | ||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | case VIDIOCSCHAN: | ||
391 | { | ||
392 | /* The spec says the argument is an integer, but | ||
393 | the bttv driver uses a video_channel arg, which | ||
394 | makes sense becasue it also has the norm flag. | ||
395 | */ | ||
396 | struct video_channel *v = arg; | ||
397 | if (v->channel != 0) | ||
398 | return -EINVAL; | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | |||
403 | /* Picture functions; contrast etc. */ | ||
404 | case VIDIOCGPICT: | ||
405 | { | ||
406 | struct video_picture *p = arg; | ||
407 | int val; | ||
408 | |||
409 | val = pwc_get_brightness(pdev); | ||
410 | if (val >= 0) | ||
411 | p->brightness = (val<<9); | ||
412 | else | ||
413 | p->brightness = 0xffff; | ||
414 | val = pwc_get_contrast(pdev); | ||
415 | if (val >= 0) | ||
416 | p->contrast = (val<<10); | ||
417 | else | ||
418 | p->contrast = 0xffff; | ||
419 | /* Gamma, Whiteness, what's the difference? :) */ | ||
420 | val = pwc_get_gamma(pdev); | ||
421 | if (val >= 0) | ||
422 | p->whiteness = (val<<11); | ||
423 | else | ||
424 | p->whiteness = 0xffff; | ||
425 | if (pwc_get_saturation(pdev, &val)<0) | ||
426 | p->colour = 0xffff; | ||
427 | else | ||
428 | p->colour = 32768 + val * 327; | ||
429 | p->depth = 24; | ||
430 | p->palette = pdev->vpalette; | ||
431 | p->hue = 0xFFFF; /* N/A */ | ||
432 | break; | ||
433 | } | ||
434 | |||
435 | case VIDIOCSPICT: | ||
436 | { | ||
437 | struct video_picture *p = arg; | ||
438 | /* | ||
439 | * FIXME: Suppose we are mid read | ||
440 | ANSWER: No problem: the firmware of the camera | ||
441 | can handle brightness/contrast/etc | ||
442 | changes at _any_ time, and the palette | ||
443 | is used exactly once in the uncompress | ||
444 | routine. | ||
445 | */ | ||
446 | pwc_set_brightness(pdev, p->brightness); | ||
447 | pwc_set_contrast(pdev, p->contrast); | ||
448 | pwc_set_gamma(pdev, p->whiteness); | ||
449 | pwc_set_saturation(pdev, (p->colour-32768)/327); | ||
450 | if (p->palette && p->palette != pdev->vpalette) { | ||
451 | switch (p->palette) { | ||
452 | case VIDEO_PALETTE_YUV420P: | ||
453 | case VIDEO_PALETTE_RAW: | ||
454 | pdev->vpalette = p->palette; | ||
455 | return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | ||
456 | break; | ||
457 | default: | ||
458 | return -EINVAL; | ||
459 | break; | ||
460 | } | ||
461 | } | ||
462 | break; | ||
463 | } | ||
464 | |||
465 | /* Window/size parameters */ | ||
466 | case VIDIOCGWIN: | ||
467 | { | ||
468 | struct video_window *vw = arg; | ||
469 | |||
470 | vw->x = 0; | ||
471 | vw->y = 0; | ||
472 | vw->width = pdev->view.x; | ||
473 | vw->height = pdev->view.y; | ||
474 | vw->chromakey = 0; | ||
475 | vw->flags = (pdev->vframes << PWC_FPS_SHIFT) | | ||
476 | (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0); | ||
477 | break; | ||
478 | } | ||
479 | |||
480 | case VIDIOCSWIN: | ||
481 | { | ||
482 | struct video_window *vw = arg; | ||
483 | int fps, snapshot, ret; | ||
484 | |||
485 | fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT; | ||
486 | snapshot = vw->flags & PWC_FPS_SNAPSHOT; | ||
487 | if (fps == 0) | ||
488 | fps = pdev->vframes; | ||
489 | if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot) | ||
490 | return 0; | ||
491 | ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot); | ||
492 | if (ret) | ||
493 | return ret; | ||
494 | break; | ||
495 | } | ||
496 | |||
497 | /* We don't have overlay support (yet) */ | ||
498 | case VIDIOCGFBUF: | ||
499 | { | ||
500 | struct video_buffer *vb = arg; | ||
501 | |||
502 | memset(vb,0,sizeof(*vb)); | ||
503 | break; | ||
504 | } | ||
505 | |||
506 | /* mmap() functions */ | ||
507 | case VIDIOCGMBUF: | ||
508 | { | ||
509 | /* Tell the user program how much memory is needed for a mmap() */ | ||
510 | struct video_mbuf *vm = arg; | ||
511 | int i; | ||
512 | |||
513 | memset(vm, 0, sizeof(*vm)); | ||
514 | vm->size = pwc_mbufs * pdev->len_per_image; | ||
515 | vm->frames = pwc_mbufs; /* double buffering should be enough for most applications */ | ||
516 | for (i = 0; i < pwc_mbufs; i++) | ||
517 | vm->offsets[i] = i * pdev->len_per_image; | ||
518 | break; | ||
519 | } | ||
520 | |||
521 | case VIDIOCMCAPTURE: | ||
522 | { | ||
523 | /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */ | ||
524 | struct video_mmap *vm = arg; | ||
525 | |||
526 | PWC_DEBUG_READ("VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format); | ||
527 | if (vm->frame < 0 || vm->frame >= pwc_mbufs) | ||
528 | return -EINVAL; | ||
529 | |||
530 | /* xawtv is nasty. It probes the available palettes | ||
531 | by setting a very small image size and trying | ||
532 | various palettes... The driver doesn't support | ||
533 | such small images, so I'm working around it. | ||
534 | */ | ||
535 | if (vm->format) | ||
536 | { | ||
537 | switch (vm->format) | ||
538 | { | ||
539 | case VIDEO_PALETTE_YUV420P: | ||
540 | case VIDEO_PALETTE_RAW: | ||
541 | break; | ||
542 | default: | ||
543 | return -EINVAL; | ||
544 | break; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | if ((vm->width != pdev->view.x || vm->height != pdev->view.y) && | ||
549 | (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) { | ||
550 | int ret; | ||
551 | |||
552 | PWC_DEBUG_OPEN("VIDIOCMCAPTURE: changing size to please xawtv :-(.\n"); | ||
553 | ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | ||
554 | if (ret) | ||
555 | return ret; | ||
556 | } /* ... size mismatch */ | ||
557 | |||
558 | /* FIXME: should we lock here? */ | ||
559 | if (pdev->image_used[vm->frame]) | ||
560 | return -EBUSY; /* buffer wasn't available. Bummer */ | ||
561 | pdev->image_used[vm->frame] = 1; | ||
562 | |||
563 | /* Okay, we're done here. In the SYNC call we wait until a | ||
564 | frame comes available, then expand image into the given | ||
565 | buffer. | ||
566 | In contrast to the CPiA cam the Philips cams deliver a | ||
567 | constant stream, almost like a grabber card. Also, | ||
568 | we have separate buffers for the rawdata and the image, | ||
569 | meaning we can nearly always expand into the requested buffer. | ||
570 | */ | ||
571 | PWC_DEBUG_READ("VIDIOCMCAPTURE done.\n"); | ||
572 | break; | ||
573 | } | ||
574 | |||
575 | case VIDIOCSYNC: | ||
576 | { | ||
577 | /* The doc says: "Whenever a buffer is used it should | ||
578 | call VIDIOCSYNC to free this frame up and continue." | ||
579 | |||
580 | The only odd thing about this whole procedure is | ||
581 | that MCAPTURE flags the buffer as "in use", and | ||
582 | SYNC immediately unmarks it, while it isn't | ||
583 | after SYNC that you know that the buffer actually | ||
584 | got filled! So you better not start a CAPTURE in | ||
585 | the same frame immediately (use double buffering). | ||
586 | This is not a problem for this cam, since it has | ||
587 | extra intermediate buffers, but a hardware | ||
588 | grabber card will then overwrite the buffer | ||
589 | you're working on. | ||
590 | */ | ||
591 | int *mbuf = arg; | ||
592 | int ret; | ||
593 | |||
594 | PWC_DEBUG_READ("VIDIOCSYNC called (%d).\n", *mbuf); | ||
595 | |||
596 | /* bounds check */ | ||
597 | if (*mbuf < 0 || *mbuf >= pwc_mbufs) | ||
598 | return -EINVAL; | ||
599 | /* check if this buffer was requested anyway */ | ||
600 | if (pdev->image_used[*mbuf] == 0) | ||
601 | return -EINVAL; | ||
602 | |||
603 | /* Add ourselves to the frame wait-queue. | ||
604 | |||
605 | FIXME: needs auditing for safety. | ||
606 | QUESTION: In what respect? I think that using the | ||
607 | frameq is safe now. | ||
608 | */ | ||
609 | add_wait_queue(&pdev->frameq, &wait); | ||
610 | while (pdev->full_frames == NULL) { | ||
611 | /* Check for unplugged/etc. here */ | ||
612 | if (pdev->error_status) { | ||
613 | remove_wait_queue(&pdev->frameq, &wait); | ||
614 | set_current_state(TASK_RUNNING); | ||
615 | return -pdev->error_status; | ||
616 | } | ||
617 | |||
618 | if (signal_pending(current)) { | ||
619 | remove_wait_queue(&pdev->frameq, &wait); | ||
620 | set_current_state(TASK_RUNNING); | ||
621 | return -ERESTARTSYS; | ||
622 | } | ||
623 | schedule(); | ||
624 | set_current_state(TASK_INTERRUPTIBLE); | ||
625 | } | ||
626 | remove_wait_queue(&pdev->frameq, &wait); | ||
627 | set_current_state(TASK_RUNNING); | ||
628 | |||
629 | /* The frame is ready. Expand in the image buffer | ||
630 | requested by the user. I don't care if you | ||
631 | mmap() 5 buffers and request data in this order: | ||
632 | buffer 4 2 3 0 1 2 3 0 4 3 1 . . . | ||
633 | Grabber hardware may not be so forgiving. | ||
634 | */ | ||
635 | PWC_DEBUG_READ("VIDIOCSYNC: frame ready.\n"); | ||
636 | pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */ | ||
637 | /* Decompress, etc */ | ||
638 | ret = pwc_handle_frame(pdev); | ||
639 | pdev->image_used[*mbuf] = 0; | ||
640 | if (ret) | ||
641 | return -EFAULT; | ||
642 | break; | ||
643 | } | ||
644 | |||
645 | case VIDIOCGAUDIO: | ||
646 | { | ||
647 | struct video_audio *v = arg; | ||
648 | |||
649 | strcpy(v->name, "Microphone"); | ||
650 | v->audio = -1; /* unknown audio minor */ | ||
651 | v->flags = 0; | ||
652 | v->mode = VIDEO_SOUND_MONO; | ||
653 | v->volume = 0; | ||
654 | v->bass = 0; | ||
655 | v->treble = 0; | ||
656 | v->balance = 0x8000; | ||
657 | v->step = 1; | ||
658 | break; | ||
659 | } | ||
660 | |||
661 | case VIDIOCSAUDIO: | ||
662 | { | ||
663 | /* Dummy: nothing can be set */ | ||
664 | break; | ||
665 | } | ||
666 | |||
667 | case VIDIOCGUNIT: | ||
668 | { | ||
669 | struct video_unit *vu = arg; | ||
670 | |||
671 | vu->video = pdev->vdev->minor & 0x3F; | ||
672 | vu->audio = -1; /* not known yet */ | ||
673 | vu->vbi = -1; | ||
674 | vu->radio = -1; | ||
675 | vu->teletext = -1; | ||
676 | break; | ||
677 | } | ||
678 | |||
679 | /* V4L2 Layer */ | ||
680 | case VIDIOC_QUERYCAP: | ||
681 | { | ||
682 | struct v4l2_capability *cap = arg; | ||
683 | |||
684 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCAP) This application "\ | ||
685 | "try to use the v4l2 layer\n"); | ||
686 | strcpy(cap->driver,PWC_NAME); | ||
687 | strlcpy(cap->card, vdev->name, sizeof(cap->card)); | ||
688 | usb_make_path(pdev->udev,cap->bus_info,sizeof(cap->bus_info)); | ||
689 | cap->version = PWC_VERSION_CODE; | ||
690 | cap->capabilities = | ||
691 | V4L2_CAP_VIDEO_CAPTURE | | ||
692 | V4L2_CAP_STREAMING | | ||
693 | V4L2_CAP_READWRITE; | ||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | case VIDIOC_ENUMINPUT: | ||
698 | { | ||
699 | struct v4l2_input *i = arg; | ||
700 | |||
701 | if ( i->index ) /* Only one INPUT is supported */ | ||
702 | return -EINVAL; | ||
703 | |||
704 | memset(i, 0, sizeof(struct v4l2_input)); | ||
705 | strcpy(i->name, "usb"); | ||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | case VIDIOC_G_INPUT: | ||
710 | { | ||
711 | int *i = arg; | ||
712 | *i = 0; /* Only one INPUT is supported */ | ||
713 | return 0; | ||
714 | } | ||
715 | case VIDIOC_S_INPUT: | ||
716 | { | ||
717 | int *i = arg; | ||
718 | |||
719 | if ( *i ) { /* Only one INPUT is supported */ | ||
720 | PWC_DEBUG_IOCTL("Only one input source is"\ | ||
721 | " supported with this webcam.\n"); | ||
722 | return -EINVAL; | ||
723 | } | ||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | /* TODO: */ | ||
728 | case VIDIOC_QUERYCTRL: | ||
729 | { | ||
730 | struct v4l2_queryctrl *c = arg; | ||
731 | int i; | ||
732 | |||
733 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) query id=%d\n", c->id); | ||
734 | for (i=0; i<sizeof(pwc_controls)/sizeof(struct v4l2_queryctrl); i++) { | ||
735 | if (pwc_controls[i].id == c->id) { | ||
736 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n"); | ||
737 | memcpy(c,&pwc_controls[i],sizeof(struct v4l2_queryctrl)); | ||
738 | return 0; | ||
739 | } | ||
740 | } | ||
741 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) not found\n"); | ||
742 | |||
743 | return -EINVAL; | ||
744 | } | ||
745 | case VIDIOC_G_CTRL: | ||
746 | { | ||
747 | struct v4l2_control *c = arg; | ||
748 | int ret; | ||
749 | |||
750 | switch (c->id) | ||
751 | { | ||
752 | case V4L2_CID_BRIGHTNESS: | ||
753 | c->value = pwc_get_brightness(pdev); | ||
754 | if (c->value<0) | ||
755 | return -EINVAL; | ||
756 | return 0; | ||
757 | case V4L2_CID_CONTRAST: | ||
758 | c->value = pwc_get_contrast(pdev); | ||
759 | if (c->value<0) | ||
760 | return -EINVAL; | ||
761 | return 0; | ||
762 | case V4L2_CID_SATURATION: | ||
763 | ret = pwc_get_saturation(pdev, &c->value); | ||
764 | if (ret<0) | ||
765 | return -EINVAL; | ||
766 | return 0; | ||
767 | case V4L2_CID_GAMMA: | ||
768 | c->value = pwc_get_gamma(pdev); | ||
769 | if (c->value<0) | ||
770 | return -EINVAL; | ||
771 | return 0; | ||
772 | case V4L2_CID_RED_BALANCE: | ||
773 | ret = pwc_get_red_gain(pdev, &c->value); | ||
774 | if (ret<0) | ||
775 | return -EINVAL; | ||
776 | c->value >>= 8; | ||
777 | return 0; | ||
778 | case V4L2_CID_BLUE_BALANCE: | ||
779 | ret = pwc_get_blue_gain(pdev, &c->value); | ||
780 | if (ret<0) | ||
781 | return -EINVAL; | ||
782 | c->value >>= 8; | ||
783 | return 0; | ||
784 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
785 | ret = pwc_get_awb(pdev); | ||
786 | if (ret<0) | ||
787 | return -EINVAL; | ||
788 | c->value = (ret == PWC_WB_MANUAL)?0:1; | ||
789 | return 0; | ||
790 | case V4L2_CID_GAIN: | ||
791 | ret = pwc_get_agc(pdev, &c->value); | ||
792 | if (ret<0) | ||
793 | return -EINVAL; | ||
794 | c->value >>= 8; | ||
795 | return 0; | ||
796 | case V4L2_CID_AUTOGAIN: | ||
797 | ret = pwc_get_agc(pdev, &c->value); | ||
798 | if (ret<0) | ||
799 | return -EINVAL; | ||
800 | c->value = (c->value < 0)?1:0; | ||
801 | return 0; | ||
802 | case V4L2_CID_EXPOSURE: | ||
803 | ret = pwc_get_shutter_speed(pdev, &c->value); | ||
804 | if (ret<0) | ||
805 | return -EINVAL; | ||
806 | return 0; | ||
807 | case V4L2_CID_PRIVATE_COLOUR_MODE: | ||
808 | ret = pwc_get_colour_mode(pdev, &c->value); | ||
809 | if (ret < 0) | ||
810 | return -EINVAL; | ||
811 | return 0; | ||
812 | case V4L2_CID_PRIVATE_AUTOCONTOUR: | ||
813 | ret = pwc_get_contour(pdev, &c->value); | ||
814 | if (ret < 0) | ||
815 | return -EINVAL; | ||
816 | c->value=(c->value == -1?1:0); | ||
817 | return 0; | ||
818 | case V4L2_CID_PRIVATE_CONTOUR: | ||
819 | ret = pwc_get_contour(pdev, &c->value); | ||
820 | if (ret < 0) | ||
821 | return -EINVAL; | ||
822 | c->value >>= 10; | ||
823 | return 0; | ||
824 | case V4L2_CID_PRIVATE_BACKLIGHT: | ||
825 | ret = pwc_get_backlight(pdev, &c->value); | ||
826 | if (ret < 0) | ||
827 | return -EINVAL; | ||
828 | return 0; | ||
829 | case V4L2_CID_PRIVATE_FLICKERLESS: | ||
830 | ret = pwc_get_flicker(pdev, &c->value); | ||
831 | if (ret < 0) | ||
832 | return -EINVAL; | ||
833 | c->value=(c->value?1:0); | ||
834 | return 0; | ||
835 | case V4L2_CID_PRIVATE_NOISE_REDUCTION: | ||
836 | ret = pwc_get_dynamic_noise(pdev, &c->value); | ||
837 | if (ret < 0) | ||
838 | return -EINVAL; | ||
839 | return 0; | ||
840 | |||
841 | case V4L2_CID_PRIVATE_SAVE_USER: | ||
842 | case V4L2_CID_PRIVATE_RESTORE_USER: | ||
843 | case V4L2_CID_PRIVATE_RESTORE_FACTORY: | ||
844 | return -EINVAL; | ||
845 | } | ||
846 | return -EINVAL; | ||
847 | } | ||
848 | case VIDIOC_S_CTRL: | ||
849 | { | ||
850 | struct v4l2_control *c = arg; | ||
851 | int ret; | ||
852 | |||
853 | switch (c->id) | ||
854 | { | ||
855 | case V4L2_CID_BRIGHTNESS: | ||
856 | c->value <<= 9; | ||
857 | ret = pwc_set_brightness(pdev, c->value); | ||
858 | if (ret<0) | ||
859 | return -EINVAL; | ||
860 | return 0; | ||
861 | case V4L2_CID_CONTRAST: | ||
862 | c->value <<= 10; | ||
863 | ret = pwc_set_contrast(pdev, c->value); | ||
864 | if (ret<0) | ||
865 | return -EINVAL; | ||
866 | return 0; | ||
867 | case V4L2_CID_SATURATION: | ||
868 | ret = pwc_set_saturation(pdev, c->value); | ||
869 | if (ret<0) | ||
870 | return -EINVAL; | ||
871 | return 0; | ||
872 | case V4L2_CID_GAMMA: | ||
873 | c->value <<= 11; | ||
874 | ret = pwc_set_gamma(pdev, c->value); | ||
875 | if (ret<0) | ||
876 | return -EINVAL; | ||
877 | return 0; | ||
878 | case V4L2_CID_RED_BALANCE: | ||
879 | c->value <<= 8; | ||
880 | ret = pwc_set_red_gain(pdev, c->value); | ||
881 | if (ret<0) | ||
882 | return -EINVAL; | ||
883 | return 0; | ||
884 | case V4L2_CID_BLUE_BALANCE: | ||
885 | c->value <<= 8; | ||
886 | ret = pwc_set_blue_gain(pdev, c->value); | ||
887 | if (ret<0) | ||
888 | return -EINVAL; | ||
889 | return 0; | ||
890 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
891 | c->value = (c->value == 0)?PWC_WB_MANUAL:PWC_WB_AUTO; | ||
892 | ret = pwc_set_awb(pdev, c->value); | ||
893 | if (ret<0) | ||
894 | return -EINVAL; | ||
895 | return 0; | ||
896 | case V4L2_CID_EXPOSURE: | ||
897 | c->value <<= 8; | ||
898 | ret = pwc_set_shutter_speed(pdev, c->value?0:1, c->value); | ||
899 | if (ret<0) | ||
900 | return -EINVAL; | ||
901 | return 0; | ||
902 | case V4L2_CID_AUTOGAIN: | ||
903 | /* autogain off means nothing without a gain */ | ||
904 | if (c->value == 0) | ||
905 | return 0; | ||
906 | ret = pwc_set_agc(pdev, c->value, 0); | ||
907 | if (ret<0) | ||
908 | return -EINVAL; | ||
909 | return 0; | ||
910 | case V4L2_CID_GAIN: | ||
911 | c->value <<= 8; | ||
912 | ret = pwc_set_agc(pdev, 0, c->value); | ||
913 | if (ret<0) | ||
914 | return -EINVAL; | ||
915 | return 0; | ||
916 | case V4L2_CID_PRIVATE_SAVE_USER: | ||
917 | if (pwc_save_user(pdev)) | ||
918 | return -EINVAL; | ||
919 | return 0; | ||
920 | case V4L2_CID_PRIVATE_RESTORE_USER: | ||
921 | if (pwc_restore_user(pdev)) | ||
922 | return -EINVAL; | ||
923 | return 0; | ||
924 | case V4L2_CID_PRIVATE_RESTORE_FACTORY: | ||
925 | if (pwc_restore_factory(pdev)) | ||
926 | return -EINVAL; | ||
927 | return 0; | ||
928 | case V4L2_CID_PRIVATE_COLOUR_MODE: | ||
929 | ret = pwc_set_colour_mode(pdev, c->value); | ||
930 | if (ret < 0) | ||
931 | return -EINVAL; | ||
932 | return 0; | ||
933 | case V4L2_CID_PRIVATE_AUTOCONTOUR: | ||
934 | c->value=(c->value == 1)?-1:0; | ||
935 | ret = pwc_set_contour(pdev, c->value); | ||
936 | if (ret < 0) | ||
937 | return -EINVAL; | ||
938 | return 0; | ||
939 | case V4L2_CID_PRIVATE_CONTOUR: | ||
940 | c->value <<= 10; | ||
941 | ret = pwc_set_contour(pdev, c->value); | ||
942 | if (ret < 0) | ||
943 | return -EINVAL; | ||
944 | return 0; | ||
945 | case V4L2_CID_PRIVATE_BACKLIGHT: | ||
946 | ret = pwc_set_backlight(pdev, c->value); | ||
947 | if (ret < 0) | ||
948 | return -EINVAL; | ||
949 | return 0; | ||
950 | case V4L2_CID_PRIVATE_FLICKERLESS: | ||
951 | ret = pwc_set_flicker(pdev, c->value); | ||
952 | if (ret < 0) | ||
953 | return -EINVAL; | ||
954 | case V4L2_CID_PRIVATE_NOISE_REDUCTION: | ||
955 | ret = pwc_set_dynamic_noise(pdev, c->value); | ||
956 | if (ret < 0) | ||
957 | return -EINVAL; | ||
958 | return 0; | ||
959 | |||
960 | } | ||
961 | return -EINVAL; | ||
962 | } | ||
963 | |||
964 | case VIDIOC_ENUM_FMT: | ||
965 | { | ||
966 | struct v4l2_fmtdesc *f = arg; | ||
967 | int index; | ||
968 | |||
969 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
970 | return -EINVAL; | ||
971 | |||
972 | /* We only support two format: the raw format, and YUV */ | ||
973 | index = f->index; | ||
974 | memset(f,0,sizeof(struct v4l2_fmtdesc)); | ||
975 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
976 | f->index = index; | ||
977 | switch(index) | ||
978 | { | ||
979 | case 0: | ||
980 | /* RAW format */ | ||
981 | f->pixelformat = pdev->type<=646?V4L2_PIX_FMT_PWC1:V4L2_PIX_FMT_PWC2; | ||
982 | f->flags = V4L2_FMT_FLAG_COMPRESSED; | ||
983 | strlcpy(f->description,"Raw Philips Webcam",sizeof(f->description)); | ||
984 | break; | ||
985 | case 1: | ||
986 | f->pixelformat = V4L2_PIX_FMT_YUV420; | ||
987 | strlcpy(f->description,"4:2:0, planar, Y-Cb-Cr",sizeof(f->description)); | ||
988 | break; | ||
989 | default: | ||
990 | return -EINVAL; | ||
991 | } | ||
992 | return 0; | ||
993 | } | ||
994 | |||
995 | case VIDIOC_G_FMT: | ||
996 | { | ||
997 | struct v4l2_format *f = arg; | ||
998 | |||
999 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",pdev->image.x,pdev->image.y); | ||
1000 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1001 | return -EINVAL; | ||
1002 | |||
1003 | pwc_vidioc_fill_fmt(pdev, f); | ||
1004 | |||
1005 | return 0; | ||
1006 | } | ||
1007 | |||
1008 | case VIDIOC_TRY_FMT: | ||
1009 | return pwc_vidioc_try_fmt(pdev, arg); | ||
1010 | |||
1011 | case VIDIOC_S_FMT: | ||
1012 | return pwc_vidioc_set_fmt(pdev, arg); | ||
1013 | |||
1014 | case VIDIOC_G_STD: | ||
1015 | { | ||
1016 | v4l2_std_id *std = arg; | ||
1017 | *std = V4L2_STD_UNKNOWN; | ||
1018 | return 0; | ||
1019 | } | ||
1020 | |||
1021 | case VIDIOC_S_STD: | ||
1022 | { | ||
1023 | v4l2_std_id *std = arg; | ||
1024 | if (*std != V4L2_STD_UNKNOWN) | ||
1025 | return -EINVAL; | ||
1026 | return 0; | ||
1027 | } | ||
1028 | |||
1029 | case VIDIOC_ENUMSTD: | ||
1030 | { | ||
1031 | struct v4l2_standard *std = arg; | ||
1032 | if (std->index != 0) | ||
1033 | return -EINVAL; | ||
1034 | std->id = V4L2_STD_UNKNOWN; | ||
1035 | strncpy(std->name, "webcam", sizeof(std->name)); | ||
1036 | return 0; | ||
1037 | } | ||
1038 | |||
1039 | case VIDIOC_REQBUFS: | ||
1040 | { | ||
1041 | struct v4l2_requestbuffers *rb = arg; | ||
1042 | int nbuffers; | ||
1043 | |||
1044 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n",rb->count); | ||
1045 | if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1046 | return -EINVAL; | ||
1047 | if (rb->memory != V4L2_MEMORY_MMAP) | ||
1048 | return -EINVAL; | ||
1049 | |||
1050 | nbuffers = rb->count; | ||
1051 | if (nbuffers < 2) | ||
1052 | nbuffers = 2; | ||
1053 | else if (nbuffers > pwc_mbufs) | ||
1054 | nbuffers = pwc_mbufs; | ||
1055 | /* Force to use our # of buffers */ | ||
1056 | rb->count = pwc_mbufs; | ||
1057 | return 0; | ||
1058 | } | ||
1059 | |||
1060 | case VIDIOC_QUERYBUF: | ||
1061 | { | ||
1062 | struct v4l2_buffer *buf = arg; | ||
1063 | int index; | ||
1064 | |||
1065 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n",buf->index); | ||
1066 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1067 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n"); | ||
1068 | return -EINVAL; | ||
1069 | } | ||
1070 | if (buf->memory != V4L2_MEMORY_MMAP) { | ||
1071 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad memory type\n"); | ||
1072 | return -EINVAL; | ||
1073 | } | ||
1074 | index = buf->index; | ||
1075 | if (index < 0 || index >= pwc_mbufs) { | ||
1076 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index); | ||
1077 | return -EINVAL; | ||
1078 | } | ||
1079 | |||
1080 | memset(buf, 0, sizeof(struct v4l2_buffer)); | ||
1081 | buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1082 | buf->index = index; | ||
1083 | buf->m.offset = index * pdev->len_per_image; | ||
1084 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | ||
1085 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); | ||
1086 | else | ||
1087 | buf->bytesused = pdev->view.size; | ||
1088 | buf->field = V4L2_FIELD_NONE; | ||
1089 | buf->memory = V4L2_MEMORY_MMAP; | ||
1090 | //buf->flags = V4L2_BUF_FLAG_MAPPED; | ||
1091 | buf->length = pdev->len_per_image; | ||
1092 | |||
1093 | PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n",buf->index); | ||
1094 | PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n",buf->m.offset); | ||
1095 | PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n",buf->bytesused); | ||
1096 | |||
1097 | return 0; | ||
1098 | } | ||
1099 | |||
1100 | case VIDIOC_QBUF: | ||
1101 | { | ||
1102 | struct v4l2_buffer *buf = arg; | ||
1103 | |||
1104 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n",buf->index); | ||
1105 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1106 | return -EINVAL; | ||
1107 | if (buf->memory != V4L2_MEMORY_MMAP) | ||
1108 | return -EINVAL; | ||
1109 | if (buf->index < 0 || buf->index >= pwc_mbufs) | ||
1110 | return -EINVAL; | ||
1111 | |||
1112 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
1113 | buf->flags &= ~V4L2_BUF_FLAG_DONE; | ||
1114 | |||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | case VIDIOC_DQBUF: | ||
1119 | { | ||
1120 | struct v4l2_buffer *buf = arg; | ||
1121 | int ret; | ||
1122 | |||
1123 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n"); | ||
1124 | |||
1125 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1126 | return -EINVAL; | ||
1127 | |||
1128 | /* Add ourselves to the frame wait-queue. | ||
1129 | |||
1130 | FIXME: needs auditing for safety. | ||
1131 | QUESTION: In what respect? I think that using the | ||
1132 | frameq is safe now. | ||
1133 | */ | ||
1134 | add_wait_queue(&pdev->frameq, &wait); | ||
1135 | while (pdev->full_frames == NULL) { | ||
1136 | if (pdev->error_status) { | ||
1137 | remove_wait_queue(&pdev->frameq, &wait); | ||
1138 | set_current_state(TASK_RUNNING); | ||
1139 | return -pdev->error_status; | ||
1140 | } | ||
1141 | |||
1142 | if (signal_pending(current)) { | ||
1143 | remove_wait_queue(&pdev->frameq, &wait); | ||
1144 | set_current_state(TASK_RUNNING); | ||
1145 | return -ERESTARTSYS; | ||
1146 | } | ||
1147 | schedule(); | ||
1148 | set_current_state(TASK_INTERRUPTIBLE); | ||
1149 | } | ||
1150 | remove_wait_queue(&pdev->frameq, &wait); | ||
1151 | set_current_state(TASK_RUNNING); | ||
1152 | |||
1153 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n"); | ||
1154 | /* Decompress data in pdev->images[pdev->fill_image] */ | ||
1155 | ret = pwc_handle_frame(pdev); | ||
1156 | if (ret) | ||
1157 | return -EFAULT; | ||
1158 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n"); | ||
1159 | |||
1160 | buf->index = pdev->fill_image; | ||
1161 | if (pdev->vpalette == VIDEO_PALETTE_RAW) | ||
1162 | buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); | ||
1163 | else | ||
1164 | buf->bytesused = pdev->view.size; | ||
1165 | buf->flags = V4L2_BUF_FLAG_MAPPED; | ||
1166 | buf->field = V4L2_FIELD_NONE; | ||
1167 | do_gettimeofday(&buf->timestamp); | ||
1168 | buf->sequence = 0; | ||
1169 | buf->memory = V4L2_MEMORY_MMAP; | ||
1170 | buf->m.offset = pdev->fill_image * pdev->len_per_image; | ||
1171 | buf->length = buf->bytesused; | ||
1172 | pwc_next_image(pdev); | ||
1173 | |||
1174 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index); | ||
1175 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n",buf->length); | ||
1176 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n",buf->m.offset); | ||
1177 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n",buf->bytesused); | ||
1178 | PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n"); | ||
1179 | return 0; | ||
1180 | |||
1181 | } | ||
1182 | |||
1183 | case VIDIOC_STREAMON: | ||
1184 | { | ||
1185 | /* WARNING: pwc_try_video_mode() called pwc_isoc_init */ | ||
1186 | pwc_isoc_init(pdev); | ||
1187 | return 0; | ||
1188 | } | ||
1189 | |||
1190 | case VIDIOC_STREAMOFF: | ||
1191 | { | ||
1192 | pwc_isoc_cleanup(pdev); | ||
1193 | return 0; | ||
1194 | } | ||
1195 | |||
1196 | default: | ||
1197 | return pwc_ioctl(pdev, cmd, arg); | ||
1198 | } /* ..switch */ | ||
1199 | return 0; | ||
1200 | } | ||
1201 | |||
1202 | /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ | ||
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 1b0ee0ced0ed..629f79e44fb6 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* (C) 1999-2003 Nemosoft Unv. | 1 | /* (C) 1999-2003 Nemosoft Unv. |
2 | (C) 2004 Luc Saillard (luc@saillard.org) | 2 | (C) 2004-2006 Luc Saillard (luc@saillard.org) |
3 | 3 | ||
4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx | 4 | NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx |
5 | driver and thus may have bugs that are not present in the original version. | 5 | driver and thus may have bugs that are not present in the original version. |
@@ -29,51 +29,87 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/usb.h> | 30 | #include <linux/usb.h> |
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | #include <linux/videodev.h> | ||
33 | #include <linux/wait.h> | 32 | #include <linux/wait.h> |
34 | #include <linux/smp_lock.h> | 33 | #include <linux/smp_lock.h> |
34 | #include <linux/version.h> | ||
35 | #include <asm/semaphore.h> | 35 | #include <asm/semaphore.h> |
36 | #include <asm/errno.h> | 36 | #include <asm/errno.h> |
37 | #include <linux/videodev.h> | ||
38 | #include <media/v4l2-common.h> | ||
37 | 39 | ||
38 | #include "pwc-uncompress.h" | 40 | #include "pwc-uncompress.h" |
39 | #include "pwc-ioctl.h" | 41 | #include <media/pwc-ioctl.h> |
40 | |||
41 | /* Defines and structures for the Philips webcam */ | ||
42 | /* Used for checking memory corruption/pointer validation */ | ||
43 | #define PWC_MAGIC 0x89DC10ABUL | ||
44 | #undef PWC_MAGIC | ||
45 | 42 | ||
46 | /* Turn some debugging options on/off */ | 43 | /* Turn some debugging options on/off */ |
47 | #define PWC_DEBUG 0 | 44 | #ifndef CONFIG_PWC_DEBUG |
45 | #define CONFIG_PWC_DEBUG 1 | ||
46 | #endif | ||
47 | |||
48 | /* Version block */ | ||
49 | #define PWC_MAJOR 10 | ||
50 | #define PWC_MINOR 0 | ||
51 | #define PWC_EXTRAMINOR 12 | ||
52 | #define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR) | ||
53 | #define PWC_VERSION "10.0.12" | ||
54 | #define PWC_NAME "pwc" | ||
55 | #define PFX PWC_NAME ": " | ||
56 | |||
48 | 57 | ||
49 | /* Trace certain actions in the driver */ | 58 | /* Trace certain actions in the driver */ |
50 | #define TRACE_MODULE 0x0001 | 59 | #define PWC_DEBUG_LEVEL_MODULE (1<<0) |
51 | #define TRACE_PROBE 0x0002 | 60 | #define PWC_DEBUG_LEVEL_PROBE (1<<1) |
52 | #define TRACE_OPEN 0x0004 | 61 | #define PWC_DEBUG_LEVEL_OPEN (1<<2) |
53 | #define TRACE_READ 0x0008 | 62 | #define PWC_DEBUG_LEVEL_READ (1<<3) |
54 | #define TRACE_MEMORY 0x0010 | 63 | #define PWC_DEBUG_LEVEL_MEMORY (1<<4) |
55 | #define TRACE_FLOW 0x0020 | 64 | #define PWC_DEBUG_LEVEL_FLOW (1<<5) |
56 | #define TRACE_SIZE 0x0040 | 65 | #define PWC_DEBUG_LEVEL_SIZE (1<<6) |
57 | #define TRACE_PWCX 0x0080 | 66 | #define PWC_DEBUG_LEVEL_IOCTL (1<<7) |
58 | #define TRACE_SEQUENCE 0x1000 | 67 | #define PWC_DEBUG_LEVEL_TRACE (1<<8) |
59 | 68 | ||
60 | #define Trace(R, A...) if (pwc_trace & R) printk(KERN_DEBUG PWC_NAME " " A) | 69 | #define PWC_DEBUG_MODULE(fmt, args...) PWC_DEBUG(MODULE, fmt, ##args) |
61 | #define Debug(A...) printk(KERN_DEBUG PWC_NAME " " A) | 70 | #define PWC_DEBUG_PROBE(fmt, args...) PWC_DEBUG(PROBE, fmt, ##args) |
62 | #define Info(A...) printk(KERN_INFO PWC_NAME " " A) | 71 | #define PWC_DEBUG_OPEN(fmt, args...) PWC_DEBUG(OPEN, fmt, ##args) |
63 | #define Err(A...) printk(KERN_ERR PWC_NAME " " A) | 72 | #define PWC_DEBUG_READ(fmt, args...) PWC_DEBUG(READ, fmt, ##args) |
73 | #define PWC_DEBUG_MEMORY(fmt, args...) PWC_DEBUG(MEMORY, fmt, ##args) | ||
74 | #define PWC_DEBUG_FLOW(fmt, args...) PWC_DEBUG(FLOW, fmt, ##args) | ||
75 | #define PWC_DEBUG_SIZE(fmt, args...) PWC_DEBUG(SIZE, fmt, ##args) | ||
76 | #define PWC_DEBUG_IOCTL(fmt, args...) PWC_DEBUG(IOCTL, fmt, ##args) | ||
77 | #define PWC_DEBUG_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args) | ||
78 | |||
79 | |||
80 | #if CONFIG_PWC_DEBUG | ||
81 | |||
82 | #define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE) | ||
83 | |||
84 | #define PWC_DEBUG(level, fmt, args...) do {\ | ||
85 | if ((PWC_DEBUG_LEVEL_ ##level) & pwc_trace) \ | ||
86 | printk(KERN_DEBUG PFX fmt, ##args); \ | ||
87 | } while(0) | ||
88 | |||
89 | #define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args) | ||
90 | #define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args) | ||
91 | #define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args) | ||
92 | #define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args) | ||
93 | |||
94 | #else /* if ! CONFIG_PWC_DEBUG */ | ||
95 | |||
96 | #define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args) | ||
97 | #define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args) | ||
98 | #define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args) | ||
99 | #define PWC_TRACE(fmt, args...) do { } while(0) | ||
100 | #define PWC_DEBUG(level, fmt, args...) do { } while(0) | ||
101 | |||
102 | #define pwc_trace 0 | ||
64 | 103 | ||
104 | #endif | ||
65 | 105 | ||
66 | /* Defines for ToUCam cameras */ | 106 | /* Defines for ToUCam cameras */ |
67 | #define TOUCAM_HEADER_SIZE 8 | 107 | #define TOUCAM_HEADER_SIZE 8 |
68 | #define TOUCAM_TRAILER_SIZE 4 | 108 | #define TOUCAM_TRAILER_SIZE 4 |
69 | 109 | ||
70 | #define FEATURE_MOTOR_PANTILT 0x0001 | 110 | #define FEATURE_MOTOR_PANTILT 0x0001 |
71 | 111 | #define FEATURE_CODEC1 0x0002 | |
72 | /* Version block */ | 112 | #define FEATURE_CODEC2 0x0004 |
73 | #define PWC_MAJOR 9 | ||
74 | #define PWC_MINOR 0 | ||
75 | #define PWC_VERSION "9.0.2-unofficial" | ||
76 | #define PWC_NAME "pwc" | ||
77 | 113 | ||
78 | /* Turn certain features on/off */ | 114 | /* Turn certain features on/off */ |
79 | #define PWC_INT_PIPE 0 | 115 | #define PWC_INT_PIPE 0 |
@@ -95,6 +131,18 @@ | |||
95 | /* Absolute maximum number of buffers available for mmap() */ | 131 | /* Absolute maximum number of buffers available for mmap() */ |
96 | #define MAX_IMAGES 10 | 132 | #define MAX_IMAGES 10 |
97 | 133 | ||
134 | /* Some macros to quickly find the type of a webcam */ | ||
135 | #define DEVICE_USE_CODEC1(x) ((x)<675) | ||
136 | #define DEVICE_USE_CODEC2(x) ((x)>=675 && (x)<700) | ||
137 | #define DEVICE_USE_CODEC3(x) ((x)>=700) | ||
138 | #define DEVICE_USE_CODEC23(x) ((x)>=675) | ||
139 | |||
140 | |||
141 | #ifndef V4L2_PIX_FMT_PWC1 | ||
142 | #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') | ||
143 | #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') | ||
144 | #endif | ||
145 | |||
98 | /* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ | 146 | /* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ |
99 | struct pwc_iso_buf | 147 | struct pwc_iso_buf |
100 | { | 148 | { |
@@ -110,17 +158,19 @@ struct pwc_frame_buf | |||
110 | void *data; | 158 | void *data; |
111 | volatile int filled; /* number of bytes filled */ | 159 | volatile int filled; /* number of bytes filled */ |
112 | struct pwc_frame_buf *next; /* list */ | 160 | struct pwc_frame_buf *next; /* list */ |
113 | #if PWC_DEBUG | 161 | }; |
114 | int sequence; /* Sequence number */ | 162 | |
115 | #endif | 163 | /* additionnal informations used when dealing image between kernel and userland */ |
164 | struct pwc_imgbuf | ||
165 | { | ||
166 | unsigned long offset; /* offset of this buffer in the big array of image_data */ | ||
167 | int vma_use_count; /* count the number of time this memory is mapped */ | ||
116 | }; | 168 | }; |
117 | 169 | ||
118 | struct pwc_device | 170 | struct pwc_device |
119 | { | 171 | { |
120 | struct video_device *vdev; | 172 | struct video_device *vdev; |
121 | #ifdef PWC_MAGIC | 173 | |
122 | int magic; | ||
123 | #endif | ||
124 | /* Pointer to our usb_device */ | 174 | /* Pointer to our usb_device */ |
125 | struct usb_device *udev; | 175 | struct usb_device *udev; |
126 | 176 | ||
@@ -177,12 +227,8 @@ struct pwc_device | |||
177 | int frame_size; | 227 | int frame_size; |
178 | int frame_total_size; /* including header & trailer */ | 228 | int frame_total_size; /* including header & trailer */ |
179 | int drop_frames; | 229 | int drop_frames; |
180 | #if PWC_DEBUG | ||
181 | int sequence; /* Debugging aid */ | ||
182 | #endif | ||
183 | 230 | ||
184 | /* 3: decompression */ | 231 | /* 3: decompression */ |
185 | struct pwc_decompressor *decompressor; /* function block with decompression routines */ | ||
186 | void *decompress_data; /* private data for decompression engine */ | 232 | void *decompress_data; /* private data for decompression engine */ |
187 | 233 | ||
188 | /* 4: image */ | 234 | /* 4: image */ |
@@ -198,7 +244,7 @@ struct pwc_device | |||
198 | struct pwc_coord offset; /* offset within the viewport */ | 244 | struct pwc_coord offset; /* offset within the viewport */ |
199 | 245 | ||
200 | void *image_data; /* total buffer, which is subdivided into ... */ | 246 | void *image_data; /* total buffer, which is subdivided into ... */ |
201 | void *image_ptr[MAX_IMAGES]; /* ...several images... */ | 247 | struct pwc_imgbuf images[MAX_IMAGES];/* ...several images... */ |
202 | int fill_image; /* ...which are rotated. */ | 248 | int fill_image; /* ...which are rotated. */ |
203 | int len_per_image; /* length per image */ | 249 | int len_per_image; /* length per image */ |
204 | int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ | 250 | int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ |
@@ -211,6 +257,7 @@ struct pwc_device | |||
211 | struct pwc_mpt_range angle_range; | 257 | struct pwc_mpt_range angle_range; |
212 | int pan_angle; /* in degrees * 100 */ | 258 | int pan_angle; /* in degrees * 100 */ |
213 | int tilt_angle; /* absolute angle; 0,0 is home position */ | 259 | int tilt_angle; /* absolute angle; 0,0 is home position */ |
260 | int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */ | ||
214 | 261 | ||
215 | /*** Misc. data ***/ | 262 | /*** Misc. data ***/ |
216 | wait_queue_head_t frameq; /* When waiting for a frame to finish... */ | 263 | wait_queue_head_t frameq; /* When waiting for a frame to finish... */ |
@@ -219,20 +266,26 @@ struct pwc_device | |||
219 | #endif | 266 | #endif |
220 | }; | 267 | }; |
221 | 268 | ||
222 | |||
223 | #ifdef __cplusplus | 269 | #ifdef __cplusplus |
224 | extern "C" { | 270 | extern "C" { |
225 | #endif | 271 | #endif |
226 | 272 | ||
227 | /* Global variable */ | 273 | /* Global variables */ |
274 | #if CONFIG_PWC_DEBUG | ||
228 | extern int pwc_trace; | 275 | extern int pwc_trace; |
276 | #endif | ||
277 | extern int pwc_mbufs; | ||
229 | 278 | ||
230 | /** functions in pwc-if.c */ | 279 | /** functions in pwc-if.c */ |
231 | int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot); | 280 | int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot); |
281 | int pwc_handle_frame(struct pwc_device *pdev); | ||
282 | void pwc_next_image(struct pwc_device *pdev); | ||
283 | int pwc_isoc_init(struct pwc_device *pdev); | ||
284 | void pwc_isoc_cleanup(struct pwc_device *pdev); | ||
232 | 285 | ||
233 | /** Functions in pwc-misc.c */ | 286 | /** Functions in pwc-misc.c */ |
234 | /* sizes in pixels */ | 287 | /* sizes in pixels */ |
235 | extern struct pwc_coord pwc_image_sizes[PSZ_MAX]; | 288 | extern const struct pwc_coord pwc_image_sizes[PSZ_MAX]; |
236 | 289 | ||
237 | int pwc_decode_size(struct pwc_device *pdev, int width, int height); | 290 | int pwc_decode_size(struct pwc_device *pdev, int width, int height); |
238 | void pwc_construct(struct pwc_device *pdev); | 291 | void pwc_construct(struct pwc_device *pdev); |
@@ -240,6 +293,9 @@ void pwc_construct(struct pwc_device *pdev); | |||
240 | /** Functions in pwc-ctrl.c */ | 293 | /** Functions in pwc-ctrl.c */ |
241 | /* Request a certain video mode. Returns < 0 if not possible */ | 294 | /* Request a certain video mode. Returns < 0 if not possible */ |
242 | extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot); | 295 | extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot); |
296 | /* Calculate the number of bytes per image (not frame) */ | ||
297 | extern int pwc_mpt_reset(struct pwc_device *pdev, int flags); | ||
298 | extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt); | ||
243 | 299 | ||
244 | /* Various controls; should be obvious. Value 0..65535, or < 0 on error */ | 300 | /* Various controls; should be obvious. Value 0..65535, or < 0 on error */ |
245 | extern int pwc_get_brightness(struct pwc_device *pdev); | 301 | extern int pwc_get_brightness(struct pwc_device *pdev); |
@@ -248,10 +304,36 @@ extern int pwc_get_contrast(struct pwc_device *pdev); | |||
248 | extern int pwc_set_contrast(struct pwc_device *pdev, int value); | 304 | extern int pwc_set_contrast(struct pwc_device *pdev, int value); |
249 | extern int pwc_get_gamma(struct pwc_device *pdev); | 305 | extern int pwc_get_gamma(struct pwc_device *pdev); |
250 | extern int pwc_set_gamma(struct pwc_device *pdev, int value); | 306 | extern int pwc_set_gamma(struct pwc_device *pdev, int value); |
251 | extern int pwc_get_saturation(struct pwc_device *pdev); | 307 | extern int pwc_get_saturation(struct pwc_device *pdev, int *value); |
252 | extern int pwc_set_saturation(struct pwc_device *pdev, int value); | 308 | extern int pwc_set_saturation(struct pwc_device *pdev, int value); |
253 | extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); | 309 | extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); |
254 | extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); | 310 | extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); |
311 | extern int pwc_restore_user(struct pwc_device *pdev); | ||
312 | extern int pwc_save_user(struct pwc_device *pdev); | ||
313 | extern int pwc_restore_factory(struct pwc_device *pdev); | ||
314 | |||
315 | /* exported for use by v4l2 controls */ | ||
316 | extern int pwc_get_red_gain(struct pwc_device *pdev, int *value); | ||
317 | extern int pwc_set_red_gain(struct pwc_device *pdev, int value); | ||
318 | extern int pwc_get_blue_gain(struct pwc_device *pdev, int *value); | ||
319 | extern int pwc_set_blue_gain(struct pwc_device *pdev, int value); | ||
320 | extern int pwc_get_awb(struct pwc_device *pdev); | ||
321 | extern int pwc_set_awb(struct pwc_device *pdev, int mode); | ||
322 | extern int pwc_set_agc(struct pwc_device *pdev, int mode, int value); | ||
323 | extern int pwc_get_agc(struct pwc_device *pdev, int *value); | ||
324 | extern int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value); | ||
325 | extern int pwc_get_shutter_speed(struct pwc_device *pdev, int *value); | ||
326 | |||
327 | extern int pwc_set_colour_mode(struct pwc_device *pdev, int colour); | ||
328 | extern int pwc_get_colour_mode(struct pwc_device *pdev, int *colour); | ||
329 | extern int pwc_set_contour(struct pwc_device *pdev, int contour); | ||
330 | extern int pwc_get_contour(struct pwc_device *pdev, int *contour); | ||
331 | extern int pwc_set_backlight(struct pwc_device *pdev, int backlight); | ||
332 | extern int pwc_get_backlight(struct pwc_device *pdev, int *backlight); | ||
333 | extern int pwc_set_flicker(struct pwc_device *pdev, int flicker); | ||
334 | extern int pwc_get_flicker(struct pwc_device *pdev, int *flicker); | ||
335 | extern int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise); | ||
336 | extern int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise); | ||
255 | 337 | ||
256 | /* Power down or up the camera; not supported by all models */ | 338 | /* Power down or up the camera; not supported by all models */ |
257 | extern int pwc_camera_power(struct pwc_device *pdev, int power); | 339 | extern int pwc_camera_power(struct pwc_device *pdev, int power); |
@@ -259,6 +341,9 @@ extern int pwc_camera_power(struct pwc_device *pdev, int power); | |||
259 | /* Private ioctl()s; see pwc-ioctl.h */ | 341 | /* Private ioctl()s; see pwc-ioctl.h */ |
260 | extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); | 342 | extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); |
261 | 343 | ||
344 | /** Functions in pwc-v4l.c */ | ||
345 | extern int pwc_video_do_ioctl(struct inode *inode, struct file *file, | ||
346 | unsigned int cmd, void *arg); | ||
262 | 347 | ||
263 | /** pwc-uncompress.c */ | 348 | /** pwc-uncompress.c */ |
264 | /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ | 349 | /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ |
@@ -270,3 +355,4 @@ extern int pwc_decompress(struct pwc_device *pdev); | |||
270 | 355 | ||
271 | 356 | ||
272 | #endif | 357 | #endif |
358 | /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ | ||
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index dd830e0e5e96..59a187272c83 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/i2c.h> | 46 | #include <linux/i2c.h> |
47 | #include <linux/videotext.h> | 47 | #include <linux/videotext.h> |
48 | #include <linux/videodev.h> | 48 | #include <linux/videodev.h> |
49 | #include <media/v4l2-common.h> | ||
49 | #include <linux/mutex.h> | 50 | #include <linux/mutex.h> |
50 | 51 | ||
51 | #include "saa5246a.h" | 52 | #include "saa5246a.h" |
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 531e9461cb66..19a8d65699f8 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/i2c.h> | 56 | #include <linux/i2c.h> |
57 | #include <linux/videotext.h> | 57 | #include <linux/videotext.h> |
58 | #include <linux/videodev.h> | 58 | #include <linux/videodev.h> |
59 | #include <media/v4l2-common.h> | ||
59 | #include <linux/mutex.h> | 60 | #include <linux/mutex.h> |
60 | 61 | ||
61 | 62 | ||
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 41d951db6ec0..676b9970eb2e 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c | |||
@@ -43,6 +43,7 @@ MODULE_LICENSE("GPL"); | |||
43 | #define I2C_NAME(s) (s)->name | 43 | #define I2C_NAME(s) (s)->name |
44 | 44 | ||
45 | #include <linux/videodev.h> | 45 | #include <linux/videodev.h> |
46 | #include <media/v4l2-common.h> | ||
46 | #include <linux/video_decoder.h> | 47 | #include <linux/video_decoder.h> |
47 | 48 | ||
48 | static int debug = 0; | 49 | static int debug = 0; |
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index dceebc0b1250..b59c11717273 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
@@ -72,6 +72,10 @@ struct saa7115_state { | |||
72 | int sat; | 72 | int sat; |
73 | enum v4l2_chip_ident ident; | 73 | enum v4l2_chip_ident ident; |
74 | u32 audclk_freq; | 74 | u32 audclk_freq; |
75 | u32 crystal_freq; | ||
76 | u8 ucgc; | ||
77 | u8 cgcdiv; | ||
78 | u8 apll; | ||
75 | }; | 79 | }; |
76 | 80 | ||
77 | /* ----------------------------------------------------------------------- */ | 81 | /* ----------------------------------------------------------------------- */ |
@@ -375,10 +379,6 @@ static const unsigned char saa7113_init_auto_input[] = { | |||
375 | }; | 379 | }; |
376 | 380 | ||
377 | static const unsigned char saa7115_init_misc[] = { | 381 | static const unsigned char saa7115_init_misc[] = { |
378 | 0x38, 0x03, /* audio stuff */ | ||
379 | 0x39, 0x10, | ||
380 | 0x3a, 0x08, | ||
381 | |||
382 | 0x81, 0x01, /* reg 0x15,0x16 define blanking window */ | 382 | 0x81, 0x01, /* reg 0x15,0x16 define blanking window */ |
383 | 0x82, 0x00, | 383 | 0x82, 0x00, |
384 | 0x83, 0x01, /* I port settings */ | 384 | 0x83, 0x01, /* I port settings */ |
@@ -584,6 +584,7 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq) | |||
584 | u32 acni; | 584 | u32 acni; |
585 | u32 hz; | 585 | u32 hz; |
586 | u64 f; | 586 | u64 f; |
587 | u8 acc = 0; /* reg 0x3a, audio clock control */ | ||
587 | 588 | ||
588 | v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq); | 589 | v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq); |
589 | 590 | ||
@@ -591,18 +592,34 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq) | |||
591 | if (freq < 32000 || freq > 48000) | 592 | if (freq < 32000 || freq > 48000) |
592 | return -EINVAL; | 593 | return -EINVAL; |
593 | 594 | ||
595 | /* The saa7113 has no audio clock */ | ||
596 | if (state->ident == V4L2_IDENT_SAA7113) | ||
597 | return 0; | ||
598 | |||
594 | /* hz is the refresh rate times 100 */ | 599 | /* hz is the refresh rate times 100 */ |
595 | hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000; | 600 | hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000; |
596 | /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */ | 601 | /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */ |
597 | acpf = (25600 * freq) / hz; | 602 | acpf = (25600 * freq) / hz; |
598 | /* acni = (256 * freq * 2^23) / crystal_frequency = | 603 | /* acni = (256 * freq * 2^23) / crystal_frequency = |
599 | (freq * 2^(8+23)) / crystal_frequency = | 604 | (freq * 2^(8+23)) / crystal_frequency = |
600 | (freq << 31) / 32.11 MHz */ | 605 | (freq << 31) / crystal_frequency */ |
601 | f = freq; | 606 | f = freq; |
602 | f = f << 31; | 607 | f = f << 31; |
603 | do_div(f, 32110000); | 608 | do_div(f, state->crystal_freq); |
604 | acni = f; | 609 | acni = f; |
610 | if (state->ucgc) { | ||
611 | acpf = acpf * state->cgcdiv / 16; | ||
612 | acni = acni * state->cgcdiv / 16; | ||
613 | acc = 0x80; | ||
614 | if (state->cgcdiv == 3) | ||
615 | acc |= 0x40; | ||
616 | } | ||
617 | if (state->apll) | ||
618 | acc |= 0x08; | ||
605 | 619 | ||
620 | saa7115_write(client, 0x38, 0x03); | ||
621 | saa7115_write(client, 0x39, 0x10); | ||
622 | saa7115_write(client, 0x3a, acc); | ||
606 | saa7115_write(client, 0x30, acpf & 0xff); | 623 | saa7115_write(client, 0x30, acpf & 0xff); |
607 | saa7115_write(client, 0x31, (acpf >> 8) & 0xff); | 624 | saa7115_write(client, 0x31, (acpf >> 8) & 0xff); |
608 | saa7115_write(client, 0x32, (acpf >> 16) & 0x03); | 625 | saa7115_write(client, 0x32, (acpf >> 16) & 0x03); |
@@ -1073,48 +1090,6 @@ static void saa7115_decode_vbi_line(struct i2c_client *client, | |||
1073 | 1090 | ||
1074 | /* ============ SAA7115 AUDIO settings (end) ============= */ | 1091 | /* ============ SAA7115 AUDIO settings (end) ============= */ |
1075 | 1092 | ||
1076 | static struct v4l2_queryctrl saa7115_qctrl[] = { | ||
1077 | { | ||
1078 | .id = V4L2_CID_BRIGHTNESS, | ||
1079 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1080 | .name = "Brightness", | ||
1081 | .minimum = 0, | ||
1082 | .maximum = 255, | ||
1083 | .step = 1, | ||
1084 | .default_value = 128, | ||
1085 | .flags = 0, | ||
1086 | }, { | ||
1087 | .id = V4L2_CID_CONTRAST, | ||
1088 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1089 | .name = "Contrast", | ||
1090 | .minimum = 0, | ||
1091 | .maximum = 127, | ||
1092 | .step = 1, | ||
1093 | .default_value = 64, | ||
1094 | .flags = 0, | ||
1095 | }, { | ||
1096 | .id = V4L2_CID_SATURATION, | ||
1097 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1098 | .name = "Saturation", | ||
1099 | .minimum = 0, | ||
1100 | .maximum = 127, | ||
1101 | .step = 1, | ||
1102 | .default_value = 64, | ||
1103 | .flags = 0, | ||
1104 | }, { | ||
1105 | .id = V4L2_CID_HUE, | ||
1106 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1107 | .name = "Hue", | ||
1108 | .minimum = -128, | ||
1109 | .maximum = 127, | ||
1110 | .step = 1, | ||
1111 | .default_value = 0, | ||
1112 | .flags = 0, | ||
1113 | }, | ||
1114 | }; | ||
1115 | |||
1116 | /* ----------------------------------------------------------------------- */ | ||
1117 | |||
1118 | static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) | 1093 | static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) |
1119 | { | 1094 | { |
1120 | struct saa7115_state *state = i2c_get_clientdata(client); | 1095 | struct saa7115_state *state = i2c_get_clientdata(client); |
@@ -1158,14 +1133,16 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar | |||
1158 | case VIDIOC_QUERYCTRL: | 1133 | case VIDIOC_QUERYCTRL: |
1159 | { | 1134 | { |
1160 | struct v4l2_queryctrl *qc = arg; | 1135 | struct v4l2_queryctrl *qc = arg; |
1161 | int i; | ||
1162 | 1136 | ||
1163 | for (i = 0; i < ARRAY_SIZE(saa7115_qctrl); i++) | 1137 | switch (qc->id) { |
1164 | if (qc->id && qc->id == saa7115_qctrl[i].id) { | 1138 | case V4L2_CID_BRIGHTNESS: |
1165 | memcpy(qc, &saa7115_qctrl[i], sizeof(*qc)); | 1139 | case V4L2_CID_CONTRAST: |
1166 | return 0; | 1140 | case V4L2_CID_SATURATION: |
1167 | } | 1141 | case V4L2_CID_HUE: |
1168 | return -EINVAL; | 1142 | return v4l2_ctrl_query_fill_std(qc); |
1143 | default: | ||
1144 | return -EINVAL; | ||
1145 | } | ||
1169 | } | 1146 | } |
1170 | 1147 | ||
1171 | case VIDIOC_G_STD: | 1148 | case VIDIOC_G_STD: |
@@ -1221,34 +1198,6 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar | |||
1221 | break; | 1198 | break; |
1222 | } | 1199 | } |
1223 | 1200 | ||
1224 | case VIDIOC_G_INPUT: | ||
1225 | *(int *)arg = state->input; | ||
1226 | break; | ||
1227 | |||
1228 | case VIDIOC_S_INPUT: | ||
1229 | v4l_dbg(1, debug, client, "decoder set input %d\n", *iarg); | ||
1230 | /* inputs from 0-9 are available */ | ||
1231 | if (*iarg < 0 || *iarg > 9) { | ||
1232 | return -EINVAL; | ||
1233 | } | ||
1234 | |||
1235 | if (state->input == *iarg) | ||
1236 | break; | ||
1237 | v4l_dbg(1, debug, client, "now setting %s input\n", | ||
1238 | *iarg >= 6 ? "S-Video" : "Composite"); | ||
1239 | state->input = *iarg; | ||
1240 | |||
1241 | /* select mode */ | ||
1242 | saa7115_write(client, 0x02, | ||
1243 | (saa7115_read(client, 0x02) & 0xf0) | | ||
1244 | state->input); | ||
1245 | |||
1246 | /* bypass chrominance trap for modes 6..9 */ | ||
1247 | saa7115_write(client, 0x09, | ||
1248 | (saa7115_read(client, 0x09) & 0x7f) | | ||
1249 | (state->input < 6 ? 0x0 : 0x80)); | ||
1250 | break; | ||
1251 | |||
1252 | case VIDIOC_STREAMON: | 1201 | case VIDIOC_STREAMON: |
1253 | case VIDIOC_STREAMOFF: | 1202 | case VIDIOC_STREAMOFF: |
1254 | v4l_dbg(1, debug, client, "%s output\n", | 1203 | v4l_dbg(1, debug, client, "%s output\n", |
@@ -1260,6 +1209,21 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar | |||
1260 | } | 1209 | } |
1261 | break; | 1210 | break; |
1262 | 1211 | ||
1212 | case VIDIOC_INT_S_CRYSTAL_FREQ: | ||
1213 | { | ||
1214 | struct v4l2_crystal_freq *freq = arg; | ||
1215 | |||
1216 | if (freq->freq != SAA7115_FREQ_32_11_MHZ && | ||
1217 | freq->freq != SAA7115_FREQ_24_576_MHZ) | ||
1218 | return -EINVAL; | ||
1219 | state->crystal_freq = freq->freq; | ||
1220 | state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4; | ||
1221 | state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0; | ||
1222 | state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0; | ||
1223 | saa7115_set_audio_clock_freq(client, state->audclk_freq); | ||
1224 | break; | ||
1225 | } | ||
1226 | |||
1263 | case VIDIOC_INT_DECODE_VBI_LINE: | 1227 | case VIDIOC_INT_DECODE_VBI_LINE: |
1264 | saa7115_decode_vbi_line(client, arg); | 1228 | saa7115_decode_vbi_line(client, arg); |
1265 | break; | 1229 | break; |
@@ -1401,10 +1365,13 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1401 | v4l_dbg(1, debug, client, "writing init values\n"); | 1365 | v4l_dbg(1, debug, client, "writing init values\n"); |
1402 | 1366 | ||
1403 | /* init to 60hz/48khz */ | 1367 | /* init to 60hz/48khz */ |
1404 | if (state->ident == V4L2_IDENT_SAA7113) | 1368 | if (state->ident == V4L2_IDENT_SAA7113) { |
1369 | state->crystal_freq = SAA7115_FREQ_24_576_MHZ; | ||
1405 | saa7115_writeregs(client, saa7113_init_auto_input); | 1370 | saa7115_writeregs(client, saa7113_init_auto_input); |
1406 | else | 1371 | } else { |
1372 | state->crystal_freq = SAA7115_FREQ_32_11_MHZ; | ||
1407 | saa7115_writeregs(client, saa7115_init_auto_input); | 1373 | saa7115_writeregs(client, saa7115_init_auto_input); |
1374 | } | ||
1408 | saa7115_writeregs(client, saa7115_init_misc); | 1375 | saa7115_writeregs(client, saa7115_init_misc); |
1409 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); | 1376 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); |
1410 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); | 1377 | saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); |
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index c271e2e14105..ad401bdefeaf 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c | |||
@@ -270,7 +270,7 @@ static const char * const wss_strs[] = { | |||
270 | "letterbox 16:9 top", | 270 | "letterbox 16:9 top", |
271 | "invalid", | 271 | "invalid", |
272 | "invalid", | 272 | "invalid", |
273 | "16:9 full format anamorphic" | 273 | "16:9 full format anamorphic", |
274 | "4:3 full format", | 274 | "4:3 full format", |
275 | "invalid", | 275 | "invalid", |
276 | "invalid", | 276 | "invalid", |
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 0e0ba50946e8..de7b9e6e932a 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -39,6 +39,23 @@ enum saa6752hs_videoformat { | |||
39 | SAA6752HS_VF_UNKNOWN, | 39 | SAA6752HS_VF_UNKNOWN, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct saa6752hs_mpeg_params { | ||
43 | /* transport streams */ | ||
44 | __u16 ts_pid_pmt; | ||
45 | __u16 ts_pid_audio; | ||
46 | __u16 ts_pid_video; | ||
47 | __u16 ts_pid_pcr; | ||
48 | |||
49 | /* audio */ | ||
50 | enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate; | ||
51 | |||
52 | /* video */ | ||
53 | enum v4l2_mpeg_video_aspect vi_aspect; | ||
54 | enum v4l2_mpeg_video_bitrate_mode vi_bitrate_mode; | ||
55 | __u32 vi_bitrate; | ||
56 | __u32 vi_bitrate_peak; | ||
57 | }; | ||
58 | |||
42 | static const struct v4l2_format v4l2_format_table[] = | 59 | static const struct v4l2_format v4l2_format_table[] = |
43 | { | 60 | { |
44 | [SAA6752HS_VF_D1] = | 61 | [SAA6752HS_VF_D1] = |
@@ -55,18 +72,19 @@ static const struct v4l2_format v4l2_format_table[] = | |||
55 | 72 | ||
56 | struct saa6752hs_state { | 73 | struct saa6752hs_state { |
57 | struct i2c_client client; | 74 | struct i2c_client client; |
58 | struct v4l2_mpeg_compression params; | 75 | struct v4l2_mpeg_compression old_params; |
76 | struct saa6752hs_mpeg_params params; | ||
59 | enum saa6752hs_videoformat video_format; | 77 | enum saa6752hs_videoformat video_format; |
60 | v4l2_std_id standard; | 78 | v4l2_std_id standard; |
61 | }; | 79 | }; |
62 | 80 | ||
63 | enum saa6752hs_command { | 81 | enum saa6752hs_command { |
64 | SAA6752HS_COMMAND_RESET = 0, | 82 | SAA6752HS_COMMAND_RESET = 0, |
65 | SAA6752HS_COMMAND_STOP = 1, | 83 | SAA6752HS_COMMAND_STOP = 1, |
66 | SAA6752HS_COMMAND_START = 2, | 84 | SAA6752HS_COMMAND_START = 2, |
67 | SAA6752HS_COMMAND_PAUSE = 3, | 85 | SAA6752HS_COMMAND_PAUSE = 3, |
68 | SAA6752HS_COMMAND_RECONFIGURE = 4, | 86 | SAA6752HS_COMMAND_RECONFIGURE = 4, |
69 | SAA6752HS_COMMAND_SLEEP = 5, | 87 | SAA6752HS_COMMAND_SLEEP = 5, |
70 | SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6, | 88 | SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6, |
71 | 89 | ||
72 | SAA6752HS_COMMAND_MAX | 90 | SAA6752HS_COMMAND_MAX |
@@ -129,7 +147,22 @@ static u8 PMT[] = { | |||
129 | 0x00, 0x00, 0x00, 0x00 /* CRC32 */ | 147 | 0x00, 0x00, 0x00, 0x00 /* CRC32 */ |
130 | }; | 148 | }; |
131 | 149 | ||
132 | static struct v4l2_mpeg_compression param_defaults = | 150 | static struct saa6752hs_mpeg_params param_defaults = |
151 | { | ||
152 | .ts_pid_pmt = 16, | ||
153 | .ts_pid_video = 260, | ||
154 | .ts_pid_audio = 256, | ||
155 | .ts_pid_pcr = 259, | ||
156 | |||
157 | .vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3, | ||
158 | .vi_bitrate = 4000, | ||
159 | .vi_bitrate_peak = 6000, | ||
160 | .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, | ||
161 | |||
162 | .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K, | ||
163 | }; | ||
164 | |||
165 | static struct v4l2_mpeg_compression old_param_defaults = | ||
133 | { | 166 | { |
134 | .st_type = V4L2_MPEG_TS_2, | 167 | .st_type = V4L2_MPEG_TS_2, |
135 | .st_bitrate = { | 168 | .st_bitrate = { |
@@ -228,45 +261,57 @@ static int saa6752hs_chip_command(struct i2c_client* client, | |||
228 | 261 | ||
229 | 262 | ||
230 | static int saa6752hs_set_bitrate(struct i2c_client* client, | 263 | static int saa6752hs_set_bitrate(struct i2c_client* client, |
231 | struct v4l2_mpeg_compression* params) | 264 | struct saa6752hs_mpeg_params* params) |
232 | { | 265 | { |
233 | u8 buf[3]; | 266 | u8 buf[3]; |
267 | int tot_bitrate; | ||
234 | 268 | ||
235 | /* set the bitrate mode */ | 269 | /* set the bitrate mode */ |
236 | buf[0] = 0x71; | 270 | buf[0] = 0x71; |
237 | buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1; | 271 | buf[1] = (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ? 0 : 1; |
238 | i2c_master_send(client, buf, 2); | 272 | i2c_master_send(client, buf, 2); |
239 | 273 | ||
240 | /* set the video bitrate */ | 274 | /* set the video bitrate */ |
241 | if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) { | 275 | if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { |
242 | /* set the target bitrate */ | 276 | /* set the target bitrate */ |
243 | buf[0] = 0x80; | 277 | buf[0] = 0x80; |
244 | buf[1] = params->vi_bitrate.target >> 8; | 278 | buf[1] = params->vi_bitrate >> 8; |
245 | buf[2] = params->vi_bitrate.target & 0xff; | 279 | buf[2] = params->vi_bitrate & 0xff; |
246 | i2c_master_send(client, buf, 3); | 280 | i2c_master_send(client, buf, 3); |
247 | 281 | ||
248 | /* set the max bitrate */ | 282 | /* set the max bitrate */ |
249 | buf[0] = 0x81; | 283 | buf[0] = 0x81; |
250 | buf[1] = params->vi_bitrate.max >> 8; | 284 | buf[1] = params->vi_bitrate_peak >> 8; |
251 | buf[2] = params->vi_bitrate.max & 0xff; | 285 | buf[2] = params->vi_bitrate_peak & 0xff; |
252 | i2c_master_send(client, buf, 3); | 286 | i2c_master_send(client, buf, 3); |
287 | tot_bitrate = params->vi_bitrate_peak; | ||
253 | } else { | 288 | } else { |
254 | /* set the target bitrate (no max bitrate for CBR) */ | 289 | /* set the target bitrate (no max bitrate for CBR) */ |
255 | buf[0] = 0x81; | 290 | buf[0] = 0x81; |
256 | buf[1] = params->vi_bitrate.target >> 8; | 291 | buf[1] = params->vi_bitrate >> 8; |
257 | buf[2] = params->vi_bitrate.target & 0xff; | 292 | buf[2] = params->vi_bitrate & 0xff; |
258 | i2c_master_send(client, buf, 3); | 293 | i2c_master_send(client, buf, 3); |
294 | tot_bitrate = params->vi_bitrate; | ||
259 | } | 295 | } |
260 | 296 | ||
261 | /* set the audio bitrate */ | 297 | /* set the audio bitrate */ |
262 | buf[0] = 0x94; | 298 | buf[0] = 0x94; |
263 | buf[1] = (256 == params->au_bitrate.target) ? 0 : 1; | 299 | buf[1] = (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 0 : 1; |
264 | i2c_master_send(client, buf, 2); | 300 | i2c_master_send(client, buf, 2); |
301 | tot_bitrate += (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 256 : 384; | ||
302 | |||
303 | /* Note: the total max bitrate is determined by adding the video and audio | ||
304 | bitrates together and also adding an extra 768kbit/s to stay on the | ||
305 | safe side. If more control should be required, then an extra MPEG control | ||
306 | should be added. */ | ||
307 | tot_bitrate += 768; | ||
308 | if (tot_bitrate > MPEG_TOTAL_TARGET_BITRATE_MAX) | ||
309 | tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX; | ||
265 | 310 | ||
266 | /* set the total bitrate */ | 311 | /* set the total bitrate */ |
267 | buf[0] = 0xb1; | 312 | buf[0] = 0xb1; |
268 | buf[1] = params->st_bitrate.target >> 8; | 313 | buf[1] = tot_bitrate >> 8; |
269 | buf[2] = params->st_bitrate.target & 0xff; | 314 | buf[2] = tot_bitrate & 0xff; |
270 | i2c_master_send(client, buf, 3); | 315 | i2c_master_send(client, buf, 3); |
271 | 316 | ||
272 | return 0; | 317 | return 0; |
@@ -318,50 +363,188 @@ static void saa6752hs_set_subsampling(struct i2c_client* client, | |||
318 | } | 363 | } |
319 | 364 | ||
320 | 365 | ||
321 | static void saa6752hs_set_params(struct i2c_client* client, | 366 | static void saa6752hs_old_set_params(struct i2c_client* client, |
322 | struct v4l2_mpeg_compression* params) | 367 | struct v4l2_mpeg_compression* params) |
323 | { | 368 | { |
324 | struct saa6752hs_state *h = i2c_get_clientdata(client); | 369 | struct saa6752hs_state *h = i2c_get_clientdata(client); |
325 | 370 | ||
326 | /* check PIDs */ | 371 | /* check PIDs */ |
327 | if (params->ts_pid_pmt <= MPEG_PID_MAX) | 372 | if (params->ts_pid_pmt <= MPEG_PID_MAX) { |
373 | h->old_params.ts_pid_pmt = params->ts_pid_pmt; | ||
328 | h->params.ts_pid_pmt = params->ts_pid_pmt; | 374 | h->params.ts_pid_pmt = params->ts_pid_pmt; |
329 | if (params->ts_pid_pcr <= MPEG_PID_MAX) | 375 | } |
376 | if (params->ts_pid_pcr <= MPEG_PID_MAX) { | ||
377 | h->old_params.ts_pid_pcr = params->ts_pid_pcr; | ||
330 | h->params.ts_pid_pcr = params->ts_pid_pcr; | 378 | h->params.ts_pid_pcr = params->ts_pid_pcr; |
331 | if (params->ts_pid_video <= MPEG_PID_MAX) | 379 | } |
380 | if (params->ts_pid_video <= MPEG_PID_MAX) { | ||
381 | h->old_params.ts_pid_video = params->ts_pid_video; | ||
332 | h->params.ts_pid_video = params->ts_pid_video; | 382 | h->params.ts_pid_video = params->ts_pid_video; |
333 | if (params->ts_pid_audio <= MPEG_PID_MAX) | 383 | } |
384 | if (params->ts_pid_audio <= MPEG_PID_MAX) { | ||
385 | h->old_params.ts_pid_audio = params->ts_pid_audio; | ||
334 | h->params.ts_pid_audio = params->ts_pid_audio; | 386 | h->params.ts_pid_audio = params->ts_pid_audio; |
387 | } | ||
335 | 388 | ||
336 | /* check bitrate parameters */ | 389 | /* check bitrate parameters */ |
337 | if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) || | 390 | if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) || |
338 | (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) | 391 | (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) { |
339 | h->params.vi_bitrate.mode = params->vi_bitrate.mode; | 392 | h->old_params.vi_bitrate.mode = params->vi_bitrate.mode; |
393 | h->params.vi_bitrate_mode = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? | ||
394 | V4L2_MPEG_VIDEO_BITRATE_MODE_VBR : V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; | ||
395 | } | ||
340 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) | 396 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) |
341 | h->params.st_bitrate.target = params->st_bitrate.target; | 397 | h->old_params.st_bitrate.target = params->st_bitrate.target; |
342 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) | 398 | if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) |
343 | h->params.vi_bitrate.target = params->vi_bitrate.target; | 399 | h->old_params.vi_bitrate.target = params->vi_bitrate.target; |
344 | if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) | 400 | if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) |
345 | h->params.vi_bitrate.max = params->vi_bitrate.max; | 401 | h->old_params.vi_bitrate.max = params->vi_bitrate.max; |
346 | if (params->au_bitrate.mode != V4L2_BITRATE_NONE) | 402 | if (params->au_bitrate.mode != V4L2_BITRATE_NONE) |
347 | h->params.au_bitrate.target = params->au_bitrate.target; | 403 | h->old_params.au_bitrate.target = params->au_bitrate.target; |
348 | 404 | ||
349 | /* aspect ratio */ | 405 | /* aspect ratio */ |
350 | if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 || | 406 | if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 || |
351 | params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) | 407 | params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) { |
352 | h->params.vi_aspect_ratio = params->vi_aspect_ratio; | 408 | h->old_params.vi_aspect_ratio = params->vi_aspect_ratio; |
409 | if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3) | ||
410 | h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3; | ||
411 | else | ||
412 | h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_16x9; | ||
413 | } | ||
353 | 414 | ||
354 | /* range checks */ | 415 | /* range checks */ |
355 | if (h->params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX) | 416 | if (h->old_params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX) |
356 | h->params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX; | 417 | h->old_params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX; |
357 | if (h->params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX) | 418 | if (h->old_params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX) |
358 | h->params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX; | 419 | h->old_params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX; |
359 | if (h->params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX) | 420 | if (h->old_params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX) |
360 | h->params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX; | 421 | h->old_params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX; |
361 | if (h->params.au_bitrate.target <= 256) | 422 | h->params.vi_bitrate = params->vi_bitrate.target; |
362 | h->params.au_bitrate.target = 256; | 423 | h->params.vi_bitrate_peak = params->vi_bitrate.max; |
424 | if (h->old_params.au_bitrate.target <= 256) { | ||
425 | h->old_params.au_bitrate.target = 256; | ||
426 | h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K; | ||
427 | } | ||
428 | else { | ||
429 | h->old_params.au_bitrate.target = 384; | ||
430 | h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_384K; | ||
431 | } | ||
432 | } | ||
433 | |||
434 | static int handle_ctrl(struct saa6752hs_mpeg_params *params, | ||
435 | struct v4l2_ext_control *ctrl, int cmd) | ||
436 | { | ||
437 | int old = 0, new; | ||
438 | int set = cmd == VIDIOC_S_EXT_CTRLS; | ||
439 | |||
440 | new = ctrl->value; | ||
441 | switch (ctrl->id) { | ||
442 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
443 | old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; | ||
444 | if (set && new != old) | ||
445 | return -ERANGE; | ||
446 | new = old; | ||
447 | break; | ||
448 | case V4L2_CID_MPEG_STREAM_PID_PMT: | ||
449 | old = params->ts_pid_pmt; | ||
450 | if (set && new > MPEG_PID_MAX) | ||
451 | return -ERANGE; | ||
452 | if (new > MPEG_PID_MAX) | ||
453 | new = MPEG_PID_MAX; | ||
454 | params->ts_pid_pmt = new; | ||
455 | break; | ||
456 | case V4L2_CID_MPEG_STREAM_PID_AUDIO: | ||
457 | old = params->ts_pid_audio; | ||
458 | if (set && new > MPEG_PID_MAX) | ||
459 | return -ERANGE; | ||
460 | if (new > MPEG_PID_MAX) | ||
461 | new = MPEG_PID_MAX; | ||
462 | params->ts_pid_audio = new; | ||
463 | break; | ||
464 | case V4L2_CID_MPEG_STREAM_PID_VIDEO: | ||
465 | old = params->ts_pid_video; | ||
466 | if (set && new > MPEG_PID_MAX) | ||
467 | return -ERANGE; | ||
468 | if (new > MPEG_PID_MAX) | ||
469 | new = MPEG_PID_MAX; | ||
470 | params->ts_pid_video = new; | ||
471 | break; | ||
472 | case V4L2_CID_MPEG_STREAM_PID_PCR: | ||
473 | old = params->ts_pid_pcr; | ||
474 | if (set && new > MPEG_PID_MAX) | ||
475 | return -ERANGE; | ||
476 | if (new > MPEG_PID_MAX) | ||
477 | new = MPEG_PID_MAX; | ||
478 | params->ts_pid_pcr = new; | ||
479 | break; | ||
480 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
481 | old = V4L2_MPEG_AUDIO_ENCODING_LAYER_2; | ||
482 | if (set && new != old) | ||
483 | return -ERANGE; | ||
484 | new = old; | ||
485 | break; | ||
486 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: | ||
487 | old = params->au_l2_bitrate; | ||
488 | if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K && | ||
489 | new != V4L2_MPEG_AUDIO_L2_BITRATE_384K) | ||
490 | return -ERANGE; | ||
491 | if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K) | ||
492 | new = V4L2_MPEG_AUDIO_L2_BITRATE_256K; | ||
493 | else | ||
494 | new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; | ||
495 | params->au_l2_bitrate = new; | ||
496 | break; | ||
497 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | ||
498 | old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; | ||
499 | if (set && new != old) | ||
500 | return -ERANGE; | ||
501 | new = old; | ||
502 | break; | ||
503 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
504 | old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2; | ||
505 | if (set && new != old) | ||
506 | return -ERANGE; | ||
507 | new = old; | ||
508 | break; | ||
509 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
510 | old = params->vi_aspect; | ||
511 | if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 && | ||
512 | new != V4L2_MPEG_VIDEO_ASPECT_4x3) | ||
513 | return -ERANGE; | ||
514 | if (new != V4L2_MPEG_VIDEO_ASPECT_16x9) | ||
515 | new = V4L2_MPEG_VIDEO_ASPECT_4x3; | ||
516 | params->vi_aspect = new; | ||
517 | break; | ||
518 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
519 | old = params->vi_bitrate * 1000; | ||
520 | new = 1000 * (new / 1000); | ||
521 | if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
522 | return -ERANGE; | ||
523 | if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
524 | new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; | ||
525 | params->vi_bitrate = new / 1000; | ||
526 | break; | ||
527 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
528 | old = params->vi_bitrate_peak * 1000; | ||
529 | new = 1000 * (new / 1000); | ||
530 | if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
531 | return -ERANGE; | ||
532 | if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) | ||
533 | new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; | ||
534 | params->vi_bitrate_peak = new / 1000; | ||
535 | break; | ||
536 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
537 | old = params->vi_bitrate_mode; | ||
538 | params->vi_bitrate_mode = new; | ||
539 | break; | ||
540 | default: | ||
541 | return -EINVAL; | ||
542 | } | ||
543 | if (cmd == VIDIOC_G_EXT_CTRLS) | ||
544 | ctrl->value = old; | ||
363 | else | 545 | else |
364 | h->params.au_bitrate.target = 384; | 546 | ctrl->value = new; |
547 | return 0; | ||
365 | } | 548 | } |
366 | 549 | ||
367 | static int saa6752hs_init(struct i2c_client* client) | 550 | static int saa6752hs_init(struct i2c_client* client) |
@@ -395,22 +578,22 @@ static int saa6752hs_init(struct i2c_client* client) | |||
395 | buf[2] = 0x0D; | 578 | buf[2] = 0x0D; |
396 | i2c_master_send(client,buf,3); | 579 | i2c_master_send(client,buf,3); |
397 | 580 | ||
398 | /* Set minimum Q-scale {4} */ | 581 | /* Set minimum Q-scale {4} */ |
399 | buf[0] = 0x82; | 582 | buf[0] = 0x82; |
400 | buf[1] = 0x04; | 583 | buf[1] = 0x04; |
401 | i2c_master_send(client,buf,2); | 584 | i2c_master_send(client,buf,2); |
402 | 585 | ||
403 | /* Set maximum Q-scale {12} */ | 586 | /* Set maximum Q-scale {12} */ |
404 | buf[0] = 0x83; | 587 | buf[0] = 0x83; |
405 | buf[1] = 0x0C; | 588 | buf[1] = 0x0C; |
406 | i2c_master_send(client,buf,2); | 589 | i2c_master_send(client,buf,2); |
407 | 590 | ||
408 | /* Set Output Protocol */ | 591 | /* Set Output Protocol */ |
409 | buf[0] = 0xD0; | 592 | buf[0] = 0xD0; |
410 | buf[1] = 0x81; | 593 | buf[1] = 0x81; |
411 | i2c_master_send(client,buf,2); | 594 | i2c_master_send(client,buf,2); |
412 | 595 | ||
413 | /* Set video output stream format {TS} */ | 596 | /* Set video output stream format {TS} */ |
414 | buf[0] = 0xB0; | 597 | buf[0] = 0xB0; |
415 | buf[1] = 0x05; | 598 | buf[1] = 0x05; |
416 | i2c_master_send(client,buf,2); | 599 | i2c_master_send(client,buf,2); |
@@ -441,7 +624,7 @@ static int saa6752hs_init(struct i2c_client* client) | |||
441 | localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; | 624 | localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; |
442 | localPMT[sizeof(PMT) - 1] = crc & 0xFF; | 625 | localPMT[sizeof(PMT) - 1] = crc & 0xFF; |
443 | 626 | ||
444 | /* Set Audio PID */ | 627 | /* Set Audio PID */ |
445 | buf[0] = 0xC1; | 628 | buf[0] = 0xC1; |
446 | buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; | 629 | buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; |
447 | buf[2] = h->params.ts_pid_audio & 0xFF; | 630 | buf[2] = h->params.ts_pid_audio & 0xFF; |
@@ -489,11 +672,11 @@ static int saa6752hs_init(struct i2c_client* client) | |||
489 | buf[3] = 0x82; | 672 | buf[3] = 0x82; |
490 | buf[4] = 0xB0; | 673 | buf[4] = 0xB0; |
491 | buf[5] = buf2[0]; | 674 | buf[5] = buf2[0]; |
492 | switch(h->params.vi_aspect_ratio) { | 675 | switch(h->params.vi_aspect) { |
493 | case V4L2_MPEG_ASPECT_16_9: | 676 | case V4L2_MPEG_VIDEO_ASPECT_16x9: |
494 | buf[6] = buf2[1] | 0x40; | 677 | buf[6] = buf2[1] | 0x40; |
495 | break; | 678 | break; |
496 | case V4L2_MPEG_ASPECT_4_3: | 679 | case V4L2_MPEG_VIDEO_ASPECT_4x3: |
497 | default: | 680 | default: |
498 | buf[6] = buf2[1] & 0xBF; | 681 | buf[6] = buf2[1] & 0xBF; |
499 | break; | 682 | break; |
@@ -515,6 +698,7 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) | |||
515 | return -ENOMEM; | 698 | return -ENOMEM; |
516 | h->client = client_template; | 699 | h->client = client_template; |
517 | h->params = param_defaults; | 700 | h->params = param_defaults; |
701 | h->old_params = old_param_defaults; | ||
518 | h->client.adapter = adap; | 702 | h->client.adapter = adap; |
519 | h->client.addr = addr; | 703 | h->client.addr = addr; |
520 | 704 | ||
@@ -550,20 +734,45 @@ static int | |||
550 | saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | 734 | saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) |
551 | { | 735 | { |
552 | struct saa6752hs_state *h = i2c_get_clientdata(client); | 736 | struct saa6752hs_state *h = i2c_get_clientdata(client); |
553 | struct v4l2_mpeg_compression *params = arg; | 737 | struct v4l2_ext_controls *ctrls = arg; |
738 | struct v4l2_mpeg_compression *old_params = arg; | ||
739 | struct saa6752hs_mpeg_params params; | ||
554 | int err = 0; | 740 | int err = 0; |
741 | int i; | ||
555 | 742 | ||
556 | switch (cmd) { | 743 | switch (cmd) { |
557 | case VIDIOC_S_MPEGCOMP: | 744 | case VIDIOC_S_MPEGCOMP: |
558 | if (NULL == params) { | 745 | if (NULL == old_params) { |
559 | /* apply settings and start encoder */ | 746 | /* apply settings and start encoder */ |
560 | saa6752hs_init(client); | 747 | saa6752hs_init(client); |
561 | break; | 748 | break; |
562 | } | 749 | } |
563 | saa6752hs_set_params(client, params); | 750 | saa6752hs_old_set_params(client, old_params); |
564 | /* fall through */ | 751 | /* fall through */ |
565 | case VIDIOC_G_MPEGCOMP: | 752 | case VIDIOC_G_MPEGCOMP: |
566 | *params = h->params; | 753 | *old_params = h->old_params; |
754 | break; | ||
755 | case VIDIOC_S_EXT_CTRLS: | ||
756 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
757 | return -EINVAL; | ||
758 | if (ctrls->count == 0) { | ||
759 | /* apply settings and start encoder */ | ||
760 | saa6752hs_init(client); | ||
761 | break; | ||
762 | } | ||
763 | /* fall through */ | ||
764 | case VIDIOC_TRY_EXT_CTRLS: | ||
765 | case VIDIOC_G_EXT_CTRLS: | ||
766 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
767 | return -EINVAL; | ||
768 | params = h->params; | ||
769 | for (i = 0; i < ctrls->count; i++) { | ||
770 | if ((err = handle_ctrl(¶ms, ctrls->controls + i, cmd))) { | ||
771 | ctrls->error_idx = i; | ||
772 | return err; | ||
773 | } | ||
774 | } | ||
775 | h->params = params; | ||
567 | break; | 776 | break; |
568 | case VIDIOC_G_FMT: | 777 | case VIDIOC_G_FMT: |
569 | { | 778 | { |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index bb3e0ba946d3..d77e6a8d9432 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -818,7 +818,7 @@ static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol, | |||
818 | break; | 818 | break; |
819 | } | 819 | } |
820 | 820 | ||
821 | /* output xbar always main channel */ | 821 | /* output xbar always main channel */ |
822 | saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10); | 822 | saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10); |
823 | 823 | ||
824 | if (left || right) { // We've got data, turn the input on | 824 | if (left || right) { // We've got data, turn the input on |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 86eae3528330..927413aded10 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -2160,7 +2160,7 @@ struct saa7134_board saa7134_boards[] = { | |||
2160 | .radio = { | 2160 | .radio = { |
2161 | .name = name_radio, | 2161 | .name = name_radio, |
2162 | .amux = LINE2, | 2162 | .amux = LINE2, |
2163 | }, | 2163 | }, |
2164 | }, | 2164 | }, |
2165 | [SAA7134_BOARD_GOTVIEW_7135] = { | 2165 | [SAA7134_BOARD_GOTVIEW_7135] = { |
2166 | /* Mike Baikov <mike@baikov.com> */ | 2166 | /* Mike Baikov <mike@baikov.com> */ |
@@ -2842,6 +2842,55 @@ struct saa7134_board saa7134_boards[] = { | |||
2842 | .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */ | 2842 | .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */ |
2843 | }, | 2843 | }, |
2844 | }, | 2844 | }, |
2845 | [SAA7134_BOARD_FLYVIDEO3000_NTSC] = { | ||
2846 | /* "Zac Bowling" <zac@zacbowling.com> */ | ||
2847 | .name = "LifeView FlyVIDEO3000 (NTSC)", | ||
2848 | .audio_clock = 0x00200000, | ||
2849 | .tuner_type = TUNER_PHILIPS_NTSC, | ||
2850 | .radio_type = UNSET, | ||
2851 | .tuner_addr = ADDR_UNSET, | ||
2852 | .radio_addr = ADDR_UNSET, | ||
2853 | |||
2854 | .gpiomask = 0xe000, | ||
2855 | .inputs = {{ | ||
2856 | .name = name_tv, | ||
2857 | .vmux = 1, | ||
2858 | .amux = TV, | ||
2859 | .gpio = 0x8000, | ||
2860 | .tv = 1, | ||
2861 | },{ | ||
2862 | .name = name_tv_mono, | ||
2863 | .vmux = 1, | ||
2864 | .amux = LINE2, | ||
2865 | .gpio = 0x0000, | ||
2866 | .tv = 1, | ||
2867 | },{ | ||
2868 | .name = name_comp1, | ||
2869 | .vmux = 0, | ||
2870 | .amux = LINE2, | ||
2871 | .gpio = 0x4000, | ||
2872 | },{ | ||
2873 | .name = name_comp2, | ||
2874 | .vmux = 3, | ||
2875 | .amux = LINE2, | ||
2876 | .gpio = 0x4000, | ||
2877 | },{ | ||
2878 | .name = name_svideo, | ||
2879 | .vmux = 8, | ||
2880 | .amux = LINE2, | ||
2881 | .gpio = 0x4000, | ||
2882 | }}, | ||
2883 | .radio = { | ||
2884 | .name = name_radio, | ||
2885 | .amux = LINE2, | ||
2886 | .gpio = 0x2000, | ||
2887 | }, | ||
2888 | .mute = { | ||
2889 | .name = name_mute, | ||
2890 | .amux = TV, | ||
2891 | .gpio = 0x8000, | ||
2892 | }, | ||
2893 | }, | ||
2845 | }; | 2894 | }; |
2846 | 2895 | ||
2847 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 2896 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); |
@@ -2901,6 +2950,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2901 | },{ | 2950 | },{ |
2902 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2951 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2903 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 2952 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
2953 | .subvendor = 0x5169, | ||
2954 | .subdevice = 0x0138, | ||
2955 | .driver_data = SAA7134_BOARD_FLYVIDEO3000_NTSC, | ||
2956 | },{ | ||
2957 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2958 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
2904 | .subvendor = 0x5168, | 2959 | .subvendor = 0x5168, |
2905 | .subdevice = 0x0138, | 2960 | .subdevice = 0x0138, |
2906 | .driver_data = SAA7134_BOARD_FLYVIDEO3000, | 2961 | .driver_data = SAA7134_BOARD_FLYVIDEO3000, |
@@ -3459,6 +3514,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
3459 | switch (dev->board) { | 3514 | switch (dev->board) { |
3460 | case SAA7134_BOARD_FLYVIDEO2000: | 3515 | case SAA7134_BOARD_FLYVIDEO2000: |
3461 | case SAA7134_BOARD_FLYVIDEO3000: | 3516 | case SAA7134_BOARD_FLYVIDEO3000: |
3517 | case SAA7134_BOARD_FLYVIDEO3000_NTSC: | ||
3462 | dev->has_remote = SAA7134_REMOTE_GPIO; | 3518 | dev->has_remote = SAA7134_REMOTE_GPIO; |
3463 | board_flyvideo(dev); | 3519 | board_flyvideo(dev); |
3464 | break; | 3520 | break; |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 222a36c38917..279828b8f299 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -132,9 +132,8 @@ static int mt352_aver777_init(struct dvb_frontend* fe) | |||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, | 135 | static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe, |
136 | struct dvb_frontend_parameters* params, | 136 | struct dvb_frontend_parameters* params) |
137 | u8* pllbuf) | ||
138 | { | 137 | { |
139 | u8 off[] = { 0x00, 0xf1}; | 138 | u8 off[] = { 0x00, 0xf1}; |
140 | u8 on[] = { 0x00, 0x71}; | 139 | u8 on[] = { 0x00, 0x71}; |
@@ -147,30 +146,31 @@ static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, | |||
147 | f.tuner = 0; | 146 | f.tuner = 0; |
148 | f.type = V4L2_TUNER_DIGITAL_TV; | 147 | f.type = V4L2_TUNER_DIGITAL_TV; |
149 | f.frequency = params->frequency / 1000 * 16 / 1000; | 148 | f.frequency = params->frequency / 1000 * 16 / 1000; |
149 | if (fe->ops.i2c_gate_ctrl) | ||
150 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
150 | i2c_transfer(&dev->i2c_adap, &msg, 1); | 151 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
151 | saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f); | 152 | saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f); |
152 | msg.buf = on; | 153 | msg.buf = on; |
154 | if (fe->ops.i2c_gate_ctrl) | ||
155 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
153 | i2c_transfer(&dev->i2c_adap, &msg, 1); | 156 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
154 | 157 | ||
155 | pinnacle_antenna_pwr(dev, antenna_pwr); | 158 | pinnacle_antenna_pwr(dev, antenna_pwr); |
156 | 159 | ||
157 | /* mt352 setup */ | 160 | /* mt352 setup */ |
158 | mt352_pinnacle_init(fe); | 161 | return mt352_pinnacle_init(fe); |
159 | pllbuf[0] = 0xc2; | ||
160 | pllbuf[1] = 0x00; | ||
161 | pllbuf[2] = 0x00; | ||
162 | pllbuf[3] = 0x80; | ||
163 | pllbuf[4] = 0x00; | ||
164 | return 0; | ||
165 | } | 162 | } |
166 | 163 | ||
167 | static int mt352_aver777_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8* pllbuf) | 164 | static int mt352_aver777_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) |
168 | { | 165 | { |
169 | pllbuf[0] = 0xc2; | 166 | if (buf_len < 5) |
167 | return -EINVAL; | ||
168 | |||
169 | pllbuf[0] = 0x61; | ||
170 | dvb_pll_configure(&dvb_pll_philips_td1316, pllbuf+1, | 170 | dvb_pll_configure(&dvb_pll_philips_td1316, pllbuf+1, |
171 | params->frequency, | 171 | params->frequency, |
172 | params->u.ofdm.bandwidth); | 172 | params->u.ofdm.bandwidth); |
173 | return 0; | 173 | return 5; |
174 | } | 174 | } |
175 | 175 | ||
176 | static struct mt352_config pinnacle_300i = { | 176 | static struct mt352_config pinnacle_300i = { |
@@ -179,13 +179,11 @@ static struct mt352_config pinnacle_300i = { | |||
179 | .if2 = 36150, | 179 | .if2 = 36150, |
180 | .no_tuner = 1, | 180 | .no_tuner = 1, |
181 | .demod_init = mt352_pinnacle_init, | 181 | .demod_init = mt352_pinnacle_init, |
182 | .pll_set = mt352_pinnacle_pll_set, | ||
183 | }; | 182 | }; |
184 | 183 | ||
185 | static struct mt352_config avermedia_777 = { | 184 | static struct mt352_config avermedia_777 = { |
186 | .demod_address = 0xf, | 185 | .demod_address = 0xf, |
187 | .demod_init = mt352_aver777_init, | 186 | .demod_init = mt352_aver777_init, |
188 | .pll_set = mt352_aver777_pll_set, | ||
189 | }; | 187 | }; |
190 | #endif | 188 | #endif |
191 | 189 | ||
@@ -268,6 +266,8 @@ static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_ | |||
268 | tuner_buf[2] = 0xca; | 266 | tuner_buf[2] = 0xca; |
269 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | 267 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; |
270 | 268 | ||
269 | if (fe->ops.i2c_gate_ctrl) | ||
270 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
271 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) | 271 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) |
272 | return -EIO; | 272 | return -EIO; |
273 | msleep(1); | 273 | msleep(1); |
@@ -281,6 +281,8 @@ static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe) | |||
281 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; | 281 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; |
282 | 282 | ||
283 | /* setup PLL configuration */ | 283 | /* setup PLL configuration */ |
284 | if (fe->ops.i2c_gate_ctrl) | ||
285 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
284 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) | 286 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) |
285 | return -EIO; | 287 | return -EIO; |
286 | msleep(1); | 288 | msleep(1); |
@@ -290,12 +292,12 @@ static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe) | |||
290 | 292 | ||
291 | /* ------------------------------------------------------------------ */ | 293 | /* ------------------------------------------------------------------ */ |
292 | 294 | ||
293 | static int philips_tu1216_pll_60_init(struct dvb_frontend *fe) | 295 | static int philips_tu1216_tuner_60_init(struct dvb_frontend *fe) |
294 | { | 296 | { |
295 | return philips_tda6651_pll_init(0x60, fe); | 297 | return philips_tda6651_pll_init(0x60, fe); |
296 | } | 298 | } |
297 | 299 | ||
298 | static int philips_tu1216_pll_60_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 300 | static int philips_tu1216_tuner_60_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
299 | { | 301 | { |
300 | return philips_tda6651_pll_set(0x60, fe, params); | 302 | return philips_tda6651_pll_set(0x60, fe, params); |
301 | } | 303 | } |
@@ -315,20 +317,17 @@ static struct tda1004x_config philips_tu1216_60_config = { | |||
315 | .xtal_freq = TDA10046_XTAL_4M, | 317 | .xtal_freq = TDA10046_XTAL_4M, |
316 | .agc_config = TDA10046_AGC_DEFAULT, | 318 | .agc_config = TDA10046_AGC_DEFAULT, |
317 | .if_freq = TDA10046_FREQ_3617, | 319 | .if_freq = TDA10046_FREQ_3617, |
318 | .pll_init = philips_tu1216_pll_60_init, | ||
319 | .pll_set = philips_tu1216_pll_60_set, | ||
320 | .pll_sleep = NULL, | ||
321 | .request_firmware = philips_tu1216_request_firmware, | 320 | .request_firmware = philips_tu1216_request_firmware, |
322 | }; | 321 | }; |
323 | 322 | ||
324 | /* ------------------------------------------------------------------ */ | 323 | /* ------------------------------------------------------------------ */ |
325 | 324 | ||
326 | static int philips_tu1216_pll_61_init(struct dvb_frontend *fe) | 325 | static int philips_tu1216_tuner_61_init(struct dvb_frontend *fe) |
327 | { | 326 | { |
328 | return philips_tda6651_pll_init(0x61, fe); | 327 | return philips_tda6651_pll_init(0x61, fe); |
329 | } | 328 | } |
330 | 329 | ||
331 | static int philips_tu1216_pll_61_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 330 | static int philips_tu1216_tuner_61_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
332 | { | 331 | { |
333 | return philips_tda6651_pll_set(0x61, fe, params); | 332 | return philips_tda6651_pll_set(0x61, fe, params); |
334 | } | 333 | } |
@@ -341,21 +340,20 @@ static struct tda1004x_config philips_tu1216_61_config = { | |||
341 | .xtal_freq = TDA10046_XTAL_4M, | 340 | .xtal_freq = TDA10046_XTAL_4M, |
342 | .agc_config = TDA10046_AGC_DEFAULT, | 341 | .agc_config = TDA10046_AGC_DEFAULT, |
343 | .if_freq = TDA10046_FREQ_3617, | 342 | .if_freq = TDA10046_FREQ_3617, |
344 | .pll_init = philips_tu1216_pll_61_init, | ||
345 | .pll_set = philips_tu1216_pll_61_set, | ||
346 | .pll_sleep = NULL, | ||
347 | .request_firmware = philips_tu1216_request_firmware, | 343 | .request_firmware = philips_tu1216_request_firmware, |
348 | }; | 344 | }; |
349 | 345 | ||
350 | /* ------------------------------------------------------------------ */ | 346 | /* ------------------------------------------------------------------ */ |
351 | 347 | ||
352 | static int philips_europa_pll_init(struct dvb_frontend *fe) | 348 | static int philips_europa_tuner_init(struct dvb_frontend *fe) |
353 | { | 349 | { |
354 | struct saa7134_dev *dev = fe->dvb->priv; | 350 | struct saa7134_dev *dev = fe->dvb->priv; |
355 | static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab }; | 351 | static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab }; |
356 | struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) }; | 352 | struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) }; |
357 | 353 | ||
358 | /* setup PLL configuration */ | 354 | /* setup PLL configuration */ |
355 | if (fe->ops.i2c_gate_ctrl) | ||
356 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
359 | if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) | 357 | if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) |
360 | return -EIO; | 358 | return -EIO; |
361 | msleep(1); | 359 | msleep(1); |
@@ -365,18 +363,20 @@ static int philips_europa_pll_init(struct dvb_frontend *fe) | |||
365 | init_msg.len = 0x02; | 363 | init_msg.len = 0x02; |
366 | msg[0] = 0x00; | 364 | msg[0] = 0x00; |
367 | msg[1] = 0x40; | 365 | msg[1] = 0x40; |
366 | if (fe->ops.i2c_gate_ctrl) | ||
367 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
368 | if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) | 368 | if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) |
369 | return -EIO; | 369 | return -EIO; |
370 | 370 | ||
371 | return 0; | 371 | return 0; |
372 | } | 372 | } |
373 | 373 | ||
374 | static int philips_td1316_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 374 | static int philips_td1316_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
375 | { | 375 | { |
376 | return philips_tda6651_pll_set(0x61, fe, params); | 376 | return philips_tda6651_pll_set(0x61, fe, params); |
377 | } | 377 | } |
378 | 378 | ||
379 | static void philips_europa_analog(struct dvb_frontend *fe) | 379 | static int philips_europa_tuner_sleep(struct dvb_frontend *fe) |
380 | { | 380 | { |
381 | struct saa7134_dev *dev = fe->dvb->priv; | 381 | struct saa7134_dev *dev = fe->dvb->priv; |
382 | /* this message actually turns the tuner back to analog mode */ | 382 | /* this message actually turns the tuner back to analog mode */ |
@@ -391,7 +391,20 @@ static void philips_europa_analog(struct dvb_frontend *fe) | |||
391 | analog_msg.len = 0x02; | 391 | analog_msg.len = 0x02; |
392 | msg[0] = 0x00; | 392 | msg[0] = 0x00; |
393 | msg[1] = 0x14; | 393 | msg[1] = 0x14; |
394 | if (fe->ops.i2c_gate_ctrl) | ||
395 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
394 | i2c_transfer(&dev->i2c_adap, &analog_msg, 1); | 396 | i2c_transfer(&dev->i2c_adap, &analog_msg, 1); |
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static int philips_europa_demod_sleep(struct dvb_frontend *fe) | ||
401 | { | ||
402 | struct saa7134_dev *dev = fe->dvb->priv; | ||
403 | |||
404 | if (dev->original_demod_sleep) | ||
405 | dev->original_demod_sleep(fe); | ||
406 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
407 | return 0; | ||
395 | } | 408 | } |
396 | 409 | ||
397 | static struct tda1004x_config philips_europa_config = { | 410 | static struct tda1004x_config philips_europa_config = { |
@@ -402,21 +415,20 @@ static struct tda1004x_config philips_europa_config = { | |||
402 | .xtal_freq = TDA10046_XTAL_4M, | 415 | .xtal_freq = TDA10046_XTAL_4M, |
403 | .agc_config = TDA10046_AGC_IFO_AUTO_POS, | 416 | .agc_config = TDA10046_AGC_IFO_AUTO_POS, |
404 | .if_freq = TDA10046_FREQ_052, | 417 | .if_freq = TDA10046_FREQ_052, |
405 | .pll_init = philips_europa_pll_init, | ||
406 | .pll_set = philips_td1316_pll_set, | ||
407 | .pll_sleep = philips_europa_analog, | ||
408 | .request_firmware = NULL, | 418 | .request_firmware = NULL, |
409 | }; | 419 | }; |
410 | 420 | ||
411 | /* ------------------------------------------------------------------ */ | 421 | /* ------------------------------------------------------------------ */ |
412 | 422 | ||
413 | static int philips_fmd1216_pll_init(struct dvb_frontend *fe) | 423 | static int philips_fmd1216_tuner_init(struct dvb_frontend *fe) |
414 | { | 424 | { |
415 | struct saa7134_dev *dev = fe->dvb->priv; | 425 | struct saa7134_dev *dev = fe->dvb->priv; |
416 | /* this message is to set up ATC and ALC */ | 426 | /* this message is to set up ATC and ALC */ |
417 | static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; | 427 | static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; |
418 | struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; | 428 | struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; |
419 | 429 | ||
430 | if (fe->ops.i2c_gate_ctrl) | ||
431 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
420 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) | 432 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) |
421 | return -EIO; | 433 | return -EIO; |
422 | msleep(1); | 434 | msleep(1); |
@@ -424,22 +436,27 @@ static int philips_fmd1216_pll_init(struct dvb_frontend *fe) | |||
424 | return 0; | 436 | return 0; |
425 | } | 437 | } |
426 | 438 | ||
427 | static void philips_fmd1216_analog(struct dvb_frontend *fe) | 439 | static int philips_fmd1216_tuner_sleep(struct dvb_frontend *fe) |
428 | { | 440 | { |
429 | struct saa7134_dev *dev = fe->dvb->priv; | 441 | struct saa7134_dev *dev = fe->dvb->priv; |
430 | /* this message actually turns the tuner back to analog mode */ | 442 | /* this message actually turns the tuner back to analog mode */ |
431 | static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 }; | 443 | static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 }; |
432 | struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; | 444 | struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; |
433 | 445 | ||
446 | if (fe->ops.i2c_gate_ctrl) | ||
447 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
434 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | 448 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); |
435 | msleep(1); | 449 | msleep(1); |
436 | fmd1216_init[2] = 0x86; | 450 | fmd1216_init[2] = 0x86; |
437 | fmd1216_init[3] = 0x54; | 451 | fmd1216_init[3] = 0x54; |
452 | if (fe->ops.i2c_gate_ctrl) | ||
453 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
438 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | 454 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); |
439 | msleep(1); | 455 | msleep(1); |
456 | return 0; | ||
440 | } | 457 | } |
441 | 458 | ||
442 | static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 459 | static int philips_fmd1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
443 | { | 460 | { |
444 | struct saa7134_dev *dev = fe->dvb->priv; | 461 | struct saa7134_dev *dev = fe->dvb->priv; |
445 | u8 tuner_buf[4]; | 462 | u8 tuner_buf[4]; |
@@ -516,6 +533,8 @@ static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_ | |||
516 | tuner_buf[2] = 0x80 | (cp << 6) | (mode << 3) | 4; | 533 | tuner_buf[2] = 0x80 | (cp << 6) | (mode << 3) | 4; |
517 | tuner_buf[3] = 0x40 | band; | 534 | tuner_buf[3] = 0x40 | band; |
518 | 535 | ||
536 | if (fe->ops.i2c_gate_ctrl) | ||
537 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
519 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) | 538 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) |
520 | return -EIO; | 539 | return -EIO; |
521 | return 0; | 540 | return 0; |
@@ -528,9 +547,6 @@ static struct tda1004x_config medion_cardbus = { | |||
528 | .xtal_freq = TDA10046_XTAL_16M, | 547 | .xtal_freq = TDA10046_XTAL_16M, |
529 | .agc_config = TDA10046_AGC_IFO_AUTO_NEG, | 548 | .agc_config = TDA10046_AGC_IFO_AUTO_NEG, |
530 | .if_freq = TDA10046_FREQ_3613, | 549 | .if_freq = TDA10046_FREQ_3613, |
531 | .pll_init = philips_fmd1216_pll_init, | ||
532 | .pll_set = philips_fmd1216_pll_set, | ||
533 | .pll_sleep = philips_fmd1216_analog, | ||
534 | .request_firmware = NULL, | 550 | .request_firmware = NULL, |
535 | }; | 551 | }; |
536 | 552 | ||
@@ -578,12 +594,12 @@ static struct tda827x_data tda827x_dvbt[] = { | |||
578 | { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} | 594 | { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} |
579 | }; | 595 | }; |
580 | 596 | ||
581 | static int philips_tda827x_pll_init(struct dvb_frontend *fe) | 597 | static int philips_tda827x_tuner_init(struct dvb_frontend *fe) |
582 | { | 598 | { |
583 | return 0; | 599 | return 0; |
584 | } | 600 | } |
585 | 601 | ||
586 | static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 602 | static int philips_tda827x_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
587 | { | 603 | { |
588 | struct saa7134_dev *dev = fe->dvb->priv; | 604 | struct saa7134_dev *dev = fe->dvb->priv; |
589 | u8 tuner_buf[14]; | 605 | u8 tuner_buf[14]; |
@@ -630,6 +646,8 @@ static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_ | |||
630 | tuner_buf[13] = 0x40; | 646 | tuner_buf[13] = 0x40; |
631 | 647 | ||
632 | tuner_msg.len = 14; | 648 | tuner_msg.len = 14; |
649 | if (fe->ops.i2c_gate_ctrl) | ||
650 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
633 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) | 651 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) |
634 | return -EIO; | 652 | return -EIO; |
635 | 653 | ||
@@ -638,18 +656,23 @@ static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_ | |||
638 | tuner_buf[0] = 0x30; | 656 | tuner_buf[0] = 0x30; |
639 | tuner_buf[1] = 0x50 + tda827x_dvbt[i].cp; | 657 | tuner_buf[1] = 0x50 + tda827x_dvbt[i].cp; |
640 | tuner_msg.len = 2; | 658 | tuner_msg.len = 2; |
659 | if (fe->ops.i2c_gate_ctrl) | ||
660 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
641 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | 661 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); |
642 | 662 | ||
643 | return 0; | 663 | return 0; |
644 | } | 664 | } |
645 | 665 | ||
646 | static void philips_tda827x_pll_sleep(struct dvb_frontend *fe) | 666 | static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe) |
647 | { | 667 | { |
648 | struct saa7134_dev *dev = fe->dvb->priv; | 668 | struct saa7134_dev *dev = fe->dvb->priv; |
649 | static u8 tda827x_sleep[] = { 0x30, 0xd0}; | 669 | static u8 tda827x_sleep[] = { 0x30, 0xd0}; |
650 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep, | 670 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep, |
651 | .len = sizeof(tda827x_sleep) }; | 671 | .len = sizeof(tda827x_sleep) }; |
672 | if (fe->ops.i2c_gate_ctrl) | ||
673 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
652 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | 674 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); |
675 | return 0; | ||
653 | } | 676 | } |
654 | 677 | ||
655 | static struct tda1004x_config tda827x_lifeview_config = { | 678 | static struct tda1004x_config tda827x_lifeview_config = { |
@@ -659,9 +682,6 @@ static struct tda1004x_config tda827x_lifeview_config = { | |||
659 | .xtal_freq = TDA10046_XTAL_16M, | 682 | .xtal_freq = TDA10046_XTAL_16M, |
660 | .agc_config = TDA10046_AGC_TDA827X, | 683 | .agc_config = TDA10046_AGC_TDA827X, |
661 | .if_freq = TDA10046_FREQ_045, | 684 | .if_freq = TDA10046_FREQ_045, |
662 | .pll_init = philips_tda827x_pll_init, | ||
663 | .pll_set = philips_tda827x_pll_set, | ||
664 | .pll_sleep = philips_tda827x_pll_sleep, | ||
665 | .request_firmware = NULL, | 685 | .request_firmware = NULL, |
666 | }; | 686 | }; |
667 | 687 | ||
@@ -753,6 +773,8 @@ static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb | |||
753 | tuner_buf[12] = 0x00; | 773 | tuner_buf[12] = 0x00; |
754 | tuner_buf[13] = 0x39; // lpsel | 774 | tuner_buf[13] = 0x39; // lpsel |
755 | msg.len = 14; | 775 | msg.len = 14; |
776 | if (fe->ops.i2c_gate_ctrl) | ||
777 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
756 | if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) | 778 | if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) |
757 | return -EIO; | 779 | return -EIO; |
758 | 780 | ||
@@ -760,10 +782,14 @@ static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb | |||
760 | msg.len = 2; | 782 | msg.len = 2; |
761 | reg2[0] = 0x60; | 783 | reg2[0] = 0x60; |
762 | reg2[1] = 0x3c; | 784 | reg2[1] = 0x3c; |
785 | if (fe->ops.i2c_gate_ctrl) | ||
786 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
763 | i2c_transfer(&dev->i2c_adap, &msg, 1); | 787 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
764 | 788 | ||
765 | reg2[0] = 0xa0; | 789 | reg2[0] = 0xa0; |
766 | reg2[1] = 0x40; | 790 | reg2[1] = 0x40; |
791 | if (fe->ops.i2c_gate_ctrl) | ||
792 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
767 | i2c_transfer(&dev->i2c_adap, &msg, 1); | 793 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
768 | 794 | ||
769 | msleep(2); | 795 | msleep(2); |
@@ -771,36 +797,43 @@ static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb | |||
771 | reg2[0] = 0x30; | 797 | reg2[0] = 0x30; |
772 | reg2[1] = 0x10 + tda827xa_dvbt[i].scr; | 798 | reg2[1] = 0x10 + tda827xa_dvbt[i].scr; |
773 | msg.len = 2; | 799 | msg.len = 2; |
800 | if (fe->ops.i2c_gate_ctrl) | ||
801 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
774 | i2c_transfer(&dev->i2c_adap, &msg, 1); | 802 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
775 | 803 | ||
776 | msleep(550); | 804 | msleep(550); |
777 | reg2[0] = 0x50; | 805 | reg2[0] = 0x50; |
778 | reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); | 806 | reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); |
807 | if (fe->ops.i2c_gate_ctrl) | ||
808 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
779 | i2c_transfer(&dev->i2c_adap, &msg, 1); | 809 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
780 | 810 | ||
781 | return 0; | 811 | return 0; |
782 | 812 | ||
783 | } | 813 | } |
784 | 814 | ||
785 | static void philips_tda827xa_pll_sleep(u8 addr, struct dvb_frontend *fe) | 815 | static int philips_tda827xa_tuner_sleep(u8 addr, struct dvb_frontend *fe) |
786 | { | 816 | { |
787 | struct saa7134_dev *dev = fe->dvb->priv; | 817 | struct saa7134_dev *dev = fe->dvb->priv; |
788 | static u8 tda827xa_sleep[] = { 0x30, 0x90}; | 818 | static u8 tda827xa_sleep[] = { 0x30, 0x90}; |
789 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep, | 819 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep, |
790 | .len = sizeof(tda827xa_sleep) }; | 820 | .len = sizeof(tda827xa_sleep) }; |
821 | if (fe->ops.i2c_gate_ctrl) | ||
822 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
791 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | 823 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); |
792 | 824 | return 0; | |
793 | } | 825 | } |
794 | 826 | ||
795 | /* ------------------------------------------------------------------ */ | 827 | /* ------------------------------------------------------------------ */ |
796 | 828 | ||
797 | static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 829 | static int philips_tiger_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
798 | { | 830 | { |
799 | int ret; | 831 | int ret; |
800 | struct saa7134_dev *dev = fe->dvb->priv; | 832 | struct saa7134_dev *dev = fe->dvb->priv; |
801 | static u8 tda8290_close[] = { 0x21, 0xc0}; | 833 | static u8 tda8290_close[] = { 0x21, 0xc0}; |
802 | static u8 tda8290_open[] = { 0x21, 0x80}; | 834 | static u8 tda8290_open[] = { 0x21, 0x80}; |
803 | struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2}; | 835 | struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2}; |
836 | |||
804 | /* close tda8290 i2c bridge */ | 837 | /* close tda8290 i2c bridge */ |
805 | tda8290_msg.buf = tda8290_close; | 838 | tda8290_msg.buf = tda8290_close; |
806 | ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); | 839 | ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); |
@@ -816,7 +849,7 @@ static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_pa | |||
816 | return ret; | 849 | return ret; |
817 | } | 850 | } |
818 | 851 | ||
819 | static int philips_tiger_dvb_mode(struct dvb_frontend *fe) | 852 | static int philips_tiger_tuner_init(struct dvb_frontend *fe) |
820 | { | 853 | { |
821 | struct saa7134_dev *dev = fe->dvb->priv; | 854 | struct saa7134_dev *dev = fe->dvb->priv; |
822 | static u8 data[] = { 0x3c, 0x33, 0x6a}; | 855 | static u8 data[] = { 0x3c, 0x33, 0x6a}; |
@@ -827,14 +860,15 @@ static int philips_tiger_dvb_mode(struct dvb_frontend *fe) | |||
827 | return 0; | 860 | return 0; |
828 | } | 861 | } |
829 | 862 | ||
830 | static void philips_tiger_analog_mode(struct dvb_frontend *fe) | 863 | static int philips_tiger_tuner_sleep(struct dvb_frontend *fe) |
831 | { | 864 | { |
832 | struct saa7134_dev *dev = fe->dvb->priv; | 865 | struct saa7134_dev *dev = fe->dvb->priv; |
833 | static u8 data[] = { 0x3c, 0x33, 0x68}; | 866 | static u8 data[] = { 0x3c, 0x33, 0x68}; |
834 | struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; | 867 | struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; |
835 | 868 | ||
836 | i2c_transfer(&dev->i2c_adap, &msg, 1); | 869 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
837 | philips_tda827xa_pll_sleep( 0x61, fe); | 870 | philips_tda827xa_tuner_sleep( 0x61, fe); |
871 | return 0; | ||
838 | } | 872 | } |
839 | 873 | ||
840 | static struct tda1004x_config philips_tiger_config = { | 874 | static struct tda1004x_config philips_tiger_config = { |
@@ -844,15 +878,12 @@ static struct tda1004x_config philips_tiger_config = { | |||
844 | .xtal_freq = TDA10046_XTAL_16M, | 878 | .xtal_freq = TDA10046_XTAL_16M, |
845 | .agc_config = TDA10046_AGC_TDA827X, | 879 | .agc_config = TDA10046_AGC_TDA827X, |
846 | .if_freq = TDA10046_FREQ_045, | 880 | .if_freq = TDA10046_FREQ_045, |
847 | .pll_init = philips_tiger_dvb_mode, | ||
848 | .pll_set = philips_tiger_pll_set, | ||
849 | .pll_sleep = philips_tiger_analog_mode, | ||
850 | .request_firmware = NULL, | 881 | .request_firmware = NULL, |
851 | }; | 882 | }; |
852 | 883 | ||
853 | /* ------------------------------------------------------------------ */ | 884 | /* ------------------------------------------------------------------ */ |
854 | 885 | ||
855 | static int lifeview_trio_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 886 | static int lifeview_trio_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
856 | { | 887 | { |
857 | int ret; | 888 | int ret; |
858 | 889 | ||
@@ -860,16 +891,12 @@ static int lifeview_trio_pll_set(struct dvb_frontend *fe, struct dvb_frontend_pa | |||
860 | return ret; | 891 | return ret; |
861 | } | 892 | } |
862 | 893 | ||
863 | static int lifeview_trio_dvb_mode(struct dvb_frontend *fe) | 894 | static int lifeview_trio_tuner_sleep(struct dvb_frontend *fe) |
864 | { | 895 | { |
896 | philips_tda827xa_tuner_sleep(0x60, fe); | ||
865 | return 0; | 897 | return 0; |
866 | } | 898 | } |
867 | 899 | ||
868 | static void lifeview_trio_analog_mode(struct dvb_frontend *fe) | ||
869 | { | ||
870 | philips_tda827xa_pll_sleep(0x60, fe); | ||
871 | } | ||
872 | |||
873 | static struct tda1004x_config lifeview_trio_config = { | 900 | static struct tda1004x_config lifeview_trio_config = { |
874 | .demod_address = 0x09, | 901 | .demod_address = 0x09, |
875 | .invert = 1, | 902 | .invert = 1, |
@@ -877,15 +904,12 @@ static struct tda1004x_config lifeview_trio_config = { | |||
877 | .xtal_freq = TDA10046_XTAL_16M, | 904 | .xtal_freq = TDA10046_XTAL_16M, |
878 | .agc_config = TDA10046_AGC_TDA827X_GPL, | 905 | .agc_config = TDA10046_AGC_TDA827X_GPL, |
879 | .if_freq = TDA10046_FREQ_045, | 906 | .if_freq = TDA10046_FREQ_045, |
880 | .pll_init = lifeview_trio_dvb_mode, | ||
881 | .pll_set = lifeview_trio_pll_set, | ||
882 | .pll_sleep = lifeview_trio_analog_mode, | ||
883 | .request_firmware = NULL, | 907 | .request_firmware = NULL, |
884 | }; | 908 | }; |
885 | 909 | ||
886 | /* ------------------------------------------------------------------ */ | 910 | /* ------------------------------------------------------------------ */ |
887 | 911 | ||
888 | static int ads_duo_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 912 | static int ads_duo_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
889 | { | 913 | { |
890 | int ret; | 914 | int ret; |
891 | 915 | ||
@@ -893,7 +917,7 @@ static int ads_duo_pll_set(struct dvb_frontend *fe, struct dvb_frontend_paramete | |||
893 | return ret; | 917 | return ret; |
894 | } | 918 | } |
895 | 919 | ||
896 | static int ads_duo_dvb_mode(struct dvb_frontend *fe) | 920 | static int ads_duo_tuner_init(struct dvb_frontend *fe) |
897 | { | 921 | { |
898 | struct saa7134_dev *dev = fe->dvb->priv; | 922 | struct saa7134_dev *dev = fe->dvb->priv; |
899 | /* route TDA8275a AGC input to the channel decoder */ | 923 | /* route TDA8275a AGC input to the channel decoder */ |
@@ -901,12 +925,13 @@ static int ads_duo_dvb_mode(struct dvb_frontend *fe) | |||
901 | return 0; | 925 | return 0; |
902 | } | 926 | } |
903 | 927 | ||
904 | static void ads_duo_analog_mode(struct dvb_frontend *fe) | 928 | static int ads_duo_tuner_sleep(struct dvb_frontend *fe) |
905 | { | 929 | { |
906 | struct saa7134_dev *dev = fe->dvb->priv; | 930 | struct saa7134_dev *dev = fe->dvb->priv; |
907 | /* route TDA8275a AGC input to the analog IF chip*/ | 931 | /* route TDA8275a AGC input to the analog IF chip*/ |
908 | saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x20); | 932 | saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x20); |
909 | philips_tda827xa_pll_sleep( 0x61, fe); | 933 | philips_tda827xa_tuner_sleep( 0x61, fe); |
934 | return 0; | ||
910 | } | 935 | } |
911 | 936 | ||
912 | static struct tda1004x_config ads_tech_duo_config = { | 937 | static struct tda1004x_config ads_tech_duo_config = { |
@@ -916,31 +941,24 @@ static struct tda1004x_config ads_tech_duo_config = { | |||
916 | .xtal_freq = TDA10046_XTAL_16M, | 941 | .xtal_freq = TDA10046_XTAL_16M, |
917 | .agc_config = TDA10046_AGC_TDA827X_GPL, | 942 | .agc_config = TDA10046_AGC_TDA827X_GPL, |
918 | .if_freq = TDA10046_FREQ_045, | 943 | .if_freq = TDA10046_FREQ_045, |
919 | .pll_init = ads_duo_dvb_mode, | ||
920 | .pll_set = ads_duo_pll_set, | ||
921 | .pll_sleep = ads_duo_analog_mode, | ||
922 | .request_firmware = NULL, | 944 | .request_firmware = NULL, |
923 | }; | 945 | }; |
924 | 946 | ||
925 | /* ------------------------------------------------------------------ */ | 947 | /* ------------------------------------------------------------------ */ |
926 | 948 | ||
927 | static int tevion_dvb220rf_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 949 | static int tevion_dvb220rf_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
928 | { | 950 | { |
929 | int ret; | 951 | int ret; |
930 | ret = philips_tda827xa_pll_set(0x60, fe, params); | 952 | ret = philips_tda827xa_pll_set(0x60, fe, params); |
931 | return ret; | 953 | return ret; |
932 | } | 954 | } |
933 | 955 | ||
934 | static int tevion_dvb220rf_pll_init(struct dvb_frontend *fe) | 956 | static int tevion_dvb220rf_tuner_sleep(struct dvb_frontend *fe) |
935 | { | 957 | { |
958 | philips_tda827xa_tuner_sleep( 0x61, fe); | ||
936 | return 0; | 959 | return 0; |
937 | } | 960 | } |
938 | 961 | ||
939 | static void tevion_dvb220rf_pll_sleep(struct dvb_frontend *fe) | ||
940 | { | ||
941 | philips_tda827xa_pll_sleep( 0x61, fe); | ||
942 | } | ||
943 | |||
944 | static struct tda1004x_config tevion_dvbt220rf_config = { | 962 | static struct tda1004x_config tevion_dvbt220rf_config = { |
945 | .demod_address = 0x08, | 963 | .demod_address = 0x08, |
946 | .invert = 1, | 964 | .invert = 1, |
@@ -948,9 +966,6 @@ static struct tda1004x_config tevion_dvbt220rf_config = { | |||
948 | .xtal_freq = TDA10046_XTAL_16M, | 966 | .xtal_freq = TDA10046_XTAL_16M, |
949 | .agc_config = TDA10046_AGC_TDA827X, | 967 | .agc_config = TDA10046_AGC_TDA827X, |
950 | .if_freq = TDA10046_FREQ_045, | 968 | .if_freq = TDA10046_FREQ_045, |
951 | .pll_init = tevion_dvb220rf_pll_init, | ||
952 | .pll_set = tevion_dvb220rf_pll_set, | ||
953 | .pll_sleep = tevion_dvb220rf_pll_sleep, | ||
954 | .request_firmware = NULL, | 969 | .request_firmware = NULL, |
955 | }; | 970 | }; |
956 | 971 | ||
@@ -961,8 +976,6 @@ static struct tda1004x_config tevion_dvbt220rf_config = { | |||
961 | #ifdef HAVE_NXT200X | 976 | #ifdef HAVE_NXT200X |
962 | static struct nxt200x_config avertvhda180 = { | 977 | static struct nxt200x_config avertvhda180 = { |
963 | .demod_address = 0x0a, | 978 | .demod_address = 0x0a, |
964 | .pll_address = 0x61, | ||
965 | .pll_desc = &dvb_pll_tdhu2, | ||
966 | }; | 979 | }; |
967 | 980 | ||
968 | static int nxt200x_set_pll_input(u8 *buf, int input) | 981 | static int nxt200x_set_pll_input(u8 *buf, int input) |
@@ -976,8 +989,6 @@ static int nxt200x_set_pll_input(u8 *buf, int input) | |||
976 | 989 | ||
977 | static struct nxt200x_config kworldatsc110 = { | 990 | static struct nxt200x_config kworldatsc110 = { |
978 | .demod_address = 0x0a, | 991 | .demod_address = 0x0a, |
979 | .pll_address = 0x61, | ||
980 | .pll_desc = &dvb_pll_tuv1236d, | ||
981 | .set_pll_input = nxt200x_set_pll_input, | 992 | .set_pll_input = nxt200x_set_pll_input, |
982 | }; | 993 | }; |
983 | #endif | 994 | #endif |
@@ -1003,78 +1014,158 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1003 | printk("%s: pinnacle 300i dvb setup\n",dev->name); | 1014 | printk("%s: pinnacle 300i dvb setup\n",dev->name); |
1004 | dev->dvb.frontend = mt352_attach(&pinnacle_300i, | 1015 | dev->dvb.frontend = mt352_attach(&pinnacle_300i, |
1005 | &dev->i2c_adap); | 1016 | &dev->i2c_adap); |
1017 | if (dev->dvb.frontend) { | ||
1018 | dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params; | ||
1019 | } | ||
1006 | break; | 1020 | break; |
1007 | 1021 | ||
1008 | case SAA7134_BOARD_AVERMEDIA_777: | 1022 | case SAA7134_BOARD_AVERMEDIA_777: |
1009 | printk("%s: avertv 777 dvb setup\n",dev->name); | 1023 | printk("%s: avertv 777 dvb setup\n",dev->name); |
1010 | dev->dvb.frontend = mt352_attach(&avermedia_777, | 1024 | dev->dvb.frontend = mt352_attach(&avermedia_777, |
1011 | &dev->i2c_adap); | 1025 | &dev->i2c_adap); |
1026 | if (dev->dvb.frontend) { | ||
1027 | dev->dvb.frontend->ops.tuner_ops.calc_regs = mt352_aver777_tuner_calc_regs; | ||
1028 | } | ||
1012 | break; | 1029 | break; |
1013 | #endif | 1030 | #endif |
1014 | #ifdef HAVE_TDA1004X | 1031 | #ifdef HAVE_TDA1004X |
1015 | case SAA7134_BOARD_MD7134: | 1032 | case SAA7134_BOARD_MD7134: |
1016 | dev->dvb.frontend = tda10046_attach(&medion_cardbus, | 1033 | dev->dvb.frontend = tda10046_attach(&medion_cardbus, |
1017 | &dev->i2c_adap); | 1034 | &dev->i2c_adap); |
1035 | if (dev->dvb.frontend) { | ||
1036 | dev->dvb.frontend->ops.tuner_ops.init = philips_fmd1216_tuner_init; | ||
1037 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_fmd1216_tuner_sleep; | ||
1038 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_fmd1216_tuner_set_params; | ||
1039 | } | ||
1018 | break; | 1040 | break; |
1019 | case SAA7134_BOARD_PHILIPS_TOUGH: | 1041 | case SAA7134_BOARD_PHILIPS_TOUGH: |
1020 | dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config, | 1042 | dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config, |
1021 | &dev->i2c_adap); | 1043 | &dev->i2c_adap); |
1044 | if (dev->dvb.frontend) { | ||
1045 | dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_tuner_60_init; | ||
1046 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tu1216_tuner_60_set_params; | ||
1047 | } | ||
1022 | break; | 1048 | break; |
1023 | case SAA7134_BOARD_FLYDVBTDUO: | 1049 | case SAA7134_BOARD_FLYDVBTDUO: |
1024 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, | 1050 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, |
1025 | &dev->i2c_adap); | 1051 | &dev->i2c_adap); |
1052 | if (dev->dvb.frontend) { | ||
1053 | dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init; | ||
1054 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep; | ||
1055 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params; | ||
1056 | } | ||
1026 | break; | 1057 | break; |
1027 | case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: | 1058 | case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: |
1028 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, | 1059 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, |
1029 | &dev->i2c_adap); | 1060 | &dev->i2c_adap); |
1061 | if (dev->dvb.frontend) { | ||
1062 | dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init; | ||
1063 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep; | ||
1064 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params; | ||
1065 | } | ||
1030 | break; | 1066 | break; |
1031 | case SAA7134_BOARD_PHILIPS_EUROPA: | 1067 | case SAA7134_BOARD_PHILIPS_EUROPA: |
1032 | dev->dvb.frontend = tda10046_attach(&philips_europa_config, | 1068 | dev->dvb.frontend = tda10046_attach(&philips_europa_config, |
1033 | &dev->i2c_adap); | 1069 | &dev->i2c_adap); |
1070 | if (dev->dvb.frontend) { | ||
1071 | dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; | ||
1072 | dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; | ||
1073 | dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; | ||
1074 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; | ||
1075 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; | ||
1076 | } | ||
1034 | break; | 1077 | break; |
1035 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | 1078 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: |
1036 | dev->dvb.frontend = tda10046_attach(&philips_europa_config, | 1079 | dev->dvb.frontend = tda10046_attach(&philips_europa_config, |
1037 | &dev->i2c_adap); | 1080 | &dev->i2c_adap); |
1081 | if (dev->dvb.frontend) { | ||
1082 | dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; | ||
1083 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; | ||
1084 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; | ||
1085 | } | ||
1038 | break; | 1086 | break; |
1039 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | 1087 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: |
1040 | dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config, | 1088 | dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config, |
1041 | &dev->i2c_adap); | 1089 | &dev->i2c_adap); |
1090 | if (dev->dvb.frontend) { | ||
1091 | dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_tuner_61_init; | ||
1092 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tu1216_tuner_61_set_params; | ||
1093 | } | ||
1042 | break; | 1094 | break; |
1043 | case SAA7134_BOARD_PHILIPS_TIGER: | 1095 | case SAA7134_BOARD_PHILIPS_TIGER: |
1044 | dev->dvb.frontend = tda10046_attach(&philips_tiger_config, | 1096 | dev->dvb.frontend = tda10046_attach(&philips_tiger_config, |
1045 | &dev->i2c_adap); | 1097 | &dev->i2c_adap); |
1098 | if (dev->dvb.frontend) { | ||
1099 | dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init; | ||
1100 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep; | ||
1101 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params; | ||
1102 | } | ||
1046 | break; | 1103 | break; |
1047 | case SAA7134_BOARD_ASUSTeK_P7131_DUAL: | 1104 | case SAA7134_BOARD_ASUSTeK_P7131_DUAL: |
1048 | dev->dvb.frontend = tda10046_attach(&philips_tiger_config, | 1105 | dev->dvb.frontend = tda10046_attach(&philips_tiger_config, |
1049 | &dev->i2c_adap); | 1106 | &dev->i2c_adap); |
1107 | if (dev->dvb.frontend) { | ||
1108 | dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init; | ||
1109 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep; | ||
1110 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params; | ||
1111 | } | ||
1050 | break; | 1112 | break; |
1051 | case SAA7134_BOARD_FLYDVBT_LR301: | 1113 | case SAA7134_BOARD_FLYDVBT_LR301: |
1052 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, | 1114 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, |
1053 | &dev->i2c_adap); | 1115 | &dev->i2c_adap); |
1116 | if (dev->dvb.frontend) { | ||
1117 | dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init; | ||
1118 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep; | ||
1119 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params; | ||
1120 | } | ||
1054 | break; | 1121 | break; |
1055 | case SAA7134_BOARD_FLYDVB_TRIO: | 1122 | case SAA7134_BOARD_FLYDVB_TRIO: |
1056 | dev->dvb.frontend = tda10046_attach(&lifeview_trio_config, | 1123 | dev->dvb.frontend = tda10046_attach(&lifeview_trio_config, |
1057 | &dev->i2c_adap); | 1124 | &dev->i2c_adap); |
1125 | if (dev->dvb.frontend) { | ||
1126 | dev->dvb.frontend->ops.tuner_ops.sleep = lifeview_trio_tuner_sleep; | ||
1127 | dev->dvb.frontend->ops.tuner_ops.set_params = lifeview_trio_tuner_set_params; | ||
1128 | } | ||
1058 | break; | 1129 | break; |
1059 | case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: | 1130 | case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: |
1060 | dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config, | 1131 | dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config, |
1061 | &dev->i2c_adap); | 1132 | &dev->i2c_adap); |
1133 | if (dev->dvb.frontend) { | ||
1134 | dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init; | ||
1135 | dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep; | ||
1136 | dev->dvb.frontend->ops.tuner_ops.set_params = ads_duo_tuner_set_params; | ||
1137 | } | ||
1062 | break; | 1138 | break; |
1063 | case SAA7134_BOARD_TEVION_DVBT_220RF: | 1139 | case SAA7134_BOARD_TEVION_DVBT_220RF: |
1064 | dev->dvb.frontend = tda10046_attach(&tevion_dvbt220rf_config, | 1140 | dev->dvb.frontend = tda10046_attach(&tevion_dvbt220rf_config, |
1065 | &dev->i2c_adap); | 1141 | &dev->i2c_adap); |
1142 | if (dev->dvb.frontend) { | ||
1143 | dev->dvb.frontend->ops.tuner_ops.sleep = tevion_dvb220rf_tuner_sleep; | ||
1144 | dev->dvb.frontend->ops.tuner_ops.set_params = tevion_dvb220rf_tuner_set_params; | ||
1145 | } | ||
1066 | break; | 1146 | break; |
1067 | case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: | 1147 | case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: |
1068 | dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config, | 1148 | dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config, |
1069 | &dev->i2c_adap); | 1149 | &dev->i2c_adap); |
1150 | if (dev->dvb.frontend) { | ||
1151 | dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init; | ||
1152 | dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep; | ||
1153 | dev->dvb.frontend->ops.tuner_ops.set_params = ads_duo_tuner_set_params; | ||
1154 | } | ||
1070 | break; | 1155 | break; |
1071 | #endif | 1156 | #endif |
1072 | #ifdef HAVE_NXT200X | 1157 | #ifdef HAVE_NXT200X |
1073 | case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: | 1158 | case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: |
1074 | dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap); | 1159 | dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap); |
1160 | if (dev->dvb.frontend) { | ||
1161 | dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tdhu2); | ||
1162 | } | ||
1075 | break; | 1163 | break; |
1076 | case SAA7134_BOARD_KWORLD_ATSC110: | 1164 | case SAA7134_BOARD_KWORLD_ATSC110: |
1077 | dev->dvb.frontend = nxt200x_attach(&kworldatsc110, &dev->i2c_adap); | 1165 | dev->dvb.frontend = nxt200x_attach(&kworldatsc110, &dev->i2c_adap); |
1166 | if (dev->dvb.frontend) { | ||
1167 | dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tuv1236d); | ||
1168 | } | ||
1078 | break; | 1169 | break; |
1079 | #endif | 1170 | #endif |
1080 | default: | 1171 | default: |
@@ -1088,7 +1179,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1088 | } | 1179 | } |
1089 | 1180 | ||
1090 | /* register everything else */ | 1181 | /* register everything else */ |
1091 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); | 1182 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); |
1092 | } | 1183 | } |
1093 | 1184 | ||
1094 | static int dvb_fini(struct saa7134_dev *dev) | 1185 | static int dvb_fini(struct saa7134_dev *dev) |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 1d972edb3be6..65d044086ce9 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -64,8 +64,10 @@ static void ts_reset_encoder(struct saa7134_dev* dev) | |||
64 | 64 | ||
65 | static int ts_init_encoder(struct saa7134_dev* dev) | 65 | static int ts_init_encoder(struct saa7134_dev* dev) |
66 | { | 66 | { |
67 | struct v4l2_ext_controls ctrls = { V4L2_CTRL_CLASS_MPEG, 0 }; | ||
68 | |||
67 | ts_reset_encoder(dev); | 69 | ts_reset_encoder(dev); |
68 | saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL); | 70 | saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, &ctrls); |
69 | dev->empress_started = 1; | 71 | dev->empress_started = 1; |
70 | return 0; | 72 | return 0; |
71 | } | 73 | } |
@@ -162,6 +164,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file, | |||
162 | unsigned int cmd, void *arg) | 164 | unsigned int cmd, void *arg) |
163 | { | 165 | { |
164 | struct saa7134_dev *dev = file->private_data; | 166 | struct saa7134_dev *dev = file->private_data; |
167 | struct v4l2_ext_controls *ctrls = arg; | ||
165 | 168 | ||
166 | if (debug > 1) | 169 | if (debug > 1) |
167 | v4l_print_ioctl(dev->name,cmd); | 170 | v4l_print_ioctl(dev->name,cmd); |
@@ -278,12 +281,31 @@ static int ts_do_ioctl(struct inode *inode, struct file *file, | |||
278 | return saa7134_common_ioctl(dev, cmd, arg); | 281 | return saa7134_common_ioctl(dev, cmd, arg); |
279 | 282 | ||
280 | case VIDIOC_S_MPEGCOMP: | 283 | case VIDIOC_S_MPEGCOMP: |
284 | printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. " | ||
285 | "Replace with VIDIOC_S_EXT_CTRLS!"); | ||
281 | saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg); | 286 | saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg); |
282 | ts_init_encoder(dev); | 287 | ts_init_encoder(dev); |
283 | return 0; | 288 | return 0; |
284 | case VIDIOC_G_MPEGCOMP: | 289 | case VIDIOC_G_MPEGCOMP: |
290 | printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. " | ||
291 | "Replace with VIDIOC_G_EXT_CTRLS!"); | ||
285 | saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg); | 292 | saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg); |
286 | return 0; | 293 | return 0; |
294 | case VIDIOC_S_EXT_CTRLS: | ||
295 | /* count == 0 is abused in saa6752hs.c, so that special | ||
296 | case is handled here explicitly. */ | ||
297 | if (ctrls->count == 0) | ||
298 | return 0; | ||
299 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
300 | return -EINVAL; | ||
301 | saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, arg); | ||
302 | ts_init_encoder(dev); | ||
303 | return 0; | ||
304 | case VIDIOC_G_EXT_CTRLS: | ||
305 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) | ||
306 | return -EINVAL; | ||
307 | saa7134_i2c_call_clients(dev, VIDIOC_G_EXT_CTRLS, arg); | ||
308 | return 0; | ||
287 | 309 | ||
288 | default: | 310 | default: |
289 | return -ENOIOCTLCMD; | 311 | return -ENOIOCTLCMD; |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 1426e4c8602f..7c595492c56b 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -37,6 +37,10 @@ static unsigned int ir_debug = 0; | |||
37 | module_param(ir_debug, int, 0644); | 37 | module_param(ir_debug, int, 0644); |
38 | MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); | 38 | MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); |
39 | 39 | ||
40 | static int pinnacle_remote = 0; | ||
41 | module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ | ||
42 | MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); | ||
43 | |||
40 | #define dprintk(fmt, arg...) if (ir_debug) \ | 44 | #define dprintk(fmt, arg...) if (ir_debug) \ |
41 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) | 45 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) |
42 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ | 46 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ |
@@ -316,8 +320,13 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) | |||
316 | switch (dev->board) { | 320 | switch (dev->board) { |
317 | case SAA7134_BOARD_PINNACLE_PCTV_110i: | 321 | case SAA7134_BOARD_PINNACLE_PCTV_110i: |
318 | snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); | 322 | snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); |
319 | ir->get_key = get_key_pinnacle; | 323 | if (pinnacle_remote == 0) { |
320 | ir->ir_codes = ir_codes_pinnacle; | 324 | ir->get_key = get_key_pinnacle_color; |
325 | ir->ir_codes = ir_codes_pinnacle_color; | ||
326 | } else { | ||
327 | ir->get_key = get_key_pinnacle_grey; | ||
328 | ir->ir_codes = ir_codes_pinnacle_grey; | ||
329 | } | ||
321 | break; | 330 | break; |
322 | case SAA7134_BOARD_UPMOST_PURPLE_TV: | 331 | case SAA7134_BOARD_UPMOST_PURPLE_TV: |
323 | snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); | 332 | snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 353af3a8b766..d5ee99c574cc 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include <asm/io.h> | 34 | #include <asm/io.h> |
35 | 35 | ||
36 | #include <media/v4l2-common.h> | ||
36 | #include <media/tuner.h> | 37 | #include <media/tuner.h> |
37 | #include <media/ir-common.h> | 38 | #include <media/ir-common.h> |
38 | #include <media/ir-kbd-i2c.h> | 39 | #include <media/ir-kbd-i2c.h> |
@@ -221,6 +222,7 @@ struct saa7134_format { | |||
221 | #define SAA7134_BOARD_AVERMEDIA_A169_B1 92 | 222 | #define SAA7134_BOARD_AVERMEDIA_A169_B1 92 |
222 | #define SAA7134_BOARD_MD7134_BRIDGE_2 93 | 223 | #define SAA7134_BOARD_MD7134_BRIDGE_2 93 |
223 | #define SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS 94 | 224 | #define SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS 94 |
225 | #define SAA7134_BOARD_FLYVIDEO3000_NTSC 95 | ||
224 | 226 | ||
225 | #define SAA7134_MAXBOARDS 8 | 227 | #define SAA7134_MAXBOARDS 8 |
226 | #define SAA7134_INPUT_MAX 8 | 228 | #define SAA7134_INPUT_MAX 8 |
@@ -531,6 +533,7 @@ struct saa7134_dev { | |||
531 | 533 | ||
532 | /* SAA7134_MPEG_DVB only */ | 534 | /* SAA7134_MPEG_DVB only */ |
533 | struct videobuf_dvb dvb; | 535 | struct videobuf_dvb dvb; |
536 | int (*original_demod_sleep)(struct dvb_frontend* fe); | ||
534 | }; | 537 | }; |
535 | 538 | ||
536 | /* ----------------------------------------------------------- */ | 539 | /* ----------------------------------------------------------- */ |
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h index a7a216bd4413..c0891b3e0018 100644 --- a/drivers/media/video/se401.h +++ b/drivers/media/video/se401.h | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <asm/uaccess.h> | 5 | #include <asm/uaccess.h> |
6 | #include <linux/videodev.h> | 6 | #include <linux/videodev.h> |
7 | #include <media/v4l2-common.h> | ||
7 | #include <linux/smp_lock.h> | 8 | #include <linux/smp_lock.h> |
8 | #include <linux/mutex.h> | 9 | #include <linux/mutex.h> |
9 | 10 | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index ea4394dc9415..48d138a7c723 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
@@ -2608,11 +2608,9 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
2608 | case VIDIOC_G_CTRL: | 2608 | case VIDIOC_G_CTRL: |
2609 | return sn9c102_vidioc_g_ctrl(cam, arg); | 2609 | return sn9c102_vidioc_g_ctrl(cam, arg); |
2610 | 2610 | ||
2611 | case VIDIOC_S_CTRL_OLD: | ||
2612 | case VIDIOC_S_CTRL: | 2611 | case VIDIOC_S_CTRL: |
2613 | return sn9c102_vidioc_s_ctrl(cam, arg); | 2612 | return sn9c102_vidioc_s_ctrl(cam, arg); |
2614 | 2613 | ||
2615 | case VIDIOC_CROPCAP_OLD: | ||
2616 | case VIDIOC_CROPCAP: | 2614 | case VIDIOC_CROPCAP: |
2617 | return sn9c102_vidioc_cropcap(cam, arg); | 2615 | return sn9c102_vidioc_cropcap(cam, arg); |
2618 | 2616 | ||
@@ -2659,7 +2657,6 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
2659 | case VIDIOC_G_PARM: | 2657 | case VIDIOC_G_PARM: |
2660 | return sn9c102_vidioc_g_parm(cam, arg); | 2658 | return sn9c102_vidioc_g_parm(cam, arg); |
2661 | 2659 | ||
2662 | case VIDIOC_S_PARM_OLD: | ||
2663 | case VIDIOC_S_PARM: | 2660 | case VIDIOC_S_PARM: |
2664 | return sn9c102_vidioc_s_parm(cam, arg); | 2661 | return sn9c102_vidioc_s_parm(cam, arg); |
2665 | 2662 | ||
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 07476c71174a..6be9c1131e1f 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
43 | #include <linux/vmalloc.h> | 43 | #include <linux/vmalloc.h> |
44 | #include <linux/videodev.h> | 44 | #include <linux/videodev.h> |
45 | #include <media/v4l2-common.h> | ||
45 | 46 | ||
46 | #include "saa7146.h" | 47 | #include "saa7146.h" |
47 | #include "saa7146reg.h" | 48 | #include "saa7146reg.h" |
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index b38bda83a7c5..351b182d921f 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/pagemap.h> | 66 | #include <linux/pagemap.h> |
67 | #include <linux/errno.h> | 67 | #include <linux/errno.h> |
68 | #include <linux/videodev.h> | 68 | #include <linux/videodev.h> |
69 | #include <media/v4l2-common.h> | ||
69 | #include <linux/usb.h> | 70 | #include <linux/usb.h> |
70 | #include <linux/mutex.h> | 71 | #include <linux/mutex.h> |
71 | 72 | ||
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 103ccb919292..827633b3bb43 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/videodev.h> | 28 | #include <linux/videodev.h> |
29 | #include <media/v4l2-common.h> | ||
29 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
30 | #include <linux/i2c-algo-bit.h> | 31 | #include <linux/i2c-algo-bit.h> |
31 | #include <linux/init.h> | 32 | #include <linux/init.h> |
@@ -163,7 +164,7 @@ static void do_tda9875_init(struct i2c_client *client) | |||
163 | struct tda9875 *t = i2c_get_clientdata(client); | 164 | struct tda9875 *t = i2c_get_clientdata(client); |
164 | dprintk("In tda9875_init\n"); | 165 | dprintk("In tda9875_init\n"); |
165 | tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/ | 166 | tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/ |
166 | tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/ | 167 | tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/ |
167 | tda9875_write(client, TDA9875_C1MSB, 0x00 ); /*Car1(FM) MSB XMHz*/ | 168 | tda9875_write(client, TDA9875_C1MSB, 0x00 ); /*Car1(FM) MSB XMHz*/ |
168 | tda9875_write(client, TDA9875_C1MIB, 0x00 ); /*Car1(FM) MIB XMHz*/ | 169 | tda9875_write(client, TDA9875_C1MIB, 0x00 ); /*Car1(FM) MIB XMHz*/ |
169 | tda9875_write(client, TDA9875_C1LSB, 0x00 ); /*Car1(FM) LSB XMHz*/ | 170 | tda9875_write(client, TDA9875_C1LSB, 0x00 ); /*Car1(FM) LSB XMHz*/ |
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 0d54f6c1982b..b6ae969563b2 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
@@ -18,49 +18,21 @@ | |||
18 | TDA9886 (PAL, SECAM, NTSC) | 18 | TDA9886 (PAL, SECAM, NTSC) |
19 | TDA9887 (PAL, SECAM, NTSC, FM Radio) | 19 | TDA9887 (PAL, SECAM, NTSC, FM Radio) |
20 | 20 | ||
21 | found on: | 21 | Used as part of several tuners |
22 | - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv) | ||
23 | TDA9887 (world), TDA9885 (USA) | ||
24 | Note: OP2 of tda988x must be set to 1, else MT2032 is disabled! | ||
25 | - KNC One TV-Station RDS (saa7134) | ||
26 | - Hauppauge PVR-150/500 (possibly more) | ||
27 | */ | 22 | */ |
28 | 23 | ||
24 | #define tda9887_info(fmt, arg...) do {\ | ||
25 | printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \ | ||
26 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) | ||
27 | #define tda9887_dbg(fmt, arg...) do {\ | ||
28 | if (tuner_debug) \ | ||
29 | printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \ | ||
30 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) | ||
29 | 31 | ||
30 | /* Addresses to scan */ | ||
31 | static unsigned short normal_i2c[] = { | ||
32 | 0x84 >>1, | ||
33 | 0x86 >>1, | ||
34 | 0x96 >>1, | ||
35 | I2C_CLIENT_END, | ||
36 | }; | ||
37 | I2C_CLIENT_INSMOD; | ||
38 | |||
39 | /* insmod options */ | ||
40 | static unsigned int debug = 0; | ||
41 | module_param(debug, int, 0644); | ||
42 | MODULE_LICENSE("GPL"); | ||
43 | 32 | ||
44 | /* ---------------------------------------------------------------------- */ | 33 | /* ---------------------------------------------------------------------- */ |
45 | 34 | ||
46 | #define UNSET (-1U) | 35 | #define UNSET (-1U) |
47 | #define tda9887_info(fmt, arg...) do {\ | ||
48 | printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \ | ||
49 | i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0) | ||
50 | #define tda9887_dbg(fmt, arg...) do {\ | ||
51 | if (debug) \ | ||
52 | printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \ | ||
53 | i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0) | ||
54 | |||
55 | struct tda9887 { | ||
56 | struct i2c_client client; | ||
57 | v4l2_std_id std; | ||
58 | enum tuner_mode mode; | ||
59 | unsigned int config; | ||
60 | unsigned int using_v4l2; | ||
61 | unsigned int radio_mode; | ||
62 | unsigned char data[4]; | ||
63 | }; | ||
64 | 36 | ||
65 | struct tvnorm { | 37 | struct tvnorm { |
66 | v4l2_std_id std; | 38 | v4l2_std_id std; |
@@ -70,9 +42,6 @@ struct tvnorm { | |||
70 | unsigned char e; | 42 | unsigned char e; |
71 | }; | 43 | }; |
72 | 44 | ||
73 | static struct i2c_driver driver; | ||
74 | static struct i2c_client client_template; | ||
75 | |||
76 | /* ---------------------------------------------------------------------- */ | 45 | /* ---------------------------------------------------------------------- */ |
77 | 46 | ||
78 | // | 47 | // |
@@ -281,7 +250,7 @@ static struct tvnorm radio_mono = { | |||
281 | 250 | ||
282 | /* ---------------------------------------------------------------------- */ | 251 | /* ---------------------------------------------------------------------- */ |
283 | 252 | ||
284 | static void dump_read_message(struct tda9887 *t, unsigned char *buf) | 253 | static void dump_read_message(struct tuner *t, unsigned char *buf) |
285 | { | 254 | { |
286 | static char *afc[16] = { | 255 | static char *afc[16] = { |
287 | "- 12.5 kHz", | 256 | "- 12.5 kHz", |
@@ -309,7 +278,7 @@ static void dump_read_message(struct tda9887 *t, unsigned char *buf) | |||
309 | tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); | 278 | tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); |
310 | } | 279 | } |
311 | 280 | ||
312 | static void dump_write_message(struct tda9887 *t, unsigned char *buf) | 281 | static void dump_write_message(struct tuner *t, unsigned char *buf) |
313 | { | 282 | { |
314 | static char *sound[4] = { | 283 | static char *sound[4] = { |
315 | "AM/TV", | 284 | "AM/TV", |
@@ -405,13 +374,13 @@ static void dump_write_message(struct tda9887 *t, unsigned char *buf) | |||
405 | 374 | ||
406 | /* ---------------------------------------------------------------------- */ | 375 | /* ---------------------------------------------------------------------- */ |
407 | 376 | ||
408 | static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) | 377 | static int tda9887_set_tvnorm(struct tuner *t, char *buf) |
409 | { | 378 | { |
410 | struct tvnorm *norm = NULL; | 379 | struct tvnorm *norm = NULL; |
411 | int i; | 380 | int i; |
412 | 381 | ||
413 | if (t->mode == T_RADIO) { | 382 | if (t->mode == V4L2_TUNER_RADIO) { |
414 | if (t->radio_mode == V4L2_TUNER_MODE_MONO) | 383 | if (t->audmode == V4L2_TUNER_MODE_MONO) |
415 | norm = &radio_mono; | 384 | norm = &radio_mono; |
416 | else | 385 | else |
417 | norm = &radio_stereo; | 386 | norm = &radio_stereo; |
@@ -445,7 +414,7 @@ module_param(port2, int, 0644); | |||
445 | module_param(qss, int, 0644); | 414 | module_param(qss, int, 0644); |
446 | module_param(adjust, int, 0644); | 415 | module_param(adjust, int, 0644); |
447 | 416 | ||
448 | static int tda9887_set_insmod(struct tda9887 *t, char *buf) | 417 | static int tda9887_set_insmod(struct tuner *t, char *buf) |
449 | { | 418 | { |
450 | if (UNSET != port1) { | 419 | if (UNSET != port1) { |
451 | if (port1) | 420 | if (port1) |
@@ -474,27 +443,27 @@ static int tda9887_set_insmod(struct tda9887 *t, char *buf) | |||
474 | return 0; | 443 | return 0; |
475 | } | 444 | } |
476 | 445 | ||
477 | static int tda9887_set_config(struct tda9887 *t, char *buf) | 446 | static int tda9887_set_config(struct tuner *t, char *buf) |
478 | { | 447 | { |
479 | if (t->config & TDA9887_PORT1_ACTIVE) | 448 | if (t->tda9887_config & TDA9887_PORT1_ACTIVE) |
480 | buf[1] &= ~cOutputPort1Inactive; | 449 | buf[1] &= ~cOutputPort1Inactive; |
481 | if (t->config & TDA9887_PORT1_INACTIVE) | 450 | if (t->tda9887_config & TDA9887_PORT1_INACTIVE) |
482 | buf[1] |= cOutputPort1Inactive; | 451 | buf[1] |= cOutputPort1Inactive; |
483 | if (t->config & TDA9887_PORT2_ACTIVE) | 452 | if (t->tda9887_config & TDA9887_PORT2_ACTIVE) |
484 | buf[1] &= ~cOutputPort2Inactive; | 453 | buf[1] &= ~cOutputPort2Inactive; |
485 | if (t->config & TDA9887_PORT2_INACTIVE) | 454 | if (t->tda9887_config & TDA9887_PORT2_INACTIVE) |
486 | buf[1] |= cOutputPort2Inactive; | 455 | buf[1] |= cOutputPort2Inactive; |
487 | 456 | ||
488 | if (t->config & TDA9887_QSS) | 457 | if (t->tda9887_config & TDA9887_QSS) |
489 | buf[1] |= cQSS; | 458 | buf[1] |= cQSS; |
490 | if (t->config & TDA9887_INTERCARRIER) | 459 | if (t->tda9887_config & TDA9887_INTERCARRIER) |
491 | buf[1] &= ~cQSS; | 460 | buf[1] &= ~cQSS; |
492 | 461 | ||
493 | if (t->config & TDA9887_AUTOMUTE) | 462 | if (t->tda9887_config & TDA9887_AUTOMUTE) |
494 | buf[1] |= cAutoMuteFmActive; | 463 | buf[1] |= cAutoMuteFmActive; |
495 | if (t->config & TDA9887_DEEMPHASIS_MASK) { | 464 | if (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) { |
496 | buf[2] &= ~0x60; | 465 | buf[2] &= ~0x60; |
497 | switch (t->config & TDA9887_DEEMPHASIS_MASK) { | 466 | switch (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) { |
498 | case TDA9887_DEEMPHASIS_NONE: | 467 | case TDA9887_DEEMPHASIS_NONE: |
499 | buf[2] |= cDeemphasisOFF; | 468 | buf[2] |= cDeemphasisOFF; |
500 | break; | 469 | break; |
@@ -506,153 +475,36 @@ static int tda9887_set_config(struct tda9887 *t, char *buf) | |||
506 | break; | 475 | break; |
507 | } | 476 | } |
508 | } | 477 | } |
509 | if (t->config & TDA9887_TOP_SET) { | 478 | if (t->tda9887_config & TDA9887_TOP_SET) { |
510 | buf[2] &= ~cTopMask; | 479 | buf[2] &= ~cTopMask; |
511 | buf[2] |= (t->config >> 8) & cTopMask; | 480 | buf[2] |= (t->tda9887_config >> 8) & cTopMask; |
512 | } | 481 | } |
513 | if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) | 482 | if ((t->tda9887_config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) |
514 | buf[1] &= ~cQSS; | 483 | buf[1] &= ~cQSS; |
515 | return 0; | 484 | return 0; |
516 | } | 485 | } |
517 | 486 | ||
518 | /* ---------------------------------------------------------------------- */ | 487 | /* ---------------------------------------------------------------------- */ |
519 | 488 | ||
520 | static char pal[] = "--"; | 489 | static int tda9887_status(struct tuner *t) |
521 | static char secam[] = "--"; | ||
522 | static char ntsc[] = "-"; | ||
523 | |||
524 | module_param_string(pal, pal, sizeof(pal), 0644); | ||
525 | module_param_string(secam, secam, sizeof(secam), 0644); | ||
526 | module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); | ||
527 | |||
528 | static int tda9887_fixup_std(struct tda9887 *t) | ||
529 | { | ||
530 | /* get more precise norm info from insmod option */ | ||
531 | if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { | ||
532 | switch (pal[0]) { | ||
533 | case 'b': | ||
534 | case 'B': | ||
535 | case 'g': | ||
536 | case 'G': | ||
537 | case 'h': | ||
538 | case 'H': | ||
539 | case 'n': | ||
540 | case 'N': | ||
541 | if (pal[1] == 'c' || pal[1] == 'C') { | ||
542 | tda9887_dbg("insmod fixup: PAL => PAL-Nc\n"); | ||
543 | t->std = V4L2_STD_PAL_Nc; | ||
544 | } else { | ||
545 | tda9887_dbg("insmod fixup: PAL => PAL-BGHN\n"); | ||
546 | t->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N; | ||
547 | } | ||
548 | break; | ||
549 | case 'i': | ||
550 | case 'I': | ||
551 | tda9887_dbg("insmod fixup: PAL => PAL-I\n"); | ||
552 | t->std = V4L2_STD_PAL_I; | ||
553 | break; | ||
554 | case 'd': | ||
555 | case 'D': | ||
556 | case 'k': | ||
557 | case 'K': | ||
558 | tda9887_dbg("insmod fixup: PAL => PAL-DK\n"); | ||
559 | t->std = V4L2_STD_PAL_DK; | ||
560 | break; | ||
561 | case 'm': | ||
562 | case 'M': | ||
563 | tda9887_dbg("insmod fixup: PAL => PAL-M\n"); | ||
564 | t->std = V4L2_STD_PAL_M; | ||
565 | break; | ||
566 | case '-': | ||
567 | /* default parameter, do nothing */ | ||
568 | break; | ||
569 | default: | ||
570 | tda9887_info("pal= argument not recognised\n"); | ||
571 | break; | ||
572 | } | ||
573 | } | ||
574 | if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { | ||
575 | switch (secam[0]) { | ||
576 | case 'b': | ||
577 | case 'B': | ||
578 | case 'g': | ||
579 | case 'G': | ||
580 | case 'h': | ||
581 | case 'H': | ||
582 | tda9887_dbg("insmod fixup: SECAM => SECAM-BGH\n"); | ||
583 | t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; | ||
584 | break; | ||
585 | case 'd': | ||
586 | case 'D': | ||
587 | case 'k': | ||
588 | case 'K': | ||
589 | tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n"); | ||
590 | t->std = V4L2_STD_SECAM_DK; | ||
591 | break; | ||
592 | case 'l': | ||
593 | case 'L': | ||
594 | if (secam[1] == 'c' || secam[1] == 'C') { | ||
595 | tda9887_dbg("insmod fixup: SECAM => SECAM-L'\n"); | ||
596 | t->std = V4L2_STD_SECAM_LC; | ||
597 | } else { | ||
598 | tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); | ||
599 | t->std = V4L2_STD_SECAM_L; | ||
600 | } | ||
601 | break; | ||
602 | case '-': | ||
603 | /* default parameter, do nothing */ | ||
604 | break; | ||
605 | default: | ||
606 | tda9887_info("secam= argument not recognised\n"); | ||
607 | break; | ||
608 | } | ||
609 | } | ||
610 | if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { | ||
611 | switch (ntsc[0]) { | ||
612 | case 'm': | ||
613 | case 'M': | ||
614 | tda9887_dbg("insmod fixup: NTSC => NTSC-M\n"); | ||
615 | t->std = V4L2_STD_NTSC_M; | ||
616 | break; | ||
617 | case 'j': | ||
618 | case 'J': | ||
619 | tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); | ||
620 | t->std = V4L2_STD_NTSC_M_JP; | ||
621 | break; | ||
622 | case 'k': | ||
623 | case 'K': | ||
624 | tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n"); | ||
625 | t->std = V4L2_STD_NTSC_M_KR; | ||
626 | break; | ||
627 | case '-': | ||
628 | /* default parameter, do nothing */ | ||
629 | break; | ||
630 | default: | ||
631 | tda9887_info("ntsc= argument not recognised\n"); | ||
632 | break; | ||
633 | } | ||
634 | } | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | static int tda9887_status(struct tda9887 *t) | ||
639 | { | 490 | { |
640 | unsigned char buf[1]; | 491 | unsigned char buf[1]; |
641 | int rc; | 492 | int rc; |
642 | 493 | ||
643 | memset(buf,0,sizeof(buf)); | 494 | memset(buf,0,sizeof(buf)); |
644 | if (1 != (rc = i2c_master_recv(&t->client,buf,1))) | 495 | if (1 != (rc = i2c_master_recv(&t->i2c,buf,1))) |
645 | tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc); | 496 | tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc); |
646 | dump_read_message(t, buf); | 497 | dump_read_message(t, buf); |
647 | return 0; | 498 | return 0; |
648 | } | 499 | } |
649 | 500 | ||
650 | static int tda9887_configure(struct tda9887 *t) | 501 | static void tda9887_configure(struct i2c_client *client) |
651 | { | 502 | { |
503 | struct tuner *t = i2c_get_clientdata(client); | ||
652 | int rc; | 504 | int rc; |
653 | 505 | ||
654 | memset(t->data,0,sizeof(t->data)); | 506 | memset(t->tda9887_data,0,sizeof(t->tda9887_data)); |
655 | tda9887_set_tvnorm(t,t->data); | 507 | tda9887_set_tvnorm(t,t->tda9887_data); |
656 | 508 | ||
657 | /* A note on the port settings: | 509 | /* A note on the port settings: |
658 | These settings tend to depend on the specifics of the board. | 510 | These settings tend to depend on the specifics of the board. |
@@ -667,249 +519,84 @@ static int tda9887_configure(struct tda9887 *t) | |||
667 | the ports should be set to active (0), but, again, that may | 519 | the ports should be set to active (0), but, again, that may |
668 | differ depending on the precise hardware configuration. | 520 | differ depending on the precise hardware configuration. |
669 | */ | 521 | */ |
670 | t->data[1] |= cOutputPort1Inactive; | 522 | t->tda9887_data[1] |= cOutputPort1Inactive; |
671 | t->data[1] |= cOutputPort2Inactive; | 523 | t->tda9887_data[1] |= cOutputPort2Inactive; |
672 | 524 | ||
673 | tda9887_set_config(t,t->data); | 525 | tda9887_set_config(t,t->tda9887_data); |
674 | tda9887_set_insmod(t,t->data); | 526 | tda9887_set_insmod(t,t->tda9887_data); |
675 | 527 | ||
676 | if (t->mode == T_STANDBY) { | 528 | if (t->mode == T_STANDBY) { |
677 | t->data[1] |= cForcedMuteAudioON; | 529 | t->tda9887_data[1] |= cForcedMuteAudioON; |
678 | } | 530 | } |
679 | 531 | ||
680 | tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", | 532 | tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", |
681 | t->data[1],t->data[2],t->data[3]); | 533 | t->tda9887_data[1],t->tda9887_data[2],t->tda9887_data[3]); |
682 | if (debug > 1) | 534 | if (tuner_debug > 1) |
683 | dump_write_message(t, t->data); | 535 | dump_write_message(t, t->tda9887_data); |
684 | 536 | ||
685 | if (4 != (rc = i2c_master_send(&t->client,t->data,4))) | 537 | if (4 != (rc = i2c_master_send(&t->i2c,t->tda9887_data,4))) |
686 | tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc); | 538 | tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc); |
687 | 539 | ||
688 | if (debug > 2) { | 540 | if (tuner_debug > 2) { |
689 | msleep_interruptible(1000); | 541 | msleep_interruptible(1000); |
690 | tda9887_status(t); | 542 | tda9887_status(t); |
691 | } | 543 | } |
692 | return 0; | ||
693 | } | 544 | } |
694 | 545 | ||
695 | /* ---------------------------------------------------------------------- */ | 546 | /* ---------------------------------------------------------------------- */ |
696 | 547 | ||
697 | static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) | 548 | static void tda9887_tuner_status(struct i2c_client *client) |
698 | { | 549 | { |
699 | struct tda9887 *t; | 550 | struct tuner *t = i2c_get_clientdata(client); |
700 | 551 | tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->tda9887_data[1], t->tda9887_data[2], t->tda9887_data[3]); | |
701 | client_template.adapter = adap; | ||
702 | client_template.addr = addr; | ||
703 | |||
704 | if (NULL == (t = kzalloc(sizeof(*t), GFP_KERNEL))) | ||
705 | return -ENOMEM; | ||
706 | |||
707 | t->client = client_template; | ||
708 | t->std = 0; | ||
709 | t->radio_mode = V4L2_TUNER_MODE_STEREO; | ||
710 | |||
711 | tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name); | ||
712 | |||
713 | i2c_set_clientdata(&t->client, t); | ||
714 | i2c_attach_client(&t->client); | ||
715 | |||
716 | return 0; | ||
717 | } | 552 | } |
718 | 553 | ||
719 | static int tda9887_probe(struct i2c_adapter *adap) | 554 | static int tda9887_get_afc(struct i2c_client *client) |
720 | { | 555 | { |
721 | if (adap->class & I2C_CLASS_TV_ANALOG) | 556 | struct tuner *t = i2c_get_clientdata(client); |
722 | return i2c_probe(adap, &addr_data, tda9887_attach); | 557 | static int AFC_BITS_2_kHz[] = { |
723 | return 0; | 558 | -12500, -37500, -62500, -97500, |
724 | } | 559 | -112500, -137500, -162500, -187500, |
560 | 187500, 162500, 137500, 112500, | ||
561 | 97500 , 62500, 37500 , 12500 | ||
562 | }; | ||
563 | int afc=0; | ||
564 | __u8 reg = 0; | ||
725 | 565 | ||
726 | static int tda9887_detach(struct i2c_client *client) | 566 | if (1 == i2c_master_recv(&t->i2c,®,1)) |
727 | { | 567 | afc = AFC_BITS_2_kHz[(reg>>1)&0x0f]; |
728 | struct tda9887 *t = i2c_get_clientdata(client); | ||
729 | 568 | ||
730 | i2c_detach_client(client); | 569 | return afc; |
731 | kfree(t); | ||
732 | return 0; | ||
733 | } | 570 | } |
734 | 571 | ||
735 | #define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ | 572 | static void tda9887_standby(struct i2c_client *client) |
736 | tda9887_info("switching to v4l2\n"); \ | ||
737 | t->using_v4l2 = 1; | ||
738 | #define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ | ||
739 | tda9887_info("ignore v4l1 call\n"); \ | ||
740 | return 0; } | ||
741 | |||
742 | static int | ||
743 | tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) | ||
744 | { | 573 | { |
745 | struct tda9887 *t = i2c_get_clientdata(client); | 574 | tda9887_configure(client); |
746 | |||
747 | switch (cmd) { | ||
748 | |||
749 | /* --- configuration --- */ | ||
750 | case AUDC_SET_RADIO: | ||
751 | { | ||
752 | t->mode = T_RADIO; | ||
753 | tda9887_configure(t); | ||
754 | break; | ||
755 | } | ||
756 | case TUNER_SET_STANDBY: | ||
757 | { | ||
758 | t->mode = T_STANDBY; | ||
759 | tda9887_configure(t); | ||
760 | break; | ||
761 | } | ||
762 | case TDA9887_SET_CONFIG: | ||
763 | { | ||
764 | int *i = arg; | ||
765 | |||
766 | t->config = *i; | ||
767 | tda9887_configure(t); | ||
768 | break; | ||
769 | } | ||
770 | /* --- v4l ioctls --- */ | ||
771 | /* take care: bttv does userspace copying, we'll get a | ||
772 | kernel pointer here... */ | ||
773 | case VIDIOCSCHAN: | ||
774 | { | ||
775 | static const v4l2_std_id map[] = { | ||
776 | [ VIDEO_MODE_PAL ] = V4L2_STD_PAL, | ||
777 | [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M, | ||
778 | [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM, | ||
779 | [ 4 /* bttv */ ] = V4L2_STD_PAL_M, | ||
780 | [ 5 /* bttv */ ] = V4L2_STD_PAL_N, | ||
781 | [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP, | ||
782 | }; | ||
783 | struct video_channel *vc = arg; | ||
784 | |||
785 | CHECK_V4L2; | ||
786 | t->mode = T_ANALOG_TV; | ||
787 | if (vc->norm < ARRAY_SIZE(map)) | ||
788 | t->std = map[vc->norm]; | ||
789 | tda9887_fixup_std(t); | ||
790 | tda9887_configure(t); | ||
791 | break; | ||
792 | } | ||
793 | case VIDIOC_S_STD: | ||
794 | { | ||
795 | v4l2_std_id *id = arg; | ||
796 | |||
797 | SWITCH_V4L2; | ||
798 | t->mode = T_ANALOG_TV; | ||
799 | t->std = *id; | ||
800 | tda9887_fixup_std(t); | ||
801 | tda9887_configure(t); | ||
802 | break; | ||
803 | } | ||
804 | case VIDIOC_S_FREQUENCY: | ||
805 | { | ||
806 | struct v4l2_frequency *f = arg; | ||
807 | |||
808 | SWITCH_V4L2; | ||
809 | if (V4L2_TUNER_ANALOG_TV == f->type) { | ||
810 | if (t->mode == T_ANALOG_TV) | ||
811 | return 0; | ||
812 | t->mode = T_ANALOG_TV; | ||
813 | } | ||
814 | if (V4L2_TUNER_RADIO == f->type) { | ||
815 | if (t->mode == T_RADIO) | ||
816 | return 0; | ||
817 | t->mode = T_RADIO; | ||
818 | } | ||
819 | tda9887_configure(t); | ||
820 | break; | ||
821 | } | ||
822 | case VIDIOC_G_TUNER: | ||
823 | { | ||
824 | static int AFC_BITS_2_kHz[] = { | ||
825 | -12500, -37500, -62500, -97500, | ||
826 | -112500, -137500, -162500, -187500, | ||
827 | 187500, 162500, 137500, 112500, | ||
828 | 97500 , 62500, 37500 , 12500 | ||
829 | }; | ||
830 | struct v4l2_tuner* tuner = arg; | ||
831 | |||
832 | if (t->mode == T_RADIO) { | ||
833 | __u8 reg = 0; | ||
834 | tuner->afc=0; | ||
835 | if (1 == i2c_master_recv(&t->client,®,1)) | ||
836 | tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f]; | ||
837 | } | ||
838 | break; | ||
839 | } | ||
840 | case VIDIOC_S_TUNER: | ||
841 | { | ||
842 | struct v4l2_tuner* tuner = arg; | ||
843 | |||
844 | if (t->mode == T_RADIO) { | ||
845 | t->radio_mode = tuner->audmode; | ||
846 | tda9887_configure (t); | ||
847 | } | ||
848 | break; | ||
849 | } | ||
850 | case VIDIOC_LOG_STATUS: | ||
851 | { | ||
852 | tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]); | ||
853 | break; | ||
854 | } | ||
855 | default: | ||
856 | /* nothing */ | ||
857 | break; | ||
858 | } | ||
859 | return 0; | ||
860 | } | 575 | } |
861 | 576 | ||
862 | static int tda9887_suspend(struct device * dev, pm_message_t state) | 577 | static void tda9887_set_freq(struct i2c_client *client, unsigned int freq) |
863 | { | 578 | { |
864 | struct i2c_client *c = container_of(dev, struct i2c_client, dev); | 579 | tda9887_configure(client); |
865 | struct tda9887 *t = i2c_get_clientdata(c); | ||
866 | |||
867 | tda9887_dbg("suspend\n"); | ||
868 | return 0; | ||
869 | } | 580 | } |
870 | 581 | ||
871 | static int tda9887_resume(struct device * dev) | 582 | int tda9887_tuner_init(struct i2c_client *c) |
872 | { | 583 | { |
873 | struct i2c_client *c = container_of(dev, struct i2c_client, dev); | 584 | struct tuner *t = i2c_get_clientdata(c); |
874 | struct tda9887 *t = i2c_get_clientdata(c); | ||
875 | 585 | ||
876 | tda9887_dbg("resume\n"); | 586 | strlcpy(c->name, "tda9887", sizeof(c->name)); |
877 | tda9887_configure(t); | ||
878 | return 0; | ||
879 | } | ||
880 | 587 | ||
881 | /* ----------------------------------------------------------------------- */ | 588 | tda9887_info("tda988[5/6/7] found @ 0x%x (%s)\n", t->i2c.addr, |
882 | 589 | t->i2c.driver->driver.name); | |
883 | static struct i2c_driver driver = { | ||
884 | .id = I2C_DRIVERID_TDA9887, | ||
885 | .attach_adapter = tda9887_probe, | ||
886 | .detach_client = tda9887_detach, | ||
887 | .command = tda9887_command, | ||
888 | .driver = { | ||
889 | .name = "tda9887", | ||
890 | .suspend = tda9887_suspend, | ||
891 | .resume = tda9887_resume, | ||
892 | }, | ||
893 | }; | ||
894 | static struct i2c_client client_template = | ||
895 | { | ||
896 | .name = "tda9887", | ||
897 | .driver = &driver, | ||
898 | }; | ||
899 | 590 | ||
900 | static int __init tda9887_init_module(void) | 591 | t->set_tv_freq = tda9887_set_freq; |
901 | { | 592 | t->set_radio_freq = tda9887_set_freq; |
902 | return i2c_add_driver(&driver); | 593 | t->standby = tda9887_standby; |
903 | } | 594 | t->tuner_status=tda9887_tuner_status; |
595 | t->get_afc=tda9887_get_afc; | ||
904 | 596 | ||
905 | static void __exit tda9887_cleanup_module(void) | 597 | return 0; |
906 | { | ||
907 | i2c_del_driver(&driver); | ||
908 | } | 598 | } |
909 | 599 | ||
910 | module_init(tda9887_init_module); | ||
911 | module_exit(tda9887_cleanup_module); | ||
912 | |||
913 | /* | 600 | /* |
914 | * Overrides for Emacs so that we follow Linus's tabbing style. | 601 | * Overrides for Emacs so that we follow Linus's tabbing style. |
915 | * --------------------------------------------------------------------------- | 602 | * --------------------------------------------------------------------------- |
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c index c2b98f81c192..d1c41781ccc4 100644 --- a/drivers/media/video/tea5767.c +++ b/drivers/media/video/tea5767.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * I2C address is allways 0xC0. | 3 | * I2C address is allways 0xC0. |
4 | * | 4 | * |
5 | * | 5 | * |
6 | * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) | 6 | * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org) |
7 | * This code is placed under the terms of the GNU General Public License | 7 | * This code is placed under the terms of the GNU General Public License |
8 | * | 8 | * |
9 | * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa | 9 | * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa |
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c new file mode 100644 index 000000000000..76b2e96429d9 --- /dev/null +++ b/drivers/media/video/tlv320aic23b.c | |||
@@ -0,0 +1,217 @@ | |||
1 | /* | ||
2 | * tlv320aic23b - driver version 0.0.1 | ||
3 | * | ||
4 | * Copyright (C) 2006 Scott Alfter <salfter@ssai.us> | ||
5 | * | ||
6 | * Based on wm8775 driver | ||
7 | * | ||
8 | * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to> | ||
9 | * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/ioctl.h> | ||
29 | #include <asm/uaccess.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include <linux/i2c-id.h> | ||
32 | #include <linux/videodev.h> | ||
33 | #include <media/v4l2-common.h> | ||
34 | |||
35 | MODULE_DESCRIPTION("tlv320aic23b driver"); | ||
36 | MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil"); | ||
37 | MODULE_LICENSE("GPL"); | ||
38 | |||
39 | static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END }; | ||
40 | |||
41 | |||
42 | I2C_CLIENT_INSMOD; | ||
43 | |||
44 | /* ----------------------------------------------------------------------- */ | ||
45 | |||
46 | struct tlv320aic23b_state { | ||
47 | u8 muted; | ||
48 | }; | ||
49 | |||
50 | static int tlv320aic23b_write(struct i2c_client *client, int reg, u16 val) | ||
51 | { | ||
52 | int i; | ||
53 | |||
54 | if ((reg < 0 || reg > 9) && (reg != 15)) { | ||
55 | v4l_err(client, "Invalid register R%d\n", reg); | ||
56 | return -1; | ||
57 | } | ||
58 | |||
59 | for (i = 0; i < 3; i++) { | ||
60 | if (i2c_smbus_write_byte_data(client, (reg << 1) | | ||
61 | (val >> 8), val & 0xff) == 0) { | ||
62 | return 0; | ||
63 | } | ||
64 | } | ||
65 | v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg); | ||
66 | return -1; | ||
67 | } | ||
68 | |||
69 | static int tlv320aic23b_command(struct i2c_client *client, unsigned int cmd, | ||
70 | void *arg) | ||
71 | { | ||
72 | struct tlv320aic23b_state *state = i2c_get_clientdata(client); | ||
73 | struct v4l2_control *ctrl = arg; | ||
74 | u32* freq = arg; | ||
75 | |||
76 | switch (cmd) { | ||
77 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | ||
78 | switch (*freq) { | ||
79 | case 32000: /* set sample rate to 32 kHz */ | ||
80 | tlv320aic23b_write(client, 8, 0x018); | ||
81 | break; | ||
82 | case 44100: /* set sample rate to 44.1 kHz */ | ||
83 | tlv320aic23b_write(client, 8, 0x022); | ||
84 | break; | ||
85 | case 48000: /* set sample rate to 48 kHz */ | ||
86 | tlv320aic23b_write(client, 8, 0x000); | ||
87 | break; | ||
88 | default: | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | break; | ||
92 | |||
93 | case VIDIOC_G_CTRL: | ||
94 | if (ctrl->id != V4L2_CID_AUDIO_MUTE) | ||
95 | return -EINVAL; | ||
96 | ctrl->value = state->muted; | ||
97 | break; | ||
98 | |||
99 | case VIDIOC_S_CTRL: | ||
100 | if (ctrl->id != V4L2_CID_AUDIO_MUTE) | ||
101 | return -EINVAL; | ||
102 | state->muted = ctrl->value; | ||
103 | tlv320aic23b_write(client, 0, 0x180); /* mute both channels */ | ||
104 | /* set gain on both channels to +3.0 dB */ | ||
105 | if (!state->muted) | ||
106 | tlv320aic23b_write(client, 0, 0x119); | ||
107 | break; | ||
108 | |||
109 | case VIDIOC_LOG_STATUS: | ||
110 | v4l_info(client, "Input: %s\n", | ||
111 | state->muted ? "muted" : "active"); | ||
112 | break; | ||
113 | |||
114 | default: | ||
115 | return -EINVAL; | ||
116 | } | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | /* ----------------------------------------------------------------------- */ | ||
121 | |||
122 | /* i2c implementation */ | ||
123 | |||
124 | /* | ||
125 | * Generic i2c probe | ||
126 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
127 | */ | ||
128 | |||
129 | static struct i2c_driver i2c_driver; | ||
130 | |||
131 | static int tlv320aic23b_attach(struct i2c_adapter *adapter, int address, int kind) | ||
132 | { | ||
133 | struct i2c_client *client; | ||
134 | struct tlv320aic23b_state *state; | ||
135 | |||
136 | /* Check if the adapter supports the needed features */ | ||
137 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
138 | return 0; | ||
139 | |||
140 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
141 | if (client == 0) | ||
142 | return -ENOMEM; | ||
143 | |||
144 | client->addr = address; | ||
145 | client->adapter = adapter; | ||
146 | client->driver = &i2c_driver; | ||
147 | snprintf(client->name, sizeof(client->name) - 1, "tlv320aic23b"); | ||
148 | |||
149 | v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name); | ||
150 | |||
151 | state = kmalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL); | ||
152 | if (state == NULL) { | ||
153 | kfree(client); | ||
154 | return -ENOMEM; | ||
155 | } | ||
156 | state->muted = 0; | ||
157 | i2c_set_clientdata(client, state); | ||
158 | |||
159 | /* initialize tlv320aic23b */ | ||
160 | tlv320aic23b_write(client, 15, 0x000); /* RESET */ | ||
161 | tlv320aic23b_write(client, 6, 0x00A); /* turn off DAC & mic input */ | ||
162 | tlv320aic23b_write(client, 7, 0x049); /* left-justified, 24-bit, master mode */ | ||
163 | tlv320aic23b_write(client, 0, 0x119); /* set gain on both channels to +3.0 dB */ | ||
164 | tlv320aic23b_write(client, 8, 0x000); /* set sample rate to 48 kHz */ | ||
165 | tlv320aic23b_write(client, 9, 0x001); /* activate digital interface */ | ||
166 | |||
167 | i2c_attach_client(client); | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int tlv320aic23b_probe(struct i2c_adapter *adapter) | ||
173 | { | ||
174 | if (adapter->class & I2C_CLASS_TV_ANALOG) | ||
175 | return i2c_probe(adapter, &addr_data, tlv320aic23b_attach); | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int tlv320aic23b_detach(struct i2c_client *client) | ||
180 | { | ||
181 | int err; | ||
182 | |||
183 | err = i2c_detach_client(client); | ||
184 | if (err) { | ||
185 | return err; | ||
186 | } | ||
187 | kfree(client); | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | /* ----------------------------------------------------------------------- */ | ||
193 | |||
194 | /* i2c implementation */ | ||
195 | static struct i2c_driver i2c_driver = { | ||
196 | .driver = { | ||
197 | .name = "tlv320aic23b", | ||
198 | }, | ||
199 | .id = I2C_DRIVERID_TLV320AIC23B, | ||
200 | .attach_adapter = tlv320aic23b_probe, | ||
201 | .detach_client = tlv320aic23b_detach, | ||
202 | .command = tlv320aic23b_command, | ||
203 | }; | ||
204 | |||
205 | |||
206 | static int __init tlv320aic23b_init_module(void) | ||
207 | { | ||
208 | return i2c_add_driver(&i2c_driver); | ||
209 | } | ||
210 | |||
211 | static void __exit tlv320aic23b_cleanup_module(void) | ||
212 | { | ||
213 | i2c_del_driver(&i2c_driver); | ||
214 | } | ||
215 | |||
216 | module_init(tlv320aic23b_init_module); | ||
217 | module_exit(tlv320aic23b_cleanup_module); | ||
diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c index 74ab48c09c6a..bdf506e6ae27 100644 --- a/drivers/media/video/tuner-3036.c +++ b/drivers/media/video/tuner-3036.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/videodev.h> | 27 | #include <linux/videodev.h> |
28 | #include <media/v4l2-common.h> | ||
28 | 29 | ||
29 | #include <media/tuner.h> | 30 | #include <media/tuner.h> |
30 | 31 | ||
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 1013b4de89a2..e95792fd70f8 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -199,7 +199,7 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
199 | i2c_master_send(c, buffer, 4); | 199 | i2c_master_send(c, buffer, 4); |
200 | default_tuner_init(c); | 200 | default_tuner_init(c); |
201 | break; | 201 | break; |
202 | case TUNER_LG_TDVS_H062F: | 202 | case TUNER_LG_TDVS_H06XF: |
203 | /* Set the Auxiliary Byte. */ | 203 | /* Set the Auxiliary Byte. */ |
204 | buffer[2] &= ~0x20; | 204 | buffer[2] &= ~0x20; |
205 | buffer[2] |= 0x18; | 205 | buffer[2] |= 0x18; |
@@ -215,6 +215,9 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
215 | i2c_master_send(c,buffer,4); | 215 | i2c_master_send(c,buffer,4); |
216 | default_tuner_init(c); | 216 | default_tuner_init(c); |
217 | break; | 217 | break; |
218 | case TUNER_TDA9887: | ||
219 | tda9887_tuner_init(c); | ||
220 | break; | ||
218 | default: | 221 | default: |
219 | default_tuner_init(c); | 222 | default_tuner_init(c); |
220 | break; | 223 | break; |
@@ -241,6 +244,8 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup) | |||
241 | { | 244 | { |
242 | struct tuner *t = i2c_get_clientdata(c); | 245 | struct tuner *t = i2c_get_clientdata(c); |
243 | 246 | ||
247 | tuner_dbg("set addr for type %i\n", t->type); | ||
248 | |||
244 | if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET && | 249 | if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET && |
245 | (t->mode_mask & tun_setup->mode_mask)) || | 250 | (t->mode_mask & tun_setup->mode_mask)) || |
246 | tun_setup->addr == c->addr)) { | 251 | tun_setup->addr == c->addr)) { |
@@ -436,6 +441,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
436 | t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ | 441 | t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ |
437 | t->audmode = V4L2_TUNER_MODE_STEREO; | 442 | t->audmode = V4L2_TUNER_MODE_STEREO; |
438 | t->mode_mask = T_UNINITIALIZED; | 443 | t->mode_mask = T_UNINITIALIZED; |
444 | t->tuner_status = tuner_status; | ||
439 | if (tuner_debug_old) { | 445 | if (tuner_debug_old) { |
440 | tuner_debug = tuner_debug_old; | 446 | tuner_debug = tuner_debug_old; |
441 | printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n"); | 447 | printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n"); |
@@ -462,10 +468,14 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
462 | case 0x4b: | 468 | case 0x4b: |
463 | /* If chip is not tda8290, don't register. | 469 | /* If chip is not tda8290, don't register. |
464 | since it can be tda9887*/ | 470 | since it can be tda9887*/ |
465 | if (tda8290_probe(&t->i2c) != 0) { | 471 | if (tda8290_probe(&t->i2c) == 0) { |
466 | tuner_dbg("chip at addr %x is not a tda8290\n", addr); | 472 | tuner_dbg("chip at addr %x is a tda8290\n", addr); |
467 | kfree(t); | 473 | } else { |
468 | return 0; | 474 | /* Default is being tda9887 */ |
475 | t->type = TUNER_TDA9887; | ||
476 | t->mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; | ||
477 | t->mode = T_STANDBY; | ||
478 | goto register_client; | ||
469 | } | 479 | } |
470 | break; | 480 | break; |
471 | case 0x60: | 481 | case 0x60: |
@@ -592,6 +602,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
592 | case TUNER_SET_STANDBY: | 602 | case TUNER_SET_STANDBY: |
593 | if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) | 603 | if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) |
594 | return 0; | 604 | return 0; |
605 | t->mode = T_STANDBY; | ||
595 | if (t->standby) | 606 | if (t->standby) |
596 | t->standby (client); | 607 | t->standby (client); |
597 | break; | 608 | break; |
@@ -604,6 +615,14 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
604 | /* Should be implemented, since bttv calls it */ | 615 | /* Should be implemented, since bttv calls it */ |
605 | tuner_dbg("VIDIOCSAUDIO not implemented.\n"); | 616 | tuner_dbg("VIDIOCSAUDIO not implemented.\n"); |
606 | break; | 617 | break; |
618 | case TDA9887_SET_CONFIG: | ||
619 | { | ||
620 | int *i = arg; | ||
621 | |||
622 | t->tda9887_config = *i; | ||
623 | set_freq(client, t->tv_freq); | ||
624 | break; | ||
625 | } | ||
607 | /* --- v4l ioctls --- */ | 626 | /* --- v4l ioctls --- */ |
608 | /* take care: bttv does userspace copying, we'll get a | 627 | /* take care: bttv does userspace copying, we'll get a |
609 | kernel pointer here... */ | 628 | kernel pointer here... */ |
@@ -744,6 +763,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
744 | switch_v4l2(); | 763 | switch_v4l2(); |
745 | 764 | ||
746 | tuner->type = t->mode; | 765 | tuner->type = t->mode; |
766 | if (t->get_afc) | ||
767 | tuner->afc=t->get_afc(client); | ||
747 | if (t->mode == V4L2_TUNER_ANALOG_TV) | 768 | if (t->mode == V4L2_TUNER_ANALOG_TV) |
748 | tuner->capability |= V4L2_TUNER_CAP_NORM; | 769 | tuner->capability |= V4L2_TUNER_CAP_NORM; |
749 | if (t->mode != V4L2_TUNER_RADIO) { | 770 | if (t->mode != V4L2_TUNER_RADIO) { |
@@ -787,7 +808,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
787 | break; | 808 | break; |
788 | } | 809 | } |
789 | case VIDIOC_LOG_STATUS: | 810 | case VIDIOC_LOG_STATUS: |
790 | tuner_status(client); | 811 | if (t->tuner_status) |
812 | t->tuner_status(client); | ||
791 | break; | 813 | break; |
792 | } | 814 | } |
793 | 815 | ||
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 5d7abed71674..6da6f82b8c88 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
@@ -105,7 +105,7 @@ static int tuner_stereo(struct i2c_client *c) | |||
105 | 105 | ||
106 | switch (t->type) { | 106 | switch (t->type) { |
107 | case TUNER_PHILIPS_FM1216ME_MK3: | 107 | case TUNER_PHILIPS_FM1216ME_MK3: |
108 | case TUNER_PHILIPS_FM1236_MK3: | 108 | case TUNER_PHILIPS_FM1236_MK3: |
109 | case TUNER_PHILIPS_FM1256_IH3: | 109 | case TUNER_PHILIPS_FM1256_IH3: |
110 | stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); | 110 | stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); |
111 | break; | 111 | break; |
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index a1ae036b44ec..9d9226cb6393 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c | |||
@@ -874,7 +874,7 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { | |||
874 | }; | 874 | }; |
875 | 875 | ||
876 | 876 | ||
877 | /* ------------ TUNER_LG_TDVS_H062F - INFINEON ATSC ------------ */ | 877 | /* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */ |
878 | 878 | ||
879 | static struct tuner_range tuner_tua6034_ntsc_ranges[] = { | 879 | static struct tuner_range tuner_tua6034_ntsc_ranges[] = { |
880 | { 16 * 165.00 /*MHz*/, 0x8e, 0x01 }, | 880 | { 16 * 165.00 /*MHz*/, 0x8e, 0x01 }, |
@@ -883,7 +883,7 @@ static struct tuner_range tuner_tua6034_ntsc_ranges[] = { | |||
883 | }; | 883 | }; |
884 | 884 | ||
885 | 885 | ||
886 | static struct tuner_params tuner_tua6034_params[] = { | 886 | static struct tuner_params tuner_lg_tdvs_h06xf_params[] = { |
887 | { | 887 | { |
888 | .type = TUNER_PARAM_TYPE_NTSC, | 888 | .type = TUNER_PARAM_TYPE_NTSC, |
889 | .ranges = tuner_tua6034_ntsc_ranges, | 889 | .ranges = tuner_tua6034_ntsc_ranges, |
@@ -1024,6 +1024,22 @@ static struct tuner_params tuner_thomson_fe6600_params[] = { | |||
1024 | }, | 1024 | }, |
1025 | }; | 1025 | }; |
1026 | 1026 | ||
1027 | /* ------------ TUNER_SAMSUNG_TCPG_6121P30A - Samsung PAL ------------ */ | ||
1028 | |||
1029 | static struct tuner_range tuner_samsung_tcpg_6121p30a_pal_ranges[] = { | ||
1030 | { 16 * 146.25 /*MHz*/, 0xce, 0x01, }, | ||
1031 | { 16 * 428.50 /*MHz*/, 0xce, 0x02, }, | ||
1032 | { 16 * 999.99 , 0xce, 0x08, }, | ||
1033 | }; | ||
1034 | |||
1035 | static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = { | ||
1036 | { | ||
1037 | .type = TUNER_PARAM_TYPE_PAL, | ||
1038 | .ranges = tuner_samsung_tcpg_6121p30a_pal_ranges, | ||
1039 | .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_pal_ranges), | ||
1040 | }, | ||
1041 | }; | ||
1042 | |||
1027 | /* --------------------------------------------------------------------- */ | 1043 | /* --------------------------------------------------------------------- */ |
1028 | 1044 | ||
1029 | struct tunertype tuners[] = { | 1045 | struct tunertype tuners[] = { |
@@ -1354,10 +1370,10 @@ struct tunertype tuners[] = { | |||
1354 | .params = tuner_philips_fmd1216me_mk3_params, | 1370 | .params = tuner_philips_fmd1216me_mk3_params, |
1355 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params), | 1371 | .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params), |
1356 | }, | 1372 | }, |
1357 | [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */ | 1373 | [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */ |
1358 | .name = "LG TDVS-H062F/TUA6034", | 1374 | .name = "LG TDVS-H06xF", /* H061F, H062F & H064F */ |
1359 | .params = tuner_tua6034_params, | 1375 | .params = tuner_lg_tdvs_h06xf_params, |
1360 | .count = ARRAY_SIZE(tuner_tua6034_params), | 1376 | .count = ARRAY_SIZE(tuner_lg_tdvs_h06xf_params), |
1361 | }, | 1377 | }, |
1362 | [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ | 1378 | [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ |
1363 | .name = "Ymec TVF66T5-B/DFF", | 1379 | .name = "Ymec TVF66T5-B/DFF", |
@@ -1400,6 +1416,16 @@ struct tunertype tuners[] = { | |||
1400 | .params = tuner_thomson_fe6600_params, | 1416 | .params = tuner_thomson_fe6600_params, |
1401 | .count = ARRAY_SIZE(tuner_thomson_fe6600_params), | 1417 | .count = ARRAY_SIZE(tuner_thomson_fe6600_params), |
1402 | }, | 1418 | }, |
1419 | [TUNER_SAMSUNG_TCPG_6121P30A] = { /* Samsung PAL */ | ||
1420 | .name = "Samsung TCPG 6121P30A", | ||
1421 | .params = tuner_samsung_tcpg_6121p30a_params, | ||
1422 | .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_params), | ||
1423 | }, | ||
1424 | [TUNER_TDA9887] = { /* Philips TDA 9887 IF PLL Demodulator. | ||
1425 | This chip is part of some modern tuners */ | ||
1426 | .name = "Philips TDA988[5,6,7] IF PLL Demodulator", | ||
1427 | /* see tda9887.c for details */ | ||
1428 | }, | ||
1403 | }; | 1429 | }; |
1404 | 1430 | ||
1405 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | 1431 | unsigned const int tuner_count = ARRAY_SIZE(tuners); |
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index b463e996961a..30f8d80ddcaa 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -200,7 +200,7 @@ hauppauge_tuner[] = | |||
200 | { TUNER_ABSENT, "Philips FQ1286A MK4"}, | 200 | { TUNER_ABSENT, "Philips FQ1286A MK4"}, |
201 | { TUNER_ABSENT, "Philips FQ1216ME MK5"}, | 201 | { TUNER_ABSENT, "Philips FQ1216ME MK5"}, |
202 | { TUNER_ABSENT, "Philips FQ1236 MK5"}, | 202 | { TUNER_ABSENT, "Philips FQ1236 MK5"}, |
203 | { TUNER_ABSENT, "Samsung TCPG_6121P30A"}, | 203 | { TUNER_SAMSUNG_TCPG_6121P30A, "Samsung TCPG 6121P30A"}, |
204 | { TUNER_TCL_2002MB, "TCL 2002MB_3H"}, | 204 | { TUNER_TCL_2002MB, "TCL 2002MB_3H"}, |
205 | { TUNER_ABSENT, "TCL 2002MI_3H"}, | 205 | { TUNER_ABSENT, "TCL 2002MI_3H"}, |
206 | { TUNER_TCL_2002N, "TCL 2002N 5H"}, | 206 | { TUNER_TCL_2002N, "TCL 2002N 5H"}, |
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c index 9e86caeb96a7..1654576de10e 100644 --- a/drivers/media/video/tvmixer.c +++ b/drivers/media/video/tvmixer.c | |||
@@ -198,10 +198,6 @@ static int tvmixer_open(struct inode *inode, struct file *file) | |||
198 | 198 | ||
199 | /* lock bttv in memory while the mixer is in use */ | 199 | /* lock bttv in memory while the mixer is in use */ |
200 | file->private_data = mix; | 200 | file->private_data = mix; |
201 | #ifndef I2C_PEC | ||
202 | if (client->adapter->inc_use) | ||
203 | client->adapter->inc_use(client->adapter); | ||
204 | #endif | ||
205 | if (client->adapter->owner) | 201 | if (client->adapter->owner) |
206 | try_module_get(client->adapter->owner); | 202 | try_module_get(client->adapter->owner); |
207 | return 0; | 203 | return 0; |
@@ -217,10 +213,6 @@ static int tvmixer_release(struct inode *inode, struct file *file) | |||
217 | return -ENODEV; | 213 | return -ENODEV; |
218 | } | 214 | } |
219 | 215 | ||
220 | #ifndef I2C_PEC | ||
221 | if (client->adapter->dec_use) | ||
222 | client->adapter->dec_use(client->adapter); | ||
223 | #endif | ||
224 | if (client->adapter->owner) | 216 | if (client->adapter->owner) |
225 | module_put(client->adapter->owner); | 217 | module_put(client->adapter->owner); |
226 | return 0; | 218 | return 0; |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index dab4973bcf82..b167ffab2520 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/video_decoder.h> | 11 | #include <linux/video_decoder.h> |
12 | #include <media/v4l2-common.h> | 12 | #include <media/v4l2-common.h> |
13 | #include <media/tvp5150.h> | ||
13 | 14 | ||
14 | #include "tvp5150_reg.h" | 15 | #include "tvp5150_reg.h" |
15 | 16 | ||
@@ -89,7 +90,7 @@ struct tvp5150 { | |||
89 | struct i2c_client *client; | 90 | struct i2c_client *client; |
90 | 91 | ||
91 | v4l2_std_id norm; /* Current set standard */ | 92 | v4l2_std_id norm; /* Current set standard */ |
92 | int input; | 93 | struct v4l2_routing route; |
93 | int enable; | 94 | int enable; |
94 | int bright; | 95 | int bright; |
95 | int contrast; | 96 | int contrast; |
@@ -283,29 +284,26 @@ static void dump_reg(struct i2c_client *c) | |||
283 | /**************************************************************************** | 284 | /**************************************************************************** |
284 | Basic functions | 285 | Basic functions |
285 | ****************************************************************************/ | 286 | ****************************************************************************/ |
286 | enum tvp5150_input { | ||
287 | TVP5150_ANALOG_CH0 = 0, | ||
288 | TVP5150_SVIDEO = 1, | ||
289 | TVP5150_ANALOG_CH1 = 2, | ||
290 | TVP5150_BLACK_SCREEN = 8 | ||
291 | }; | ||
292 | 287 | ||
293 | static inline void tvp5150_selmux(struct i2c_client *c, | 288 | static inline void tvp5150_selmux(struct i2c_client *c) |
294 | enum tvp5150_input input) | ||
295 | { | 289 | { |
296 | int opmode=0; | 290 | int opmode=0; |
297 | |||
298 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 291 | struct tvp5150 *decoder = i2c_get_clientdata(c); |
292 | int input = 0; | ||
299 | 293 | ||
300 | if (!decoder->enable) | 294 | if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable) |
301 | input |= TVP5150_BLACK_SCREEN; | 295 | input = 8; |
302 | 296 | ||
303 | switch (input) { | 297 | switch (input) { |
304 | case TVP5150_ANALOG_CH0: | 298 | case TVP5150_COMPOSITE1: |
305 | case TVP5150_ANALOG_CH1: | 299 | input |= 2; |
300 | /* fall through */ | ||
301 | case TVP5150_COMPOSITE0: | ||
306 | opmode=0x30; /* TV Mode */ | 302 | opmode=0x30; /* TV Mode */ |
307 | break; | 303 | break; |
304 | case TVP5150_SVIDEO: | ||
308 | default: | 305 | default: |
306 | input |= 1; | ||
309 | opmode=0; /* Auto Mode */ | 307 | opmode=0; /* Auto Mode */ |
310 | break; | 308 | break; |
311 | } | 309 | } |
@@ -790,7 +788,7 @@ static inline void tvp5150_reset(struct i2c_client *c) | |||
790 | tvp5150_vdp_init(c, vbi_ram_default); | 788 | tvp5150_vdp_init(c, vbi_ram_default); |
791 | 789 | ||
792 | /* Selects decoder input */ | 790 | /* Selects decoder input */ |
793 | tvp5150_selmux(c, decoder->input); | 791 | tvp5150_selmux(c); |
794 | 792 | ||
795 | /* Initializes TVP5150 to stream enabled values */ | 793 | /* Initializes TVP5150 to stream enabled values */ |
796 | tvp5150_write_inittab(c, tvp5150_init_enable); | 794 | tvp5150_write_inittab(c, tvp5150_init_enable); |
@@ -860,6 +858,21 @@ static int tvp5150_command(struct i2c_client *c, | |||
860 | case VIDIOC_INT_RESET: | 858 | case VIDIOC_INT_RESET: |
861 | tvp5150_reset(c); | 859 | tvp5150_reset(c); |
862 | break; | 860 | break; |
861 | case VIDIOC_INT_G_VIDEO_ROUTING: | ||
862 | { | ||
863 | struct v4l2_routing *route = arg; | ||
864 | |||
865 | *route = decoder->route; | ||
866 | break; | ||
867 | } | ||
868 | case VIDIOC_INT_S_VIDEO_ROUTING: | ||
869 | { | ||
870 | struct v4l2_routing *route = arg; | ||
871 | |||
872 | decoder->route = *route; | ||
873 | tvp5150_selmux(c); | ||
874 | break; | ||
875 | } | ||
863 | case VIDIOC_S_STD: | 876 | case VIDIOC_S_STD: |
864 | if (decoder->norm == *(v4l2_std_id *)arg) | 877 | if (decoder->norm == *(v4l2_std_id *)arg) |
865 | break; | 878 | break; |
@@ -1063,7 +1076,7 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, | |||
1063 | rv = i2c_attach_client(c); | 1076 | rv = i2c_attach_client(c); |
1064 | 1077 | ||
1065 | core->norm = V4L2_STD_ALL; /* Default is autodetect */ | 1078 | core->norm = V4L2_STD_ALL; /* Default is autodetect */ |
1066 | core->input = 2; | 1079 | core->route.input = TVP5150_COMPOSITE1; |
1067 | core->enable = 1; | 1080 | core->enable = 1; |
1068 | core->bright = 32768; | 1081 | core->bright = 32768; |
1069 | core->contrast = 32768; | 1082 | core->contrast = 32768; |
diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig index 39269a2c5635..59fb899f31f3 100644 --- a/drivers/media/video/usbvideo/Kconfig +++ b/drivers/media/video/usbvideo/Kconfig | |||
@@ -36,3 +36,15 @@ config USB_KONICAWC | |||
36 | 36 | ||
37 | To compile this driver as a module, choose M here: the | 37 | To compile this driver as a module, choose M here: the |
38 | module will be called konicawc. | 38 | module will be called konicawc. |
39 | |||
40 | config USB_QUICKCAM_MESSENGER | ||
41 | tristate "USB Logitech Quickcam Messenger" | ||
42 | depends on USB && VIDEO_DEV | ||
43 | select VIDEO_USBVIDEO | ||
44 | ---help--- | ||
45 | Say Y or M here to enable support for the USB Logitech Quickcam | ||
46 | Messenger webcam. | ||
47 | |||
48 | To compile this driver as a module, choose M here: the | ||
49 | module will be called quickcam_messenger. | ||
50 | |||
diff --git a/drivers/media/video/usbvideo/Makefile b/drivers/media/video/usbvideo/Makefile index bb52eb8dc2f9..4a1b144bee4d 100644 --- a/drivers/media/video/usbvideo/Makefile +++ b/drivers/media/video/usbvideo/Makefile | |||
@@ -2,3 +2,4 @@ obj-$(CONFIG_VIDEO_USBVIDEO) += usbvideo.o | |||
2 | obj-$(CONFIG_USB_IBMCAM) += ibmcam.o ultracam.o | 2 | obj-$(CONFIG_USB_IBMCAM) += ibmcam.o ultracam.o |
3 | obj-$(CONFIG_USB_KONICAWC) += konicawc.o | 3 | obj-$(CONFIG_USB_KONICAWC) += konicawc.o |
4 | obj-$(CONFIG_USB_VICAM) += vicam.o | 4 | obj-$(CONFIG_USB_VICAM) += vicam.o |
5 | obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += quickcam_messenger.o | ||
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c new file mode 100644 index 000000000000..3f3182a24da1 --- /dev/null +++ b/drivers/media/video/usbvideo/quickcam_messenger.c | |||
@@ -0,0 +1,1120 @@ | |||
1 | /* | ||
2 | * Driver for Logitech Quickcam Messenger usb video camera | ||
3 | * Copyright (C) Jaya Kumar | ||
4 | * | ||
5 | * This work was sponsored by CIS(M) Sdn Bhd. | ||
6 | * History: | ||
7 | * 05/08/2006 - Jaya Kumar | ||
8 | * I wrote this based on the konicawc by Simon Evans. | ||
9 | * - | ||
10 | * Full credit for reverse engineering and creating an initial | ||
11 | * working linux driver for the VV6422 goes to the qce-ga project by | ||
12 | * Tuukka Toivonen, Jochen Hoenicke, Peter McConnell, | ||
13 | * Cristiano De Michele, Georg Acher, Jean-Frederic Clere as well as | ||
14 | * others. | ||
15 | * --- | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or | ||
19 | * (at your option) any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/input.h> | ||
36 | #include <linux/usb_input.h> | ||
37 | |||
38 | #include "usbvideo.h" | ||
39 | #include "quickcam_messenger.h" | ||
40 | |||
41 | /* | ||
42 | * Version Information | ||
43 | */ | ||
44 | |||
45 | #ifdef CONFIG_USB_DEBUG | ||
46 | static int debug; | ||
47 | #define DEBUG(n, format, arg...) \ | ||
48 | if (n <= debug) { \ | ||
49 | printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \ | ||
50 | } | ||
51 | #else | ||
52 | #define DEBUG(n, arg...) | ||
53 | static const int debug = 0; | ||
54 | #endif | ||
55 | |||
56 | #define DRIVER_VERSION "v0.01" | ||
57 | #define DRIVER_DESC "Logitech Quickcam Messenger USB" | ||
58 | |||
59 | #define USB_LOGITECH_VENDOR_ID 0x046D | ||
60 | #define USB_QCM_PRODUCT_ID 0x08F0 | ||
61 | |||
62 | #define MAX_CAMERAS 1 | ||
63 | |||
64 | #define MAX_COLOUR 32768 | ||
65 | #define MAX_HUE 32768 | ||
66 | #define MAX_BRIGHTNESS 32768 | ||
67 | #define MAX_CONTRAST 32768 | ||
68 | #define MAX_WHITENESS 32768 | ||
69 | |||
70 | static int size = SIZE_320X240; | ||
71 | static int colour = MAX_COLOUR; | ||
72 | static int hue = MAX_HUE; | ||
73 | static int brightness = MAX_BRIGHTNESS; | ||
74 | static int contrast = MAX_CONTRAST; | ||
75 | static int whiteness = MAX_WHITENESS; | ||
76 | |||
77 | static struct usbvideo *cams; | ||
78 | |||
79 | static struct usb_device_id qcm_table [] = { | ||
80 | { USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) }, | ||
81 | { } | ||
82 | }; | ||
83 | MODULE_DEVICE_TABLE(usb, qcm_table); | ||
84 | |||
85 | #ifdef CONFIG_INPUT | ||
86 | static void qcm_register_input(struct qcm *cam, struct usb_device *dev) | ||
87 | { | ||
88 | struct input_dev *input_dev; | ||
89 | |||
90 | usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); | ||
91 | strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); | ||
92 | |||
93 | cam->input = input_dev = input_allocate_device(); | ||
94 | if (!input_dev) { | ||
95 | warn("insufficient mem for cam input device"); | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | input_dev->name = "QCM button"; | ||
100 | input_dev->phys = cam->input_physname; | ||
101 | usb_to_input_id(dev, &input_dev->id); | ||
102 | input_dev->cdev.dev = &dev->dev; | ||
103 | |||
104 | input_dev->evbit[0] = BIT(EV_KEY); | ||
105 | input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); | ||
106 | |||
107 | input_dev->private = cam; | ||
108 | |||
109 | input_register_device(cam->input); | ||
110 | } | ||
111 | |||
112 | static void qcm_unregister_input(struct qcm *cam) | ||
113 | { | ||
114 | if (cam->input) { | ||
115 | input_unregister_device(cam->input); | ||
116 | cam->input = NULL; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static void qcm_report_buttonstat(struct qcm *cam) | ||
121 | { | ||
122 | if (cam->input) { | ||
123 | input_report_key(cam->input, BTN_0, cam->button_sts); | ||
124 | input_sync(cam->input); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | static void qcm_int_irq(struct urb *urb, struct pt_regs *regs) | ||
129 | { | ||
130 | int ret; | ||
131 | struct uvd *uvd = urb->context; | ||
132 | struct qcm *cam; | ||
133 | |||
134 | if (!CAMERA_IS_OPERATIONAL(uvd)) | ||
135 | return; | ||
136 | |||
137 | if (!uvd->streaming) | ||
138 | return; | ||
139 | |||
140 | uvd->stats.urb_count++; | ||
141 | |||
142 | if (urb->status < 0) | ||
143 | uvd->stats.iso_err_count++; | ||
144 | else { | ||
145 | if (urb->actual_length > 0 ) { | ||
146 | cam = (struct qcm *) uvd->user_data; | ||
147 | if (cam->button_sts_buf == 0x88) | ||
148 | cam->button_sts = 0x0; | ||
149 | else if (cam->button_sts_buf == 0x80) | ||
150 | cam->button_sts = 0x1; | ||
151 | qcm_report_buttonstat(cam); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
156 | if (ret < 0) | ||
157 | err("usb_submit_urb error (%d)", ret); | ||
158 | } | ||
159 | |||
160 | static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd) | ||
161 | { | ||
162 | int errflag; | ||
163 | usb_fill_int_urb(cam->button_urb, uvd->dev, | ||
164 | usb_rcvintpipe(uvd->dev, uvd->video_endp + 1), | ||
165 | &cam->button_sts_buf, | ||
166 | 1, | ||
167 | qcm_int_irq, | ||
168 | uvd, 16); | ||
169 | |||
170 | errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL); | ||
171 | if (errflag) | ||
172 | err ("usb_submit_int ret %d", errflag); | ||
173 | return errflag; | ||
174 | } | ||
175 | |||
176 | static void qcm_stop_int_data(struct qcm *cam) | ||
177 | { | ||
178 | usb_kill_urb(cam->button_urb); | ||
179 | } | ||
180 | |||
181 | static int qcm_alloc_int_urb(struct qcm *cam) | ||
182 | { | ||
183 | cam->button_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
184 | |||
185 | if (!cam->button_urb) | ||
186 | return -ENOMEM; | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static void qcm_free_int(struct qcm *cam) | ||
192 | { | ||
193 | if (cam->button_urb) | ||
194 | usb_free_urb(cam->button_urb); | ||
195 | } | ||
196 | #endif /* CONFIG_INPUT */ | ||
197 | |||
198 | static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val) | ||
199 | { | ||
200 | int ret; | ||
201 | |||
202 | /* we'll wait up to 3 slices but no more */ | ||
203 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
204 | 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, | ||
205 | reg, 0, &val, 1, 3*HZ); | ||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | static int qcm_stv_setw(struct usb_device *dev, u16 reg, u16 val) | ||
210 | { | ||
211 | int ret; | ||
212 | |||
213 | /* we'll wait up to 3 slices but no more */ | ||
214 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
215 | 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, | ||
216 | reg, 0, &val, 2, 3*HZ); | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | static int qcm_stv_getw(struct usb_device *dev, unsigned short reg, | ||
221 | __le16 *val) | ||
222 | { | ||
223 | int ret; | ||
224 | |||
225 | /* we'll wait up to 3 slices but no more */ | ||
226 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
227 | 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE, | ||
228 | reg, 0, val, 2, 3*HZ); | ||
229 | return ret; | ||
230 | } | ||
231 | |||
232 | static int qcm_camera_on(struct uvd *uvd) | ||
233 | { | ||
234 | int ret; | ||
235 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01)); | ||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static int qcm_camera_off(struct uvd *uvd) | ||
240 | { | ||
241 | int ret; | ||
242 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00)); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b) | ||
247 | { | ||
248 | unsigned int segment, valsat; | ||
249 | signed int h = (signed int) hue; | ||
250 | unsigned int s = (sat - 32768) * 2; /* rescale */ | ||
251 | unsigned int v = val; | ||
252 | unsigned int p; | ||
253 | |||
254 | /* | ||
255 | the registers controling gain are 8 bit of which | ||
256 | we affect only the last 4 bits with our gain. | ||
257 | we know that if saturation is 0, (unsaturated) then | ||
258 | we're grayscale (center axis of the colour cone) so | ||
259 | we set rgb=value. we use a formula obtained from | ||
260 | wikipedia to map the cone to the RGB plane. it's | ||
261 | as follows for the human value case of h=0..360, | ||
262 | s=0..1, v=0..1 | ||
263 | h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s) | ||
264 | q = v(1 - f*s) , t = v(1 - (1-f)s) | ||
265 | h_i==0 => r=v , g=t, b=p | ||
266 | h_i==1 => r=q , g=v, b=p | ||
267 | h_i==2 => r=p , g=v, b=t | ||
268 | h_i==3 => r=p , g=q, b=v | ||
269 | h_i==4 => r=t , g=p, b=v | ||
270 | h_i==5 => r=v , g=p, b=q | ||
271 | the bottom side (the point) and the stuff just up | ||
272 | of that is black so we simplify those two cases. | ||
273 | */ | ||
274 | if (sat < 32768) { | ||
275 | /* anything less than this is unsaturated */ | ||
276 | *r = val; | ||
277 | *g = val; | ||
278 | *b = val; | ||
279 | return; | ||
280 | } | ||
281 | if (val <= (0xFFFF/8)) { | ||
282 | /* anything less than this is black */ | ||
283 | *r = 0; | ||
284 | *g = 0; | ||
285 | *b = 0; | ||
286 | return; | ||
287 | } | ||
288 | |||
289 | /* the rest of this code is copying tukkat's | ||
290 | implementation of the hsv2rgb conversion as taken | ||
291 | from qc-usb-messenger code. the 10923 is 0xFFFF/6 | ||
292 | to divide the cone into 6 sectors. */ | ||
293 | |||
294 | segment = (h + 10923) & 0xFFFF; | ||
295 | segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */ | ||
296 | hue -= segment * 21845; /* -10923..10923 */ | ||
297 | h = hue; | ||
298 | h *= 3; | ||
299 | valsat = v*s >> 16; /* 0..65534 */ | ||
300 | p = v - valsat; | ||
301 | if (h >= 0) { | ||
302 | unsigned int t = v - (valsat * (32769 - h) >> 15); | ||
303 | switch (segment) { | ||
304 | case 0: /* R-> */ | ||
305 | *r = v; | ||
306 | *g = t; | ||
307 | *b = p; | ||
308 | break; | ||
309 | case 1: /* G-> */ | ||
310 | *r = p; | ||
311 | *g = v; | ||
312 | *b = t; | ||
313 | break; | ||
314 | case 2: /* B-> */ | ||
315 | *r = t; | ||
316 | *g = p; | ||
317 | *b = v; | ||
318 | break; | ||
319 | } | ||
320 | } else { | ||
321 | unsigned int q = v - (valsat * (32769 + h) >> 15); | ||
322 | switch (segment) { | ||
323 | case 0: /* ->R */ | ||
324 | *r = v; | ||
325 | *g = p; | ||
326 | *b = q; | ||
327 | break; | ||
328 | case 1: /* ->G */ | ||
329 | *r = q; | ||
330 | *g = v; | ||
331 | *b = p; | ||
332 | break; | ||
333 | case 2: /* ->B */ | ||
334 | *r = p; | ||
335 | *g = q; | ||
336 | *b = v; | ||
337 | break; | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | |||
342 | static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue, | ||
343 | u16 saturation, u16 value) | ||
344 | { | ||
345 | int ret; | ||
346 | u16 r=0,g=0,b=0; | ||
347 | |||
348 | /* this code is based on qc-usb-messenger */ | ||
349 | qcm_hsv2rgb(hue, saturation, value, &r, &g, &b); | ||
350 | |||
351 | r >>= 12; | ||
352 | g >>= 12; | ||
353 | b >>= 12; | ||
354 | |||
355 | /* min val is 8 */ | ||
356 | r = max((u16) 8, r); | ||
357 | g = max((u16) 8, g); | ||
358 | b = max((u16) 8, b); | ||
359 | |||
360 | r |= 0x30; | ||
361 | g |= 0x30; | ||
362 | b |= 0x30; | ||
363 | |||
364 | /* set the r,g,b gain registers */ | ||
365 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r)); | ||
366 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g)); | ||
367 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b)); | ||
368 | |||
369 | /* doing as qc-usb did */ | ||
370 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A)); | ||
371 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01)); | ||
372 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01)); | ||
373 | |||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure) | ||
378 | { | ||
379 | int ret; | ||
380 | int formedval; | ||
381 | |||
382 | /* calculation was from qc-usb-messenger driver */ | ||
383 | formedval = ( exposure >> 12 ); | ||
384 | |||
385 | /* max value for formedval is 14 */ | ||
386 | formedval = min(formedval, 14); | ||
387 | |||
388 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, | ||
389 | 0x143A, 0xF0 | formedval)); | ||
390 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01)); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast, | ||
395 | int hue, int colour) | ||
396 | { | ||
397 | int ret; | ||
398 | /* brightness is exposure, contrast is gain, colour is saturation */ | ||
399 | CHECK_RET(ret, | ||
400 | qcm_sensor_set_exposure(uvd, brightness)); | ||
401 | CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast)); | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static int qcm_sensor_setsize(struct uvd *uvd, u8 size) | ||
407 | { | ||
408 | int ret; | ||
409 | |||
410 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size)); | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness) | ||
415 | { | ||
416 | int ret; | ||
417 | /* some rescaling as done by the qc-usb-messenger code */ | ||
418 | if (whiteness > 0xC000) | ||
419 | whiteness = 0xC000 + (whiteness & 0x3FFF)*8; | ||
420 | |||
421 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D, | ||
422 | (whiteness >> 8) & 0xFF)); | ||
423 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E, | ||
424 | (whiteness >> 16) & 0x03)); | ||
425 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01)); | ||
426 | |||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static int qcm_sensor_init(struct uvd *uvd) | ||
431 | { | ||
432 | struct qcm *cam = (struct qcm *) uvd->user_data; | ||
433 | int ret; | ||
434 | int i; | ||
435 | |||
436 | for (i=0; i < sizeof(regval_table)/sizeof(regval_table[0]) ; i++) { | ||
437 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, | ||
438 | regval_table[i].reg, | ||
439 | regval_table[i].val)); | ||
440 | } | ||
441 | |||
442 | CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1, | ||
443 | cpu_to_le16(ISOC_PACKET_SIZE))); | ||
444 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08)); | ||
445 | CHECK_RET(ret, ret = qcm_stv_setb(uvd->dev, 0x143f, 0x01)); | ||
446 | |||
447 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00)); | ||
448 | |||
449 | CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd)); | ||
450 | |||
451 | CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness, | ||
452 | uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour)); | ||
453 | |||
454 | CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness)); | ||
455 | CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd)); | ||
456 | |||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | static int qcm_set_camera_size(struct uvd *uvd) | ||
461 | { | ||
462 | int ret; | ||
463 | struct qcm *cam = (struct qcm *) uvd->user_data; | ||
464 | |||
465 | CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd)); | ||
466 | cam->width = camera_sizes[cam->size].width; | ||
467 | cam->height = camera_sizes[cam->size].height; | ||
468 | uvd->videosize = VIDEOSIZE(cam->width, cam->height); | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static int qcm_setup_on_open(struct uvd *uvd) | ||
474 | { | ||
475 | int ret; | ||
476 | |||
477 | CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue, | ||
478 | uvd->vpic.colour, uvd->vpic.contrast)); | ||
479 | CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness)); | ||
480 | CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness)); | ||
481 | CHECK_RET(ret, qcm_set_camera_size(uvd)); | ||
482 | CHECK_RET(ret, qcm_camera_on(uvd)); | ||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static void qcm_adjust_picture(struct uvd *uvd) | ||
487 | { | ||
488 | int ret; | ||
489 | struct qcm *cam = (struct qcm *) uvd->user_data; | ||
490 | |||
491 | ret = qcm_camera_off(uvd); | ||
492 | if (ret) { | ||
493 | err("can't turn camera off. abandoning pic adjustment"); | ||
494 | return; | ||
495 | } | ||
496 | |||
497 | /* if there's been a change in contrast, hue, or | ||
498 | colour then we need to recalculate hsv in order | ||
499 | to update gains */ | ||
500 | if ((cam->contrast != uvd->vpic.contrast) || | ||
501 | (cam->hue != uvd->vpic.hue) || | ||
502 | (cam->colour != uvd->vpic.colour)) { | ||
503 | cam->contrast = uvd->vpic.contrast; | ||
504 | cam->hue = uvd->vpic.hue; | ||
505 | cam->colour = uvd->vpic.colour; | ||
506 | ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour, | ||
507 | cam->contrast); | ||
508 | if (ret) { | ||
509 | err("can't set gains. abandoning pic adjustment"); | ||
510 | return; | ||
511 | } | ||
512 | } | ||
513 | |||
514 | if (cam->brightness != uvd->vpic.brightness) { | ||
515 | cam->brightness = uvd->vpic.brightness; | ||
516 | ret = qcm_sensor_set_exposure(uvd, cam->brightness); | ||
517 | if (ret) { | ||
518 | err("can't set exposure. abandoning pic adjustment"); | ||
519 | return; | ||
520 | } | ||
521 | } | ||
522 | |||
523 | if (cam->whiteness != uvd->vpic.whiteness) { | ||
524 | cam->whiteness = uvd->vpic.whiteness; | ||
525 | qcm_sensor_set_shutter(uvd, cam->whiteness); | ||
526 | if (ret) { | ||
527 | err("can't set shutter. abandoning pic adjustment"); | ||
528 | return; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | ret = qcm_camera_on(uvd); | ||
533 | if (ret) { | ||
534 | err("can't reenable camera. pic adjustment failed"); | ||
535 | return; | ||
536 | } | ||
537 | } | ||
538 | |||
539 | static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen) | ||
540 | { | ||
541 | int datalen; | ||
542 | int totaldata; | ||
543 | struct framehdr { | ||
544 | __be16 id; | ||
545 | __be16 len; | ||
546 | }; | ||
547 | struct framehdr *fhdr; | ||
548 | |||
549 | totaldata = 0; | ||
550 | while (framelen) { | ||
551 | fhdr = (struct framehdr *) cdata; | ||
552 | datalen = be16_to_cpu(fhdr->len); | ||
553 | framelen -= 4; | ||
554 | cdata += 4; | ||
555 | |||
556 | if ((fhdr->id) == cpu_to_be16(0x8001)) { | ||
557 | RingQueue_Enqueue(&uvd->dp, marker, 4); | ||
558 | totaldata += 4; | ||
559 | continue; | ||
560 | } | ||
561 | if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) { | ||
562 | RingQueue_Enqueue(&uvd->dp, cdata, datalen); | ||
563 | totaldata += datalen; | ||
564 | } | ||
565 | framelen -= datalen; | ||
566 | cdata += datalen; | ||
567 | } | ||
568 | return totaldata; | ||
569 | } | ||
570 | |||
571 | static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb) | ||
572 | { | ||
573 | int totlen; | ||
574 | int i; | ||
575 | unsigned char *cdata; | ||
576 | |||
577 | totlen=0; | ||
578 | for (i = 0; i < dataurb->number_of_packets; i++) { | ||
579 | int n = dataurb->iso_frame_desc[i].actual_length; | ||
580 | int st = dataurb->iso_frame_desc[i].status; | ||
581 | |||
582 | cdata = dataurb->transfer_buffer + | ||
583 | dataurb->iso_frame_desc[i].offset; | ||
584 | |||
585 | if (st < 0) { | ||
586 | warn("Data error: packet=%d. len=%d. status=%d.", | ||
587 | i, n, st); | ||
588 | uvd->stats.iso_err_count++; | ||
589 | continue; | ||
590 | } | ||
591 | if (!n) | ||
592 | continue; | ||
593 | |||
594 | totlen += qcm_process_frame(uvd, cdata, n); | ||
595 | } | ||
596 | return totlen; | ||
597 | } | ||
598 | |||
599 | static void resubmit_urb(struct uvd *uvd, struct urb *urb) | ||
600 | { | ||
601 | int ret; | ||
602 | |||
603 | urb->dev = uvd->dev; | ||
604 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
605 | if (ret) | ||
606 | err("usb_submit_urb error (%d)", ret); | ||
607 | } | ||
608 | |||
609 | static void qcm_isoc_irq(struct urb *urb, struct pt_regs *regs) | ||
610 | { | ||
611 | int len; | ||
612 | struct uvd *uvd = urb->context; | ||
613 | |||
614 | if (!CAMERA_IS_OPERATIONAL(uvd)) | ||
615 | return; | ||
616 | |||
617 | if (!uvd->streaming) | ||
618 | return; | ||
619 | |||
620 | uvd->stats.urb_count++; | ||
621 | |||
622 | if (!urb->actual_length) { | ||
623 | resubmit_urb(uvd, urb); | ||
624 | return; | ||
625 | } | ||
626 | |||
627 | len = qcm_compress_iso(uvd, urb); | ||
628 | resubmit_urb(uvd, urb); | ||
629 | uvd->stats.urb_length = len; | ||
630 | uvd->stats.data_count += len; | ||
631 | if (len) | ||
632 | RingQueue_WakeUpInterruptible(&uvd->dp); | ||
633 | } | ||
634 | |||
635 | static int qcm_start_data(struct uvd *uvd) | ||
636 | { | ||
637 | struct qcm *cam = (struct qcm *) uvd->user_data; | ||
638 | int i; | ||
639 | int errflag; | ||
640 | int pktsz; | ||
641 | int err; | ||
642 | |||
643 | pktsz = uvd->iso_packet_len; | ||
644 | if (!CAMERA_IS_OPERATIONAL(uvd)) { | ||
645 | err("Camera is not operational"); | ||
646 | return -EFAULT; | ||
647 | } | ||
648 | |||
649 | err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive); | ||
650 | if (err < 0) { | ||
651 | err("usb_set_interface error"); | ||
652 | uvd->last_error = err; | ||
653 | return -EBUSY; | ||
654 | } | ||
655 | |||
656 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
657 | int j, k; | ||
658 | struct urb *urb = uvd->sbuf[i].urb; | ||
659 | urb->dev = uvd->dev; | ||
660 | urb->context = uvd; | ||
661 | urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp); | ||
662 | urb->interval = 1; | ||
663 | urb->transfer_flags = URB_ISO_ASAP; | ||
664 | urb->transfer_buffer = uvd->sbuf[i].data; | ||
665 | urb->complete = qcm_isoc_irq; | ||
666 | urb->number_of_packets = FRAMES_PER_DESC; | ||
667 | urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC; | ||
668 | for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) { | ||
669 | urb->iso_frame_desc[j].offset = k; | ||
670 | urb->iso_frame_desc[j].length = pktsz; | ||
671 | } | ||
672 | } | ||
673 | |||
674 | uvd->streaming = 1; | ||
675 | uvd->curframe = -1; | ||
676 | for (i=0; i < USBVIDEO_NUMSBUF; i++) { | ||
677 | errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); | ||
678 | if (errflag) | ||
679 | err ("usb_submit_isoc(%d) ret %d", i, errflag); | ||
680 | } | ||
681 | |||
682 | CHECK_RET(err, qcm_setup_input_int(cam, uvd)); | ||
683 | CHECK_RET(err, qcm_camera_on(uvd)); | ||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | static void qcm_stop_data(struct uvd *uvd) | ||
688 | { | ||
689 | struct qcm *cam = (struct qcm *) uvd->user_data; | ||
690 | int i, j; | ||
691 | int ret; | ||
692 | |||
693 | if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL)) | ||
694 | return; | ||
695 | |||
696 | ret = qcm_camera_off(uvd); | ||
697 | if (ret) | ||
698 | warn("couldn't turn the cam off."); | ||
699 | |||
700 | uvd->streaming = 0; | ||
701 | |||
702 | /* Unschedule all of the iso td's */ | ||
703 | for (i=0; i < USBVIDEO_NUMSBUF; i++) | ||
704 | usb_kill_urb(uvd->sbuf[i].urb); | ||
705 | |||
706 | qcm_stop_int_data(cam); | ||
707 | |||
708 | if (!uvd->remove_pending) { | ||
709 | /* Set packet size to 0 */ | ||
710 | j = usb_set_interface(uvd->dev, uvd->iface, | ||
711 | uvd->ifaceAltInactive); | ||
712 | if (j < 0) { | ||
713 | err("usb_set_interface() error %d.", j); | ||
714 | uvd->last_error = j; | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | |||
719 | static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame) | ||
720 | { | ||
721 | struct qcm *cam = (struct qcm *) uvd->user_data; | ||
722 | int x; | ||
723 | struct rgb *rgbL0; | ||
724 | struct rgb *rgbL1; | ||
725 | struct bayL0 *bayL0; | ||
726 | struct bayL1 *bayL1; | ||
727 | int hor,ver,hordel,verdel; | ||
728 | assert(frame != NULL); | ||
729 | |||
730 | switch (cam->size) { | ||
731 | case SIZE_160X120: | ||
732 | hor = 162; ver = 124; hordel = 1; verdel = 2; | ||
733 | break; | ||
734 | case SIZE_320X240: | ||
735 | default: | ||
736 | hor = 324; ver = 248; hordel = 2; verdel = 4; | ||
737 | break; | ||
738 | } | ||
739 | |||
740 | if (frame->scanstate == ScanState_Scanning) { | ||
741 | while (RingQueue_GetLength(&uvd->dp) >= | ||
742 | 4 + (hor*verdel + hordel)) { | ||
743 | if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) && | ||
744 | (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) && | ||
745 | (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) && | ||
746 | (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) { | ||
747 | frame->curline = 0; | ||
748 | frame->scanstate = ScanState_Lines; | ||
749 | frame->frameState = FrameState_Grabbing; | ||
750 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4); | ||
751 | /* | ||
752 | * if we're starting, we need to discard the first | ||
753 | * 4 lines of y bayer data | ||
754 | * and the first 2 gr elements of x bayer data | ||
755 | */ | ||
756 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, | ||
757 | (hor*verdel + hordel)); | ||
758 | break; | ||
759 | } | ||
760 | RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1); | ||
761 | } | ||
762 | } | ||
763 | |||
764 | if (frame->scanstate == ScanState_Scanning) | ||
765 | return; | ||
766 | |||
767 | /* now we can start processing bayer data so long as we have at least | ||
768 | * 2 lines worth of data. this is the simplest demosaicing method that | ||
769 | * I could think of. I use each 2x2 bayer element without interpolation | ||
770 | * to generate 4 rgb pixels. | ||
771 | */ | ||
772 | while ( frame->curline < cam->height && | ||
773 | (RingQueue_GetLength(&uvd->dp) >= hor*2)) { | ||
774 | /* get 2 lines of bayer for demosaicing | ||
775 | * into 2 lines of RGB */ | ||
776 | RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2); | ||
777 | bayL0 = (struct bayL0 *) cam->scratch; | ||
778 | bayL1 = (struct bayL1 *) (cam->scratch + hor); | ||
779 | /* frame->curline is the rgb y line */ | ||
780 | rgbL0 = (struct rgb *) | ||
781 | ( frame->data + (cam->width*3*frame->curline)); | ||
782 | /* w/2 because we're already doing 2 pixels */ | ||
783 | rgbL1 = rgbL0 + (cam->width/2); | ||
784 | |||
785 | for (x=0; x < cam->width; x+=2) { | ||
786 | rgbL0->r = bayL0->r; | ||
787 | rgbL0->g = bayL0->g; | ||
788 | rgbL0->b = bayL1->b; | ||
789 | |||
790 | rgbL0->r2 = bayL0->r; | ||
791 | rgbL0->g2 = bayL1->g; | ||
792 | rgbL0->b2 = bayL1->b; | ||
793 | |||
794 | rgbL1->r = bayL0->r; | ||
795 | rgbL1->g = bayL1->g; | ||
796 | rgbL1->b = bayL1->b; | ||
797 | |||
798 | rgbL1->r2 = bayL0->r; | ||
799 | rgbL1->g2 = bayL1->g; | ||
800 | rgbL1->b2 = bayL1->b; | ||
801 | |||
802 | rgbL0++; | ||
803 | rgbL1++; | ||
804 | |||
805 | bayL0++; | ||
806 | bayL1++; | ||
807 | } | ||
808 | |||
809 | frame->seqRead_Length += cam->width*3*2; | ||
810 | frame->curline += 2; | ||
811 | } | ||
812 | /* See if we filled the frame */ | ||
813 | if (frame->curline == cam->height) { | ||
814 | frame->frameState = FrameState_Done_Hold; | ||
815 | frame->curline = 0; | ||
816 | uvd->curframe = -1; | ||
817 | uvd->stats.frame_num++; | ||
818 | } | ||
819 | } | ||
820 | |||
821 | /* taken from konicawc */ | ||
822 | static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw) | ||
823 | { | ||
824 | int ret; | ||
825 | int newsize; | ||
826 | int oldsize; | ||
827 | int x = vw->width; | ||
828 | int y = vw->height; | ||
829 | struct qcm *cam = (struct qcm *) uvd->user_data; | ||
830 | |||
831 | if (x > 0 && y > 0) { | ||
832 | DEBUG(2, "trying to find size %d,%d", x, y); | ||
833 | for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) { | ||
834 | if ((camera_sizes[newsize].width == x) && | ||
835 | (camera_sizes[newsize].height == y)) | ||
836 | break; | ||
837 | } | ||
838 | } else | ||
839 | newsize = cam->size; | ||
840 | |||
841 | if (newsize > MAX_FRAME_SIZE) { | ||
842 | DEBUG(1, "couldn't find size %d,%d", x, y); | ||
843 | return -EINVAL; | ||
844 | } | ||
845 | |||
846 | if (newsize == cam->size) { | ||
847 | DEBUG(1, "Nothing to do"); | ||
848 | return 0; | ||
849 | } | ||
850 | |||
851 | qcm_stop_data(uvd); | ||
852 | |||
853 | if (cam->size != newsize) { | ||
854 | oldsize = cam->size; | ||
855 | cam->size = newsize; | ||
856 | ret = qcm_set_camera_size(uvd); | ||
857 | if (ret) { | ||
858 | err("Couldn't set camera size, err=%d",ret); | ||
859 | /* restore the original size */ | ||
860 | cam->size = oldsize; | ||
861 | return ret; | ||
862 | } | ||
863 | } | ||
864 | |||
865 | /* Flush the input queue and clear any current frame in progress */ | ||
866 | |||
867 | RingQueue_Flush(&uvd->dp); | ||
868 | if (uvd->curframe != -1) { | ||
869 | uvd->frame[uvd->curframe].curline = 0; | ||
870 | uvd->frame[uvd->curframe].seqRead_Length = 0; | ||
871 | uvd->frame[uvd->curframe].seqRead_Index = 0; | ||
872 | } | ||
873 | |||
874 | CHECK_RET(ret, qcm_start_data(uvd)); | ||
875 | return 0; | ||
876 | } | ||
877 | |||
878 | static int qcm_configure_video(struct uvd *uvd) | ||
879 | { | ||
880 | int ret; | ||
881 | memset(&uvd->vpic, 0, sizeof(uvd->vpic)); | ||
882 | memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old)); | ||
883 | |||
884 | uvd->vpic.colour = colour; | ||
885 | uvd->vpic.hue = hue; | ||
886 | uvd->vpic.brightness = brightness; | ||
887 | uvd->vpic.contrast = contrast; | ||
888 | uvd->vpic.whiteness = whiteness; | ||
889 | uvd->vpic.depth = 24; | ||
890 | uvd->vpic.palette = VIDEO_PALETTE_RGB24; | ||
891 | |||
892 | memset(&uvd->vcap, 0, sizeof(uvd->vcap)); | ||
893 | strcpy(uvd->vcap.name, "QCM USB Camera"); | ||
894 | uvd->vcap.type = VID_TYPE_CAPTURE; | ||
895 | uvd->vcap.channels = 1; | ||
896 | uvd->vcap.audios = 0; | ||
897 | |||
898 | uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width; | ||
899 | uvd->vcap.minheight = camera_sizes[SIZE_160X120].height; | ||
900 | uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width; | ||
901 | uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height; | ||
902 | |||
903 | memset(&uvd->vchan, 0, sizeof(uvd->vchan)); | ||
904 | uvd->vchan.flags = 0 ; | ||
905 | uvd->vchan.tuners = 0; | ||
906 | uvd->vchan.channel = 0; | ||
907 | uvd->vchan.type = VIDEO_TYPE_CAMERA; | ||
908 | strcpy(uvd->vchan.name, "Camera"); | ||
909 | |||
910 | CHECK_RET(ret, qcm_sensor_init(uvd)); | ||
911 | return 0; | ||
912 | } | ||
913 | |||
914 | static int qcm_probe(struct usb_interface *intf, | ||
915 | const struct usb_device_id *devid) | ||
916 | { | ||
917 | int err; | ||
918 | struct uvd *uvd; | ||
919 | struct usb_device *dev = interface_to_usbdev(intf); | ||
920 | struct qcm *cam; | ||
921 | size_t buffer_size; | ||
922 | unsigned char video_ep; | ||
923 | struct usb_host_interface *interface; | ||
924 | struct usb_endpoint_descriptor *endpoint; | ||
925 | int i,j; | ||
926 | unsigned int ifacenum, ifacenum_inact=0; | ||
927 | __le16 sensor_id; | ||
928 | |||
929 | /* we don't support multiconfig cams */ | ||
930 | if (dev->descriptor.bNumConfigurations != 1) | ||
931 | return -ENODEV; | ||
932 | |||
933 | /* first check for the video interface and not | ||
934 | * the audio interface */ | ||
935 | interface = &intf->cur_altsetting[0]; | ||
936 | if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) | ||
937 | || (interface->desc.bInterfaceSubClass != | ||
938 | USB_CLASS_VENDOR_SPEC)) | ||
939 | return -ENODEV; | ||
940 | |||
941 | /* | ||
942 | walk through each endpoint in each setting in the interface | ||
943 | stop when we find the one that's an isochronous IN endpoint. | ||
944 | */ | ||
945 | for (i=0; i < intf->num_altsetting; i++) { | ||
946 | interface = &intf->cur_altsetting[i]; | ||
947 | ifacenum = interface->desc.bAlternateSetting; | ||
948 | /* walk the end points */ | ||
949 | for (j=0; j < interface->desc.bNumEndpoints; j++) { | ||
950 | endpoint = &interface->endpoint[j].desc; | ||
951 | |||
952 | if ((endpoint->bEndpointAddress & | ||
953 | USB_ENDPOINT_DIR_MASK) != USB_DIR_IN) | ||
954 | continue; /* not input then not good */ | ||
955 | |||
956 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
957 | if (!buffer_size) { | ||
958 | ifacenum_inact = ifacenum; | ||
959 | continue; /* 0 pkt size is not what we want */ | ||
960 | } | ||
961 | |||
962 | if ((endpoint->bmAttributes & | ||
963 | USB_ENDPOINT_XFERTYPE_MASK) == | ||
964 | USB_ENDPOINT_XFER_ISOC) { | ||
965 | video_ep = endpoint->bEndpointAddress; | ||
966 | /* break out of the search */ | ||
967 | goto good_videoep; | ||
968 | } | ||
969 | } | ||
970 | } | ||
971 | /* failed out since nothing useful was found */ | ||
972 | err("No suitable endpoint was found\n"); | ||
973 | return -ENODEV; | ||
974 | |||
975 | good_videoep: | ||
976 | /* disable isochronous stream before doing anything else */ | ||
977 | err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0); | ||
978 | if (err < 0) { | ||
979 | err("Failed to disable sensor stream"); | ||
980 | return -EIO; | ||
981 | } | ||
982 | |||
983 | /* | ||
984 | Check that this is the same unknown sensor that is known to work. This | ||
985 | sensor is suspected to be the ST VV6422C001. I'll check the same value | ||
986 | that the qc-usb driver checks. This value is probably not even the | ||
987 | sensor ID since it matches the USB dev ID. Oh well. If it doesn't | ||
988 | match, it's probably a diff sensor so exit and apologize. | ||
989 | */ | ||
990 | err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id); | ||
991 | if (err < 0) { | ||
992 | err("Couldn't read sensor values. Err %d\n",err); | ||
993 | return err; | ||
994 | } | ||
995 | if (sensor_id != cpu_to_le16(0x08F0)) { | ||
996 | err("Sensor ID %x != %x. Unsupported. Sorry\n", | ||
997 | le16_to_cpu(sensor_id), (0x08F0)); | ||
998 | return -ENODEV; | ||
999 | } | ||
1000 | |||
1001 | uvd = usbvideo_AllocateDevice(cams); | ||
1002 | if (!uvd) | ||
1003 | return -ENOMEM; | ||
1004 | |||
1005 | cam = (struct qcm *) uvd->user_data; | ||
1006 | |||
1007 | /* buf for doing demosaicing */ | ||
1008 | cam->scratch = kmalloc(324*2, GFP_KERNEL); | ||
1009 | if (!cam->scratch) /* uvd freed in dereg */ | ||
1010 | return -ENOMEM; | ||
1011 | |||
1012 | /* yes, if we fail after here, cam->scratch gets freed | ||
1013 | by qcm_free_uvd */ | ||
1014 | |||
1015 | err = qcm_alloc_int_urb(cam); | ||
1016 | if (err < 0) | ||
1017 | return err; | ||
1018 | |||
1019 | /* yes, if we fail after here, int urb gets freed | ||
1020 | by qcm_free_uvd */ | ||
1021 | |||
1022 | RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240); | ||
1023 | cam->width = camera_sizes[size].width; | ||
1024 | cam->height = camera_sizes[size].height; | ||
1025 | cam->size = size; | ||
1026 | |||
1027 | uvd->debug = debug; | ||
1028 | uvd->flags = 0; | ||
1029 | uvd->dev = dev; | ||
1030 | uvd->iface = intf->altsetting->desc.bInterfaceNumber; | ||
1031 | uvd->ifaceAltActive = ifacenum; | ||
1032 | uvd->ifaceAltInactive = ifacenum_inact; | ||
1033 | uvd->video_endp = video_ep; | ||
1034 | uvd->iso_packet_len = buffer_size; | ||
1035 | uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24; | ||
1036 | uvd->defaultPalette = VIDEO_PALETTE_RGB24; | ||
1037 | uvd->canvas = VIDEOSIZE(320, 240); | ||
1038 | uvd->videosize = VIDEOSIZE(cam->width, cam->height); | ||
1039 | err = qcm_configure_video(uvd); | ||
1040 | if (err) { | ||
1041 | err("failed to configure video settings"); | ||
1042 | return err; | ||
1043 | } | ||
1044 | |||
1045 | err = usbvideo_RegisterVideoDevice(uvd); | ||
1046 | if (err) { /* the uvd gets freed in Deregister */ | ||
1047 | err("usbvideo_RegisterVideoDevice() failed."); | ||
1048 | return err; | ||
1049 | } | ||
1050 | |||
1051 | uvd->max_frame_size = (320 * 240 * 3); | ||
1052 | qcm_register_input(cam, dev); | ||
1053 | usb_set_intfdata(intf, uvd); | ||
1054 | return 0; | ||
1055 | } | ||
1056 | |||
1057 | static void qcm_free_uvd(struct uvd *uvd) | ||
1058 | { | ||
1059 | struct qcm *cam = (struct qcm *) uvd->user_data; | ||
1060 | |||
1061 | kfree(cam->scratch); | ||
1062 | qcm_unregister_input(cam); | ||
1063 | qcm_free_int(cam); | ||
1064 | } | ||
1065 | |||
1066 | static struct usbvideo_cb qcm_driver = { | ||
1067 | .probe = qcm_probe, | ||
1068 | .setupOnOpen = qcm_setup_on_open, | ||
1069 | .processData = qcm_process_isoc, | ||
1070 | .setVideoMode = qcm_set_video_mode, | ||
1071 | .startDataPump = qcm_start_data, | ||
1072 | .stopDataPump = qcm_stop_data, | ||
1073 | .adjustPicture = qcm_adjust_picture, | ||
1074 | .userFree = qcm_free_uvd | ||
1075 | }; | ||
1076 | |||
1077 | static int __init qcm_init(void) | ||
1078 | { | ||
1079 | info(DRIVER_DESC " " DRIVER_VERSION); | ||
1080 | |||
1081 | return usbvideo_register( | ||
1082 | &cams, | ||
1083 | MAX_CAMERAS, | ||
1084 | sizeof(struct qcm), | ||
1085 | "QCM", | ||
1086 | &qcm_driver, | ||
1087 | THIS_MODULE, | ||
1088 | qcm_table); | ||
1089 | } | ||
1090 | |||
1091 | static void __exit qcm_exit(void) | ||
1092 | { | ||
1093 | usbvideo_Deregister(&cams); | ||
1094 | } | ||
1095 | |||
1096 | module_param(size, int, 0); | ||
1097 | MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240"); | ||
1098 | module_param(colour, int, 0); | ||
1099 | MODULE_PARM_DESC(colour, "Initial colour"); | ||
1100 | module_param(hue, int, 0); | ||
1101 | MODULE_PARM_DESC(hue, "Initial hue"); | ||
1102 | module_param(brightness, int, 0); | ||
1103 | MODULE_PARM_DESC(brightness, "Initial brightness"); | ||
1104 | module_param(contrast, int, 0); | ||
1105 | MODULE_PARM_DESC(contrast, "Initial contrast"); | ||
1106 | module_param(whiteness, int, 0); | ||
1107 | MODULE_PARM_DESC(whiteness, "Initial whiteness"); | ||
1108 | |||
1109 | #ifdef CONFIG_USB_DEBUG | ||
1110 | module_param(debug, int, S_IRUGO | S_IWUSR); | ||
1111 | MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); | ||
1112 | #endif | ||
1113 | |||
1114 | module_init(qcm_init); | ||
1115 | module_exit(qcm_exit); | ||
1116 | |||
1117 | MODULE_LICENSE("GPL"); | ||
1118 | MODULE_AUTHOR("Jaya Kumar"); | ||
1119 | MODULE_DESCRIPTION("QCM USB Camera"); | ||
1120 | MODULE_SUPPORTED_DEVICE("QCM USB Camera"); | ||
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.h b/drivers/media/video/usbvideo/quickcam_messenger.h new file mode 100644 index 000000000000..baab9c081b52 --- /dev/null +++ b/drivers/media/video/usbvideo/quickcam_messenger.h | |||
@@ -0,0 +1,126 @@ | |||
1 | #ifndef quickcam_messenger_h | ||
2 | #define quickcam_messenger_h | ||
3 | |||
4 | #ifndef CONFIG_INPUT | ||
5 | /* if we're not using input we dummy out these functions */ | ||
6 | #define qcm_register_input(...) | ||
7 | #define qcm_unregister_input(...) | ||
8 | #define qcm_report_buttonstat(...) | ||
9 | #define qcm_setup_input_int(...) 0 | ||
10 | #define qcm_stop_int_data(...) | ||
11 | #define qcm_alloc_int_urb(...) 0 | ||
12 | #define qcm_free_int(...) | ||
13 | #endif | ||
14 | |||
15 | |||
16 | #define CHECK_RET(ret, expr) \ | ||
17 | if ((ret = expr) < 0) return ret | ||
18 | |||
19 | /* Control Registers for the STVV6422 ASIC | ||
20 | * - this define is taken from the qc-usb-messenger code | ||
21 | */ | ||
22 | #define STV_ISO_ENABLE 0x1440 | ||
23 | #define ISOC_PACKET_SIZE 1023 | ||
24 | |||
25 | /* Chip identification number including revision indicator */ | ||
26 | #define CMOS_SENSOR_IDREV 0xE00A | ||
27 | |||
28 | struct rgb { | ||
29 | u8 b; | ||
30 | u8 g; | ||
31 | u8 r; | ||
32 | u8 b2; | ||
33 | u8 g2; | ||
34 | u8 r2; | ||
35 | }; | ||
36 | |||
37 | struct bayL0 { | ||
38 | #ifdef __BIG_ENDIAN | ||
39 | u8 r; | ||
40 | u8 g; | ||
41 | #elif __LITTLE_ENDIAN | ||
42 | u8 g; | ||
43 | u8 r; | ||
44 | #else | ||
45 | #error not byte order defined | ||
46 | #endif | ||
47 | }; | ||
48 | |||
49 | struct bayL1 { | ||
50 | #ifdef __BIG_ENDIAN | ||
51 | u8 g; | ||
52 | u8 b; | ||
53 | #elif __LITTLE_ENDIAN | ||
54 | u8 b; | ||
55 | u8 g; | ||
56 | #else | ||
57 | #error not byte order defined | ||
58 | #endif | ||
59 | }; | ||
60 | |||
61 | struct cam_size { | ||
62 | u16 width; | ||
63 | u16 height; | ||
64 | u8 cmd; | ||
65 | }; | ||
66 | |||
67 | static const struct cam_size camera_sizes[] = { | ||
68 | { 160, 120, 0xf }, | ||
69 | { 320, 240, 0x2 }, | ||
70 | }; | ||
71 | |||
72 | enum frame_sizes { | ||
73 | SIZE_160X120 = 0, | ||
74 | SIZE_320X240 = 1, | ||
75 | }; | ||
76 | |||
77 | #define MAX_FRAME_SIZE SIZE_320X240 | ||
78 | |||
79 | struct qcm { | ||
80 | u16 colour; | ||
81 | u16 hue; | ||
82 | u16 brightness; | ||
83 | u16 contrast; | ||
84 | u16 whiteness; | ||
85 | |||
86 | u8 size; | ||
87 | int height; | ||
88 | int width; | ||
89 | u8 *scratch; | ||
90 | struct urb *button_urb; | ||
91 | u8 button_sts; | ||
92 | u8 button_sts_buf; | ||
93 | |||
94 | #ifdef CONFIG_INPUT | ||
95 | struct input_dev *input; | ||
96 | char input_physname[64]; | ||
97 | #endif | ||
98 | }; | ||
99 | |||
100 | struct regval { | ||
101 | u16 reg; | ||
102 | u8 val; | ||
103 | }; | ||
104 | /* this table is derived from the | ||
105 | qc-usb-messenger code */ | ||
106 | static const struct regval regval_table[] = { | ||
107 | { STV_ISO_ENABLE, 0x00 }, | ||
108 | { 0x1436, 0x00 }, { 0x1432, 0x03 }, | ||
109 | { 0x143a, 0xF9 }, { 0x0509, 0x38 }, | ||
110 | { 0x050a, 0x38 }, { 0x050b, 0x38 }, | ||
111 | { 0x050c, 0x2A }, { 0x050d, 0x01 }, | ||
112 | { 0x1431, 0x00 }, { 0x1433, 0x34 }, | ||
113 | { 0x1438, 0x18 }, { 0x1439, 0x00 }, | ||
114 | { 0x143b, 0x05 }, { 0x143c, 0x00 }, | ||
115 | { 0x143e, 0x01 }, { 0x143d, 0x00 }, | ||
116 | { 0x1442, 0xe2 }, { 0x1500, 0xd0 }, | ||
117 | { 0x1500, 0xd0 }, { 0x1500, 0x50 }, | ||
118 | { 0x1501, 0xaf }, { 0x1502, 0xc2 }, | ||
119 | { 0x1503, 0x45 }, { 0x1505, 0x02 }, | ||
120 | { 0x150e, 0x8e }, { 0x150f, 0x37 }, | ||
121 | { 0x15c0, 0x00 }, | ||
122 | }; | ||
123 | |||
124 | static const unsigned char marker[] = { 0x00, 0xff, 0x00, 0xFF }; | ||
125 | |||
126 | #endif /* quickcam_messenger_h */ | ||
diff --git a/drivers/media/video/usbvideo/usbvideo.h b/drivers/media/video/usbvideo/usbvideo.h index 3cbf4fc499a3..49dbee5f5628 100644 --- a/drivers/media/video/usbvideo/usbvideo.h +++ b/drivers/media/video/usbvideo/usbvideo.h | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/config.h> | 19 | #include <linux/config.h> |
20 | #include <linux/videodev.h> | 20 | #include <linux/videodev.h> |
21 | #include <media/v4l2-common.h> | ||
21 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
22 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
23 | 24 | ||
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index 474a29bc1760..19d3c20dc7ef 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/errno.h> | 32 | #include <linux/errno.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/videodev.h> | 34 | #include <linux/videodev.h> |
35 | #include <media/v4l2-common.h> | ||
35 | 36 | ||
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
37 | #include <asm/system.h> | 38 | #include <asm/system.h> |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index d330fa985bcc..14e523471354 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <asm/io.h> | 59 | #include <asm/io.h> |
60 | #include <asm/div64.h> | 60 | #include <asm/div64.h> |
61 | #include <linux/video_decoder.h> | 61 | #include <linux/video_decoder.h> |
62 | #define __OLD_VIDIOC_ /* To allow fixing old calls*/ | ||
62 | #include <media/v4l2-common.h> | 63 | #include <media/v4l2-common.h> |
63 | 64 | ||
64 | #ifdef CONFIG_KMOD | 65 | #ifdef CONFIG_KMOD |
@@ -293,7 +294,10 @@ static const char *v4l2_ioctls[] = { | |||
293 | #if 1 | 294 | #if 1 |
294 | [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", | 295 | [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", |
295 | #endif | 296 | #endif |
296 | [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS" | 297 | [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", |
298 | [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", | ||
299 | [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", | ||
300 | [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS" | ||
297 | }; | 301 | }; |
298 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | 302 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) |
299 | 303 | ||
@@ -331,7 +335,8 @@ static const char *v4l2_int_ioctls[] = { | |||
331 | [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", | 335 | [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", |
332 | [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", | 336 | [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", |
333 | [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", | 337 | [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", |
334 | [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING" | 338 | [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", |
339 | [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ" | ||
335 | }; | 340 | }; |
336 | #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) | 341 | #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) |
337 | 342 | ||
@@ -423,7 +428,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
423 | case TUNER_SET_TYPE_ADDR: | 428 | case TUNER_SET_TYPE_ADDR: |
424 | case TUNER_SET_STANDBY: | 429 | case TUNER_SET_STANDBY: |
425 | case TDA9887_SET_CONFIG: | 430 | case TDA9887_SET_CONFIG: |
431 | #ifdef __OLD_VIDIOC_ | ||
426 | case VIDIOC_OVERLAY_OLD: | 432 | case VIDIOC_OVERLAY_OLD: |
433 | #endif | ||
427 | case VIDIOC_STREAMOFF: | 434 | case VIDIOC_STREAMOFF: |
428 | case VIDIOC_G_OUTPUT: | 435 | case VIDIOC_G_OUTPUT: |
429 | case VIDIOC_S_OUTPUT: | 436 | case VIDIOC_S_OUTPUT: |
@@ -439,7 +446,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
439 | case VIDIOC_G_AUDIO: | 446 | case VIDIOC_G_AUDIO: |
440 | case VIDIOC_S_AUDIO: | 447 | case VIDIOC_S_AUDIO: |
441 | case VIDIOC_ENUMAUDIO: | 448 | case VIDIOC_ENUMAUDIO: |
449 | #ifdef __OLD_VIDIOC_ | ||
442 | case VIDIOC_G_AUDIO_OLD: | 450 | case VIDIOC_G_AUDIO_OLD: |
451 | #endif | ||
443 | { | 452 | { |
444 | struct v4l2_audio *p=arg; | 453 | struct v4l2_audio *p=arg; |
445 | 454 | ||
@@ -450,7 +459,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
450 | case VIDIOC_G_AUDOUT: | 459 | case VIDIOC_G_AUDOUT: |
451 | case VIDIOC_S_AUDOUT: | 460 | case VIDIOC_S_AUDOUT: |
452 | case VIDIOC_ENUMAUDOUT: | 461 | case VIDIOC_ENUMAUDOUT: |
462 | #ifdef __OLD_VIDIOC_ | ||
453 | case VIDIOC_G_AUDOUT_OLD: | 463 | case VIDIOC_G_AUDOUT_OLD: |
464 | #endif | ||
454 | { | 465 | { |
455 | struct v4l2_audioout *p=arg; | 466 | struct v4l2_audioout *p=arg; |
456 | printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", s, | 467 | printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", s, |
@@ -478,9 +489,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
478 | prt_names(p->memory,v4l2_memory_names), | 489 | prt_names(p->memory,v4l2_memory_names), |
479 | p->m.userptr); | 490 | p->m.userptr); |
480 | printk ("%s: timecode= %02d:%02d:%02d type=%d, " | 491 | printk ("%s: timecode= %02d:%02d:%02d type=%d, " |
481 | "flags=0x%08x, frames=%d, userbits=0x%p\n", | 492 | "flags=0x%08x, frames=%d, userbits=0x%08x\n", |
482 | s,tc->hours,tc->minutes,tc->seconds, | 493 | s,tc->hours,tc->minutes,tc->seconds, |
483 | tc->type, tc->flags, tc->frames, tc->userbits); | 494 | tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits); |
484 | break; | 495 | break; |
485 | } | 496 | } |
486 | case VIDIOC_QUERYCAP: | 497 | case VIDIOC_QUERYCAP: |
@@ -495,12 +506,31 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
495 | } | 506 | } |
496 | case VIDIOC_G_CTRL: | 507 | case VIDIOC_G_CTRL: |
497 | case VIDIOC_S_CTRL: | 508 | case VIDIOC_S_CTRL: |
509 | #ifdef __OLD_VIDIOC_ | ||
498 | case VIDIOC_S_CTRL_OLD: | 510 | case VIDIOC_S_CTRL_OLD: |
511 | #endif | ||
499 | { | 512 | { |
500 | struct v4l2_control *p=arg; | 513 | struct v4l2_control *p=arg; |
501 | printk ("%s: id=%d, value=%d\n", s, p->id, p->value); | 514 | printk ("%s: id=%d, value=%d\n", s, p->id, p->value); |
502 | break; | 515 | break; |
503 | } | 516 | } |
517 | case VIDIOC_G_EXT_CTRLS: | ||
518 | case VIDIOC_S_EXT_CTRLS: | ||
519 | case VIDIOC_TRY_EXT_CTRLS: | ||
520 | { | ||
521 | struct v4l2_ext_controls *p = arg; | ||
522 | int i; | ||
523 | |||
524 | printk("%s: ctrl_class=%d, count=%d\n", s, p->ctrl_class, p->count); | ||
525 | for (i = 0; i < p->count; i++) { | ||
526 | struct v4l2_ext_control *c = &p->controls[i]; | ||
527 | if (cmd == VIDIOC_G_EXT_CTRLS) | ||
528 | printk("%s: id=%d\n", s, c->id); | ||
529 | else | ||
530 | printk("%s: id=%d, value=%d\n", s, c->id, c->value); | ||
531 | } | ||
532 | break; | ||
533 | } | ||
504 | case VIDIOC_G_CROP: | 534 | case VIDIOC_G_CROP: |
505 | case VIDIOC_S_CROP: | 535 | case VIDIOC_S_CROP: |
506 | { | 536 | { |
@@ -510,7 +540,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
510 | break; | 540 | break; |
511 | } | 541 | } |
512 | case VIDIOC_CROPCAP: | 542 | case VIDIOC_CROPCAP: |
543 | #ifdef __OLD_VIDIOC_ | ||
513 | case VIDIOC_CROPCAP_OLD: | 544 | case VIDIOC_CROPCAP_OLD: |
545 | #endif | ||
514 | { | 546 | { |
515 | struct v4l2_cropcap *p=arg; | 547 | struct v4l2_cropcap *p=arg; |
516 | /*FIXME: Should also show rect structs */ | 548 | /*FIXME: Should also show rect structs */ |
@@ -667,6 +699,12 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
667 | printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output); | 699 | printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output); |
668 | break; | 700 | break; |
669 | } | 701 | } |
702 | case VIDIOC_INT_S_CRYSTAL_FREQ: | ||
703 | { | ||
704 | struct v4l2_crystal_freq *p=arg; | ||
705 | printk ("%s: freq=%u, flags=0x%x\n", s, p->freq, p->flags); | ||
706 | break; | ||
707 | } | ||
670 | case VIDIOC_G_SLICED_VBI_CAP: | 708 | case VIDIOC_G_SLICED_VBI_CAP: |
671 | { | 709 | { |
672 | struct v4l2_sliced_vbi_cap *p=arg; | 710 | struct v4l2_sliced_vbi_cap *p=arg; |
@@ -696,7 +734,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
696 | } | 734 | } |
697 | case VIDIOC_G_PARM: | 735 | case VIDIOC_G_PARM: |
698 | case VIDIOC_S_PARM: | 736 | case VIDIOC_S_PARM: |
737 | #ifdef __OLD_VIDIOC_ | ||
699 | case VIDIOC_S_PARM_OLD: | 738 | case VIDIOC_S_PARM_OLD: |
739 | #endif | ||
700 | { | 740 | { |
701 | struct v4l2_streamparm *p=arg; | 741 | struct v4l2_streamparm *p=arg; |
702 | printk ("%s: type=%d\n", s, p->type); | 742 | printk ("%s: type=%d\n", s, p->type); |
@@ -915,6 +955,484 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
915 | 955 | ||
916 | /* ----------------------------------------------------------------- */ | 956 | /* ----------------------------------------------------------------- */ |
917 | 957 | ||
958 | /* Helper functions for control handling */ | ||
959 | |||
960 | /* Check for correctness of the ctrl's value based on the data from | ||
961 | struct v4l2_queryctrl and the available menu items. Note that | ||
962 | menu_items may be NULL, in that case it is ignored. */ | ||
963 | int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, | ||
964 | const char **menu_items) | ||
965 | { | ||
966 | if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED) | ||
967 | return -EINVAL; | ||
968 | if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED) | ||
969 | return -EBUSY; | ||
970 | if (qctrl->type == V4L2_CTRL_TYPE_BUTTON || | ||
971 | qctrl->type == V4L2_CTRL_TYPE_INTEGER64 || | ||
972 | qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) | ||
973 | return 0; | ||
974 | if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum) | ||
975 | return -ERANGE; | ||
976 | if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) { | ||
977 | if (menu_items[ctrl->value] == NULL || | ||
978 | menu_items[ctrl->value][0] == '\0') | ||
979 | return -EINVAL; | ||
980 | } | ||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | /* Returns NULL or a character pointer array containing the menu for | ||
985 | the given control ID. The pointer array ends with a NULL pointer. | ||
986 | An empty string signifies a menu entry that is invalid. This allows | ||
987 | drivers to disable certain options if it is not supported. */ | ||
988 | const char **v4l2_ctrl_get_menu(u32 id) | ||
989 | { | ||
990 | static const char *mpeg_audio_sampling_freq[] = { | ||
991 | "44.1 kHz", | ||
992 | "48 kHz", | ||
993 | "32 kHz", | ||
994 | NULL | ||
995 | }; | ||
996 | static const char *mpeg_audio_encoding[] = { | ||
997 | "Layer I", | ||
998 | "Layer II", | ||
999 | "Layer III", | ||
1000 | NULL | ||
1001 | }; | ||
1002 | static const char *mpeg_audio_l1_bitrate[] = { | ||
1003 | "32 kbps", | ||
1004 | "64 kbps", | ||
1005 | "96 kbps", | ||
1006 | "128 kbps", | ||
1007 | "160 kbps", | ||
1008 | "192 kbps", | ||
1009 | "224 kbps", | ||
1010 | "256 kbps", | ||
1011 | "288 kbps", | ||
1012 | "320 kbps", | ||
1013 | "352 kbps", | ||
1014 | "384 kbps", | ||
1015 | "416 kbps", | ||
1016 | "448 kbps", | ||
1017 | NULL | ||
1018 | }; | ||
1019 | static const char *mpeg_audio_l2_bitrate[] = { | ||
1020 | "32 kbps", | ||
1021 | "48 kbps", | ||
1022 | "56 kbps", | ||
1023 | "64 kbps", | ||
1024 | "80 kbps", | ||
1025 | "96 kbps", | ||
1026 | "112 kbps", | ||
1027 | "128 kbps", | ||
1028 | "160 kbps", | ||
1029 | "192 kbps", | ||
1030 | "224 kbps", | ||
1031 | "256 kbps", | ||
1032 | "320 kbps", | ||
1033 | "384 kbps", | ||
1034 | NULL | ||
1035 | }; | ||
1036 | static const char *mpeg_audio_l3_bitrate[] = { | ||
1037 | "32 kbps", | ||
1038 | "40 kbps", | ||
1039 | "48 kbps", | ||
1040 | "56 kbps", | ||
1041 | "64 kbps", | ||
1042 | "80 kbps", | ||
1043 | "96 kbps", | ||
1044 | "112 kbps", | ||
1045 | "128 kbps", | ||
1046 | "160 kbps", | ||
1047 | "192 kbps", | ||
1048 | "224 kbps", | ||
1049 | "256 kbps", | ||
1050 | "320 kbps", | ||
1051 | NULL | ||
1052 | }; | ||
1053 | static const char *mpeg_audio_mode[] = { | ||
1054 | "Stereo", | ||
1055 | "Joint Stereo", | ||
1056 | "Dual", | ||
1057 | "Mono", | ||
1058 | NULL | ||
1059 | }; | ||
1060 | static const char *mpeg_audio_mode_extension[] = { | ||
1061 | "Bound 4", | ||
1062 | "Bound 8", | ||
1063 | "Bound 12", | ||
1064 | "Bound 16", | ||
1065 | NULL | ||
1066 | }; | ||
1067 | static const char *mpeg_audio_emphasis[] = { | ||
1068 | "No Emphasis", | ||
1069 | "50/15 us", | ||
1070 | "CCITT J17", | ||
1071 | NULL | ||
1072 | }; | ||
1073 | static const char *mpeg_audio_crc[] = { | ||
1074 | "No CRC", | ||
1075 | "16-bit CRC", | ||
1076 | NULL | ||
1077 | }; | ||
1078 | static const char *mpeg_video_encoding[] = { | ||
1079 | "MPEG-1", | ||
1080 | "MPEG-2", | ||
1081 | NULL | ||
1082 | }; | ||
1083 | static const char *mpeg_video_aspect[] = { | ||
1084 | "1x1", | ||
1085 | "4x3", | ||
1086 | "16x9", | ||
1087 | "2.21x1", | ||
1088 | NULL | ||
1089 | }; | ||
1090 | static const char *mpeg_video_bitrate_mode[] = { | ||
1091 | "Variable Bitrate", | ||
1092 | "Constant Bitrate", | ||
1093 | NULL | ||
1094 | }; | ||
1095 | static const char *mpeg_stream_type[] = { | ||
1096 | "MPEG-2 Program Stream", | ||
1097 | "MPEG-2 Transport Stream", | ||
1098 | "MPEG-1 System Stream", | ||
1099 | "MPEG-2 DVD-compatible Stream", | ||
1100 | "MPEG-1 VCD-compatible Stream", | ||
1101 | "MPEG-2 SVCD-compatible Stream", | ||
1102 | NULL | ||
1103 | }; | ||
1104 | |||
1105 | switch (id) { | ||
1106 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | ||
1107 | return mpeg_audio_sampling_freq; | ||
1108 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
1109 | return mpeg_audio_encoding; | ||
1110 | case V4L2_CID_MPEG_AUDIO_L1_BITRATE: | ||
1111 | return mpeg_audio_l1_bitrate; | ||
1112 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: | ||
1113 | return mpeg_audio_l2_bitrate; | ||
1114 | case V4L2_CID_MPEG_AUDIO_L3_BITRATE: | ||
1115 | return mpeg_audio_l3_bitrate; | ||
1116 | case V4L2_CID_MPEG_AUDIO_MODE: | ||
1117 | return mpeg_audio_mode; | ||
1118 | case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: | ||
1119 | return mpeg_audio_mode_extension; | ||
1120 | case V4L2_CID_MPEG_AUDIO_EMPHASIS: | ||
1121 | return mpeg_audio_emphasis; | ||
1122 | case V4L2_CID_MPEG_AUDIO_CRC: | ||
1123 | return mpeg_audio_crc; | ||
1124 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
1125 | return mpeg_video_encoding; | ||
1126 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
1127 | return mpeg_video_aspect; | ||
1128 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
1129 | return mpeg_video_bitrate_mode; | ||
1130 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
1131 | return mpeg_stream_type; | ||
1132 | default: | ||
1133 | return NULL; | ||
1134 | } | ||
1135 | } | ||
1136 | |||
1137 | /* Fill in a struct v4l2_queryctrl */ | ||
1138 | int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def) | ||
1139 | { | ||
1140 | const char *name; | ||
1141 | |||
1142 | qctrl->flags = 0; | ||
1143 | switch (qctrl->id) { | ||
1144 | /* USER controls */ | ||
1145 | case V4L2_CID_USER_CLASS: name = "User Controls"; break; | ||
1146 | case V4L2_CID_AUDIO_VOLUME: name = "Volume"; break; | ||
1147 | case V4L2_CID_AUDIO_MUTE: name = "Mute"; break; | ||
1148 | case V4L2_CID_AUDIO_BALANCE: name = "Balance"; break; | ||
1149 | case V4L2_CID_AUDIO_BASS: name = "Bass"; break; | ||
1150 | case V4L2_CID_AUDIO_TREBLE: name = "Treble"; break; | ||
1151 | case V4L2_CID_AUDIO_LOUDNESS: name = "Loudness"; break; | ||
1152 | case V4L2_CID_BRIGHTNESS: name = "Brightness"; break; | ||
1153 | case V4L2_CID_CONTRAST: name = "Contrast"; break; | ||
1154 | case V4L2_CID_SATURATION: name = "Saturation"; break; | ||
1155 | case V4L2_CID_HUE: name = "Hue"; break; | ||
1156 | |||
1157 | /* MPEG controls */ | ||
1158 | case V4L2_CID_MPEG_CLASS: name = "MPEG Encoder Controls"; break; | ||
1159 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: name = "Audio Sampling Frequency"; break; | ||
1160 | case V4L2_CID_MPEG_AUDIO_ENCODING: name = "Audio Encoding Layer"; break; | ||
1161 | case V4L2_CID_MPEG_AUDIO_L1_BITRATE: name = "Audio Layer I Bitrate"; break; | ||
1162 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: name = "Audio Layer II Bitrate"; break; | ||
1163 | case V4L2_CID_MPEG_AUDIO_L3_BITRATE: name = "Audio Layer III Bitrate"; break; | ||
1164 | case V4L2_CID_MPEG_AUDIO_MODE: name = "Audio Stereo Mode"; break; | ||
1165 | case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: name = "Audio Stereo Mode Extension"; break; | ||
1166 | case V4L2_CID_MPEG_AUDIO_EMPHASIS: name = "Audio Emphasis"; break; | ||
1167 | case V4L2_CID_MPEG_AUDIO_CRC: name = "Audio CRC"; break; | ||
1168 | case V4L2_CID_MPEG_VIDEO_ENCODING: name = "Video Encoding"; break; | ||
1169 | case V4L2_CID_MPEG_VIDEO_ASPECT: name = "Video Aspect"; break; | ||
1170 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: name = "Video B Frames"; break; | ||
1171 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: name = "Video GOP Size"; break; | ||
1172 | case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: name = "Video GOP Closure"; break; | ||
1173 | case V4L2_CID_MPEG_VIDEO_PULLDOWN: name = "Video Pulldown"; break; | ||
1174 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: name = "Video Bitrate Mode"; break; | ||
1175 | case V4L2_CID_MPEG_VIDEO_BITRATE: name = "Video Bitrate"; break; | ||
1176 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: name = "Video Peak Bitrate"; break; | ||
1177 | case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: name = "Video Temporal Decimation"; break; | ||
1178 | case V4L2_CID_MPEG_STREAM_TYPE: name = "Stream Type"; break; | ||
1179 | case V4L2_CID_MPEG_STREAM_PID_PMT: name = "Stream PMT Program ID"; break; | ||
1180 | case V4L2_CID_MPEG_STREAM_PID_AUDIO: name = "Stream Audio Program ID"; break; | ||
1181 | case V4L2_CID_MPEG_STREAM_PID_VIDEO: name = "Stream Video Program ID"; break; | ||
1182 | case V4L2_CID_MPEG_STREAM_PID_PCR: name = "Stream PCR Program ID"; break; | ||
1183 | case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: name = "Stream PES Audio ID"; break; | ||
1184 | case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: name = "Stream PES Video ID"; break; | ||
1185 | |||
1186 | default: | ||
1187 | return -EINVAL; | ||
1188 | } | ||
1189 | switch (qctrl->id) { | ||
1190 | case V4L2_CID_AUDIO_MUTE: | ||
1191 | case V4L2_CID_AUDIO_LOUDNESS: | ||
1192 | case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: | ||
1193 | case V4L2_CID_MPEG_VIDEO_PULLDOWN: | ||
1194 | qctrl->type = V4L2_CTRL_TYPE_BOOLEAN; | ||
1195 | min = 0; | ||
1196 | max = step = 1; | ||
1197 | break; | ||
1198 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | ||
1199 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
1200 | case V4L2_CID_MPEG_AUDIO_L1_BITRATE: | ||
1201 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: | ||
1202 | case V4L2_CID_MPEG_AUDIO_L3_BITRATE: | ||
1203 | case V4L2_CID_MPEG_AUDIO_MODE: | ||
1204 | case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: | ||
1205 | case V4L2_CID_MPEG_AUDIO_EMPHASIS: | ||
1206 | case V4L2_CID_MPEG_AUDIO_CRC: | ||
1207 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
1208 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
1209 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
1210 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
1211 | qctrl->type = V4L2_CTRL_TYPE_MENU; | ||
1212 | step = 1; | ||
1213 | break; | ||
1214 | case V4L2_CID_USER_CLASS: | ||
1215 | case V4L2_CID_MPEG_CLASS: | ||
1216 | qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS; | ||
1217 | qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; | ||
1218 | min = max = step = def = 0; | ||
1219 | break; | ||
1220 | default: | ||
1221 | qctrl->type = V4L2_CTRL_TYPE_INTEGER; | ||
1222 | break; | ||
1223 | } | ||
1224 | switch (qctrl->id) { | ||
1225 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
1226 | case V4L2_CID_MPEG_AUDIO_MODE: | ||
1227 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
1228 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
1229 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
1230 | qctrl->flags |= V4L2_CTRL_FLAG_UPDATE; | ||
1231 | break; | ||
1232 | case V4L2_CID_AUDIO_VOLUME: | ||
1233 | case V4L2_CID_AUDIO_BALANCE: | ||
1234 | case V4L2_CID_AUDIO_BASS: | ||
1235 | case V4L2_CID_AUDIO_TREBLE: | ||
1236 | case V4L2_CID_BRIGHTNESS: | ||
1237 | case V4L2_CID_CONTRAST: | ||
1238 | case V4L2_CID_SATURATION: | ||
1239 | case V4L2_CID_HUE: | ||
1240 | qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; | ||
1241 | break; | ||
1242 | } | ||
1243 | qctrl->minimum = min; | ||
1244 | qctrl->maximum = max; | ||
1245 | qctrl->step = step; | ||
1246 | qctrl->default_value = def; | ||
1247 | qctrl->reserved[0] = qctrl->reserved[1] = 0; | ||
1248 | snprintf(qctrl->name, sizeof(qctrl->name), name); | ||
1249 | return 0; | ||
1250 | } | ||
1251 | |||
1252 | /* Fill in a struct v4l2_queryctrl with standard values based on | ||
1253 | the control ID. */ | ||
1254 | int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) | ||
1255 | { | ||
1256 | switch (qctrl->id) { | ||
1257 | /* USER controls */ | ||
1258 | case V4L2_CID_USER_CLASS: | ||
1259 | case V4L2_CID_MPEG_CLASS: | ||
1260 | return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0); | ||
1261 | case V4L2_CID_AUDIO_VOLUME: | ||
1262 | return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 58880); | ||
1263 | case V4L2_CID_AUDIO_MUTE: | ||
1264 | case V4L2_CID_AUDIO_LOUDNESS: | ||
1265 | return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); | ||
1266 | case V4L2_CID_AUDIO_BALANCE: | ||
1267 | case V4L2_CID_AUDIO_BASS: | ||
1268 | case V4L2_CID_AUDIO_TREBLE: | ||
1269 | return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 32768); | ||
1270 | case V4L2_CID_BRIGHTNESS: | ||
1271 | return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128); | ||
1272 | case V4L2_CID_CONTRAST: | ||
1273 | case V4L2_CID_SATURATION: | ||
1274 | return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64); | ||
1275 | case V4L2_CID_HUE: | ||
1276 | return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0); | ||
1277 | |||
1278 | /* MPEG controls */ | ||
1279 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | ||
1280 | return v4l2_ctrl_query_fill(qctrl, | ||
1281 | V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100, | ||
1282 | V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1, | ||
1283 | V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000); | ||
1284 | case V4L2_CID_MPEG_AUDIO_ENCODING: | ||
1285 | return v4l2_ctrl_query_fill(qctrl, | ||
1286 | V4L2_MPEG_AUDIO_ENCODING_LAYER_1, | ||
1287 | V4L2_MPEG_AUDIO_ENCODING_LAYER_3, 1, | ||
1288 | V4L2_MPEG_AUDIO_ENCODING_LAYER_2); | ||
1289 | case V4L2_CID_MPEG_AUDIO_L1_BITRATE: | ||
1290 | return v4l2_ctrl_query_fill(qctrl, | ||
1291 | V4L2_MPEG_AUDIO_L1_BITRATE_32K, | ||
1292 | V4L2_MPEG_AUDIO_L1_BITRATE_448K, 1, | ||
1293 | V4L2_MPEG_AUDIO_L1_BITRATE_256K); | ||
1294 | case V4L2_CID_MPEG_AUDIO_L2_BITRATE: | ||
1295 | return v4l2_ctrl_query_fill(qctrl, | ||
1296 | V4L2_MPEG_AUDIO_L2_BITRATE_32K, | ||
1297 | V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, | ||
1298 | V4L2_MPEG_AUDIO_L2_BITRATE_224K); | ||
1299 | case V4L2_CID_MPEG_AUDIO_L3_BITRATE: | ||
1300 | return v4l2_ctrl_query_fill(qctrl, | ||
1301 | V4L2_MPEG_AUDIO_L3_BITRATE_32K, | ||
1302 | V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1, | ||
1303 | V4L2_MPEG_AUDIO_L3_BITRATE_192K); | ||
1304 | case V4L2_CID_MPEG_AUDIO_MODE: | ||
1305 | return v4l2_ctrl_query_fill(qctrl, | ||
1306 | V4L2_MPEG_AUDIO_MODE_STEREO, | ||
1307 | V4L2_MPEG_AUDIO_MODE_MONO, 1, | ||
1308 | V4L2_MPEG_AUDIO_MODE_STEREO); | ||
1309 | case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: | ||
1310 | return v4l2_ctrl_query_fill(qctrl, | ||
1311 | V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, | ||
1312 | V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1, | ||
1313 | V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4); | ||
1314 | case V4L2_CID_MPEG_AUDIO_EMPHASIS: | ||
1315 | return v4l2_ctrl_query_fill(qctrl, | ||
1316 | V4L2_MPEG_AUDIO_EMPHASIS_NONE, | ||
1317 | V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1, | ||
1318 | V4L2_MPEG_AUDIO_EMPHASIS_NONE); | ||
1319 | case V4L2_CID_MPEG_AUDIO_CRC: | ||
1320 | return v4l2_ctrl_query_fill(qctrl, | ||
1321 | V4L2_MPEG_AUDIO_CRC_NONE, | ||
1322 | V4L2_MPEG_AUDIO_CRC_CRC16, 1, | ||
1323 | V4L2_MPEG_AUDIO_CRC_NONE); | ||
1324 | case V4L2_CID_MPEG_VIDEO_ENCODING: | ||
1325 | return v4l2_ctrl_query_fill(qctrl, | ||
1326 | V4L2_MPEG_VIDEO_ENCODING_MPEG_1, | ||
1327 | V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1, | ||
1328 | V4L2_MPEG_VIDEO_ENCODING_MPEG_2); | ||
1329 | case V4L2_CID_MPEG_VIDEO_ASPECT: | ||
1330 | return v4l2_ctrl_query_fill(qctrl, | ||
1331 | V4L2_MPEG_VIDEO_ASPECT_1x1, | ||
1332 | V4L2_MPEG_VIDEO_ASPECT_221x100, 1, | ||
1333 | V4L2_MPEG_VIDEO_ASPECT_4x3); | ||
1334 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | ||
1335 | return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2); | ||
1336 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | ||
1337 | return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, 12); | ||
1338 | case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: | ||
1339 | return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1); | ||
1340 | case V4L2_CID_MPEG_VIDEO_PULLDOWN: | ||
1341 | return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); | ||
1342 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | ||
1343 | return v4l2_ctrl_query_fill(qctrl, | ||
1344 | V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, | ||
1345 | V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1, | ||
1346 | V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); | ||
1347 | case V4L2_CID_MPEG_VIDEO_BITRATE: | ||
1348 | return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000); | ||
1349 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | ||
1350 | return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000); | ||
1351 | case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: | ||
1352 | return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); | ||
1353 | case V4L2_CID_MPEG_STREAM_TYPE: | ||
1354 | return v4l2_ctrl_query_fill(qctrl, | ||
1355 | V4L2_MPEG_STREAM_TYPE_MPEG2_PS, | ||
1356 | V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1, | ||
1357 | V4L2_MPEG_STREAM_TYPE_MPEG2_PS); | ||
1358 | case V4L2_CID_MPEG_STREAM_PID_PMT: | ||
1359 | return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16); | ||
1360 | case V4L2_CID_MPEG_STREAM_PID_AUDIO: | ||
1361 | return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260); | ||
1362 | case V4L2_CID_MPEG_STREAM_PID_VIDEO: | ||
1363 | return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256); | ||
1364 | case V4L2_CID_MPEG_STREAM_PID_PCR: | ||
1365 | return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259); | ||
1366 | case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: | ||
1367 | return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); | ||
1368 | case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: | ||
1369 | return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); | ||
1370 | default: | ||
1371 | return -EINVAL; | ||
1372 | } | ||
1373 | } | ||
1374 | |||
1375 | /* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and | ||
1376 | the menu. The qctrl pointer may be NULL, in which case it is ignored. */ | ||
1377 | int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl, | ||
1378 | const char **menu_items) | ||
1379 | { | ||
1380 | int i; | ||
1381 | |||
1382 | if (menu_items == NULL || | ||
1383 | (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum))) | ||
1384 | return -EINVAL; | ||
1385 | for (i = 0; i < qmenu->index && menu_items[i]; i++) ; | ||
1386 | if (menu_items[i] == NULL || menu_items[i][0] == '\0') | ||
1387 | return -EINVAL; | ||
1388 | snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]); | ||
1389 | qmenu->reserved = 0; | ||
1390 | return 0; | ||
1391 | } | ||
1392 | |||
1393 | /* ctrl_classes points to an array of u32 pointers, the last element is | ||
1394 | a NULL pointer. Each u32 array is a 0-terminated array of control IDs. | ||
1395 | Each array must be sorted low to high and belong to the same control | ||
1396 | class. The array of u32 pointer must also be sorted, from low class IDs | ||
1397 | to high class IDs. | ||
1398 | |||
1399 | This function returns the first ID that follows after the given ID. | ||
1400 | When no more controls are available 0 is returned. */ | ||
1401 | u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) | ||
1402 | { | ||
1403 | u32 ctrl_class; | ||
1404 | const u32 *pctrl; | ||
1405 | |||
1406 | /* if no query is desired, then just return the control ID */ | ||
1407 | if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) | ||
1408 | return id; | ||
1409 | if (ctrl_classes == NULL) | ||
1410 | return 0; | ||
1411 | id &= V4L2_CTRL_ID_MASK; | ||
1412 | ctrl_class = V4L2_CTRL_ID2CLASS(id); | ||
1413 | id++; /* select next control */ | ||
1414 | /* find first class that matches (or is greater than) the class of | ||
1415 | the ID */ | ||
1416 | while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) < ctrl_class) | ||
1417 | ctrl_classes++; | ||
1418 | /* no more classes */ | ||
1419 | if (*ctrl_classes == NULL) | ||
1420 | return 0; | ||
1421 | pctrl = *ctrl_classes; | ||
1422 | /* find first ctrl within the class that is >= ID */ | ||
1423 | while (*pctrl && *pctrl < id) pctrl++; | ||
1424 | if (*pctrl) | ||
1425 | return *pctrl; | ||
1426 | /* we are at the end of the controls of the current class. */ | ||
1427 | /* continue with next class if available */ | ||
1428 | ctrl_classes++; | ||
1429 | if (*ctrl_classes == NULL) | ||
1430 | return 0; | ||
1431 | return **ctrl_classes; | ||
1432 | } | ||
1433 | |||
1434 | /* ----------------------------------------------------------------- */ | ||
1435 | |||
918 | EXPORT_SYMBOL(v4l2_video_std_construct); | 1436 | EXPORT_SYMBOL(v4l2_video_std_construct); |
919 | 1437 | ||
920 | EXPORT_SYMBOL(v4l2_prio_init); | 1438 | EXPORT_SYMBOL(v4l2_prio_init); |
@@ -929,6 +1447,13 @@ EXPORT_SYMBOL(v4l2_type_names); | |||
929 | EXPORT_SYMBOL(v4l_printk_ioctl); | 1447 | EXPORT_SYMBOL(v4l_printk_ioctl); |
930 | EXPORT_SYMBOL(v4l_printk_ioctl_arg); | 1448 | EXPORT_SYMBOL(v4l_printk_ioctl_arg); |
931 | 1449 | ||
1450 | EXPORT_SYMBOL(v4l2_ctrl_next); | ||
1451 | EXPORT_SYMBOL(v4l2_ctrl_check); | ||
1452 | EXPORT_SYMBOL(v4l2_ctrl_get_menu); | ||
1453 | EXPORT_SYMBOL(v4l2_ctrl_query_menu); | ||
1454 | EXPORT_SYMBOL(v4l2_ctrl_query_fill); | ||
1455 | EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); | ||
1456 | |||
932 | /* | 1457 | /* |
933 | * Local variables: | 1458 | * Local variables: |
934 | * c-basic-offset: 8 | 1459 | * c-basic-offset: 8 |
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c index caf3e7e2f219..7ee8a53cd336 100644 --- a/drivers/media/video/video-buf-dvb.c +++ b/drivers/media/video/video-buf-dvb.c | |||
@@ -135,14 +135,15 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) | |||
135 | 135 | ||
136 | int videobuf_dvb_register(struct videobuf_dvb *dvb, | 136 | int videobuf_dvb_register(struct videobuf_dvb *dvb, |
137 | struct module *module, | 137 | struct module *module, |
138 | void *adapter_priv) | 138 | void *adapter_priv, |
139 | struct device *device) | ||
139 | { | 140 | { |
140 | int result; | 141 | int result; |
141 | 142 | ||
142 | mutex_init(&dvb->lock); | 143 | mutex_init(&dvb->lock); |
143 | 144 | ||
144 | /* register adapter */ | 145 | /* register adapter */ |
145 | result = dvb_register_adapter(&dvb->adapter, dvb->name, module); | 146 | result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device); |
146 | if (result < 0) { | 147 | if (result < 0) { |
147 | printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", | 148 | printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", |
148 | dvb->name, result); | 149 | dvb->name, result); |
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 5f87dd5f1d0b..2dfa7f23d0ca 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c | |||
@@ -1,20 +1,31 @@ | |||
1 | /* | 1 | /* |
2 | * Video capture interface for Linux | 2 | * Video capture interface for Linux version 2 |
3 | * | 3 | * |
4 | * A generic video device interface for the LINUX operating system | 4 | * A generic video device interface for the LINUX operating system |
5 | * using a set of device structures/vectors for low level operations. | 5 | * using a set of device structures/vectors for low level operations. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
9 | * as published by the Free Software Foundation; either version | 9 | * as published by the Free Software Foundation; either version |
10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
11 | * | 11 | * |
12 | * Author: Alan Cox, <alan@redhat.com> | 12 | * Authors: Alan Cox, <alan@redhat.com> (version 1) |
13 | * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) | ||
13 | * | 14 | * |
14 | * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com> | 15 | * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com> |
15 | * - Added procfs support | 16 | * - Added procfs support |
16 | */ | 17 | */ |
17 | 18 | ||
19 | #define dbgarg(cmd, fmt, arg...) \ | ||
20 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ | ||
21 | printk (KERN_DEBUG "%s: ", vfd->name); \ | ||
22 | v4l_printk_ioctl(cmd); \ | ||
23 | printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); | ||
24 | |||
25 | #define dbgarg2(fmt, arg...) \ | ||
26 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ | ||
27 | printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); | ||
28 | |||
18 | #include <linux/module.h> | 29 | #include <linux/module.h> |
19 | #include <linux/types.h> | 30 | #include <linux/types.h> |
20 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
@@ -30,7 +41,13 @@ | |||
30 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
31 | #include <asm/system.h> | 42 | #include <asm/system.h> |
32 | 43 | ||
44 | #define __OLD_VIDIOC_ /* To allow fixing old calls*/ | ||
45 | #include <linux/videodev2.h> | ||
46 | |||
47 | #ifdef CONFIG_VIDEO_V4L1 | ||
33 | #include <linux/videodev.h> | 48 | #include <linux/videodev.h> |
49 | #endif | ||
50 | #include <media/v4l2-common.h> | ||
34 | 51 | ||
35 | #define VIDEO_NUM_DEVICES 256 | 52 | #define VIDEO_NUM_DEVICES 256 |
36 | #define VIDEO_NAME "video4linux" | 53 | #define VIDEO_NAME "video4linux" |
@@ -41,7 +58,8 @@ | |||
41 | 58 | ||
42 | static ssize_t show_name(struct class_device *cd, char *buf) | 59 | static ssize_t show_name(struct class_device *cd, char *buf) |
43 | { | 60 | { |
44 | struct video_device *vfd = container_of(cd, struct video_device, class_dev); | 61 | struct video_device *vfd = container_of(cd, struct video_device, |
62 | class_dev); | ||
45 | return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name); | 63 | return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name); |
46 | } | 64 | } |
47 | 65 | ||
@@ -62,7 +80,8 @@ void video_device_release(struct video_device *vfd) | |||
62 | 80 | ||
63 | static void video_release(struct class_device *cd) | 81 | static void video_release(struct class_device *cd) |
64 | { | 82 | { |
65 | struct video_device *vfd = container_of(cd, struct video_device, class_dev); | 83 | struct video_device *vfd = container_of(cd, struct video_device, |
84 | class_dev); | ||
66 | 85 | ||
67 | #if 1 | 86 | #if 1 |
68 | /* needed until all drivers are fixed */ | 87 | /* needed until all drivers are fixed */ |
@@ -90,7 +109,7 @@ struct video_device* video_devdata(struct file *file) | |||
90 | } | 109 | } |
91 | 110 | ||
92 | /* | 111 | /* |
93 | * Open a video device. | 112 | * Open a video device - FIXME: Obsoleted |
94 | */ | 113 | */ |
95 | static int video_open(struct inode *inode, struct file *file) | 114 | static int video_open(struct inode *inode, struct file *file) |
96 | { | 115 | { |
@@ -130,6 +149,7 @@ static int video_open(struct inode *inode, struct file *file) | |||
130 | * helper function -- handles userspace copying for ioctl arguments | 149 | * helper function -- handles userspace copying for ioctl arguments |
131 | */ | 150 | */ |
132 | 151 | ||
152 | #ifdef __OLD_VIDIOC_ | ||
133 | static unsigned int | 153 | static unsigned int |
134 | video_fix_command(unsigned int cmd) | 154 | video_fix_command(unsigned int cmd) |
135 | { | 155 | { |
@@ -155,7 +175,11 @@ video_fix_command(unsigned int cmd) | |||
155 | } | 175 | } |
156 | return cmd; | 176 | return cmd; |
157 | } | 177 | } |
178 | #endif | ||
158 | 179 | ||
180 | /* | ||
181 | * Obsolete usercopy function - Should be removed soon | ||
182 | */ | ||
159 | int | 183 | int |
160 | video_usercopy(struct inode *inode, struct file *file, | 184 | video_usercopy(struct inode *inode, struct file *file, |
161 | unsigned int cmd, unsigned long arg, | 185 | unsigned int cmd, unsigned long arg, |
@@ -166,8 +190,15 @@ video_usercopy(struct inode *inode, struct file *file, | |||
166 | void *mbuf = NULL; | 190 | void *mbuf = NULL; |
167 | void *parg = NULL; | 191 | void *parg = NULL; |
168 | int err = -EINVAL; | 192 | int err = -EINVAL; |
193 | int is_ext_ctrl; | ||
194 | size_t ctrls_size = 0; | ||
195 | void __user *user_ptr = NULL; | ||
169 | 196 | ||
197 | #ifdef __OLD_VIDIOC_ | ||
170 | cmd = video_fix_command(cmd); | 198 | cmd = video_fix_command(cmd); |
199 | #endif | ||
200 | is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || | ||
201 | cmd == VIDIOC_TRY_EXT_CTRLS); | ||
171 | 202 | ||
172 | /* Copy arguments into temp kernel buffer */ | 203 | /* Copy arguments into temp kernel buffer */ |
173 | switch (_IOC_DIR(cmd)) { | 204 | switch (_IOC_DIR(cmd)) { |
@@ -193,14 +224,43 @@ video_usercopy(struct inode *inode, struct file *file, | |||
193 | goto out; | 224 | goto out; |
194 | break; | 225 | break; |
195 | } | 226 | } |
227 | if (is_ext_ctrl) { | ||
228 | struct v4l2_ext_controls *p = parg; | ||
229 | |||
230 | /* In case of an error, tell the caller that it wasn't | ||
231 | a specific control that caused it. */ | ||
232 | p->error_idx = p->count; | ||
233 | user_ptr = (void __user *)p->controls; | ||
234 | if (p->count) { | ||
235 | ctrls_size = sizeof(struct v4l2_ext_control) * p->count; | ||
236 | /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ | ||
237 | mbuf = kmalloc(ctrls_size, GFP_KERNEL); | ||
238 | err = -ENOMEM; | ||
239 | if (NULL == mbuf) | ||
240 | goto out_ext_ctrl; | ||
241 | err = -EFAULT; | ||
242 | if (copy_from_user(mbuf, user_ptr, ctrls_size)) | ||
243 | goto out_ext_ctrl; | ||
244 | p->controls = mbuf; | ||
245 | } | ||
246 | } | ||
196 | 247 | ||
197 | /* call driver */ | 248 | /* call driver */ |
198 | err = func(inode, file, cmd, parg); | 249 | err = func(inode, file, cmd, parg); |
199 | if (err == -ENOIOCTLCMD) | 250 | if (err == -ENOIOCTLCMD) |
200 | err = -EINVAL; | 251 | err = -EINVAL; |
252 | if (is_ext_ctrl) { | ||
253 | struct v4l2_ext_controls *p = parg; | ||
254 | |||
255 | p->controls = (void *)user_ptr; | ||
256 | if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) | ||
257 | err = -EFAULT; | ||
258 | goto out_ext_ctrl; | ||
259 | } | ||
201 | if (err < 0) | 260 | if (err < 0) |
202 | goto out; | 261 | goto out; |
203 | 262 | ||
263 | out_ext_ctrl: | ||
204 | /* Copy results into user buffer */ | 264 | /* Copy results into user buffer */ |
205 | switch (_IOC_DIR(cmd)) | 265 | switch (_IOC_DIR(cmd)) |
206 | { | 266 | { |
@@ -218,6 +278,7 @@ out: | |||
218 | 278 | ||
219 | /* | 279 | /* |
220 | * open/release helper functions -- handle exclusive opens | 280 | * open/release helper functions -- handle exclusive opens |
281 | * Should be removed soon | ||
221 | */ | 282 | */ |
222 | int video_exclusive_open(struct inode *inode, struct file *file) | 283 | int video_exclusive_open(struct inode *inode, struct file *file) |
223 | { | 284 | { |
@@ -242,6 +303,1184 @@ int video_exclusive_release(struct inode *inode, struct file *file) | |||
242 | return 0; | 303 | return 0; |
243 | } | 304 | } |
244 | 305 | ||
306 | static char *v4l2_memory_names[] = { | ||
307 | [V4L2_MEMORY_MMAP] = "mmap", | ||
308 | [V4L2_MEMORY_USERPTR] = "userptr", | ||
309 | [V4L2_MEMORY_OVERLAY] = "overlay", | ||
310 | }; | ||
311 | |||
312 | |||
313 | /* FIXME: Those stuff are replicated also on v4l2-common.c */ | ||
314 | static char *v4l2_type_names_FIXME[] = { | ||
315 | [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", | ||
316 | [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", | ||
317 | [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", | ||
318 | [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", | ||
319 | [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", | ||
320 | [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", | ||
321 | [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture", | ||
322 | [V4L2_BUF_TYPE_PRIVATE] = "private", | ||
323 | }; | ||
324 | |||
325 | static char *v4l2_field_names_FIXME[] = { | ||
326 | [V4L2_FIELD_ANY] = "any", | ||
327 | [V4L2_FIELD_NONE] = "none", | ||
328 | [V4L2_FIELD_TOP] = "top", | ||
329 | [V4L2_FIELD_BOTTOM] = "bottom", | ||
330 | [V4L2_FIELD_INTERLACED] = "interlaced", | ||
331 | [V4L2_FIELD_SEQ_TB] = "seq-tb", | ||
332 | [V4L2_FIELD_SEQ_BT] = "seq-bt", | ||
333 | [V4L2_FIELD_ALTERNATE] = "alternate", | ||
334 | }; | ||
335 | |||
336 | #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown" | ||
337 | |||
338 | static void dbgbuf(unsigned int cmd, struct video_device *vfd, | ||
339 | struct v4l2_buffer *p) | ||
340 | { | ||
341 | struct v4l2_timecode *tc=&p->timecode; | ||
342 | |||
343 | dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, " | ||
344 | "bytesused=%d, flags=0x%08d, " | ||
345 | "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n", | ||
346 | (p->timestamp.tv_sec/3600), | ||
347 | (int)(p->timestamp.tv_sec/60)%60, | ||
348 | (int)(p->timestamp.tv_sec%60), | ||
349 | p->timestamp.tv_usec, | ||
350 | p->index, | ||
351 | prt_names(p->type,v4l2_type_names_FIXME), | ||
352 | p->bytesused,p->flags, | ||
353 | p->field,p->sequence, | ||
354 | prt_names(p->memory,v4l2_memory_names), | ||
355 | p->m.userptr); | ||
356 | dbgarg2 ("timecode= %02d:%02d:%02d type=%d, " | ||
357 | "flags=0x%08d, frames=%d, userbits=0x%08x\n", | ||
358 | tc->hours,tc->minutes,tc->seconds, | ||
359 | tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits); | ||
360 | } | ||
361 | |||
362 | static inline void dbgrect(struct video_device *vfd, char *s, | ||
363 | struct v4l2_rect *r) | ||
364 | { | ||
365 | dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top, | ||
366 | r->width, r->height); | ||
367 | }; | ||
368 | |||
369 | static inline void v4l_print_pix_fmt (struct video_device *vfd, | ||
370 | struct v4l2_pix_format *fmt) | ||
371 | { | ||
372 | dbgarg2 ("width=%d, height=%d, format=0x%08x, field=%s, " | ||
373 | "bytesperline=%d sizeimage=%d, colorspace=%d\n", | ||
374 | fmt->width,fmt->height,fmt->pixelformat, | ||
375 | prt_names(fmt->field,v4l2_field_names_FIXME), | ||
376 | fmt->bytesperline,fmt->sizeimage,fmt->colorspace); | ||
377 | }; | ||
378 | |||
379 | |||
380 | static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type) | ||
381 | { | ||
382 | switch (type) { | ||
383 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
384 | if (vfd->vidioc_try_fmt_cap) | ||
385 | return (0); | ||
386 | break; | ||
387 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
388 | if (vfd->vidioc_try_fmt_overlay) | ||
389 | return (0); | ||
390 | break; | ||
391 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
392 | if (vfd->vidioc_try_fmt_vbi) | ||
393 | return (0); | ||
394 | break; | ||
395 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | ||
396 | if (vfd->vidioc_try_fmt_vbi_output) | ||
397 | return (0); | ||
398 | break; | ||
399 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
400 | if (vfd->vidioc_try_fmt_vbi_capture) | ||
401 | return (0); | ||
402 | break; | ||
403 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | ||
404 | if (vfd->vidioc_try_fmt_video_output) | ||
405 | return (0); | ||
406 | break; | ||
407 | case V4L2_BUF_TYPE_VBI_OUTPUT: | ||
408 | if (vfd->vidioc_try_fmt_vbi_output) | ||
409 | return (0); | ||
410 | break; | ||
411 | case V4L2_BUF_TYPE_PRIVATE: | ||
412 | if (vfd->vidioc_try_fmt_type_private) | ||
413 | return (0); | ||
414 | break; | ||
415 | } | ||
416 | return (-EINVAL); | ||
417 | } | ||
418 | |||
419 | static int __video_do_ioctl(struct inode *inode, struct file *file, | ||
420 | unsigned int cmd, void *arg) | ||
421 | { | ||
422 | struct video_device *vfd = video_devdata(file); | ||
423 | void *fh = file->private_data; | ||
424 | int ret = -EINVAL; | ||
425 | |||
426 | if ( (vfd->debug & V4L2_DEBUG_IOCTL) && | ||
427 | !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) { | ||
428 | v4l_print_ioctl(vfd->name, cmd); | ||
429 | } | ||
430 | |||
431 | switch(cmd) { | ||
432 | /* --- capabilities ------------------------------------------ */ | ||
433 | case VIDIOC_QUERYCAP: | ||
434 | { | ||
435 | struct v4l2_capability *cap = (struct v4l2_capability*)arg; | ||
436 | memset(cap, 0, sizeof(*cap)); | ||
437 | |||
438 | if (!vfd->vidioc_querycap) | ||
439 | break; | ||
440 | |||
441 | ret=vfd->vidioc_querycap(file, fh, cap); | ||
442 | if (!ret) | ||
443 | dbgarg (cmd, "driver=%s, card=%s, bus=%s, " | ||
444 | "version=0x%08x, " | ||
445 | "capabilities=0x%08x\n", | ||
446 | cap->driver,cap->card,cap->bus_info, | ||
447 | cap->version, | ||
448 | cap->capabilities); | ||
449 | break; | ||
450 | } | ||
451 | |||
452 | /* --- priority ------------------------------------------ */ | ||
453 | case VIDIOC_G_PRIORITY: | ||
454 | { | ||
455 | enum v4l2_priority *p=arg; | ||
456 | |||
457 | if (!vfd->vidioc_g_priority) | ||
458 | break; | ||
459 | ret=vfd->vidioc_g_priority(file, fh, p); | ||
460 | if (!ret) | ||
461 | dbgarg(cmd, "priority is %d\n", *p); | ||
462 | break; | ||
463 | } | ||
464 | case VIDIOC_S_PRIORITY: | ||
465 | { | ||
466 | enum v4l2_priority *p=arg; | ||
467 | |||
468 | if (!vfd->vidioc_s_priority) | ||
469 | break; | ||
470 | dbgarg(cmd, "setting priority to %d\n", *p); | ||
471 | ret=vfd->vidioc_s_priority(file, fh, *p); | ||
472 | break; | ||
473 | } | ||
474 | |||
475 | /* --- capture ioctls ---------------------------------------- */ | ||
476 | case VIDIOC_ENUM_FMT: | ||
477 | { | ||
478 | struct v4l2_fmtdesc *f = arg; | ||
479 | enum v4l2_buf_type type; | ||
480 | unsigned int index; | ||
481 | |||
482 | index = f->index; | ||
483 | type = f->type; | ||
484 | memset(f,0,sizeof(*f)); | ||
485 | f->index = index; | ||
486 | f->type = type; | ||
487 | |||
488 | switch (type) { | ||
489 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
490 | if (vfd->vidioc_enum_fmt_cap) | ||
491 | ret=vfd->vidioc_enum_fmt_cap(file, fh, f); | ||
492 | break; | ||
493 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
494 | if (vfd->vidioc_enum_fmt_overlay) | ||
495 | ret=vfd->vidioc_enum_fmt_overlay(file, fh, f); | ||
496 | break; | ||
497 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
498 | if (vfd->vidioc_enum_fmt_vbi) | ||
499 | ret=vfd->vidioc_enum_fmt_vbi(file, fh, f); | ||
500 | break; | ||
501 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | ||
502 | if (vfd->vidioc_enum_fmt_vbi_output) | ||
503 | ret=vfd->vidioc_enum_fmt_vbi_output(file, | ||
504 | fh, f); | ||
505 | break; | ||
506 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
507 | if (vfd->vidioc_enum_fmt_vbi_capture) | ||
508 | ret=vfd->vidioc_enum_fmt_vbi_capture(file, | ||
509 | fh, f); | ||
510 | break; | ||
511 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | ||
512 | if (vfd->vidioc_enum_fmt_video_output) | ||
513 | ret=vfd->vidioc_enum_fmt_video_output(file, | ||
514 | fh, f); | ||
515 | break; | ||
516 | case V4L2_BUF_TYPE_VBI_OUTPUT: | ||
517 | if (vfd->vidioc_enum_fmt_vbi_output) | ||
518 | ret=vfd->vidioc_enum_fmt_vbi_output(file, | ||
519 | fh, f); | ||
520 | break; | ||
521 | case V4L2_BUF_TYPE_PRIVATE: | ||
522 | if (vfd->vidioc_enum_fmt_type_private) | ||
523 | ret=vfd->vidioc_enum_fmt_type_private(file, | ||
524 | fh, f); | ||
525 | break; | ||
526 | } | ||
527 | if (!ret) | ||
528 | dbgarg (cmd, "index=%d, type=%d, flags=%d, " | ||
529 | "description=%s," | ||
530 | " pixelformat=0x%8x\n", | ||
531 | f->index, f->type, f->flags, | ||
532 | f->description, | ||
533 | f->pixelformat); | ||
534 | |||
535 | break; | ||
536 | } | ||
537 | case VIDIOC_G_FMT: | ||
538 | { | ||
539 | struct v4l2_format *f = (struct v4l2_format *)arg; | ||
540 | enum v4l2_buf_type type=f->type; | ||
541 | |||
542 | memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); | ||
543 | f->type=type; | ||
544 | |||
545 | /* FIXME: Should be one dump per type */ | ||
546 | dbgarg (cmd, "type=%s\n", prt_names(type, | ||
547 | v4l2_type_names_FIXME)); | ||
548 | |||
549 | switch (type) { | ||
550 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
551 | if (vfd->vidioc_g_fmt_cap) | ||
552 | ret=vfd->vidioc_g_fmt_cap(file, fh, f); | ||
553 | if (!ret) | ||
554 | v4l_print_pix_fmt(vfd,&f->fmt.pix); | ||
555 | break; | ||
556 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
557 | if (vfd->vidioc_g_fmt_overlay) | ||
558 | ret=vfd->vidioc_g_fmt_overlay(file, fh, f); | ||
559 | break; | ||
560 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
561 | if (vfd->vidioc_g_fmt_vbi) | ||
562 | ret=vfd->vidioc_g_fmt_vbi(file, fh, f); | ||
563 | break; | ||
564 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | ||
565 | if (vfd->vidioc_g_fmt_vbi_output) | ||
566 | ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); | ||
567 | break; | ||
568 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
569 | if (vfd->vidioc_g_fmt_vbi_capture) | ||
570 | ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f); | ||
571 | break; | ||
572 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | ||
573 | if (vfd->vidioc_g_fmt_video_output) | ||
574 | ret=vfd->vidioc_g_fmt_video_output(file, | ||
575 | fh, f); | ||
576 | break; | ||
577 | case V4L2_BUF_TYPE_VBI_OUTPUT: | ||
578 | if (vfd->vidioc_g_fmt_vbi_output) | ||
579 | ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); | ||
580 | break; | ||
581 | case V4L2_BUF_TYPE_PRIVATE: | ||
582 | if (vfd->vidioc_g_fmt_type_private) | ||
583 | ret=vfd->vidioc_g_fmt_type_private(file, | ||
584 | fh, f); | ||
585 | break; | ||
586 | } | ||
587 | |||
588 | break; | ||
589 | } | ||
590 | case VIDIOC_S_FMT: | ||
591 | { | ||
592 | struct v4l2_format *f = (struct v4l2_format *)arg; | ||
593 | |||
594 | /* FIXME: Should be one dump per type */ | ||
595 | dbgarg (cmd, "type=%s\n", prt_names(f->type, | ||
596 | v4l2_type_names_FIXME)); | ||
597 | |||
598 | switch (f->type) { | ||
599 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
600 | v4l_print_pix_fmt(vfd,&f->fmt.pix); | ||
601 | if (vfd->vidioc_s_fmt_cap) | ||
602 | ret=vfd->vidioc_s_fmt_cap(file, fh, f); | ||
603 | break; | ||
604 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
605 | if (vfd->vidioc_s_fmt_overlay) | ||
606 | ret=vfd->vidioc_s_fmt_overlay(file, fh, f); | ||
607 | break; | ||
608 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
609 | if (vfd->vidioc_s_fmt_vbi) | ||
610 | ret=vfd->vidioc_s_fmt_vbi(file, fh, f); | ||
611 | break; | ||
612 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | ||
613 | if (vfd->vidioc_s_fmt_vbi_output) | ||
614 | ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f); | ||
615 | break; | ||
616 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
617 | if (vfd->vidioc_s_fmt_vbi_capture) | ||
618 | ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f); | ||
619 | break; | ||
620 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | ||
621 | if (vfd->vidioc_s_fmt_video_output) | ||
622 | ret=vfd->vidioc_s_fmt_video_output(file, | ||
623 | fh, f); | ||
624 | break; | ||
625 | case V4L2_BUF_TYPE_VBI_OUTPUT: | ||
626 | if (vfd->vidioc_s_fmt_vbi_output) | ||
627 | ret=vfd->vidioc_s_fmt_vbi_output(file, | ||
628 | fh, f); | ||
629 | break; | ||
630 | case V4L2_BUF_TYPE_PRIVATE: | ||
631 | if (vfd->vidioc_s_fmt_type_private) | ||
632 | ret=vfd->vidioc_s_fmt_type_private(file, | ||
633 | fh, f); | ||
634 | break; | ||
635 | } | ||
636 | break; | ||
637 | } | ||
638 | case VIDIOC_TRY_FMT: | ||
639 | { | ||
640 | struct v4l2_format *f = (struct v4l2_format *)arg; | ||
641 | |||
642 | /* FIXME: Should be one dump per type */ | ||
643 | dbgarg (cmd, "type=%s\n", prt_names(f->type, | ||
644 | v4l2_type_names_FIXME)); | ||
645 | switch (f->type) { | ||
646 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
647 | if (vfd->vidioc_try_fmt_cap) | ||
648 | ret=vfd->vidioc_try_fmt_cap(file, fh, f); | ||
649 | if (!ret) | ||
650 | v4l_print_pix_fmt(vfd,&f->fmt.pix); | ||
651 | break; | ||
652 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
653 | if (vfd->vidioc_try_fmt_overlay) | ||
654 | ret=vfd->vidioc_try_fmt_overlay(file, fh, f); | ||
655 | break; | ||
656 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
657 | if (vfd->vidioc_try_fmt_vbi) | ||
658 | ret=vfd->vidioc_try_fmt_vbi(file, fh, f); | ||
659 | break; | ||
660 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | ||
661 | if (vfd->vidioc_try_fmt_vbi_output) | ||
662 | ret=vfd->vidioc_try_fmt_vbi_output(file, | ||
663 | fh, f); | ||
664 | break; | ||
665 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
666 | if (vfd->vidioc_try_fmt_vbi_capture) | ||
667 | ret=vfd->vidioc_try_fmt_vbi_capture(file, | ||
668 | fh, f); | ||
669 | break; | ||
670 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | ||
671 | if (vfd->vidioc_try_fmt_video_output) | ||
672 | ret=vfd->vidioc_try_fmt_video_output(file, | ||
673 | fh, f); | ||
674 | break; | ||
675 | case V4L2_BUF_TYPE_VBI_OUTPUT: | ||
676 | if (vfd->vidioc_try_fmt_vbi_output) | ||
677 | ret=vfd->vidioc_try_fmt_vbi_output(file, | ||
678 | fh, f); | ||
679 | break; | ||
680 | case V4L2_BUF_TYPE_PRIVATE: | ||
681 | if (vfd->vidioc_try_fmt_type_private) | ||
682 | ret=vfd->vidioc_try_fmt_type_private(file, | ||
683 | fh, f); | ||
684 | break; | ||
685 | } | ||
686 | |||
687 | break; | ||
688 | } | ||
689 | /* FIXME: Those buf reqs could be handled here, | ||
690 | with some changes on videobuf to allow its header to be included at | ||
691 | videodev2.h or being merged at videodev2. | ||
692 | */ | ||
693 | case VIDIOC_REQBUFS: | ||
694 | { | ||
695 | struct v4l2_requestbuffers *p=arg; | ||
696 | |||
697 | if (!vfd->vidioc_reqbufs) | ||
698 | break; | ||
699 | ret = check_fmt (vfd, p->type); | ||
700 | if (ret) | ||
701 | break; | ||
702 | |||
703 | ret=vfd->vidioc_reqbufs(file, fh, p); | ||
704 | dbgarg (cmd, "count=%d, type=%s, memory=%s\n", | ||
705 | p->count, | ||
706 | prt_names(p->type,v4l2_type_names_FIXME), | ||
707 | prt_names(p->memory,v4l2_memory_names)); | ||
708 | break; | ||
709 | } | ||
710 | case VIDIOC_QUERYBUF: | ||
711 | { | ||
712 | struct v4l2_buffer *p=arg; | ||
713 | |||
714 | if (!vfd->vidioc_querybuf) | ||
715 | break; | ||
716 | ret = check_fmt (vfd, p->type); | ||
717 | if (ret) | ||
718 | break; | ||
719 | |||
720 | ret=vfd->vidioc_querybuf(file, fh, p); | ||
721 | if (!ret) | ||
722 | dbgbuf(cmd,vfd,p); | ||
723 | break; | ||
724 | } | ||
725 | case VIDIOC_QBUF: | ||
726 | { | ||
727 | struct v4l2_buffer *p=arg; | ||
728 | |||
729 | if (!vfd->vidioc_qbuf) | ||
730 | break; | ||
731 | ret = check_fmt (vfd, p->type); | ||
732 | if (ret) | ||
733 | break; | ||
734 | |||
735 | ret=vfd->vidioc_qbuf(file, fh, p); | ||
736 | if (!ret) | ||
737 | dbgbuf(cmd,vfd,p); | ||
738 | break; | ||
739 | } | ||
740 | case VIDIOC_DQBUF: | ||
741 | { | ||
742 | struct v4l2_buffer *p=arg; | ||
743 | if (!vfd->vidioc_qbuf) | ||
744 | break; | ||
745 | ret = check_fmt (vfd, p->type); | ||
746 | if (ret) | ||
747 | break; | ||
748 | |||
749 | ret=vfd->vidioc_qbuf(file, fh, p); | ||
750 | if (!ret) | ||
751 | dbgbuf(cmd,vfd,p); | ||
752 | break; | ||
753 | } | ||
754 | case VIDIOC_OVERLAY: | ||
755 | { | ||
756 | int *i = arg; | ||
757 | |||
758 | if (!vfd->vidioc_overlay) | ||
759 | break; | ||
760 | dbgarg (cmd, "value=%d\n",*i); | ||
761 | ret=vfd->vidioc_overlay(file, fh, *i); | ||
762 | break; | ||
763 | } | ||
764 | #ifdef HAVE_V4L1 | ||
765 | /* --- streaming capture ------------------------------------- */ | ||
766 | case VIDIOCGMBUF: | ||
767 | { | ||
768 | struct video_mbuf *p=arg; | ||
769 | |||
770 | memset(p,0,sizeof(p)); | ||
771 | |||
772 | if (!vfd->vidiocgmbuf) | ||
773 | break; | ||
774 | ret=vfd->vidiocgmbuf(file, fh, p); | ||
775 | if (!ret) | ||
776 | dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n", | ||
777 | p->size, p->frames, | ||
778 | (unsigned long)p->offsets); | ||
779 | break; | ||
780 | } | ||
781 | #endif | ||
782 | case VIDIOC_G_FBUF: | ||
783 | { | ||
784 | struct v4l2_framebuffer *p=arg; | ||
785 | if (!vfd->vidioc_g_fbuf) | ||
786 | break; | ||
787 | ret=vfd->vidioc_g_fbuf(file, fh, arg); | ||
788 | if (!ret) { | ||
789 | dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n", | ||
790 | p->capability,p->flags, | ||
791 | (unsigned long)p->base); | ||
792 | v4l_print_pix_fmt (vfd, &p->fmt); | ||
793 | } | ||
794 | break; | ||
795 | } | ||
796 | case VIDIOC_S_FBUF: | ||
797 | { | ||
798 | struct v4l2_framebuffer *p=arg; | ||
799 | if (!vfd->vidioc_s_fbuf) | ||
800 | break; | ||
801 | |||
802 | dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n", | ||
803 | p->capability,p->flags,(unsigned long)p->base); | ||
804 | v4l_print_pix_fmt (vfd, &p->fmt); | ||
805 | ret=vfd->vidioc_s_fbuf(file, fh, arg); | ||
806 | |||
807 | break; | ||
808 | } | ||
809 | case VIDIOC_STREAMON: | ||
810 | { | ||
811 | enum v4l2_buf_type i = *(int *)arg; | ||
812 | if (!vfd->vidioc_streamon) | ||
813 | break; | ||
814 | dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME)); | ||
815 | ret=vfd->vidioc_streamon(file, fh,i); | ||
816 | break; | ||
817 | } | ||
818 | case VIDIOC_STREAMOFF: | ||
819 | { | ||
820 | enum v4l2_buf_type i = *(int *)arg; | ||
821 | |||
822 | if (!vfd->vidioc_streamoff) | ||
823 | break; | ||
824 | dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME)); | ||
825 | ret=vfd->vidioc_streamoff(file, fh, i); | ||
826 | break; | ||
827 | } | ||
828 | /* ---------- tv norms ---------- */ | ||
829 | case VIDIOC_ENUMSTD: | ||
830 | { | ||
831 | struct v4l2_standard *p = arg; | ||
832 | unsigned int index = p->index; | ||
833 | |||
834 | if (!vfd->tvnormsize) { | ||
835 | printk (KERN_WARNING "%s: no TV norms defined!\n", | ||
836 | vfd->name); | ||
837 | break; | ||
838 | } | ||
839 | |||
840 | if (index<=0 || index >= vfd->tvnormsize) { | ||
841 | ret=-EINVAL; | ||
842 | break; | ||
843 | } | ||
844 | v4l2_video_std_construct(p, vfd->tvnorms[p->index].id, | ||
845 | vfd->tvnorms[p->index].name); | ||
846 | p->index = index; | ||
847 | |||
848 | dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " | ||
849 | "framelines=%d\n", p->index, | ||
850 | (unsigned long long)p->id, p->name, | ||
851 | p->frameperiod.numerator, | ||
852 | p->frameperiod.denominator, | ||
853 | p->framelines); | ||
854 | |||
855 | ret=0; | ||
856 | break; | ||
857 | } | ||
858 | case VIDIOC_G_STD: | ||
859 | { | ||
860 | v4l2_std_id *id = arg; | ||
861 | |||
862 | *id = vfd->current_norm; | ||
863 | |||
864 | dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id); | ||
865 | |||
866 | ret=0; | ||
867 | break; | ||
868 | } | ||
869 | case VIDIOC_S_STD: | ||
870 | { | ||
871 | v4l2_std_id *id = arg; | ||
872 | unsigned int i; | ||
873 | |||
874 | if (!vfd->tvnormsize) { | ||
875 | printk (KERN_WARNING "%s: no TV norms defined!\n", | ||
876 | vfd->name); | ||
877 | break; | ||
878 | } | ||
879 | |||
880 | dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id); | ||
881 | |||
882 | /* First search for exact match */ | ||
883 | for (i = 0; i < vfd->tvnormsize; i++) | ||
884 | if (*id == vfd->tvnorms[i].id) | ||
885 | break; | ||
886 | /* Then for a generic video std that contains desired std */ | ||
887 | if (i == vfd->tvnormsize) | ||
888 | for (i = 0; i < vfd->tvnormsize; i++) | ||
889 | if (*id & vfd->tvnorms[i].id) | ||
890 | break; | ||
891 | if (i == vfd->tvnormsize) { | ||
892 | break; | ||
893 | } | ||
894 | |||
895 | /* Calls the specific handler */ | ||
896 | if (vfd->vidioc_s_std) | ||
897 | ret=vfd->vidioc_s_std(file, fh, i); | ||
898 | else | ||
899 | ret=-EINVAL; | ||
900 | |||
901 | /* Updates standard information */ | ||
902 | if (!ret) | ||
903 | vfd->current_norm=*id; | ||
904 | |||
905 | break; | ||
906 | } | ||
907 | case VIDIOC_QUERYSTD: | ||
908 | { | ||
909 | v4l2_std_id *p=arg; | ||
910 | |||
911 | if (!vfd->vidioc_querystd) | ||
912 | break; | ||
913 | ret=vfd->vidioc_querystd(file, fh, arg); | ||
914 | if (!ret) | ||
915 | dbgarg (cmd, "detected std=%Lu\n", | ||
916 | (unsigned long long)*p); | ||
917 | break; | ||
918 | } | ||
919 | /* ------ input switching ---------- */ | ||
920 | /* FIXME: Inputs can be handled inside videodev2 */ | ||
921 | case VIDIOC_ENUMINPUT: | ||
922 | { | ||
923 | struct v4l2_input *p=arg; | ||
924 | int i=p->index; | ||
925 | |||
926 | if (!vfd->vidioc_enum_input) | ||
927 | break; | ||
928 | memset(p, 0, sizeof(*p)); | ||
929 | p->index=i; | ||
930 | |||
931 | ret=vfd->vidioc_enum_input(file, fh, p); | ||
932 | if (!ret) | ||
933 | dbgarg (cmd, "index=%d, name=%s, type=%d, " | ||
934 | "audioset=%d, " | ||
935 | "tuner=%d, std=%Ld, status=%d\n", | ||
936 | p->index,p->name,p->type,p->audioset, | ||
937 | p->tuner, | ||
938 | (unsigned long long)p->std, | ||
939 | p->status); | ||
940 | break; | ||
941 | } | ||
942 | case VIDIOC_G_INPUT: | ||
943 | { | ||
944 | unsigned int *i = arg; | ||
945 | |||
946 | if (!vfd->vidioc_g_input) | ||
947 | break; | ||
948 | ret=vfd->vidioc_g_input(file, fh, i); | ||
949 | if (!ret) | ||
950 | dbgarg (cmd, "value=%d\n",*i); | ||
951 | break; | ||
952 | } | ||
953 | case VIDIOC_S_INPUT: | ||
954 | { | ||
955 | unsigned int *i = arg; | ||
956 | |||
957 | if (!vfd->vidioc_s_input) | ||
958 | break; | ||
959 | dbgarg (cmd, "value=%d\n",*i); | ||
960 | ret=vfd->vidioc_s_input(file, fh, *i); | ||
961 | break; | ||
962 | } | ||
963 | |||
964 | /* ------ output switching ---------- */ | ||
965 | case VIDIOC_G_OUTPUT: | ||
966 | { | ||
967 | unsigned int *i = arg; | ||
968 | |||
969 | if (!vfd->vidioc_g_output) | ||
970 | break; | ||
971 | ret=vfd->vidioc_g_output(file, fh, i); | ||
972 | if (!ret) | ||
973 | dbgarg (cmd, "value=%d\n",*i); | ||
974 | break; | ||
975 | } | ||
976 | case VIDIOC_S_OUTPUT: | ||
977 | { | ||
978 | unsigned int *i = arg; | ||
979 | |||
980 | if (!vfd->vidioc_s_output) | ||
981 | break; | ||
982 | dbgarg (cmd, "value=%d\n",*i); | ||
983 | ret=vfd->vidioc_s_output(file, fh, *i); | ||
984 | break; | ||
985 | } | ||
986 | |||
987 | /* --- controls ---------------------------------------------- */ | ||
988 | case VIDIOC_QUERYCTRL: | ||
989 | { | ||
990 | struct v4l2_queryctrl *p=arg; | ||
991 | |||
992 | if (!vfd->vidioc_queryctrl) | ||
993 | break; | ||
994 | ret=vfd->vidioc_queryctrl(file, fh, p); | ||
995 | |||
996 | if (!ret) | ||
997 | dbgarg (cmd, "id=%d, type=%d, name=%s, " | ||
998 | "min/max=%d/%d," | ||
999 | " step=%d, default=%d, flags=0x%08x\n", | ||
1000 | p->id,p->type,p->name,p->minimum, | ||
1001 | p->maximum,p->step,p->default_value, | ||
1002 | p->flags); | ||
1003 | break; | ||
1004 | } | ||
1005 | case VIDIOC_G_CTRL: | ||
1006 | { | ||
1007 | struct v4l2_control *p = arg; | ||
1008 | |||
1009 | if (!vfd->vidioc_g_ctrl) | ||
1010 | break; | ||
1011 | dbgarg(cmd, "Enum for index=%d\n", p->id); | ||
1012 | |||
1013 | ret=vfd->vidioc_g_ctrl(file, fh, p); | ||
1014 | if (!ret) | ||
1015 | dbgarg2 ( "id=%d, value=%d\n", p->id, p->value); | ||
1016 | break; | ||
1017 | } | ||
1018 | case VIDIOC_S_CTRL: | ||
1019 | { | ||
1020 | struct v4l2_control *p = arg; | ||
1021 | |||
1022 | if (!vfd->vidioc_s_ctrl) | ||
1023 | break; | ||
1024 | dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value); | ||
1025 | |||
1026 | ret=vfd->vidioc_s_ctrl(file, fh, p); | ||
1027 | break; | ||
1028 | } | ||
1029 | case VIDIOC_G_EXT_CTRLS: | ||
1030 | { | ||
1031 | struct v4l2_ext_controls *p = arg; | ||
1032 | |||
1033 | if (vfd->vidioc_g_ext_ctrls) { | ||
1034 | dbgarg(cmd, "count=%d\n", p->count); | ||
1035 | |||
1036 | ret=vfd->vidioc_g_ext_ctrls(file, fh, p); | ||
1037 | } | ||
1038 | break; | ||
1039 | } | ||
1040 | case VIDIOC_S_EXT_CTRLS: | ||
1041 | { | ||
1042 | struct v4l2_ext_controls *p = arg; | ||
1043 | |||
1044 | if (vfd->vidioc_s_ext_ctrls) { | ||
1045 | dbgarg(cmd, "count=%d\n", p->count); | ||
1046 | |||
1047 | ret=vfd->vidioc_s_ext_ctrls(file, fh, p); | ||
1048 | } | ||
1049 | break; | ||
1050 | } | ||
1051 | case VIDIOC_TRY_EXT_CTRLS: | ||
1052 | { | ||
1053 | struct v4l2_ext_controls *p = arg; | ||
1054 | |||
1055 | if (vfd->vidioc_try_ext_ctrls) { | ||
1056 | dbgarg(cmd, "count=%d\n", p->count); | ||
1057 | |||
1058 | ret=vfd->vidioc_try_ext_ctrls(file, fh, p); | ||
1059 | } | ||
1060 | break; | ||
1061 | } | ||
1062 | case VIDIOC_QUERYMENU: | ||
1063 | { | ||
1064 | struct v4l2_querymenu *p=arg; | ||
1065 | if (!vfd->vidioc_querymenu) | ||
1066 | break; | ||
1067 | ret=vfd->vidioc_querymenu(file, fh, p); | ||
1068 | if (!ret) | ||
1069 | dbgarg (cmd, "id=%d, index=%d, name=%s\n", | ||
1070 | p->id,p->index,p->name); | ||
1071 | break; | ||
1072 | } | ||
1073 | /* --- audio ---------------------------------------------- */ | ||
1074 | case VIDIOC_ENUMAUDIO: | ||
1075 | { | ||
1076 | struct v4l2_audio *p=arg; | ||
1077 | |||
1078 | if (!vfd->vidioc_enumaudio) | ||
1079 | break; | ||
1080 | dbgarg(cmd, "Enum for index=%d\n", p->index); | ||
1081 | ret=vfd->vidioc_enumaudio(file, fh, p); | ||
1082 | if (!ret) | ||
1083 | dbgarg2("index=%d, name=%s, capability=%d, " | ||
1084 | "mode=%d\n",p->index,p->name, | ||
1085 | p->capability, p->mode); | ||
1086 | break; | ||
1087 | } | ||
1088 | case VIDIOC_G_AUDIO: | ||
1089 | { | ||
1090 | struct v4l2_audio *p=arg; | ||
1091 | |||
1092 | if (!vfd->vidioc_g_audio) | ||
1093 | break; | ||
1094 | dbgarg(cmd, "Get for index=%d\n", p->index); | ||
1095 | ret=vfd->vidioc_g_audio(file, fh, p); | ||
1096 | if (!ret) | ||
1097 | dbgarg2("index=%d, name=%s, capability=%d, " | ||
1098 | "mode=%d\n",p->index, | ||
1099 | p->name,p->capability, p->mode); | ||
1100 | break; | ||
1101 | } | ||
1102 | case VIDIOC_S_AUDIO: | ||
1103 | { | ||
1104 | struct v4l2_audio *p=arg; | ||
1105 | |||
1106 | if (!vfd->vidioc_s_audio) | ||
1107 | break; | ||
1108 | dbgarg(cmd, "index=%d, name=%s, capability=%d, " | ||
1109 | "mode=%d\n", p->index, p->name, | ||
1110 | p->capability, p->mode); | ||
1111 | ret=vfd->vidioc_s_audio(file, fh, p); | ||
1112 | break; | ||
1113 | } | ||
1114 | case VIDIOC_ENUMAUDOUT: | ||
1115 | { | ||
1116 | struct v4l2_audioout *p=arg; | ||
1117 | |||
1118 | if (!vfd->vidioc_enumaudout) | ||
1119 | break; | ||
1120 | dbgarg(cmd, "Enum for index=%d\n", p->index); | ||
1121 | ret=vfd->vidioc_enumaudout(file, fh, p); | ||
1122 | if (!ret) | ||
1123 | dbgarg2("index=%d, name=%s, capability=%d, " | ||
1124 | "mode=%d\n", p->index, p->name, | ||
1125 | p->capability,p->mode); | ||
1126 | break; | ||
1127 | } | ||
1128 | case VIDIOC_G_AUDOUT: | ||
1129 | { | ||
1130 | struct v4l2_audioout *p=arg; | ||
1131 | |||
1132 | if (!vfd->vidioc_g_audout) | ||
1133 | break; | ||
1134 | dbgarg(cmd, "Enum for index=%d\n", p->index); | ||
1135 | ret=vfd->vidioc_g_audout(file, fh, p); | ||
1136 | if (!ret) | ||
1137 | dbgarg2("index=%d, name=%s, capability=%d, " | ||
1138 | "mode=%d\n", p->index, p->name, | ||
1139 | p->capability,p->mode); | ||
1140 | break; | ||
1141 | } | ||
1142 | case VIDIOC_S_AUDOUT: | ||
1143 | { | ||
1144 | struct v4l2_audioout *p=arg; | ||
1145 | |||
1146 | if (!vfd->vidioc_s_audout) | ||
1147 | break; | ||
1148 | dbgarg(cmd, "index=%d, name=%s, capability=%d, " | ||
1149 | "mode=%d\n", p->index, p->name, | ||
1150 | p->capability,p->mode); | ||
1151 | |||
1152 | ret=vfd->vidioc_s_audout(file, fh, p); | ||
1153 | break; | ||
1154 | } | ||
1155 | case VIDIOC_G_MODULATOR: | ||
1156 | { | ||
1157 | struct v4l2_modulator *p=arg; | ||
1158 | if (!vfd->vidioc_g_modulator) | ||
1159 | break; | ||
1160 | ret=vfd->vidioc_g_modulator(file, fh, p); | ||
1161 | if (!ret) | ||
1162 | dbgarg(cmd, "index=%d, name=%s, " | ||
1163 | "capability=%d, rangelow=%d," | ||
1164 | " rangehigh=%d, txsubchans=%d\n", | ||
1165 | p->index, p->name,p->capability, | ||
1166 | p->rangelow, p->rangehigh, | ||
1167 | p->txsubchans); | ||
1168 | break; | ||
1169 | } | ||
1170 | case VIDIOC_S_MODULATOR: | ||
1171 | { | ||
1172 | struct v4l2_modulator *p=arg; | ||
1173 | if (!vfd->vidioc_s_modulator) | ||
1174 | break; | ||
1175 | dbgarg(cmd, "index=%d, name=%s, capability=%d, " | ||
1176 | "rangelow=%d, rangehigh=%d, txsubchans=%d\n", | ||
1177 | p->index, p->name,p->capability,p->rangelow, | ||
1178 | p->rangehigh,p->txsubchans); | ||
1179 | ret=vfd->vidioc_s_modulator(file, fh, p); | ||
1180 | break; | ||
1181 | } | ||
1182 | case VIDIOC_G_CROP: | ||
1183 | { | ||
1184 | struct v4l2_crop *p=arg; | ||
1185 | if (!vfd->vidioc_g_crop) | ||
1186 | break; | ||
1187 | ret=vfd->vidioc_g_crop(file, fh, p); | ||
1188 | if (!ret) { | ||
1189 | dbgarg(cmd, "type=%d\n", p->type); | ||
1190 | dbgrect(vfd, "", &p->c); | ||
1191 | } | ||
1192 | break; | ||
1193 | } | ||
1194 | case VIDIOC_S_CROP: | ||
1195 | { | ||
1196 | struct v4l2_crop *p=arg; | ||
1197 | if (!vfd->vidioc_s_crop) | ||
1198 | break; | ||
1199 | dbgarg(cmd, "type=%d\n", p->type); | ||
1200 | dbgrect(vfd, "", &p->c); | ||
1201 | ret=vfd->vidioc_s_crop(file, fh, p); | ||
1202 | break; | ||
1203 | } | ||
1204 | case VIDIOC_CROPCAP: | ||
1205 | { | ||
1206 | struct v4l2_cropcap *p=arg; | ||
1207 | /*FIXME: Should also show v4l2_fract pixelaspect */ | ||
1208 | if (!vfd->vidioc_cropcap) | ||
1209 | break; | ||
1210 | dbgarg(cmd, "type=%d\n", p->type); | ||
1211 | dbgrect(vfd, "bounds ", &p->bounds); | ||
1212 | dbgrect(vfd, "defrect ", &p->defrect); | ||
1213 | ret=vfd->vidioc_cropcap(file, fh, p); | ||
1214 | break; | ||
1215 | } | ||
1216 | case VIDIOC_G_MPEGCOMP: | ||
1217 | { | ||
1218 | struct v4l2_mpeg_compression *p=arg; | ||
1219 | |||
1220 | /*FIXME: Several fields not shown */ | ||
1221 | if (!vfd->vidioc_g_mpegcomp) | ||
1222 | break; | ||
1223 | ret=vfd->vidioc_g_mpegcomp(file, fh, p); | ||
1224 | if (!ret) | ||
1225 | dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d," | ||
1226 | " ts_pid_video=%d, ts_pid_pcr=%d, " | ||
1227 | "ps_size=%d, au_sample_rate=%d, " | ||
1228 | "au_pesid=%c, vi_frame_rate=%d, " | ||
1229 | "vi_frames_per_gop=%d, " | ||
1230 | "vi_bframes_count=%d, vi_pesid=%c\n", | ||
1231 | p->ts_pid_pmt,p->ts_pid_audio, | ||
1232 | p->ts_pid_video,p->ts_pid_pcr, | ||
1233 | p->ps_size, p->au_sample_rate, | ||
1234 | p->au_pesid, p->vi_frame_rate, | ||
1235 | p->vi_frames_per_gop, | ||
1236 | p->vi_bframes_count, p->vi_pesid); | ||
1237 | break; | ||
1238 | } | ||
1239 | case VIDIOC_S_MPEGCOMP: | ||
1240 | { | ||
1241 | struct v4l2_mpeg_compression *p=arg; | ||
1242 | /*FIXME: Several fields not shown */ | ||
1243 | if (!vfd->vidioc_s_mpegcomp) | ||
1244 | break; | ||
1245 | dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, " | ||
1246 | "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, " | ||
1247 | "au_sample_rate=%d, au_pesid=%c, " | ||
1248 | "vi_frame_rate=%d, vi_frames_per_gop=%d, " | ||
1249 | "vi_bframes_count=%d, vi_pesid=%c\n", | ||
1250 | p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video, | ||
1251 | p->ts_pid_pcr, p->ps_size, p->au_sample_rate, | ||
1252 | p->au_pesid, p->vi_frame_rate, | ||
1253 | p->vi_frames_per_gop, p->vi_bframes_count, | ||
1254 | p->vi_pesid); | ||
1255 | ret=vfd->vidioc_s_mpegcomp(file, fh, p); | ||
1256 | break; | ||
1257 | } | ||
1258 | case VIDIOC_G_JPEGCOMP: | ||
1259 | { | ||
1260 | struct v4l2_jpegcompression *p=arg; | ||
1261 | if (!vfd->vidioc_g_jpegcomp) | ||
1262 | break; | ||
1263 | ret=vfd->vidioc_g_jpegcomp(file, fh, p); | ||
1264 | if (!ret) | ||
1265 | dbgarg (cmd, "quality=%d, APPn=%d, " | ||
1266 | "APP_len=%d, COM_len=%d, " | ||
1267 | "jpeg_markers=%d\n", | ||
1268 | p->quality,p->APPn,p->APP_len, | ||
1269 | p->COM_len,p->jpeg_markers); | ||
1270 | break; | ||
1271 | } | ||
1272 | case VIDIOC_S_JPEGCOMP: | ||
1273 | { | ||
1274 | struct v4l2_jpegcompression *p=arg; | ||
1275 | if (!vfd->vidioc_g_jpegcomp) | ||
1276 | break; | ||
1277 | dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, " | ||
1278 | "COM_len=%d, jpeg_markers=%d\n", | ||
1279 | p->quality,p->APPn,p->APP_len, | ||
1280 | p->COM_len,p->jpeg_markers); | ||
1281 | ret=vfd->vidioc_s_jpegcomp(file, fh, p); | ||
1282 | break; | ||
1283 | } | ||
1284 | case VIDIOC_G_PARM: | ||
1285 | { | ||
1286 | struct v4l2_streamparm *p=arg; | ||
1287 | if (!vfd->vidioc_g_parm) | ||
1288 | break; | ||
1289 | ret=vfd->vidioc_g_parm(file, fh, p); | ||
1290 | dbgarg (cmd, "type=%d\n", p->type); | ||
1291 | break; | ||
1292 | } | ||
1293 | case VIDIOC_S_PARM: | ||
1294 | { | ||
1295 | struct v4l2_streamparm *p=arg; | ||
1296 | if (!vfd->vidioc_s_parm) | ||
1297 | break; | ||
1298 | dbgarg (cmd, "type=%d\n", p->type); | ||
1299 | ret=vfd->vidioc_s_parm(file, fh, p); | ||
1300 | break; | ||
1301 | } | ||
1302 | case VIDIOC_G_TUNER: | ||
1303 | { | ||
1304 | struct v4l2_tuner *p=arg; | ||
1305 | if (!vfd->vidioc_g_tuner) | ||
1306 | break; | ||
1307 | ret=vfd->vidioc_g_tuner(file, fh, p); | ||
1308 | if (!ret) | ||
1309 | dbgarg (cmd, "index=%d, name=%s, type=%d, " | ||
1310 | "capability=%d, rangelow=%d, " | ||
1311 | "rangehigh=%d, signal=%d, afc=%d, " | ||
1312 | "rxsubchans=%d, audmode=%d\n", | ||
1313 | p->index, p->name, p->type, | ||
1314 | p->capability, p->rangelow, | ||
1315 | p->rangehigh, p->rxsubchans, | ||
1316 | p->audmode, p->signal, p->afc); | ||
1317 | break; | ||
1318 | } | ||
1319 | case VIDIOC_S_TUNER: | ||
1320 | { | ||
1321 | struct v4l2_tuner *p=arg; | ||
1322 | if (!vfd->vidioc_s_tuner) | ||
1323 | break; | ||
1324 | dbgarg (cmd, "index=%d, name=%s, type=%d, " | ||
1325 | "capability=%d, rangelow=%d, rangehigh=%d, " | ||
1326 | "signal=%d, afc=%d, rxsubchans=%d, " | ||
1327 | "audmode=%d\n",p->index, p->name, p->type, | ||
1328 | p->capability, p->rangelow,p->rangehigh, | ||
1329 | p->rxsubchans, p->audmode, p->signal, | ||
1330 | p->afc); | ||
1331 | ret=vfd->vidioc_s_tuner(file, fh, p); | ||
1332 | break; | ||
1333 | } | ||
1334 | case VIDIOC_G_FREQUENCY: | ||
1335 | { | ||
1336 | struct v4l2_frequency *p=arg; | ||
1337 | if (!vfd->vidioc_g_frequency) | ||
1338 | break; | ||
1339 | ret=vfd->vidioc_g_frequency(file, fh, p); | ||
1340 | if (!ret) | ||
1341 | dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n", | ||
1342 | p->tuner,p->type,p->frequency); | ||
1343 | break; | ||
1344 | } | ||
1345 | case VIDIOC_S_FREQUENCY: | ||
1346 | { | ||
1347 | struct v4l2_frequency *p=arg; | ||
1348 | if (!vfd->vidioc_s_frequency) | ||
1349 | break; | ||
1350 | dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n", | ||
1351 | p->tuner,p->type,p->frequency); | ||
1352 | ret=vfd->vidioc_s_frequency(file, fh, p); | ||
1353 | break; | ||
1354 | } | ||
1355 | case VIDIOC_G_SLICED_VBI_CAP: | ||
1356 | { | ||
1357 | struct v4l2_sliced_vbi_cap *p=arg; | ||
1358 | if (!vfd->vidioc_g_sliced_vbi_cap) | ||
1359 | break; | ||
1360 | ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p); | ||
1361 | if (!ret) | ||
1362 | dbgarg (cmd, "service_set=%d\n", p->service_set); | ||
1363 | break; | ||
1364 | } | ||
1365 | case VIDIOC_LOG_STATUS: | ||
1366 | { | ||
1367 | if (!vfd->vidioc_log_status) | ||
1368 | break; | ||
1369 | ret=vfd->vidioc_log_status(file, fh); | ||
1370 | break; | ||
1371 | } | ||
1372 | |||
1373 | /* --- Others --------------------------------------------- */ | ||
1374 | |||
1375 | default: | ||
1376 | ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,__video_do_ioctl); | ||
1377 | } | ||
1378 | |||
1379 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { | ||
1380 | if (ret<0) { | ||
1381 | printk ("%s: err:\n", vfd->name); | ||
1382 | v4l_print_ioctl(vfd->name, cmd); | ||
1383 | } | ||
1384 | } | ||
1385 | |||
1386 | return ret; | ||
1387 | } | ||
1388 | |||
1389 | int video_ioctl2 (struct inode *inode, struct file *file, | ||
1390 | unsigned int cmd, unsigned long arg) | ||
1391 | { | ||
1392 | char sbuf[128]; | ||
1393 | void *mbuf = NULL; | ||
1394 | void *parg = NULL; | ||
1395 | int err = -EINVAL; | ||
1396 | int is_ext_ctrl; | ||
1397 | size_t ctrls_size = 0; | ||
1398 | void __user *user_ptr = NULL; | ||
1399 | |||
1400 | #ifdef __OLD_VIDIOC_ | ||
1401 | cmd = video_fix_command(cmd); | ||
1402 | #endif | ||
1403 | is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || | ||
1404 | cmd == VIDIOC_TRY_EXT_CTRLS); | ||
1405 | |||
1406 | /* Copy arguments into temp kernel buffer */ | ||
1407 | switch (_IOC_DIR(cmd)) { | ||
1408 | case _IOC_NONE: | ||
1409 | parg = NULL; | ||
1410 | break; | ||
1411 | case _IOC_READ: | ||
1412 | case _IOC_WRITE: | ||
1413 | case (_IOC_WRITE | _IOC_READ): | ||
1414 | if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { | ||
1415 | parg = sbuf; | ||
1416 | } else { | ||
1417 | /* too big to allocate from stack */ | ||
1418 | mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); | ||
1419 | if (NULL == mbuf) | ||
1420 | return -ENOMEM; | ||
1421 | parg = mbuf; | ||
1422 | } | ||
1423 | |||
1424 | err = -EFAULT; | ||
1425 | if (_IOC_DIR(cmd) & _IOC_WRITE) | ||
1426 | if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) | ||
1427 | goto out; | ||
1428 | break; | ||
1429 | } | ||
1430 | |||
1431 | if (is_ext_ctrl) { | ||
1432 | struct v4l2_ext_controls *p = parg; | ||
1433 | |||
1434 | /* In case of an error, tell the caller that it wasn't | ||
1435 | a specific control that caused it. */ | ||
1436 | p->error_idx = p->count; | ||
1437 | user_ptr = (void __user *)p->controls; | ||
1438 | if (p->count) { | ||
1439 | ctrls_size = sizeof(struct v4l2_ext_control) * p->count; | ||
1440 | /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ | ||
1441 | mbuf = kmalloc(ctrls_size, GFP_KERNEL); | ||
1442 | err = -ENOMEM; | ||
1443 | if (NULL == mbuf) | ||
1444 | goto out_ext_ctrl; | ||
1445 | err = -EFAULT; | ||
1446 | if (copy_from_user(mbuf, user_ptr, ctrls_size)) | ||
1447 | goto out_ext_ctrl; | ||
1448 | p->controls = mbuf; | ||
1449 | } | ||
1450 | } | ||
1451 | |||
1452 | /* Handles IOCTL */ | ||
1453 | err = __video_do_ioctl(inode, file, cmd, parg); | ||
1454 | if (err == -ENOIOCTLCMD) | ||
1455 | err = -EINVAL; | ||
1456 | if (is_ext_ctrl) { | ||
1457 | struct v4l2_ext_controls *p = parg; | ||
1458 | |||
1459 | p->controls = (void *)user_ptr; | ||
1460 | if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) | ||
1461 | err = -EFAULT; | ||
1462 | goto out_ext_ctrl; | ||
1463 | } | ||
1464 | if (err < 0) | ||
1465 | goto out; | ||
1466 | |||
1467 | out_ext_ctrl: | ||
1468 | /* Copy results into user buffer */ | ||
1469 | switch (_IOC_DIR(cmd)) | ||
1470 | { | ||
1471 | case _IOC_READ: | ||
1472 | case (_IOC_WRITE | _IOC_READ): | ||
1473 | if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) | ||
1474 | err = -EFAULT; | ||
1475 | break; | ||
1476 | } | ||
1477 | |||
1478 | out: | ||
1479 | kfree(mbuf); | ||
1480 | return err; | ||
1481 | } | ||
1482 | |||
1483 | |||
245 | static struct file_operations video_fops; | 1484 | static struct file_operations video_fops; |
246 | 1485 | ||
247 | /** | 1486 | /** |
@@ -371,7 +1610,9 @@ void video_unregister_device(struct video_device *vfd) | |||
371 | mutex_unlock(&videodev_lock); | 1610 | mutex_unlock(&videodev_lock); |
372 | } | 1611 | } |
373 | 1612 | ||
374 | 1613 | /* | |
1614 | * Video fs operations | ||
1615 | */ | ||
375 | static struct file_operations video_fops= | 1616 | static struct file_operations video_fops= |
376 | { | 1617 | { |
377 | .owner = THIS_MODULE, | 1618 | .owner = THIS_MODULE, |
@@ -387,7 +1628,7 @@ static int __init videodev_init(void) | |||
387 | { | 1628 | { |
388 | int ret; | 1629 | int ret; |
389 | 1630 | ||
390 | printk(KERN_INFO "Linux video capture interface: v1.00\n"); | 1631 | printk(KERN_INFO "Linux video capture interface: v2.00\n"); |
391 | if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) { | 1632 | if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) { |
392 | printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR); | 1633 | printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR); |
393 | return -EIO; | 1634 | return -EIO; |
@@ -418,11 +1659,12 @@ EXPORT_SYMBOL(video_devdata); | |||
418 | EXPORT_SYMBOL(video_usercopy); | 1659 | EXPORT_SYMBOL(video_usercopy); |
419 | EXPORT_SYMBOL(video_exclusive_open); | 1660 | EXPORT_SYMBOL(video_exclusive_open); |
420 | EXPORT_SYMBOL(video_exclusive_release); | 1661 | EXPORT_SYMBOL(video_exclusive_release); |
1662 | EXPORT_SYMBOL(video_ioctl2); | ||
421 | EXPORT_SYMBOL(video_device_alloc); | 1663 | EXPORT_SYMBOL(video_device_alloc); |
422 | EXPORT_SYMBOL(video_device_release); | 1664 | EXPORT_SYMBOL(video_device_release); |
423 | 1665 | ||
424 | MODULE_AUTHOR("Alan Cox"); | 1666 | MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>"); |
425 | MODULE_DESCRIPTION("Device registrar for Video4Linux drivers"); | 1667 | MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); |
426 | MODULE_LICENSE("GPL"); | 1668 | MODULE_LICENSE("GPL"); |
427 | 1669 | ||
428 | 1670 | ||
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index a8c101494cf5..268e69fdefc6 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <linux/i2c-algo-sgi.h> | 40 | #include <linux/i2c-algo-sgi.h> |
41 | 41 | ||
42 | #include <linux/videodev.h> | 42 | #include <linux/videodev.h> |
43 | #include <linux/videodev2.h> | 43 | #include <media/v4l2-common.h> |
44 | #include <linux/video_decoder.h> | 44 | #include <linux/video_decoder.h> |
45 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
46 | 46 | ||
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 779db26771c0..41d23c8acbd8 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -48,34 +48,15 @@ | |||
48 | 48 | ||
49 | #include "font.h" | 49 | #include "font.h" |
50 | 50 | ||
51 | #ifndef kzalloc | ||
52 | #define kzalloc(size, flags) \ | ||
53 | ({ \ | ||
54 | void *__ret = kmalloc(size, flags); \ | ||
55 | if (__ret) \ | ||
56 | memset(__ret, 0, size); \ | ||
57 | __ret; \ | ||
58 | }) | ||
59 | #endif | ||
60 | |||
61 | MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); | ||
62 | MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); | ||
63 | MODULE_LICENSE("Dual BSD/GPL"); | ||
64 | |||
65 | #define VIVI_MAJOR_VERSION 0 | 51 | #define VIVI_MAJOR_VERSION 0 |
66 | #define VIVI_MINOR_VERSION 4 | 52 | #define VIVI_MINOR_VERSION 4 |
67 | #define VIVI_RELEASE 0 | 53 | #define VIVI_RELEASE 0 |
68 | #define VIVI_VERSION KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) | 54 | #define VIVI_VERSION KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) |
69 | 55 | ||
70 | static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ | 56 | /* Declare static vars that will be used as parameters */ |
71 | module_param(video_nr, int, 0); | 57 | static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ |
72 | 58 | static struct video_device vivi; /* Video device */ | |
73 | static int debug = 0; | 59 | static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ |
74 | module_param(debug, int, 0); | ||
75 | |||
76 | static unsigned int vid_limit = 16; | ||
77 | module_param(vid_limit,int,0644); | ||
78 | MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); | ||
79 | 60 | ||
80 | /* supported controls */ | 61 | /* supported controls */ |
81 | static struct v4l2_queryctrl vivi_qctrl[] = { | 62 | static struct v4l2_queryctrl vivi_qctrl[] = { |
@@ -129,10 +110,10 @@ static struct v4l2_queryctrl vivi_qctrl[] = { | |||
129 | 110 | ||
130 | static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; | 111 | static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; |
131 | 112 | ||
132 | #define dprintk(level,fmt, arg...) \ | 113 | #define dprintk(level,fmt, arg...) \ |
133 | do { \ | 114 | do { \ |
134 | if (debug >= (level)) \ | 115 | if (vivi.debug >= (level)) \ |
135 | printk(KERN_DEBUG "vivi: " fmt , ## arg); \ | 116 | printk(KERN_DEBUG "vivi: " fmt , ## arg); \ |
136 | } while (0) | 117 | } while (0) |
137 | 118 | ||
138 | /* ------------------------------------------------------------------ | 119 | /* ------------------------------------------------------------------ |
@@ -190,7 +171,7 @@ struct vivi_dev { | |||
190 | 171 | ||
191 | /* various device info */ | 172 | /* various device info */ |
192 | unsigned int resources; | 173 | unsigned int resources; |
193 | struct video_device video_dev; | 174 | struct video_device vfd; |
194 | 175 | ||
195 | struct vivi_dmaqueue vidq; | 176 | struct vivi_dmaqueue vidq; |
196 | 177 | ||
@@ -248,7 +229,8 @@ static u8 bars[8][3] = { | |||
248 | #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 | 229 | #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 |
249 | #define TSTAMP_MIN_X 64 | 230 | #define TSTAMP_MIN_X 64 |
250 | 231 | ||
251 | void prep_to_addr(struct sg_to_addr to_addr[],struct videobuf_buffer *vb) | 232 | static void prep_to_addr(struct sg_to_addr to_addr[], |
233 | struct videobuf_buffer *vb) | ||
252 | { | 234 | { |
253 | int i, pos=0; | 235 | int i, pos=0; |
254 | 236 | ||
@@ -259,7 +241,7 @@ void prep_to_addr(struct sg_to_addr to_addr[],struct videobuf_buffer *vb) | |||
259 | } | 241 | } |
260 | } | 242 | } |
261 | 243 | ||
262 | inline int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) | 244 | static int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) |
263 | { | 245 | { |
264 | int p1=0,p2=pages-1,p3=pages/2; | 246 | int p1=0,p2=pages-1,p3=pages/2; |
265 | 247 | ||
@@ -280,8 +262,8 @@ inline int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) | |||
280 | return (p1); | 262 | return (p1); |
281 | } | 263 | } |
282 | 264 | ||
283 | void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, | 265 | static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, |
284 | int hmax, int line, char *timestr) | 266 | int hmax, int line, char *timestr) |
285 | { | 267 | { |
286 | int w,i,j,pos=inipos,pgpos,oldpg,y; | 268 | int w,i,j,pos=inipos,pgpos,oldpg,y; |
287 | char *p,*s,*basep; | 269 | char *p,*s,*basep; |
@@ -491,7 +473,7 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) | |||
491 | dprintk(1,"%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc); | 473 | dprintk(1,"%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc); |
492 | } | 474 | } |
493 | 475 | ||
494 | void vivi_sleep(struct vivi_dmaqueue *dma_q) | 476 | static void vivi_sleep(struct vivi_dmaqueue *dma_q) |
495 | { | 477 | { |
496 | int timeout; | 478 | int timeout; |
497 | DECLARE_WAITQUEUE(wait, current); | 479 | DECLARE_WAITQUEUE(wait, current); |
@@ -526,7 +508,7 @@ void vivi_sleep(struct vivi_dmaqueue *dma_q) | |||
526 | try_to_freeze(); | 508 | try_to_freeze(); |
527 | } | 509 | } |
528 | 510 | ||
529 | int vivi_thread(void *data) | 511 | static int vivi_thread(void *data) |
530 | { | 512 | { |
531 | struct vivi_dmaqueue *dma_q=data; | 513 | struct vivi_dmaqueue *dma_q=data; |
532 | 514 | ||
@@ -542,7 +524,7 @@ int vivi_thread(void *data) | |||
542 | return 0; | 524 | return 0; |
543 | } | 525 | } |
544 | 526 | ||
545 | int vivi_start_thread(struct vivi_dmaqueue *dma_q) | 527 | static int vivi_start_thread(struct vivi_dmaqueue *dma_q) |
546 | { | 528 | { |
547 | dma_q->frame=0; | 529 | dma_q->frame=0; |
548 | dma_q->ini_jiffies=jiffies; | 530 | dma_q->ini_jiffies=jiffies; |
@@ -560,7 +542,7 @@ int vivi_start_thread(struct vivi_dmaqueue *dma_q) | |||
560 | return 0; | 542 | return 0; |
561 | } | 543 | } |
562 | 544 | ||
563 | void vivi_stop_thread(struct vivi_dmaqueue *dma_q) | 545 | static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) |
564 | { | 546 | { |
565 | dprintk(1,"%s\n",__FUNCTION__); | 547 | dprintk(1,"%s\n",__FUNCTION__); |
566 | /* shutdown control thread */ | 548 | /* shutdown control thread */ |
@@ -666,8 +648,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
666 | return 0; | 648 | return 0; |
667 | } | 649 | } |
668 | 650 | ||
669 | void | 651 | static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) |
670 | free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) | ||
671 | { | 652 | { |
672 | dprintk(1,"%s\n",__FUNCTION__); | 653 | dprintk(1,"%s\n",__FUNCTION__); |
673 | 654 | ||
@@ -791,8 +772,8 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb | |||
791 | free_buffer(vq,buf); | 772 | free_buffer(vq,buf); |
792 | } | 773 | } |
793 | 774 | ||
794 | int vivi_map_sg (void *dev, struct scatterlist *sg, int nents, | 775 | static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents, |
795 | int direction) | 776 | int direction) |
796 | { | 777 | { |
797 | int i; | 778 | int i; |
798 | 779 | ||
@@ -808,15 +789,15 @@ int vivi_map_sg (void *dev, struct scatterlist *sg, int nents, | |||
808 | return nents; | 789 | return nents; |
809 | } | 790 | } |
810 | 791 | ||
811 | int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages, | 792 | static int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages, |
812 | int direction) | 793 | int direction) |
813 | { | 794 | { |
814 | dprintk(1,"%s\n",__FUNCTION__); | 795 | dprintk(1,"%s\n",__FUNCTION__); |
815 | return 0; | 796 | return 0; |
816 | } | 797 | } |
817 | 798 | ||
818 | int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist,int nr_pages, | 799 | static int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist, int nr_pages, |
819 | int direction) | 800 | int direction) |
820 | { | 801 | { |
821 | // dprintk(1,"%s\n",__FUNCTION__); | 802 | // dprintk(1,"%s\n",__FUNCTION__); |
822 | 803 | ||
@@ -840,7 +821,80 @@ static struct videobuf_queue_ops vivi_video_qops = { | |||
840 | IOCTL handling | 821 | IOCTL handling |
841 | ------------------------------------------------------------------*/ | 822 | ------------------------------------------------------------------*/ |
842 | 823 | ||
843 | static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh, | 824 | |
825 | static int res_get(struct vivi_dev *dev, struct vivi_fh *fh) | ||
826 | { | ||
827 | /* is it free? */ | ||
828 | down(&dev->lock); | ||
829 | if (dev->resources) { | ||
830 | /* no, someone else uses it */ | ||
831 | up(&dev->lock); | ||
832 | return 0; | ||
833 | } | ||
834 | /* it's free, grab it */ | ||
835 | dev->resources =1; | ||
836 | dprintk(1,"res: get\n"); | ||
837 | up(&dev->lock); | ||
838 | return 1; | ||
839 | } | ||
840 | |||
841 | static int res_locked(struct vivi_dev *dev) | ||
842 | { | ||
843 | return (dev->resources); | ||
844 | } | ||
845 | |||
846 | static void res_free(struct vivi_dev *dev, struct vivi_fh *fh) | ||
847 | { | ||
848 | down(&dev->lock); | ||
849 | dev->resources = 0; | ||
850 | dprintk(1,"res: put\n"); | ||
851 | up(&dev->lock); | ||
852 | } | ||
853 | |||
854 | /* ------------------------------------------------------------------ | ||
855 | IOCTL vidioc handling | ||
856 | ------------------------------------------------------------------*/ | ||
857 | static int vidioc_querycap (struct file *file, void *priv, | ||
858 | struct v4l2_capability *cap) | ||
859 | { | ||
860 | strcpy(cap->driver, "vivi"); | ||
861 | strcpy(cap->card, "vivi"); | ||
862 | cap->version = VIVI_VERSION; | ||
863 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | | ||
864 | V4L2_CAP_STREAMING | | ||
865 | V4L2_CAP_READWRITE; | ||
866 | return 0; | ||
867 | } | ||
868 | |||
869 | static int vidioc_enum_fmt_cap (struct file *file, void *priv, | ||
870 | struct v4l2_fmtdesc *f) | ||
871 | { | ||
872 | if (f->index > 0) | ||
873 | return -EINVAL; | ||
874 | |||
875 | strlcpy(f->description,format.name,sizeof(f->description)); | ||
876 | f->pixelformat = format.fourcc; | ||
877 | return 0; | ||
878 | } | ||
879 | |||
880 | static int vidioc_g_fmt_cap (struct file *file, void *priv, | ||
881 | struct v4l2_format *f) | ||
882 | { | ||
883 | struct vivi_fh *fh=priv; | ||
884 | |||
885 | f->fmt.pix.width = fh->width; | ||
886 | f->fmt.pix.height = fh->height; | ||
887 | f->fmt.pix.field = fh->vb_vidq.field; | ||
888 | f->fmt.pix.pixelformat = fh->fmt->fourcc; | ||
889 | f->fmt.pix.bytesperline = | ||
890 | (f->fmt.pix.width * fh->fmt->depth) >> 3; | ||
891 | f->fmt.pix.sizeimage = | ||
892 | f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
893 | |||
894 | return (0); | ||
895 | } | ||
896 | |||
897 | static int vidioc_try_fmt_cap (struct file *file, void *priv, | ||
844 | struct v4l2_format *f) | 898 | struct v4l2_format *f) |
845 | { | 899 | { |
846 | struct vivi_fmt *fmt; | 900 | struct vivi_fmt *fmt; |
@@ -848,7 +902,8 @@ static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh, | |||
848 | unsigned int maxw, maxh; | 902 | unsigned int maxw, maxh; |
849 | 903 | ||
850 | if (format.fourcc != f->fmt.pix.pixelformat) { | 904 | if (format.fourcc != f->fmt.pix.pixelformat) { |
851 | dprintk(1,"Fourcc format invalid.\n"); | 905 | dprintk(1,"Fourcc format (0x%08x) invalid. Driver accepts " |
906 | "only 0x%08x\n",f->fmt.pix.pixelformat,format.fourcc); | ||
852 | return -EINVAL; | 907 | return -EINVAL; |
853 | } | 908 | } |
854 | fmt=&format; | 909 | fmt=&format; |
@@ -884,356 +939,196 @@ static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh, | |||
884 | return 0; | 939 | return 0; |
885 | } | 940 | } |
886 | 941 | ||
887 | static int res_get(struct vivi_dev *dev, struct vivi_fh *fh) | 942 | /*FIXME: This seems to be generic enough to be at videodev2 */ |
943 | static int vidioc_s_fmt_cap (struct file *file, void *priv, | ||
944 | struct v4l2_format *f) | ||
888 | { | 945 | { |
889 | /* is it free? */ | 946 | struct vivi_fh *fh=priv; |
890 | down(&dev->lock); | 947 | int ret = vidioc_try_fmt_cap(file,fh,f); |
891 | if (dev->resources) { | 948 | if (ret < 0) |
892 | /* no, someone else uses it */ | 949 | return (ret); |
893 | up(&dev->lock); | 950 | |
894 | return 0; | 951 | fh->fmt = &format; |
895 | } | 952 | fh->width = f->fmt.pix.width; |
896 | /* it's free, grab it */ | 953 | fh->height = f->fmt.pix.height; |
897 | dev->resources =1; | 954 | fh->vb_vidq.field = f->fmt.pix.field; |
898 | dprintk(1,"res: get\n"); | 955 | fh->type = f->type; |
899 | up(&dev->lock); | 956 | |
900 | return 1; | 957 | return (0); |
901 | } | 958 | } |
902 | 959 | ||
903 | static inline int res_locked(struct vivi_dev *dev) | 960 | static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p) |
904 | { | 961 | { |
905 | return (dev->resources); | 962 | struct vivi_fh *fh=priv; |
906 | } | ||
907 | 963 | ||
908 | static void res_free(struct vivi_dev *dev, struct vivi_fh *fh) | 964 | return (videobuf_reqbufs(&fh->vb_vidq, p)); |
909 | { | ||
910 | down(&dev->lock); | ||
911 | dev->resources = 0; | ||
912 | dprintk(1,"res: put\n"); | ||
913 | up(&dev->lock); | ||
914 | } | 965 | } |
915 | 966 | ||
916 | static int vivi_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) | 967 | static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p) |
917 | { | 968 | { |
918 | struct vivi_fh *fh = file->private_data; | 969 | struct vivi_fh *fh=priv; |
919 | struct vivi_dev *dev = fh->dev; | ||
920 | int ret=0; | ||
921 | 970 | ||
922 | if (debug) { | 971 | return (videobuf_querybuf(&fh->vb_vidq, p)); |
923 | if (_IOC_DIR(cmd) & _IOC_WRITE) | 972 | } |
924 | v4l_printk_ioctl_arg("vivi(w)",cmd, arg); | ||
925 | else if (!_IOC_DIR(cmd) & _IOC_READ) { | ||
926 | v4l_print_ioctl("vivi", cmd); | ||
927 | } | ||
928 | } | ||
929 | 973 | ||
930 | switch(cmd) { | 974 | static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p) |
931 | /* --- capabilities ------------------------------------------ */ | 975 | { |
932 | case VIDIOC_QUERYCAP: | 976 | struct vivi_fh *fh=priv; |
933 | { | ||
934 | struct v4l2_capability *cap = (struct v4l2_capability*)arg; | ||
935 | |||
936 | memset(cap, 0, sizeof(*cap)); | ||
937 | |||
938 | strcpy(cap->driver, "vivi"); | ||
939 | strcpy(cap->card, "vivi"); | ||
940 | cap->version = VIVI_VERSION; | ||
941 | cap->capabilities = | ||
942 | V4L2_CAP_VIDEO_CAPTURE | | ||
943 | V4L2_CAP_STREAMING | | ||
944 | V4L2_CAP_READWRITE; | ||
945 | break; | ||
946 | } | ||
947 | /* --- capture ioctls ---------------------------------------- */ | ||
948 | case VIDIOC_ENUM_FMT: | ||
949 | { | ||
950 | struct v4l2_fmtdesc *f = arg; | ||
951 | enum v4l2_buf_type type; | ||
952 | unsigned int index; | ||
953 | 977 | ||
954 | index = f->index; | 978 | return (videobuf_qbuf(&fh->vb_vidq, p)); |
955 | type = f->type; | 979 | } |
956 | 980 | ||
957 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 981 | static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p) |
958 | ret=-EINVAL; | 982 | { |
959 | break; | 983 | struct vivi_fh *fh=priv; |
960 | } | ||
961 | 984 | ||
962 | switch (type) { | 985 | return (videobuf_dqbuf(&fh->vb_vidq, p, |
963 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 986 | file->f_flags & O_NONBLOCK)); |
964 | if (index > 0){ | 987 | } |
965 | ret=-EINVAL; | ||
966 | break; | ||
967 | } | ||
968 | memset(f,0,sizeof(*f)); | ||
969 | 988 | ||
970 | f->index = index; | 989 | #ifdef HAVE_V4L1 |
971 | f->type = type; | 990 | static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf) |
972 | strlcpy(f->description,format.name,sizeof(f->description)); | 991 | { |
973 | f->pixelformat = format.fourcc; | 992 | struct vivi_fh *fh=priv; |
974 | break; | 993 | struct videobuf_queue *q=&fh->vb_vidq; |
975 | default: | 994 | struct v4l2_requestbuffers req; |
976 | ret=-EINVAL; | 995 | unsigned int i, ret; |
977 | } | 996 | |
978 | break; | 997 | req.type = q->type; |
998 | req.count = 8; | ||
999 | req.memory = V4L2_MEMORY_MMAP; | ||
1000 | ret = videobuf_reqbufs(q,&req); | ||
1001 | if (ret < 0) | ||
1002 | return (ret); | ||
1003 | |||
1004 | mbuf->frames = req.count; | ||
1005 | mbuf->size = 0; | ||
1006 | for (i = 0; i < mbuf->frames; i++) { | ||
1007 | mbuf->offsets[i] = q->bufs[i]->boff; | ||
1008 | mbuf->size += q->bufs[i]->bsize; | ||
979 | } | 1009 | } |
980 | case VIDIOC_G_FMT: | 1010 | return (0); |
981 | { | 1011 | } |
982 | struct v4l2_format *f = (struct v4l2_format *)arg; | 1012 | #endif |
983 | 1013 | ||
984 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1014 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) |
985 | ret=-EINVAL; | 1015 | { |
986 | break; | 1016 | struct vivi_fh *fh=priv; |
987 | } | 1017 | struct vivi_dev *dev = fh->dev; |
988 | 1018 | ||
989 | memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); | 1019 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
990 | f->fmt.pix.width = fh->width; | 1020 | return -EINVAL; |
991 | f->fmt.pix.height = fh->height; | 1021 | if (i != fh->type) |
992 | f->fmt.pix.field = fh->vb_vidq.field; | 1022 | return -EINVAL; |
993 | f->fmt.pix.pixelformat = fh->fmt->fourcc; | ||
994 | f->fmt.pix.bytesperline = | ||
995 | (f->fmt.pix.width * fh->fmt->depth) >> 3; | ||
996 | f->fmt.pix.sizeimage = | ||
997 | f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
998 | break; | ||
999 | } | ||
1000 | case VIDIOC_S_FMT: | ||
1001 | { | ||
1002 | struct v4l2_format *f = arg; | ||
1003 | 1023 | ||
1004 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1024 | if (!res_get(dev,fh)) |
1005 | dprintk(1,"Only capture supported.\n"); | 1025 | return -EBUSY; |
1006 | ret=-EINVAL; | 1026 | return (videobuf_streamon(&fh->vb_vidq)); |
1007 | break; | 1027 | } |
1008 | } | ||
1009 | 1028 | ||
1010 | ret = vivi_try_fmt(dev,fh,f); | 1029 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) |
1011 | if (ret < 0) | 1030 | { |
1012 | break; | 1031 | struct vivi_fh *fh=priv; |
1032 | struct vivi_dev *dev = fh->dev; | ||
1013 | 1033 | ||
1014 | fh->fmt = &format; | 1034 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1015 | fh->width = f->fmt.pix.width; | 1035 | return -EINVAL; |
1016 | fh->height = f->fmt.pix.height; | 1036 | if (i != fh->type) |
1017 | fh->vb_vidq.field = f->fmt.pix.field; | 1037 | return -EINVAL; |
1018 | fh->type = f->type; | ||
1019 | 1038 | ||
1020 | break; | 1039 | videobuf_streamoff(&fh->vb_vidq); |
1021 | } | 1040 | res_free(dev,fh); |
1022 | case VIDIOC_TRY_FMT: | ||
1023 | { | ||
1024 | struct v4l2_format *f = arg; | ||
1025 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1026 | ret=-EINVAL; | ||
1027 | break; | ||
1028 | } | ||
1029 | 1041 | ||
1030 | ret=vivi_try_fmt(dev,fh,f); | 1042 | return (0); |
1031 | break; | 1043 | } |
1032 | } | 1044 | |
1033 | case VIDIOC_REQBUFS: | 1045 | static struct v4l2_tvnorm tvnorms[] = { |
1034 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1035 | ret=-EINVAL; | ||
1036 | break; | ||
1037 | } | ||
1038 | ret=videobuf_reqbufs(&fh->vb_vidq, arg); | ||
1039 | break; | ||
1040 | case VIDIOC_QUERYBUF: | ||
1041 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1042 | ret=-EINVAL; | ||
1043 | break; | ||
1044 | } | ||
1045 | ret=videobuf_querybuf(&fh->vb_vidq, arg); | ||
1046 | break; | ||
1047 | case VIDIOC_QBUF: | ||
1048 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1049 | ret=-EINVAL; | ||
1050 | break; | ||
1051 | } | ||
1052 | ret=videobuf_qbuf(&fh->vb_vidq, arg); | ||
1053 | break; | ||
1054 | case VIDIOC_DQBUF: | ||
1055 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1056 | ret=-EINVAL; | ||
1057 | break; | ||
1058 | } | ||
1059 | ret=videobuf_dqbuf(&fh->vb_vidq, arg, | ||
1060 | file->f_flags & O_NONBLOCK); | ||
1061 | break; | ||
1062 | #ifdef HAVE_V4L1 | ||
1063 | /* --- streaming capture ------------------------------------- */ | ||
1064 | case VIDIOCGMBUF: | ||
1065 | { | ||
1066 | struct video_mbuf *mbuf = arg; | ||
1067 | struct videobuf_queue *q=&fh->vb_vidq; | ||
1068 | struct v4l2_requestbuffers req; | ||
1069 | unsigned int i; | ||
1070 | |||
1071 | memset(&req,0,sizeof(req)); | ||
1072 | req.type = q->type; | ||
1073 | req.count = 8; | ||
1074 | req.memory = V4L2_MEMORY_MMAP; | ||
1075 | ret = videobuf_reqbufs(q,&req); | ||
1076 | if (ret < 0) | ||
1077 | break; | ||
1078 | memset(mbuf,0,sizeof(*mbuf)); | ||
1079 | mbuf->frames = req.count; | ||
1080 | mbuf->size = 0; | ||
1081 | for (i = 0; i < mbuf->frames; i++) { | ||
1082 | mbuf->offsets[i] = q->bufs[i]->boff; | ||
1083 | mbuf->size += q->bufs[i]->bsize; | ||
1084 | } | ||
1085 | break; | ||
1086 | } | ||
1087 | #endif | ||
1088 | case VIDIOC_STREAMON: | ||
1089 | { | ||
1090 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1091 | return -EINVAL; | ||
1092 | if (!res_get(dev,fh)) | ||
1093 | return -EBUSY; | ||
1094 | ret=videobuf_streamon(&fh->vb_vidq); | ||
1095 | break; | ||
1096 | } | ||
1097 | case VIDIOC_STREAMOFF: | ||
1098 | { | 1046 | { |
1099 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1047 | .name = "NTSC-M", |
1100 | ret=-EINVAL; | 1048 | .id = V4L2_STD_NTSC_M, |
1101 | break; | ||
1102 | } | ||
1103 | ret = videobuf_streamoff(&fh->vb_vidq); | ||
1104 | if (ret < 0) | ||
1105 | break; | ||
1106 | res_free(dev,fh); | ||
1107 | break; | ||
1108 | } | 1049 | } |
1109 | /* ---------- tv norms ---------- */ | 1050 | }; |
1110 | case VIDIOC_ENUMSTD: | ||
1111 | { | ||
1112 | struct v4l2_standard *e = arg; | ||
1113 | 1051 | ||
1114 | if (e->index>0) { | 1052 | static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id a) |
1115 | ret=-EINVAL; | 1053 | { |
1116 | break; | ||
1117 | } | ||
1118 | ret = v4l2_video_std_construct(e, V4L2_STD_NTSC_M, "NTSC-M"); | ||
1119 | 1054 | ||
1120 | /* Allows vivi to use different fps from video std */ | 1055 | return 0; |
1121 | e->frameperiod.numerator = WAKE_NUMERATOR; | 1056 | } |
1122 | e->frameperiod.denominator = WAKE_DENOMINATOR; | ||
1123 | 1057 | ||
1124 | break; | 1058 | /* only one input in this sample driver */ |
1125 | } | 1059 | static int vidioc_enum_input (struct file *file, void *priv, |
1126 | case VIDIOC_G_STD: | 1060 | struct v4l2_input *inp) |
1127 | { | 1061 | { |
1128 | v4l2_std_id *id = arg; | 1062 | if (inp->index != 0) |
1063 | return -EINVAL; | ||
1129 | 1064 | ||
1130 | *id = V4L2_STD_NTSC_M; | 1065 | inp->type = V4L2_INPUT_TYPE_CAMERA; |
1131 | break; | 1066 | inp->std = V4L2_STD_NTSC_M; |
1132 | } | 1067 | strcpy(inp->name,"Camera"); |
1133 | case VIDIOC_S_STD: | ||
1134 | { | ||
1135 | break; | ||
1136 | } | ||
1137 | /* ------ input switching ---------- */ | ||
1138 | case VIDIOC_ENUMINPUT: | ||
1139 | { /* only one input in this sample driver */ | ||
1140 | struct v4l2_input *inp = arg; | ||
1141 | 1068 | ||
1142 | if (inp->index != 0) { | 1069 | return (0); |
1143 | ret=-EINVAL; | 1070 | } |
1144 | break; | ||
1145 | } | ||
1146 | memset(inp, 0, sizeof(*inp)); | ||
1147 | 1071 | ||
1148 | inp->index = 0; | 1072 | static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) |
1149 | inp->type = V4L2_INPUT_TYPE_CAMERA; | 1073 | { |
1150 | inp->std = V4L2_STD_NTSC_M; | 1074 | *i = 0; |
1151 | strcpy(inp->name,"Camera"); | ||
1152 | break; | ||
1153 | } | ||
1154 | case VIDIOC_G_INPUT: | ||
1155 | { | ||
1156 | unsigned int *i = arg; | ||
1157 | 1075 | ||
1158 | *i = 0; | 1076 | return (0); |
1159 | break; | 1077 | } |
1160 | } | 1078 | static int vidioc_s_input (struct file *file, void *priv, unsigned int i) |
1161 | case VIDIOC_S_INPUT: | 1079 | { |
1162 | { | 1080 | if (i > 0) |
1163 | unsigned int *i = arg; | 1081 | return -EINVAL; |
1164 | 1082 | ||
1165 | if (*i > 0) | 1083 | return (0); |
1166 | ret=-EINVAL; | 1084 | } |
1167 | break; | ||
1168 | } | ||
1169 | 1085 | ||
1170 | /* --- controls ---------------------------------------------- */ | 1086 | /* --- controls ---------------------------------------------- */ |
1171 | case VIDIOC_QUERYCTRL: | 1087 | static int vidioc_queryctrl (struct file *file, void *priv, |
1172 | { | 1088 | struct v4l2_queryctrl *qc) |
1173 | struct v4l2_queryctrl *qc = arg; | 1089 | { |
1174 | int i; | 1090 | int i; |
1175 | |||
1176 | for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) | ||
1177 | if (qc->id && qc->id == vivi_qctrl[i].id) { | ||
1178 | memcpy(qc, &(vivi_qctrl[i]), | ||
1179 | sizeof(*qc)); | ||
1180 | break; | ||
1181 | } | ||
1182 | 1091 | ||
1183 | ret=-EINVAL; | 1092 | for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) |
1184 | break; | 1093 | if (qc->id && qc->id == vivi_qctrl[i].id) { |
1185 | } | 1094 | memcpy(qc, &(vivi_qctrl[i]), |
1186 | case VIDIOC_G_CTRL: | 1095 | sizeof(*qc)); |
1187 | { | 1096 | return (0); |
1188 | struct v4l2_control *ctrl = arg; | 1097 | } |
1189 | int i; | ||
1190 | 1098 | ||
1191 | for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) | 1099 | return -EINVAL; |
1192 | if (ctrl->id == vivi_qctrl[i].id) { | 1100 | } |
1193 | ctrl->value=qctl_regs[i]; | ||
1194 | break; | ||
1195 | } | ||
1196 | 1101 | ||
1197 | ret=-EINVAL; | 1102 | static int vidioc_g_ctrl (struct file *file, void *priv, |
1198 | break; | 1103 | struct v4l2_control *ctrl) |
1199 | } | 1104 | { |
1200 | case VIDIOC_S_CTRL: | 1105 | int i; |
1201 | { | ||
1202 | struct v4l2_control *ctrl = arg; | ||
1203 | int i; | ||
1204 | for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) | ||
1205 | if (ctrl->id == vivi_qctrl[i].id) { | ||
1206 | if (ctrl->value < | ||
1207 | vivi_qctrl[i].minimum | ||
1208 | || ctrl->value > | ||
1209 | vivi_qctrl[i].maximum) { | ||
1210 | ret=-ERANGE; | ||
1211 | break; | ||
1212 | } | ||
1213 | qctl_regs[i]=ctrl->value; | ||
1214 | break; | ||
1215 | } | ||
1216 | ret=-EINVAL; | ||
1217 | break; | ||
1218 | } | ||
1219 | default: | ||
1220 | ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,vivi_do_ioctl); | ||
1221 | } | ||
1222 | 1106 | ||
1223 | if (debug) { | 1107 | for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) |
1224 | if (ret<0) { | 1108 | if (ctrl->id == vivi_qctrl[i].id) { |
1225 | v4l_print_ioctl("vivi(err)", cmd); | 1109 | ctrl->value=qctl_regs[i]; |
1226 | dprintk(1,"errcode=%d\n",ret); | 1110 | return (0); |
1227 | } else if (_IOC_DIR(cmd) & _IOC_READ) | 1111 | } |
1228 | v4l_printk_ioctl_arg("vivi(r)",cmd, arg); | ||
1229 | } | ||
1230 | 1112 | ||
1231 | return ret; | 1113 | return -EINVAL; |
1232 | } | 1114 | } |
1233 | 1115 | static int vidioc_s_ctrl (struct file *file, void *priv, | |
1234 | static int vivi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 1116 | struct v4l2_control *ctrl) |
1235 | { | 1117 | { |
1236 | return video_usercopy(inode, file, cmd, arg, vivi_do_ioctl); | 1118 | int i; |
1119 | |||
1120 | for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) | ||
1121 | if (ctrl->id == vivi_qctrl[i].id) { | ||
1122 | if (ctrl->value < | ||
1123 | vivi_qctrl[i].minimum | ||
1124 | || ctrl->value > | ||
1125 | vivi_qctrl[i].maximum) { | ||
1126 | return (-ERANGE); | ||
1127 | } | ||
1128 | qctl_regs[i]=ctrl->value; | ||
1129 | return (0); | ||
1130 | } | ||
1131 | return -EINVAL; | ||
1237 | } | 1132 | } |
1238 | 1133 | ||
1239 | /* ------------------------------------------------------------------ | 1134 | /* ------------------------------------------------------------------ |
@@ -1255,7 +1150,7 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1255 | 1150 | ||
1256 | list_for_each(list,&vivi_devlist) { | 1151 | list_for_each(list,&vivi_devlist) { |
1257 | h = list_entry(list, struct vivi_dev, vivi_devlist); | 1152 | h = list_entry(list, struct vivi_dev, vivi_devlist); |
1258 | if (h->video_dev.minor == minor) { | 1153 | if (h->vfd.minor == minor) { |
1259 | dev = h; | 1154 | dev = h; |
1260 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1155 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1261 | } | 1156 | } |
@@ -1264,6 +1159,7 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1264 | return -ENODEV; | 1159 | return -ENODEV; |
1265 | 1160 | ||
1266 | 1161 | ||
1162 | |||
1267 | /* If more than one user, mutex should be added */ | 1163 | /* If more than one user, mutex should be added */ |
1268 | dev->users++; | 1164 | dev->users++; |
1269 | 1165 | ||
@@ -1279,6 +1175,7 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1279 | 1175 | ||
1280 | file->private_data = fh; | 1176 | file->private_data = fh; |
1281 | fh->dev = dev; | 1177 | fh->dev = dev; |
1178 | |||
1282 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1179 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1283 | fh->fmt = &format; | 1180 | fh->fmt = &format; |
1284 | fh->width = 640; | 1181 | fh->width = 640; |
@@ -1314,7 +1211,7 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1314 | static ssize_t | 1211 | static ssize_t |
1315 | vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) | 1212 | vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) |
1316 | { | 1213 | { |
1317 | struct vivi_fh *fh = file->private_data; | 1214 | struct vivi_fh *fh = file->private_data; |
1318 | 1215 | ||
1319 | if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1216 | if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1320 | if (res_locked(fh->dev)) | 1217 | if (res_locked(fh->dev)) |
@@ -1328,8 +1225,8 @@ vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) | |||
1328 | static unsigned int | 1225 | static unsigned int |
1329 | vivi_poll(struct file *file, struct poll_table_struct *wait) | 1226 | vivi_poll(struct file *file, struct poll_table_struct *wait) |
1330 | { | 1227 | { |
1331 | struct vivi_fh *fh = file->private_data; | 1228 | struct vivi_fh *fh = file->private_data; |
1332 | struct vivi_buffer *buf; | 1229 | struct vivi_buffer *buf; |
1333 | 1230 | ||
1334 | dprintk(1,"%s\n",__FUNCTION__); | 1231 | dprintk(1,"%s\n",__FUNCTION__); |
1335 | 1232 | ||
@@ -1358,8 +1255,8 @@ vivi_poll(struct file *file, struct poll_table_struct *wait) | |||
1358 | 1255 | ||
1359 | static int vivi_release(struct inode *inode, struct file *file) | 1256 | static int vivi_release(struct inode *inode, struct file *file) |
1360 | { | 1257 | { |
1361 | struct vivi_fh *fh = file->private_data; | 1258 | struct vivi_fh *fh = file->private_data; |
1362 | struct vivi_dev *dev = fh->dev; | 1259 | struct vivi_dev *dev = fh->dev; |
1363 | struct vivi_dmaqueue *vidq = &dev->vidq; | 1260 | struct vivi_dmaqueue *vidq = &dev->vidq; |
1364 | 1261 | ||
1365 | int minor = iminor(inode); | 1262 | int minor = iminor(inode); |
@@ -1379,7 +1276,7 @@ static int vivi_release(struct inode *inode, struct file *file) | |||
1379 | static int | 1276 | static int |
1380 | vivi_mmap(struct file *file, struct vm_area_struct * vma) | 1277 | vivi_mmap(struct file *file, struct vm_area_struct * vma) |
1381 | { | 1278 | { |
1382 | struct vivi_fh *fh = file->private_data; | 1279 | struct vivi_fh *fh = file->private_data; |
1383 | int ret; | 1280 | int ret; |
1384 | 1281 | ||
1385 | dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma); | 1282 | dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma); |
@@ -1400,20 +1297,44 @@ static struct file_operations vivi_fops = { | |||
1400 | .release = vivi_release, | 1297 | .release = vivi_release, |
1401 | .read = vivi_read, | 1298 | .read = vivi_read, |
1402 | .poll = vivi_poll, | 1299 | .poll = vivi_poll, |
1403 | .ioctl = vivi_ioctl, | 1300 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
1404 | .mmap = vivi_mmap, | 1301 | .mmap = vivi_mmap, |
1405 | .llseek = no_llseek, | 1302 | .llseek = no_llseek, |
1406 | }; | 1303 | }; |
1407 | 1304 | ||
1408 | static struct video_device vivi = { | 1305 | static struct video_device vivi = { |
1409 | .name = "VTM Virtual Video Capture Board", | 1306 | .name = "vivi", |
1410 | .type = VID_TYPE_CAPTURE, | 1307 | .type = VID_TYPE_CAPTURE, |
1411 | .hardware = 0, | 1308 | .hardware = 0, |
1412 | .fops = &vivi_fops, | 1309 | .fops = &vivi_fops, |
1413 | .minor = -1, | 1310 | .minor = -1, |
1414 | // .release = video_device_release, | 1311 | // .release = video_device_release, |
1312 | |||
1313 | .vidioc_querycap = vidioc_querycap, | ||
1314 | .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, | ||
1315 | .vidioc_g_fmt_cap = vidioc_g_fmt_cap, | ||
1316 | .vidioc_try_fmt_cap = vidioc_try_fmt_cap, | ||
1317 | .vidioc_s_fmt_cap = vidioc_s_fmt_cap, | ||
1318 | .vidioc_reqbufs = vidioc_reqbufs, | ||
1319 | .vidioc_querybuf = vidioc_querybuf, | ||
1320 | .vidioc_qbuf = vidioc_qbuf, | ||
1321 | .vidioc_dqbuf = vidioc_dqbuf, | ||
1322 | .vidioc_s_std = vidioc_s_std, | ||
1323 | .vidioc_enum_input = vidioc_enum_input, | ||
1324 | .vidioc_g_input = vidioc_g_input, | ||
1325 | .vidioc_s_input = vidioc_s_input, | ||
1326 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1327 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1328 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1329 | .vidioc_streamon = vidioc_streamon, | ||
1330 | .vidioc_streamoff = vidioc_streamoff, | ||
1331 | #ifdef HAVE_V4L1 | ||
1332 | .vidiocgmbuf = vidiocgmbuf, | ||
1333 | #endif | ||
1334 | .tvnorms = tvnorms, | ||
1335 | .tvnormsize = ARRAY_SIZE(tvnorms), | ||
1415 | }; | 1336 | }; |
1416 | /* ------------------------------------------------------------------ | 1337 | /* ----------------------------------------------------------------- |
1417 | Initialization and module stuff | 1338 | Initialization and module stuff |
1418 | ------------------------------------------------------------------*/ | 1339 | ------------------------------------------------------------------*/ |
1419 | 1340 | ||
@@ -1457,3 +1378,16 @@ static void __exit vivi_exit(void) | |||
1457 | 1378 | ||
1458 | module_init(vivi_init); | 1379 | module_init(vivi_init); |
1459 | module_exit(vivi_exit); | 1380 | module_exit(vivi_exit); |
1381 | |||
1382 | MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); | ||
1383 | MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); | ||
1384 | MODULE_LICENSE("Dual BSD/GPL"); | ||
1385 | |||
1386 | module_param(video_nr, int, 0); | ||
1387 | |||
1388 | module_param_named(debug,vivi.debug, int, 0644); | ||
1389 | MODULE_PARM_DESC(debug,"activates debug info"); | ||
1390 | |||
1391 | module_param(vid_limit,int,0644); | ||
1392 | MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); | ||
1393 | |||
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 40b205b91481..1eca7e65d235 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #define I2C_NAME(x) (x)->name | 34 | #define I2C_NAME(x) (x)->name |
35 | 35 | ||
36 | #include <linux/videodev.h> | 36 | #include <linux/videodev.h> |
37 | #include <media/v4l2-common.h> | ||
37 | #include <linux/video_decoder.h> | 38 | #include <linux/video_decoder.h> |
38 | 39 | ||
39 | #define I2C_VPX3220 0x86 | 40 | #define I2C_VPX3220 0x86 |
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 80ef8a1b8f63..4bdc886abc4c 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/init.h> | 58 | #include <linux/init.h> |
59 | #include <linux/delay.h> | 59 | #include <linux/delay.h> |
60 | #include <linux/videodev.h> | 60 | #include <linux/videodev.h> |
61 | #include <media/v4l2-common.h> | ||
61 | #include <linux/parport.h> | 62 | #include <linux/parport.h> |
62 | 63 | ||
63 | //#define DEBUG // Undef me for production | 64 | //#define DEBUG // Undef me for production |
diff --git a/drivers/media/video/zc0301/Kconfig b/drivers/media/video/zc0301/Kconfig index 115833e4f4dd..a859a6920189 100644 --- a/drivers/media/video/zc0301/Kconfig +++ b/drivers/media/video/zc0301/Kconfig | |||
@@ -1,9 +1,9 @@ | |||
1 | config USB_ZC0301 | 1 | config USB_ZC0301 |
2 | tristate "USB ZC0301 Image Processor and Control Chip support" | 2 | tristate "USB ZC0301[P] Image Processor and Control Chip support" |
3 | depends on USB && VIDEO_V4L1 | 3 | depends on USB && VIDEO_V4L1 |
4 | ---help--- | 4 | ---help--- |
5 | Say Y here if you want support for cameras based on the ZC0301 | 5 | Say Y here if you want support for cameras based on the ZC0301 or |
6 | Image Processor and Control Chip. | 6 | ZC0301P Image Processors and Control Chips. |
7 | 7 | ||
8 | See <file:Documentation/video4linux/zc0301.txt> for more info. | 8 | See <file:Documentation/video4linux/zc0301.txt> for more info. |
9 | 9 | ||
diff --git a/drivers/media/video/zc0301/Makefile b/drivers/media/video/zc0301/Makefile index d749199d8f06..d9e6d97fade6 100644 --- a/drivers/media/video/zc0301/Makefile +++ b/drivers/media/video/zc0301/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | zc0301-objs := zc0301_core.o zc0301_pas202bcb.o | 1 | zc0301-objs := zc0301_core.o zc0301_pb0330.o zc0301_pas202bcb.o |
2 | 2 | ||
3 | obj-$(CONFIG_USB_ZC0301) += zc0301.o | 3 | obj-$(CONFIG_USB_ZC0301) += zc0301.o |
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index 0fad39754f7a..1b2be2d2a3ec 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | * Video4Linux2 driver for ZC0301 Image Processor and Control Chip * | 2 | * Video4Linux2 driver for ZC0301[P] Image Processor and Control Chip * |
3 | * * | 3 | * * |
4 | * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * | 4 | * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * |
5 | * * | 5 | * * |
@@ -47,13 +47,13 @@ | |||
47 | 47 | ||
48 | /*****************************************************************************/ | 48 | /*****************************************************************************/ |
49 | 49 | ||
50 | #define ZC0301_MODULE_NAME "V4L2 driver for ZC0301 " \ | 50 | #define ZC0301_MODULE_NAME "V4L2 driver for ZC0301[P] " \ |
51 | "Image Processor and Control Chip" | 51 | "Image Processor and Control Chip" |
52 | #define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia" | 52 | #define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia" |
53 | #define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" | 53 | #define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" |
54 | #define ZC0301_MODULE_LICENSE "GPL" | 54 | #define ZC0301_MODULE_LICENSE "GPL" |
55 | #define ZC0301_MODULE_VERSION "1:1.03" | 55 | #define ZC0301_MODULE_VERSION "1:1.05" |
56 | #define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 3) | 56 | #define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 5) |
57 | 57 | ||
58 | /*****************************************************************************/ | 58 | /*****************************************************************************/ |
59 | 59 | ||
@@ -427,10 +427,11 @@ resubmit_urb: | |||
427 | static int zc0301_start_transfer(struct zc0301_device* cam) | 427 | static int zc0301_start_transfer(struct zc0301_device* cam) |
428 | { | 428 | { |
429 | struct usb_device *udev = cam->usbdev; | 429 | struct usb_device *udev = cam->usbdev; |
430 | struct usb_host_interface* altsetting = usb_altnum_to_altsetting( | ||
431 | usb_ifnum_to_if(udev, 0), | ||
432 | ZC0301_ALTERNATE_SETTING); | ||
433 | const unsigned int psz = altsetting->endpoint[0].desc.wMaxPacketSize; | ||
430 | struct urb* urb; | 434 | struct urb* urb; |
431 | const unsigned int wMaxPacketSize[] = {0, 128, 192, 256, 384, | ||
432 | 512, 768, 1023}; | ||
433 | const unsigned int psz = wMaxPacketSize[ZC0301_ALTERNATE_SETTING]; | ||
434 | s8 i, j; | 435 | s8 i, j; |
435 | int err = 0; | 436 | int err = 0; |
436 | 437 | ||
@@ -1772,11 +1773,9 @@ static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
1772 | case VIDIOC_G_CTRL: | 1773 | case VIDIOC_G_CTRL: |
1773 | return zc0301_vidioc_g_ctrl(cam, arg); | 1774 | return zc0301_vidioc_g_ctrl(cam, arg); |
1774 | 1775 | ||
1775 | case VIDIOC_S_CTRL_OLD: | ||
1776 | case VIDIOC_S_CTRL: | 1776 | case VIDIOC_S_CTRL: |
1777 | return zc0301_vidioc_s_ctrl(cam, arg); | 1777 | return zc0301_vidioc_s_ctrl(cam, arg); |
1778 | 1778 | ||
1779 | case VIDIOC_CROPCAP_OLD: | ||
1780 | case VIDIOC_CROPCAP: | 1779 | case VIDIOC_CROPCAP: |
1781 | return zc0301_vidioc_cropcap(cam, arg); | 1780 | return zc0301_vidioc_cropcap(cam, arg); |
1782 | 1781 | ||
@@ -1823,7 +1822,6 @@ static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
1823 | case VIDIOC_G_PARM: | 1822 | case VIDIOC_G_PARM: |
1824 | return zc0301_vidioc_g_parm(cam, arg); | 1823 | return zc0301_vidioc_g_parm(cam, arg); |
1825 | 1824 | ||
1826 | case VIDIOC_S_PARM_OLD: | ||
1827 | case VIDIOC_S_PARM: | 1825 | case VIDIOC_S_PARM: |
1828 | return zc0301_vidioc_s_parm(cam, arg); | 1826 | return zc0301_vidioc_s_parm(cam, arg); |
1829 | 1827 | ||
@@ -1914,7 +1912,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
1914 | 1912 | ||
1915 | mutex_init(&cam->dev_mutex); | 1913 | mutex_init(&cam->dev_mutex); |
1916 | 1914 | ||
1917 | DBG(2, "ZC0301 Image Processor and Control Chip detected " | 1915 | DBG(2, "ZC0301[P] Image Processor and Control Chip detected " |
1918 | "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct); | 1916 | "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct); |
1919 | 1917 | ||
1920 | for (i = 0; zc0301_sensor_table[i]; i++) { | 1918 | for (i = 0; zc0301_sensor_table[i]; i++) { |
@@ -1936,7 +1934,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
1936 | cam->state |= DEV_MISCONFIGURED; | 1934 | cam->state |= DEV_MISCONFIGURED; |
1937 | } | 1935 | } |
1938 | 1936 | ||
1939 | strcpy(cam->v4ldev->name, "ZC0301 PC Camera"); | 1937 | strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera"); |
1940 | cam->v4ldev->owner = THIS_MODULE; | 1938 | cam->v4ldev->owner = THIS_MODULE; |
1941 | cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; | 1939 | cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; |
1942 | cam->v4ldev->hardware = 0; | 1940 | cam->v4ldev->hardware = 0; |
diff --git a/drivers/media/video/zc0301/zc0301_pas202bcb.c b/drivers/media/video/zc0301/zc0301_pas202bcb.c index eaadf0252049..ecfd39a56df1 100644 --- a/drivers/media/video/zc0301/zc0301_pas202bcb.c +++ b/drivers/media/video/zc0301/zc0301_pas202bcb.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | * Plug-in for PAS202BCB image sensor connected to the ZC030! Image * | 2 | * Plug-in for PAS202BCB image sensor connected to the ZC0301[P] Image * |
3 | * Processor and Control Chip * | 3 | * Processor and Control Chip * |
4 | * * | 4 | * * |
5 | * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * | 5 | * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * |
6 | * * | 6 | * * |
7 | * Initialization values of the ZC0301 have been taken from the SPCA5XX * | 7 | * Initialization values of the ZC0301[P] have been taken from the SPCA5XX * |
8 | * driver maintained by Michel Xhaard <mxhaard@magic.fr> * | 8 | * driver maintained by Michel Xhaard <mxhaard@magic.fr> * |
9 | * * | 9 | * * |
10 | * This program is free software; you can redistribute it and/or modify * | 10 | * This program is free software; you can redistribute it and/or modify * |
diff --git a/drivers/media/video/zc0301/zc0301_pb0330.c b/drivers/media/video/zc0301/zc0301_pb0330.c new file mode 100644 index 000000000000..ed8542e6c50f --- /dev/null +++ b/drivers/media/video/zc0301/zc0301_pb0330.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /*************************************************************************** | ||
2 | * Plug-in for PB-0330 image sensor connected to the ZC0301[P] Image * | ||
3 | * Processor and Control Chip * | ||
4 | * * | ||
5 | * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * | ||
6 | * * | ||
7 | * Initialization values of the ZC0301[P] have been taken from the SPCA5XX * | ||
8 | * driver maintained by Michel Xhaard <mxhaard@magic.fr> * | ||
9 | * * | ||
10 | * This program is free software; you can redistribute it and/or modify * | ||
11 | * it under the terms of the GNU General Public License as published by * | ||
12 | * the Free Software Foundation; either version 2 of the License, or * | ||
13 | * (at your option) any later version. * | ||
14 | * * | ||
15 | * This program is distributed in the hope that it will be useful, * | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
18 | * GNU General Public License for more details. * | ||
19 | * * | ||
20 | * You should have received a copy of the GNU General Public License * | ||
21 | * along with this program; if not, write to the Free Software * | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | ||
23 | ***************************************************************************/ | ||
24 | |||
25 | #include <linux/delay.h> | ||
26 | #include "zc0301_sensor.h" | ||
27 | |||
28 | |||
29 | static struct zc0301_sensor pb0330; | ||
30 | |||
31 | |||
32 | static int pb0330_init(struct zc0301_device* cam) | ||
33 | { | ||
34 | int err = 0; | ||
35 | |||
36 | err += zc0301_write_reg(cam, 0x0000, 0x01); | ||
37 | err += zc0301_write_reg(cam, 0x0008, 0x03); | ||
38 | err += zc0301_write_reg(cam, 0x0010, 0x0A); | ||
39 | err += zc0301_write_reg(cam, 0x0002, 0x00); | ||
40 | err += zc0301_write_reg(cam, 0x0003, 0x02); | ||
41 | err += zc0301_write_reg(cam, 0x0004, 0x80); | ||
42 | err += zc0301_write_reg(cam, 0x0005, 0x01); | ||
43 | err += zc0301_write_reg(cam, 0x0006, 0xE0); | ||
44 | err += zc0301_write_reg(cam, 0x0001, 0x01); | ||
45 | err += zc0301_write_reg(cam, 0x0012, 0x05); | ||
46 | err += zc0301_write_reg(cam, 0x0012, 0x07); | ||
47 | err += zc0301_write_reg(cam, 0x0098, 0x00); | ||
48 | err += zc0301_write_reg(cam, 0x009A, 0x00); | ||
49 | err += zc0301_write_reg(cam, 0x011A, 0x00); | ||
50 | err += zc0301_write_reg(cam, 0x011C, 0x00); | ||
51 | err += zc0301_write_reg(cam, 0x0012, 0x05); | ||
52 | |||
53 | err += zc0301_i2c_write(cam, 0x01, 0x0006); | ||
54 | err += zc0301_i2c_write(cam, 0x02, 0x0011); | ||
55 | err += zc0301_i2c_write(cam, 0x03, 0x01E7); | ||
56 | err += zc0301_i2c_write(cam, 0x04, 0x0287); | ||
57 | err += zc0301_i2c_write(cam, 0x06, 0x0003); | ||
58 | err += zc0301_i2c_write(cam, 0x07, 0x3002); | ||
59 | err += zc0301_i2c_write(cam, 0x20, 0x1100); | ||
60 | err += zc0301_i2c_write(cam, 0x2F, 0xF7B0); | ||
61 | err += zc0301_i2c_write(cam, 0x30, 0x0005); | ||
62 | err += zc0301_i2c_write(cam, 0x31, 0x0000); | ||
63 | err += zc0301_i2c_write(cam, 0x34, 0x0100); | ||
64 | err += zc0301_i2c_write(cam, 0x35, 0x0060); | ||
65 | err += zc0301_i2c_write(cam, 0x3D, 0x068F); | ||
66 | err += zc0301_i2c_write(cam, 0x40, 0x01E0); | ||
67 | err += zc0301_i2c_write(cam, 0x58, 0x0078); | ||
68 | err += zc0301_i2c_write(cam, 0x62, 0x0411); | ||
69 | |||
70 | err += zc0301_write_reg(cam, 0x0087, 0x10); | ||
71 | err += zc0301_write_reg(cam, 0x0101, 0x37); | ||
72 | err += zc0301_write_reg(cam, 0x0012, 0x05); | ||
73 | err += zc0301_write_reg(cam, 0x0100, 0x0D); | ||
74 | err += zc0301_write_reg(cam, 0x0189, 0x06); | ||
75 | err += zc0301_write_reg(cam, 0x01AD, 0x00); | ||
76 | err += zc0301_write_reg(cam, 0x01C5, 0x03); | ||
77 | err += zc0301_write_reg(cam, 0x01CB, 0x13); | ||
78 | err += zc0301_write_reg(cam, 0x0250, 0x08); | ||
79 | err += zc0301_write_reg(cam, 0x0301, 0x08); | ||
80 | err += zc0301_write_reg(cam, 0x01A8, 0x60); | ||
81 | err += zc0301_write_reg(cam, 0x018D, 0x6C); | ||
82 | err += zc0301_write_reg(cam, 0x01AD, 0x09); | ||
83 | err += zc0301_write_reg(cam, 0x01AE, 0x15); | ||
84 | err += zc0301_write_reg(cam, 0x010A, 0x50); | ||
85 | err += zc0301_write_reg(cam, 0x010B, 0xF8); | ||
86 | err += zc0301_write_reg(cam, 0x010C, 0xF8); | ||
87 | err += zc0301_write_reg(cam, 0x010D, 0xF8); | ||
88 | err += zc0301_write_reg(cam, 0x010E, 0x50); | ||
89 | err += zc0301_write_reg(cam, 0x010F, 0xF8); | ||
90 | err += zc0301_write_reg(cam, 0x0110, 0xF8); | ||
91 | err += zc0301_write_reg(cam, 0x0111, 0xF8); | ||
92 | err += zc0301_write_reg(cam, 0x0112, 0x50); | ||
93 | err += zc0301_write_reg(cam, 0x0008, 0x03); | ||
94 | err += zc0301_write_reg(cam, 0x01C6, 0x08); | ||
95 | err += zc0301_write_reg(cam, 0x01CB, 0x0F); | ||
96 | err += zc0301_write_reg(cam, 0x010A, 0x50); | ||
97 | err += zc0301_write_reg(cam, 0x010B, 0xF8); | ||
98 | err += zc0301_write_reg(cam, 0x010C, 0xF8); | ||
99 | err += zc0301_write_reg(cam, 0x010D, 0xF8); | ||
100 | err += zc0301_write_reg(cam, 0x010E, 0x50); | ||
101 | err += zc0301_write_reg(cam, 0x010F, 0xF8); | ||
102 | err += zc0301_write_reg(cam, 0x0110, 0xF8); | ||
103 | err += zc0301_write_reg(cam, 0x0111, 0xF8); | ||
104 | err += zc0301_write_reg(cam, 0x0112, 0x50); | ||
105 | err += zc0301_write_reg(cam, 0x0180, 0x00); | ||
106 | err += zc0301_write_reg(cam, 0x0019, 0x00); | ||
107 | |||
108 | err += zc0301_i2c_write(cam, 0x05, 0x0066); | ||
109 | err += zc0301_i2c_write(cam, 0x09, 0x02B2); | ||
110 | err += zc0301_i2c_write(cam, 0x10, 0x0002); | ||
111 | |||
112 | err += zc0301_write_reg(cam, 0x011D, 0x60); | ||
113 | err += zc0301_write_reg(cam, 0x0190, 0x00); | ||
114 | err += zc0301_write_reg(cam, 0x0191, 0x07); | ||
115 | err += zc0301_write_reg(cam, 0x0192, 0x8C); | ||
116 | err += zc0301_write_reg(cam, 0x0195, 0x00); | ||
117 | err += zc0301_write_reg(cam, 0x0196, 0x00); | ||
118 | err += zc0301_write_reg(cam, 0x0197, 0x8A); | ||
119 | err += zc0301_write_reg(cam, 0x018C, 0x10); | ||
120 | err += zc0301_write_reg(cam, 0x018F, 0x20); | ||
121 | err += zc0301_write_reg(cam, 0x01A9, 0x14); | ||
122 | err += zc0301_write_reg(cam, 0x01AA, 0x24); | ||
123 | err += zc0301_write_reg(cam, 0x001D, 0xD7); | ||
124 | err += zc0301_write_reg(cam, 0x001E, 0xF0); | ||
125 | err += zc0301_write_reg(cam, 0x001F, 0xF8); | ||
126 | err += zc0301_write_reg(cam, 0x0020, 0xFF); | ||
127 | err += zc0301_write_reg(cam, 0x01AD, 0x09); | ||
128 | err += zc0301_write_reg(cam, 0x01AE, 0x15); | ||
129 | err += zc0301_write_reg(cam, 0x0180, 0x40); | ||
130 | err += zc0301_write_reg(cam, 0x0180, 0x42); | ||
131 | |||
132 | msleep(100); | ||
133 | |||
134 | return err; | ||
135 | } | ||
136 | |||
137 | |||
138 | static struct zc0301_sensor pb0330 = { | ||
139 | .name = "PB-0330", | ||
140 | .init = &pb0330_init, | ||
141 | .cropcap = { | ||
142 | .bounds = { | ||
143 | .left = 0, | ||
144 | .top = 0, | ||
145 | .width = 640, | ||
146 | .height = 480, | ||
147 | }, | ||
148 | .defrect = { | ||
149 | .left = 0, | ||
150 | .top = 0, | ||
151 | .width = 640, | ||
152 | .height = 480, | ||
153 | }, | ||
154 | }, | ||
155 | .pix_format = { | ||
156 | .width = 640, | ||
157 | .height = 480, | ||
158 | .pixelformat = V4L2_PIX_FMT_JPEG, | ||
159 | .priv = 8, | ||
160 | }, | ||
161 | }; | ||
162 | |||
163 | |||
164 | int zc0301_probe_pb0330(struct zc0301_device* cam) | ||
165 | { | ||
166 | int r0, err = 0; | ||
167 | |||
168 | err += zc0301_write_reg(cam, 0x0000, 0x01); | ||
169 | err += zc0301_write_reg(cam, 0x0010, 0x0a); | ||
170 | err += zc0301_write_reg(cam, 0x0001, 0x01); | ||
171 | err += zc0301_write_reg(cam, 0x0012, 0x03); | ||
172 | err += zc0301_write_reg(cam, 0x0012, 0x01); | ||
173 | |||
174 | msleep(10); | ||
175 | |||
176 | r0 = zc0301_i2c_read(cam, 0x00, 2); | ||
177 | |||
178 | if (r0 < 0 || err) | ||
179 | return -EIO; | ||
180 | |||
181 | if (r0 != 0x8243) | ||
182 | return -ENODEV; | ||
183 | |||
184 | zc0301_attach_sensor(cam, &pb0330); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h index 1f95c28b1015..4363a915b1f4 100644 --- a/drivers/media/video/zc0301/zc0301_sensor.h +++ b/drivers/media/video/zc0301/zc0301_sensor.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | * API for image sensors connected to the ZC030! Image Processor and * | 2 | * API for image sensors connected to the ZC0301 Image Processor and * |
3 | * Control Chip * | 3 | * Control Chip * |
4 | * * | 4 | * * |
5 | * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * | 5 | * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * |
@@ -35,11 +35,13 @@ struct zc0301_sensor; | |||
35 | /*****************************************************************************/ | 35 | /*****************************************************************************/ |
36 | 36 | ||
37 | extern int zc0301_probe_pas202bcb(struct zc0301_device* cam); | 37 | extern int zc0301_probe_pas202bcb(struct zc0301_device* cam); |
38 | extern int zc0301_probe_pb0330(struct zc0301_device* cam); | ||
38 | 39 | ||
39 | #define ZC0301_SENSOR_TABLE \ | 40 | #define ZC0301_SENSOR_TABLE \ |
40 | /* Weak detections must go at the end of the list */ \ | 41 | /* Weak detections must go at the end of the list */ \ |
41 | static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \ | 42 | static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \ |
42 | &zc0301_probe_pas202bcb, \ | 43 | &zc0301_probe_pas202bcb, \ |
44 | &zc0301_probe_pb0330, \ | ||
43 | NULL, \ | 45 | NULL, \ |
44 | }; | 46 | }; |
45 | 47 | ||
@@ -58,14 +60,28 @@ zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor); | |||
58 | 60 | ||
59 | #define ZC0301_ID_TABLE \ | 61 | #define ZC0301_ID_TABLE \ |
60 | static const struct usb_device_id zc0301_id_table[] = { \ | 62 | static const struct usb_device_id zc0301_id_table[] = { \ |
61 | { ZC0301_USB_DEVICE(0x041e, 0x4017, 0xff), }, \ | 63 | { ZC0301_USB_DEVICE(0x041e, 0x4017, 0xff), }, /* ICM105 */ \ |
62 | { ZC0301_USB_DEVICE(0x041e, 0x401c, 0xff), }, /* PAS106 */ \ | 64 | { ZC0301_USB_DEVICE(0x041e, 0x401c, 0xff), }, /* PAS106 */ \ |
63 | { ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131B */ \ | 65 | { ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131 */ \ |
66 | { ZC0301_USB_DEVICE(0x041e, 0x401f, 0xff), }, /* TAS5130 */ \ | ||
67 | { ZC0301_USB_DEVICE(0x041e, 0x4022, 0xff), }, \ | ||
64 | { ZC0301_USB_DEVICE(0x041e, 0x4034, 0xff), }, /* PAS106 */ \ | 68 | { ZC0301_USB_DEVICE(0x041e, 0x4034, 0xff), }, /* PAS106 */ \ |
65 | { ZC0301_USB_DEVICE(0x041e, 0x4035, 0xff), }, /* PAS106 */ \ | 69 | { ZC0301_USB_DEVICE(0x041e, 0x4035, 0xff), }, /* PAS106 */ \ |
66 | { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \ | 70 | { ZC0301_USB_DEVICE(0x041e, 0x4036, 0xff), }, /* HV7131 */ \ |
71 | { ZC0301_USB_DEVICE(0x041e, 0x403a, 0xff), }, /* HV7131 */ \ | ||
72 | { ZC0301_USB_DEVICE(0x0458, 0x7007, 0xff), }, /* TAS5130 */ \ | ||
73 | { ZC0301_USB_DEVICE(0x0458, 0x700C, 0xff), }, /* TAS5130 */ \ | ||
74 | { ZC0301_USB_DEVICE(0x0458, 0x700f, 0xff), }, /* TAS5130 */ \ | ||
75 | { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ | ||
76 | { ZC0301_USB_DEVICE(0x055f, 0xd003, 0xff), }, /* TAS5130 */ \ | ||
77 | { ZC0301_USB_DEVICE(0x055f, 0xd004, 0xff), }, /* TAS5130 */ \ | ||
78 | { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ | ||
67 | { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \ | 79 | { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \ |
68 | { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130D */ \ | 80 | { ZC0301_USB_DEVICE(0x0ac8, 0x301b, 0xff), }, /* PB-0330/HV7131 */ \ |
81 | { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \ | ||
82 | { ZC0301_USB_DEVICE(0x10fd, 0x0128, 0xff), }, /* TAS5130 */ \ | ||
83 | { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130 */ \ | ||
84 | { ZC0301_USB_DEVICE(0x10fd, 0x804e, 0xff), }, /* TAS5130 */ \ | ||
69 | { } \ | 85 | { } \ |
70 | }; | 86 | }; |
71 | 87 | ||
diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h index 0166f555a5ca..ffcda95ed9d4 100644 --- a/drivers/media/video/zoran.h +++ b/drivers/media/video/zoran.h | |||
@@ -159,7 +159,7 @@ Private IOCTL to set up for displaying MJPEG | |||
159 | #define BUZ_MAX_FRAME 256 /* Must be a power of 2 */ | 159 | #define BUZ_MAX_FRAME 256 /* Must be a power of 2 */ |
160 | #define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */ | 160 | #define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */ |
161 | 161 | ||
162 | #define BUZ_MAX_INPUT 8 | 162 | #define BUZ_MAX_INPUT 16 |
163 | 163 | ||
164 | #if VIDEO_MAX_FRAME <= 32 | 164 | #if VIDEO_MAX_FRAME <= 32 |
165 | # define V4L_MAX_FRAME 32 | 165 | # define V4L_MAX_FRAME 32 |
@@ -191,6 +191,9 @@ enum card_type { | |||
191 | /* Iomega */ | 191 | /* Iomega */ |
192 | BUZ, | 192 | BUZ, |
193 | 193 | ||
194 | /* AverMedia */ | ||
195 | AVS6EYES, | ||
196 | |||
194 | /* total number of cards */ | 197 | /* total number of cards */ |
195 | NUM_CARDS | 198 | NUM_CARDS |
196 | }; | 199 | }; |
@@ -379,6 +382,9 @@ struct card_info { | |||
379 | /* is the /GWS line conected? */ | 382 | /* is the /GWS line conected? */ |
380 | u8 gws_not_connected; | 383 | u8 gws_not_connected; |
381 | 384 | ||
385 | /* avs6eyes mux setting */ | ||
386 | u8 input_mux; | ||
387 | |||
382 | void (*init) (struct zoran * zr); | 388 | void (*init) (struct zoran * zr); |
383 | }; | 389 | }; |
384 | 390 | ||
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c index 0a85c9e7fb48..958c1e6fc852 100644 --- a/drivers/media/video/zoran_card.c +++ b/drivers/media/video/zoran_card.c | |||
@@ -27,6 +27,8 @@ | |||
27 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 27 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/delay.h> | ||
31 | |||
30 | #include <linux/config.h> | 32 | #include <linux/config.h> |
31 | #include <linux/types.h> | 33 | #include <linux/types.h> |
32 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
@@ -38,6 +40,7 @@ | |||
38 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
39 | #include <linux/i2c-algo-bit.h> | 41 | #include <linux/i2c-algo-bit.h> |
40 | #include <linux/videodev.h> | 42 | #include <linux/videodev.h> |
43 | #include <media/v4l2-common.h> | ||
41 | #include <linux/spinlock.h> | 44 | #include <linux/spinlock.h> |
42 | #include <linux/sem.h> | 45 | #include <linux/sem.h> |
43 | #include <linux/kmod.h> | 46 | #include <linux/kmod.h> |
@@ -93,6 +96,11 @@ module_param(default_input, int, 0); | |||
93 | MODULE_PARM_DESC(default_input, | 96 | MODULE_PARM_DESC(default_input, |
94 | "Default input (0=Composite, 1=S-Video, 2=Internal)"); | 97 | "Default input (0=Composite, 1=S-Video, 2=Internal)"); |
95 | 98 | ||
99 | static int default_mux = 1; /* 6 Eyes input selection */ | ||
100 | module_param(default_mux, int, 0); | ||
101 | MODULE_PARM_DESC(default_mux, | ||
102 | "Default 6 Eyes mux setting (Input selection)"); | ||
103 | |||
96 | static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */ | 104 | static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */ |
97 | module_param(default_norm, int, 0); | 105 | module_param(default_norm, int, 0); |
98 | MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); | 106 | MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); |
@@ -301,6 +309,30 @@ lml33_init (struct zoran *zr) | |||
301 | GPIO(zr, 2, 1); // Set Composite input/output | 309 | GPIO(zr, 2, 1); // Set Composite input/output |
302 | } | 310 | } |
303 | 311 | ||
312 | static void | ||
313 | avs6eyes_init (struct zoran *zr) | ||
314 | { | ||
315 | // AverMedia 6-Eyes original driver by Christer Weinigel | ||
316 | |||
317 | // Lifted straight from Christer's old driver and | ||
318 | // modified slightly by Martin Samuelsson. | ||
319 | |||
320 | int mux = default_mux; /* 1 = BT866, 7 = VID1 */ | ||
321 | |||
322 | GPIO(zr, 4, 1); /* Bt866 SLEEP on */ | ||
323 | udelay(2); | ||
324 | |||
325 | GPIO(zr, 0, 1); /* ZR36060 /RESET on */ | ||
326 | GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */ | ||
327 | GPIO(zr, 2, mux & 1); /* MUX S0 */ | ||
328 | GPIO(zr, 3, 0); /* /FRAME on */ | ||
329 | GPIO(zr, 4, 0); /* Bt866 SLEEP off */ | ||
330 | GPIO(zr, 5, mux & 2); /* MUX S1 */ | ||
331 | GPIO(zr, 6, 0); /* ? */ | ||
332 | GPIO(zr, 7, mux & 4); /* MUX S2 */ | ||
333 | |||
334 | } | ||
335 | |||
304 | static char * | 336 | static char * |
305 | i2cid_to_modulename (u16 i2c_id) | 337 | i2cid_to_modulename (u16 i2c_id) |
306 | { | 338 | { |
@@ -391,6 +423,14 @@ static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 }; | |||
391 | static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 }; | 423 | static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 }; |
392 | static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 }; | 424 | static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 }; |
393 | 425 | ||
426 | /* FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I | ||
427 | * copy Maxim's left shift hack for the 6 Eyes. | ||
428 | * | ||
429 | * Christer's driver used the unshifted norms, though... | ||
430 | * /Sam */ | ||
431 | static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 }; | ||
432 | static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 }; | ||
433 | |||
394 | static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | 434 | static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { |
395 | { | 435 | { |
396 | .type = DC10_old, | 436 | .type = DC10_old, |
@@ -419,6 +459,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
419 | .gpcs = { -1, 0 }, | 459 | .gpcs = { -1, 0 }, |
420 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | 460 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, |
421 | .gws_not_connected = 0, | 461 | .gws_not_connected = 0, |
462 | .input_mux = 0, | ||
422 | .init = &dc10_init, | 463 | .init = &dc10_init, |
423 | }, { | 464 | }, { |
424 | .type = DC10_new, | 465 | .type = DC10_new, |
@@ -445,6 +486,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
445 | .gpcs = { -1, 1}, | 486 | .gpcs = { -1, 1}, |
446 | .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, | 487 | .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, |
447 | .gws_not_connected = 0, | 488 | .gws_not_connected = 0, |
489 | .input_mux = 0, | ||
448 | .init = &dc10plus_init, | 490 | .init = &dc10plus_init, |
449 | }, { | 491 | }, { |
450 | .type = DC10plus, | 492 | .type = DC10plus, |
@@ -474,6 +516,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
474 | .gpcs = { -1, 1 }, | 516 | .gpcs = { -1, 1 }, |
475 | .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, | 517 | .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, |
476 | .gws_not_connected = 0, | 518 | .gws_not_connected = 0, |
519 | .input_mux = 0, | ||
477 | .init = &dc10plus_init, | 520 | .init = &dc10plus_init, |
478 | }, { | 521 | }, { |
479 | .type = DC30, | 522 | .type = DC30, |
@@ -502,6 +545,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
502 | .gpcs = { -1, 0 }, | 545 | .gpcs = { -1, 0 }, |
503 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | 546 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, |
504 | .gws_not_connected = 0, | 547 | .gws_not_connected = 0, |
548 | .input_mux = 0, | ||
505 | .init = &dc10_init, | 549 | .init = &dc10_init, |
506 | }, { | 550 | }, { |
507 | .type = DC30plus, | 551 | .type = DC30plus, |
@@ -532,6 +576,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
532 | .gpcs = { -1, 0 }, | 576 | .gpcs = { -1, 0 }, |
533 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | 577 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, |
534 | .gws_not_connected = 0, | 578 | .gws_not_connected = 0, |
579 | .input_mux = 0, | ||
535 | .init = &dc10_init, | 580 | .init = &dc10_init, |
536 | }, { | 581 | }, { |
537 | .type = LML33, | 582 | .type = LML33, |
@@ -558,6 +603,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
558 | .gpcs = { 3, 1 }, | 603 | .gpcs = { 3, 1 }, |
559 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, | 604 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, |
560 | .gws_not_connected = 1, | 605 | .gws_not_connected = 1, |
606 | .input_mux = 0, | ||
561 | .init = &lml33_init, | 607 | .init = &lml33_init, |
562 | }, { | 608 | }, { |
563 | .type = LML33R10, | 609 | .type = LML33R10, |
@@ -586,6 +632,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
586 | .gpcs = { 3, 1 }, | 632 | .gpcs = { 3, 1 }, |
587 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, | 633 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, |
588 | .gws_not_connected = 1, | 634 | .gws_not_connected = 1, |
635 | .input_mux = 0, | ||
589 | .init = &lml33_init, | 636 | .init = &lml33_init, |
590 | }, { | 637 | }, { |
591 | .type = BUZ, | 638 | .type = BUZ, |
@@ -614,8 +661,49 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { | |||
614 | .gpcs = { 3, 1 }, | 661 | .gpcs = { 3, 1 }, |
615 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, | 662 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, |
616 | .gws_not_connected = 1, | 663 | .gws_not_connected = 1, |
664 | .input_mux = 0, | ||
617 | .init = &buz_init, | 665 | .init = &buz_init, |
666 | }, { | ||
667 | .type = AVS6EYES, | ||
668 | .name = "6-Eyes", | ||
669 | /* AverMedia chose not to brand the 6-Eyes. Thus it | ||
670 | can't be autodetected, and requires card=x. */ | ||
671 | .vendor_id = -1, | ||
672 | .device_id = -1, | ||
673 | .i2c_decoder = I2C_DRIVERID_KS0127, | ||
674 | .i2c_encoder = I2C_DRIVERID_BT866, | ||
675 | .video_codec = CODEC_TYPE_ZR36060, | ||
676 | |||
677 | .inputs = 10, | ||
678 | .input = { | ||
679 | { 0, "Composite 1" }, | ||
680 | { 1, "Composite 2" }, | ||
681 | { 2, "Composite 3" }, | ||
682 | { 4, "Composite 4" }, | ||
683 | { 5, "Composite 5" }, | ||
684 | { 6, "Composite 6" }, | ||
685 | { 8, "S-Video 1" }, | ||
686 | { 9, "S-Video 2" }, | ||
687 | {10, "S-Video 3" }, | ||
688 | {15, "YCbCr" } | ||
689 | }, | ||
690 | .norms = 2, | ||
691 | .tvn = { | ||
692 | &f50ccir601_avs6eyes, | ||
693 | &f60ccir601_avs6eyes, | ||
694 | NULL | ||
695 | }, | ||
696 | .jpeg_int = ZR36057_ISR_GIRQ1, | ||
697 | .vsync_int = ZR36057_ISR_GIRQ0, | ||
698 | .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam | ||
699 | .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam | ||
700 | .gpcs = { 3, 1 }, // Validity unknown /Sam | ||
701 | .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 }, // Validity unknown /Sam | ||
702 | .gws_not_connected = 1, | ||
703 | .input_mux = 1, | ||
704 | .init = &avs6eyes_init, | ||
618 | } | 705 | } |
706 | |||
619 | }; | 707 | }; |
620 | 708 | ||
621 | /* | 709 | /* |
diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c index c690b2ee880a..02168d9c2187 100644 --- a/drivers/media/video/zoran_device.c +++ b/drivers/media/video/zoran_device.c | |||
@@ -536,7 +536,7 @@ zr36057_overlay (struct zoran *zr, | |||
536 | * All error messages are internal driver checking only! */ | 536 | * All error messages are internal driver checking only! */ |
537 | 537 | ||
538 | /* video display top and bottom registers */ | 538 | /* video display top and bottom registers */ |
539 | reg = (u32) zr->buffer.base + | 539 | reg = (long) zr->buffer.base + |
540 | zr->overlay_settings.x * | 540 | zr->overlay_settings.x * |
541 | ((zr->overlay_settings.format->depth + 7) / 8) + | 541 | ((zr->overlay_settings.format->depth + 7) / 8) + |
542 | zr->overlay_settings.y * | 542 | zr->overlay_settings.y * |
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index b5a576a37fd2..9711f6248ef7 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c | |||
@@ -73,6 +73,7 @@ | |||
73 | ) | 73 | ) |
74 | 74 | ||
75 | #include <linux/videodev.h> | 75 | #include <linux/videodev.h> |
76 | #include <media/v4l2-common.h> | ||
76 | #include "videocodec.h" | 77 | #include "videocodec.h" |
77 | 78 | ||
78 | #include <asm/io.h> | 79 | #include <asm/io.h> |
@@ -2047,7 +2048,7 @@ zoran_do_ioctl (struct inode *inode, | |||
2047 | dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr)); | 2048 | dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr)); |
2048 | 2049 | ||
2049 | memset(vcap, 0, sizeof(struct video_capability)); | 2050 | memset(vcap, 0, sizeof(struct video_capability)); |
2050 | strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)); | 2051 | strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)-1); |
2051 | vcap->type = ZORAN_VID_TYPE; | 2052 | vcap->type = ZORAN_VID_TYPE; |
2052 | 2053 | ||
2053 | vcap->channels = zr->card.inputs; | 2054 | vcap->channels = zr->card.inputs; |
@@ -2689,8 +2690,8 @@ zoran_do_ioctl (struct inode *inode, | |||
2689 | dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr)); | 2690 | dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr)); |
2690 | 2691 | ||
2691 | memset(cap, 0, sizeof(*cap)); | 2692 | memset(cap, 0, sizeof(*cap)); |
2692 | strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)); | 2693 | strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); |
2693 | strncpy(cap->driver, "zoran", sizeof(cap->driver)); | 2694 | strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); |
2694 | snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", | 2695 | snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", |
2695 | pci_name(zr->pci_dev)); | 2696 | pci_name(zr->pci_dev)); |
2696 | cap->version = | 2697 | cap->version = |
@@ -2742,7 +2743,7 @@ zoran_do_ioctl (struct inode *inode, | |||
2742 | memset(fmt, 0, sizeof(*fmt)); | 2743 | memset(fmt, 0, sizeof(*fmt)); |
2743 | fmt->index = index; | 2744 | fmt->index = index; |
2744 | fmt->type = type; | 2745 | fmt->type = type; |
2745 | strncpy(fmt->description, zoran_formats[i].name, 31); | 2746 | strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); |
2746 | fmt->pixelformat = zoran_formats[i].fourcc; | 2747 | fmt->pixelformat = zoran_formats[i].fourcc; |
2747 | if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) | 2748 | if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) |
2748 | fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; | 2749 | fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; |
@@ -3566,16 +3567,16 @@ zoran_do_ioctl (struct inode *inode, | |||
3566 | 3567 | ||
3567 | switch (ctrl->id) { | 3568 | switch (ctrl->id) { |
3568 | case V4L2_CID_BRIGHTNESS: | 3569 | case V4L2_CID_BRIGHTNESS: |
3569 | strncpy(ctrl->name, "Brightness", 31); | 3570 | strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); |
3570 | break; | 3571 | break; |
3571 | case V4L2_CID_CONTRAST: | 3572 | case V4L2_CID_CONTRAST: |
3572 | strncpy(ctrl->name, "Contrast", 31); | 3573 | strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); |
3573 | break; | 3574 | break; |
3574 | case V4L2_CID_SATURATION: | 3575 | case V4L2_CID_SATURATION: |
3575 | strncpy(ctrl->name, "Saturation", 31); | 3576 | strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1); |
3576 | break; | 3577 | break; |
3577 | case V4L2_CID_HUE: | 3578 | case V4L2_CID_HUE: |
3578 | strncpy(ctrl->name, "Hue", 31); | 3579 | strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1); |
3579 | break; | 3580 | break; |
3580 | } | 3581 | } |
3581 | 3582 | ||
@@ -3693,7 +3694,7 @@ zoran_do_ioctl (struct inode *inode, | |||
3693 | &caps); | 3694 | &caps); |
3694 | if (caps.flags & VIDEO_DECODER_AUTO) { | 3695 | if (caps.flags & VIDEO_DECODER_AUTO) { |
3695 | std->id = V4L2_STD_ALL; | 3696 | std->id = V4L2_STD_ALL; |
3696 | strncpy(std->name, "Autodetect", 31); | 3697 | strncpy(std->name, "Autodetect", sizeof(std->name)-1); |
3697 | return 0; | 3698 | return 0; |
3698 | } else | 3699 | } else |
3699 | return -EINVAL; | 3700 | return -EINVAL; |
@@ -3701,21 +3702,21 @@ zoran_do_ioctl (struct inode *inode, | |||
3701 | switch (std->index) { | 3702 | switch (std->index) { |
3702 | case 0: | 3703 | case 0: |
3703 | std->id = V4L2_STD_PAL; | 3704 | std->id = V4L2_STD_PAL; |
3704 | strncpy(std->name, "PAL", 31); | 3705 | strncpy(std->name, "PAL", sizeof(std->name)-1); |
3705 | std->frameperiod.numerator = 1; | 3706 | std->frameperiod.numerator = 1; |
3706 | std->frameperiod.denominator = 25; | 3707 | std->frameperiod.denominator = 25; |
3707 | std->framelines = zr->card.tvn[0]->Ht; | 3708 | std->framelines = zr->card.tvn[0]->Ht; |
3708 | break; | 3709 | break; |
3709 | case 1: | 3710 | case 1: |
3710 | std->id = V4L2_STD_NTSC; | 3711 | std->id = V4L2_STD_NTSC; |
3711 | strncpy(std->name, "NTSC", 31); | 3712 | strncpy(std->name, "NTSC", sizeof(std->name)-1); |
3712 | std->frameperiod.numerator = 1001; | 3713 | std->frameperiod.numerator = 1001; |
3713 | std->frameperiod.denominator = 30000; | 3714 | std->frameperiod.denominator = 30000; |
3714 | std->framelines = zr->card.tvn[1]->Ht; | 3715 | std->framelines = zr->card.tvn[1]->Ht; |
3715 | break; | 3716 | break; |
3716 | case 2: | 3717 | case 2: |
3717 | std->id = V4L2_STD_SECAM; | 3718 | std->id = V4L2_STD_SECAM; |
3718 | strncpy(std->name, "SECAM", 31); | 3719 | strncpy(std->name, "SECAM", sizeof(std->name)-1); |
3719 | std->frameperiod.numerator = 1; | 3720 | std->frameperiod.numerator = 1; |
3720 | std->frameperiod.denominator = 25; | 3721 | std->frameperiod.denominator = 25; |
3721 | std->framelines = zr->card.tvn[2]->Ht; | 3722 | std->framelines = zr->card.tvn[2]->Ht; |
@@ -3871,7 +3872,7 @@ zoran_do_ioctl (struct inode *inode, | |||
3871 | memset(outp, 0, sizeof(*outp)); | 3872 | memset(outp, 0, sizeof(*outp)); |
3872 | outp->index = 0; | 3873 | outp->index = 0; |
3873 | outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; | 3874 | outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; |
3874 | strncpy(outp->name, "Autodetect", 31); | 3875 | strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); |
3875 | 3876 | ||
3876 | return 0; | 3877 | return 0; |
3877 | } | 3878 | } |
diff --git a/drivers/media/video/zoran_procfs.c b/drivers/media/video/zoran_procfs.c index a00fae90229a..f4ffe79bdc5b 100644 --- a/drivers/media/video/zoran_procfs.c +++ b/drivers/media/video/zoran_procfs.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/seq_file.h> | 43 | #include <linux/seq_file.h> |
44 | 44 | ||
45 | #include <linux/ctype.h> | 45 | #include <linux/ctype.h> |
46 | #include <linux/poll.h> | ||
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
47 | 48 | ||
48 | #include "videocodec.h" | 49 | #include "videocodec.h" |
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 23c1827b2d0b..f4ddd3431f17 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c | |||
@@ -102,6 +102,8 @@ | |||
102 | #include <linux/config.h> | 102 | #include <linux/config.h> |
103 | #include <linux/version.h> | 103 | #include <linux/version.h> |
104 | 104 | ||
105 | #define __OLD_VIDIOC_ | ||
106 | |||
105 | #include "matroxfb_base.h" | 107 | #include "matroxfb_base.h" |
106 | #include "matroxfb_misc.h" | 108 | #include "matroxfb_misc.h" |
107 | #include "matroxfb_accel.h" | 109 | #include "matroxfb_accel.h" |
@@ -158,9 +160,9 @@ static void update_crtc2(WPMINFO unsigned int pos) { | |||
158 | 160 | ||
159 | /* Make sure that displays are compatible */ | 161 | /* Make sure that displays are compatible */ |
160 | if (info && (info->fbcon.var.bits_per_pixel == ACCESS_FBINFO(fbcon).var.bits_per_pixel) | 162 | if (info && (info->fbcon.var.bits_per_pixel == ACCESS_FBINFO(fbcon).var.bits_per_pixel) |
161 | && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual) | 163 | && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual) |
162 | && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length) | 164 | && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length) |
163 | ) { | 165 | ) { |
164 | switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { | 166 | switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { |
165 | case 16: | 167 | case 16: |
166 | case 32: | 168 | case 32: |
@@ -224,7 +226,7 @@ static irqreturn_t matrox_irq(int irq, void *dev_id, struct pt_regs *fp) | |||
224 | 226 | ||
225 | int matroxfb_enable_irq(WPMINFO int reenable) { | 227 | int matroxfb_enable_irq(WPMINFO int reenable) { |
226 | u_int32_t bm; | 228 | u_int32_t bm; |
227 | 229 | ||
228 | if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) | 230 | if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) |
229 | bm = 0x220; | 231 | bm = 0x220; |
230 | else | 232 | else |
@@ -241,7 +243,7 @@ int matroxfb_enable_irq(WPMINFO int reenable) { | |||
241 | mga_outl(M_IEN, mga_inl(M_IEN) | bm); | 243 | mga_outl(M_IEN, mga_inl(M_IEN) | bm); |
242 | } else if (reenable) { | 244 | } else if (reenable) { |
243 | u_int32_t ien; | 245 | u_int32_t ien; |
244 | 246 | ||
245 | ien = mga_inl(M_IEN); | 247 | ien = mga_inl(M_IEN); |
246 | if ((ien & bm) != bm) { | 248 | if ((ien & bm) != bm) { |
247 | printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien); | 249 | printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien); |
@@ -347,7 +349,7 @@ static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) { | |||
347 | mga_setr(M_EXTVGA_INDEX, 0x00, p2); | 349 | mga_setr(M_EXTVGA_INDEX, 0x00, p2); |
348 | } | 350 | } |
349 | matroxfb_DAC_unlock_irqrestore(flags); | 351 | matroxfb_DAC_unlock_irqrestore(flags); |
350 | 352 | ||
351 | update_crtc2(PMINFO pos); | 353 | update_crtc2(PMINFO pos); |
352 | 354 | ||
353 | CRITEND | 355 | CRITEND |
@@ -390,7 +392,7 @@ static void matroxfb_remove(WPMINFO int dummy) { | |||
390 | static int matroxfb_open(struct fb_info *info, int user) | 392 | static int matroxfb_open(struct fb_info *info, int user) |
391 | { | 393 | { |
392 | MINFO_FROM_INFO(info); | 394 | MINFO_FROM_INFO(info); |
393 | 395 | ||
394 | DBG_LOOP(__FUNCTION__) | 396 | DBG_LOOP(__FUNCTION__) |
395 | 397 | ||
396 | if (ACCESS_FBINFO(dead)) { | 398 | if (ACCESS_FBINFO(dead)) { |
@@ -406,7 +408,7 @@ static int matroxfb_open(struct fb_info *info, int user) | |||
406 | static int matroxfb_release(struct fb_info *info, int user) | 408 | static int matroxfb_release(struct fb_info *info, int user) |
407 | { | 409 | { |
408 | MINFO_FROM_INFO(info); | 410 | MINFO_FROM_INFO(info); |
409 | 411 | ||
410 | DBG_LOOP(__FUNCTION__) | 412 | DBG_LOOP(__FUNCTION__) |
411 | 413 | ||
412 | if (user) { | 414 | if (user) { |
@@ -854,7 +856,7 @@ static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank) | |||
854 | vblank->flags |= FB_VBLANK_VBLANKING; | 856 | vblank->flags |= FB_VBLANK_VBLANKING; |
855 | if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { | 857 | if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { |
856 | vblank->flags |= FB_VBLANK_HAVE_COUNT; | 858 | vblank->flags |= FB_VBLANK_HAVE_COUNT; |
857 | /* Only one writer, aligned int value... | 859 | /* Only one writer, aligned int value... |
858 | it should work without lock and without atomic_t */ | 860 | it should work without lock and without atomic_t */ |
859 | vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt; | 861 | vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt; |
860 | } | 862 | } |
@@ -870,7 +872,7 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
870 | { | 872 | { |
871 | void __user *argp = (void __user *)arg; | 873 | void __user *argp = (void __user *)arg; |
872 | MINFO_FROM_INFO(info); | 874 | MINFO_FROM_INFO(info); |
873 | 875 | ||
874 | DBG(__FUNCTION__) | 876 | DBG(__FUNCTION__) |
875 | 877 | ||
876 | if (ACCESS_FBINFO(dead)) { | 878 | if (ACCESS_FBINFO(dead)) { |
@@ -1081,7 +1083,7 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1081 | case VIDIOC_QUERYCAP: | 1083 | case VIDIOC_QUERYCAP: |
1082 | { | 1084 | { |
1083 | struct v4l2_capability r; | 1085 | struct v4l2_capability r; |
1084 | 1086 | ||
1085 | memset(&r, 0, sizeof(r)); | 1087 | memset(&r, 0, sizeof(r)); |
1086 | strcpy(r.driver, "matroxfb"); | 1088 | strcpy(r.driver, "matroxfb"); |
1087 | strcpy(r.card, "Matrox"); | 1089 | strcpy(r.card, "Matrox"); |
@@ -1091,7 +1093,7 @@ static int matroxfb_ioctl(struct fb_info *info, | |||
1091 | if (copy_to_user(argp, &r, sizeof(r))) | 1093 | if (copy_to_user(argp, &r, sizeof(r))) |
1092 | return -EFAULT; | 1094 | return -EFAULT; |
1093 | return 0; | 1095 | return 0; |
1094 | 1096 | ||
1095 | } | 1097 | } |
1096 | case VIDIOC_QUERYCTRL: | 1098 | case VIDIOC_QUERYCTRL: |
1097 | { | 1099 | { |
@@ -1690,8 +1692,8 @@ static int initMatrox2(WPMINFO struct board* b){ | |||
1690 | pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd); | 1692 | pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd); |
1691 | mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */ | 1693 | mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */ |
1692 | mga_option |= MX_OPTION_BSWAP; | 1694 | mga_option |= MX_OPTION_BSWAP; |
1693 | /* disable palette snooping */ | 1695 | /* disable palette snooping */ |
1694 | cmd &= ~PCI_COMMAND_VGA_PALETTE; | 1696 | cmd &= ~PCI_COMMAND_VGA_PALETTE; |
1695 | if (pci_dev_present(intel_82437)) { | 1697 | if (pci_dev_present(intel_82437)) { |
1696 | if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) { | 1698 | if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) { |
1697 | printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n"); | 1699 | printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n"); |
@@ -1809,12 +1811,12 @@ static int initMatrox2(WPMINFO struct board* b){ | |||
1809 | 1811 | ||
1810 | if (fv) { | 1812 | if (fv) { |
1811 | tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres | 1813 | tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres |
1812 | + vesafb_defined.lower_margin + vesafb_defined.vsync_len); | 1814 | + vesafb_defined.lower_margin + vesafb_defined.vsync_len); |
1813 | if ((tmp < fh) || (fh == 0)) fh = tmp; | 1815 | if ((tmp < fh) || (fh == 0)) fh = tmp; |
1814 | } | 1816 | } |
1815 | if (fh) { | 1817 | if (fh) { |
1816 | tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres | 1818 | tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres |
1817 | + vesafb_defined.right_margin + vesafb_defined.hsync_len); | 1819 | + vesafb_defined.right_margin + vesafb_defined.hsync_len); |
1818 | if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp; | 1820 | if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp; |
1819 | } | 1821 | } |
1820 | tmp = (maxclk + 499) / 500; | 1822 | tmp = (maxclk + 499) / 500; |
@@ -1890,14 +1892,14 @@ static int initMatrox2(WPMINFO struct board* b){ | |||
1890 | 1892 | ||
1891 | /* there is no console on this fb... but we have to initialize hardware | 1893 | /* there is no console on this fb... but we have to initialize hardware |
1892 | * until someone tells me what is proper thing to do */ | 1894 | * until someone tells me what is proper thing to do */ |
1893 | if (!ACCESS_FBINFO(initialized)) { | 1895 | if (!ACCESS_FBINFO(initialized)) { |
1894 | printk(KERN_INFO "fb%d: initializing hardware\n", | 1896 | printk(KERN_INFO "fb%d: initializing hardware\n", |
1895 | ACCESS_FBINFO(fbcon.node)); | 1897 | ACCESS_FBINFO(fbcon.node)); |
1896 | /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var | 1898 | /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var |
1897 | * already before, so register_framebuffer works correctly. */ | 1899 | * already before, so register_framebuffer works correctly. */ |
1898 | vesafb_defined.activate |= FB_ACTIVATE_FORCE; | 1900 | vesafb_defined.activate |= FB_ACTIVATE_FORCE; |
1899 | fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); | 1901 | fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); |
1900 | } | 1902 | } |
1901 | 1903 | ||
1902 | return 0; | 1904 | return 0; |
1903 | failVideoIO:; | 1905 | failVideoIO:; |
@@ -2356,7 +2358,7 @@ static int __init matroxfb_setup(char *options) { | |||
2356 | else if (!strncmp(this_opt, "dfp:", 4)) { | 2358 | else if (!strncmp(this_opt, "dfp:", 4)) { |
2357 | dfp_type = simple_strtoul(this_opt+4, NULL, 0); | 2359 | dfp_type = simple_strtoul(this_opt+4, NULL, 0); |
2358 | dfp = 1; | 2360 | dfp = 1; |
2359 | } | 2361 | } |
2360 | #ifdef CONFIG_PPC_PMAC | 2362 | #ifdef CONFIG_PPC_PMAC |
2361 | else if (!strncmp(this_opt, "vmode:", 6)) { | 2363 | else if (!strncmp(this_opt, "vmode:", 6)) { |
2362 | unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0); | 2364 | unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0); |