diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-17 00:15:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-17 00:15:42 -0400 |
commit | 0dd5198672dd2bbeb933862e1fc82162e0b636be (patch) | |
tree | c9efed20d90603c4d1626c21bd7aab1e7fc74a58 /drivers/media | |
parent | c868d550115b9ccc0027c67265b9520790f05601 (diff) | |
parent | 11c635a25b9f3a5d87409ce46cf2e05c500251ec (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (425 commits)
V4L/DVB (11870): gspca - main: VIDIOC_ENUM_FRAMESIZES ioctl added.
V4L/DVB (12004): poll method lose race condition
V4L/DVB (11894): flexcop-pci: dmesg visible names broken
V4L/DVB (11892): Siano: smsendian - declare function as extern
V4L/DVB (11891): Siano: smscore - bind the GPIO SMS protocol
V4L/DVB (11890): Siano: smscore - remove redundant code
V4L/DVB (11889): Siano: smsdvb - add DVB v3 events
V4L/DVB (11888): Siano: smsusb - remove redundant ifdef
V4L/DVB (11887): Siano: smscards - add board (target) events
V4L/DVB (11886): Siano: smscore - fix some new GPIO definitions names
V4L/DVB (11885): Siano: Add new GPIO management interface
V4L/DVB (11884): Siano: smssdio - revert to stand alone module
V4L/DVB (11883): Siano: cards - add two additional (USB) devices
V4L/DVB (11824): Siano: smsusb - change exit func debug msg
V4L/DVB (11823): Siano: smsusb - fix typo in module description
V4L/DVB (11822): Siano: smscore - bug fix at get_device_mode
V4L/DVB (11821): Siano: smscore - fix isdb-t firmware name
V4L/DVB (11820): Siano: smscore - fix byte ordering bug
V4L/DVB (11819): Siano: smscore - fix get_common_buffer bug
V4L/DVB (11818): Siano: smscards - assign gpio to HPG targets
...
Diffstat (limited to 'drivers/media')
235 files changed, 21513 insertions, 6400 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 223c36ede5ae..ba69beeb0e21 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig | |||
@@ -2,8 +2,14 @@ | |||
2 | # Multimedia device configuration | 2 | # Multimedia device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "Multimedia devices" | 5 | menuconfig MEDIA_SUPPORT |
6 | tristate "Multimedia support" | ||
6 | depends on HAS_IOMEM | 7 | depends on HAS_IOMEM |
8 | help | ||
9 | If you want to use Video for Linux, DVB for Linux, or DAB adapters, | ||
10 | enable this option and other options below. | ||
11 | |||
12 | if MEDIA_SUPPORT | ||
7 | 13 | ||
8 | comment "Multimedia core support" | 14 | comment "Multimedia core support" |
9 | 15 | ||
@@ -136,4 +142,4 @@ config USB_DABUSB | |||
136 | module will be called dabusb. | 142 | module will be called dabusb. |
137 | endif # DAB | 143 | endif # DAB |
138 | 144 | ||
139 | endmenu | 145 | endif # MEDIA_SUPPORT |
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index 78412c9c424a..149d54cdf7b9 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c | |||
@@ -416,6 +416,24 @@ static int simple_std_setup(struct dvb_frontend *fe, | |||
416 | return 0; | 416 | return 0; |
417 | } | 417 | } |
418 | 418 | ||
419 | static int simple_set_aux_byte(struct dvb_frontend *fe, u8 config, u8 aux) | ||
420 | { | ||
421 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
422 | int rc; | ||
423 | u8 buffer[2]; | ||
424 | |||
425 | buffer[0] = (config & ~0x38) | 0x18; | ||
426 | buffer[1] = aux; | ||
427 | |||
428 | tuner_dbg("setting aux byte: 0x%02x 0x%02x\n", buffer[0], buffer[1]); | ||
429 | |||
430 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2); | ||
431 | if (2 != rc) | ||
432 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n", rc); | ||
433 | |||
434 | return rc == 2 ? 0 : rc; | ||
435 | } | ||
436 | |||
419 | static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, | 437 | static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, |
420 | u16 div, u8 config, u8 cb) | 438 | u16 div, u8 config, u8 cb) |
421 | { | 439 | { |
@@ -424,17 +442,10 @@ static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, | |||
424 | 442 | ||
425 | switch (priv->type) { | 443 | switch (priv->type) { |
426 | case TUNER_LG_TDVS_H06XF: | 444 | case TUNER_LG_TDVS_H06XF: |
427 | /* Set the Auxiliary Byte. */ | 445 | simple_set_aux_byte(fe, config, 0x20); |
428 | buffer[0] = buffer[2]; | 446 | break; |
429 | buffer[0] &= ~0x20; | 447 | case TUNER_PHILIPS_FQ1216LME_MK3: |
430 | buffer[0] |= 0x18; | 448 | simple_set_aux_byte(fe, config, 0x60); /* External AGC */ |
431 | buffer[1] = 0x20; | ||
432 | tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]); | ||
433 | |||
434 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2); | ||
435 | if (2 != rc) | ||
436 | tuner_warn("i2c i/o error: rc == %d " | ||
437 | "(should be 2)\n", rc); | ||
438 | break; | 449 | break; |
439 | case TUNER_MICROTUNE_4042FI5: | 450 | case TUNER_MICROTUNE_4042FI5: |
440 | { | 451 | { |
@@ -506,6 +517,11 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) | |||
506 | case TUNER_THOMSON_DTT761X: | 517 | case TUNER_THOMSON_DTT761X: |
507 | buffer[3] = 0x39; | 518 | buffer[3] = 0x39; |
508 | break; | 519 | break; |
520 | case TUNER_PHILIPS_FQ1216LME_MK3: | ||
521 | tuner_err("This tuner doesn't have FM\n"); | ||
522 | /* Set the low band for sanity, since it covers 88-108 MHz */ | ||
523 | buffer[3] = 0x01; | ||
524 | break; | ||
509 | case TUNER_MICROTUNE_4049FM5: | 525 | case TUNER_MICROTUNE_4049FM5: |
510 | default: | 526 | default: |
511 | buffer[3] = 0xa4; | 527 | buffer[3] = 0xa4; |
@@ -678,12 +694,12 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, | |||
678 | return 0; | 694 | return 0; |
679 | } | 695 | } |
680 | 696 | ||
681 | /* Bandswitch byte */ | ||
682 | simple_radio_bandswitch(fe, &buffer[0]); | ||
683 | |||
684 | buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | | 697 | buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | |
685 | TUNER_RATIO_SELECT_50; /* 50 kHz step */ | 698 | TUNER_RATIO_SELECT_50; /* 50 kHz step */ |
686 | 699 | ||
700 | /* Bandswitch byte */ | ||
701 | simple_radio_bandswitch(fe, &buffer[0]); | ||
702 | |||
687 | /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps | 703 | /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps |
688 | freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) = | 704 | freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) = |
689 | freq * (1/800) */ | 705 | freq * (1/800) */ |
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c index 7c0bc064c008..6a7f1a417c27 100644 --- a/drivers/media/common/tuners/tuner-types.c +++ b/drivers/media/common/tuners/tuner-types.c | |||
@@ -578,6 +578,31 @@ static struct tuner_params tuner_fm1216me_mk3_params[] = { | |||
578 | }, | 578 | }, |
579 | }; | 579 | }; |
580 | 580 | ||
581 | /* ------------ TUNER_PHILIPS_FM1216MK5 - Philips PAL ------------ */ | ||
582 | |||
583 | static struct tuner_range tuner_fm1216mk5_pal_ranges[] = { | ||
584 | { 16 * 158.00 /*MHz*/, 0xce, 0x01, }, | ||
585 | { 16 * 441.00 /*MHz*/, 0xce, 0x02, }, | ||
586 | { 16 * 864.00 , 0xce, 0x04, }, | ||
587 | }; | ||
588 | |||
589 | static struct tuner_params tuner_fm1216mk5_params[] = { | ||
590 | { | ||
591 | .type = TUNER_PARAM_TYPE_PAL, | ||
592 | .ranges = tuner_fm1216mk5_pal_ranges, | ||
593 | .count = ARRAY_SIZE(tuner_fm1216mk5_pal_ranges), | ||
594 | .cb_first_if_lower_freq = 1, | ||
595 | .has_tda9887 = 1, | ||
596 | .port1_active = 1, | ||
597 | .port2_active = 1, | ||
598 | .port2_invert_for_secam_lc = 1, | ||
599 | .port1_fm_high_sensitivity = 1, | ||
600 | .default_top_mid = -2, | ||
601 | .default_top_secam_mid = -2, | ||
602 | .default_top_secam_high = -2, | ||
603 | }, | ||
604 | }; | ||
605 | |||
581 | /* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */ | 606 | /* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */ |
582 | 607 | ||
583 | static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = { | 608 | static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = { |
@@ -1254,6 +1279,28 @@ static struct tuner_params tuner_tcl_mf02gip_5n_params[] = { | |||
1254 | }, | 1279 | }, |
1255 | }; | 1280 | }; |
1256 | 1281 | ||
1282 | /* 80-89 */ | ||
1283 | /* --------- TUNER_PHILIPS_FQ1216LME_MK3 -- active loopthrough, no FM ------- */ | ||
1284 | |||
1285 | static struct tuner_params tuner_fq1216lme_mk3_params[] = { | ||
1286 | { | ||
1287 | .type = TUNER_PARAM_TYPE_PAL, | ||
1288 | .ranges = tuner_fm1216me_mk3_pal_ranges, | ||
1289 | .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges), | ||
1290 | .cb_first_if_lower_freq = 1, /* not specified, but safe to do */ | ||
1291 | .has_tda9887 = 1, /* TDA9886 */ | ||
1292 | .port1_active = 1, | ||
1293 | .port2_active = 1, | ||
1294 | .port2_invert_for_secam_lc = 1, | ||
1295 | .default_top_low = 4, | ||
1296 | .default_top_mid = 4, | ||
1297 | .default_top_high = 4, | ||
1298 | .default_top_secam_low = 4, | ||
1299 | .default_top_secam_mid = 4, | ||
1300 | .default_top_secam_high = 4, | ||
1301 | }, | ||
1302 | }; | ||
1303 | |||
1257 | /* --------------------------------------------------------------------- */ | 1304 | /* --------------------------------------------------------------------- */ |
1258 | 1305 | ||
1259 | struct tunertype tuners[] = { | 1306 | struct tunertype tuners[] = { |
@@ -1694,6 +1741,18 @@ struct tunertype tuners[] = { | |||
1694 | .initdata = tua603x_agc112, | 1741 | .initdata = tua603x_agc112, |
1695 | .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, | 1742 | .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, |
1696 | }, | 1743 | }, |
1744 | [TUNER_PHILIPS_FM1216MK5] = { /* Philips PAL */ | ||
1745 | .name = "Philips PAL/SECAM multi (FM1216 MK5)", | ||
1746 | .params = tuner_fm1216mk5_params, | ||
1747 | .count = ARRAY_SIZE(tuner_fm1216mk5_params), | ||
1748 | }, | ||
1749 | |||
1750 | /* 80-89 */ | ||
1751 | [TUNER_PHILIPS_FQ1216LME_MK3] = { /* PAL/SECAM, Loop-thru, no FM */ | ||
1752 | .name = "Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough", | ||
1753 | .params = tuner_fq1216lme_mk3_params, | ||
1754 | .count = ARRAY_SIZE(tuner_fq1216lme_mk3_params), | ||
1755 | }, | ||
1697 | }; | 1756 | }; |
1698 | EXPORT_SYMBOL(tuners); | 1757 | EXPORT_SYMBOL(tuners); |
1699 | 1758 | ||
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 7636c33bc1e9..b6da9c3873fe 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
@@ -30,7 +30,7 @@ MODULE_PARM_DESC(debug, "enable verbose debug messages"); | |||
30 | 30 | ||
31 | static int no_poweroff; | 31 | static int no_poweroff; |
32 | module_param(no_poweroff, int, 0644); | 32 | module_param(no_poweroff, int, 0644); |
33 | MODULE_PARM_DESC(debug, "0 (default) powers device off when not used.\n" | 33 | MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n" |
34 | "1 keep device energized and with tuner ready all the times.\n" | 34 | "1 keep device energized and with tuner ready all the times.\n" |
35 | " Faster, but consumes more power and keeps the device hotter\n"); | 35 | " Faster, but consumes more power and keeps the device hotter\n"); |
36 | 36 | ||
@@ -272,7 +272,7 @@ static int load_all_firmwares(struct dvb_frontend *fe) | |||
272 | fname = firmware_name; | 272 | fname = firmware_name; |
273 | 273 | ||
274 | tuner_dbg("Reading firmware %s\n", fname); | 274 | tuner_dbg("Reading firmware %s\n", fname); |
275 | rc = request_firmware(&fw, fname, &priv->i2c_props.adap->dev); | 275 | rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent); |
276 | if (rc < 0) { | 276 | if (rc < 0) { |
277 | if (rc == -ENOENT) | 277 | if (rc == -ENOENT) |
278 | tuner_err("Error: firmware %s not found.\n", | 278 | tuner_err("Error: firmware %s not found.\n", |
@@ -917,22 +917,29 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | |||
917 | * that xc2028 will be in a safe state. | 917 | * that xc2028 will be in a safe state. |
918 | * Maybe this might also be needed for DTV. | 918 | * Maybe this might also be needed for DTV. |
919 | */ | 919 | */ |
920 | if (new_mode == T_ANALOG_TV) { | 920 | if (new_mode == T_ANALOG_TV) |
921 | rc = send_seq(priv, {0x00, 0x00}); | 921 | rc = send_seq(priv, {0x00, 0x00}); |
922 | } else if (priv->cur_fw.type & ATSC) { | 922 | |
923 | offset = 1750000; | 923 | /* |
924 | } else { | 924 | * Digital modes require an offset to adjust to the |
925 | offset = 2750000; | 925 | * proper frequency. |
926 | * Analog modes require offset = 0 | ||
927 | */ | ||
928 | if (new_mode == T_DIGITAL_TV) { | ||
929 | /* Sets the offset according with firmware */ | ||
930 | if (priv->cur_fw.type & DTV6) | ||
931 | offset = 1750000; | ||
932 | else if (priv->cur_fw.type & DTV7) | ||
933 | offset = 2250000; | ||
934 | else /* DTV8 or DTV78 */ | ||
935 | offset = 2750000; | ||
936 | |||
926 | /* | 937 | /* |
927 | * We must adjust the offset by 500kHz in two cases in order | 938 | * We must adjust the offset by 500kHz when |
928 | * to correctly center the IF output: | 939 | * tuning a 7MHz VHF channel with DTV78 firmware |
929 | * 1) When the ZARLINK456 or DIBCOM52 tables were explicitly | 940 | * (used in Australia, Italy and Germany) |
930 | * selected and a 7MHz channel is tuned; | ||
931 | * 2) When tuning a VHF channel with DTV78 firmware. | ||
932 | */ | 941 | */ |
933 | if (((priv->cur_fw.type & DTV7) && | 942 | if ((priv->cur_fw.type & DTV78) && freq < 470000000) |
934 | (priv->cur_fw.scode_table & (ZARLINK456 | DIBCOM52))) || | ||
935 | ((priv->cur_fw.type & DTV78) && freq < 470000000)) | ||
936 | offset -= 500000; | 943 | offset -= 500000; |
937 | } | 944 | } |
938 | 945 | ||
@@ -991,7 +998,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe, | |||
991 | if (priv->ctrl.input1) | 998 | if (priv->ctrl.input1) |
992 | type |= INPUT1; | 999 | type |= INPUT1; |
993 | return generic_set_freq(fe, (625l * p->frequency) / 10, | 1000 | return generic_set_freq(fe, (625l * p->frequency) / 10, |
994 | T_ANALOG_TV, type, 0, 0); | 1001 | T_RADIO, type, 0, 0); |
995 | } | 1002 | } |
996 | 1003 | ||
997 | /* if std is not defined, choose one */ | 1004 | /* if std is not defined, choose one */ |
@@ -1022,21 +1029,20 @@ static int xc2028_set_params(struct dvb_frontend *fe, | |||
1022 | switch(fe->ops.info.type) { | 1029 | switch(fe->ops.info.type) { |
1023 | case FE_OFDM: | 1030 | case FE_OFDM: |
1024 | bw = p->u.ofdm.bandwidth; | 1031 | bw = p->u.ofdm.bandwidth; |
1025 | break; | 1032 | /* |
1026 | case FE_QAM: | 1033 | * The only countries with 6MHz seem to be Taiwan/Uruguay. |
1027 | tuner_info("WARN: There are some reports that " | 1034 | * Both seem to require QAM firmware for OFDM decoding |
1028 | "QAM 6 MHz doesn't work.\n" | 1035 | * Tested in Taiwan by Terry Wu <terrywu2009@gmail.com> |
1029 | "If this works for you, please report by " | 1036 | */ |
1030 | "e-mail to: v4l-dvb-maintainer@linuxtv.org\n"); | 1037 | if (bw == BANDWIDTH_6_MHZ) |
1031 | bw = BANDWIDTH_6_MHZ; | 1038 | type |= QAM; |
1032 | type |= QAM; | ||
1033 | break; | 1039 | break; |
1034 | case FE_ATSC: | 1040 | case FE_ATSC: |
1035 | bw = BANDWIDTH_6_MHZ; | 1041 | bw = BANDWIDTH_6_MHZ; |
1036 | /* The only ATSC firmware (at least on v2.7) is D2633 */ | 1042 | /* The only ATSC firmware (at least on v2.7) is D2633 */ |
1037 | type |= ATSC | D2633; | 1043 | type |= ATSC | D2633; |
1038 | break; | 1044 | break; |
1039 | /* DVB-S is not supported */ | 1045 | /* DVB-S and pure QAM (FE_QAM) are not supported */ |
1040 | default: | 1046 | default: |
1041 | return -EINVAL; | 1047 | return -EINVAL; |
1042 | } | 1048 | } |
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index b54598550dc4..f4ffcdc9b848 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2007 Xceive Corporation | 4 | * Copyright (c) 2007 Xceive Corporation |
5 | * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org> | 5 | * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org> |
6 | * Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -36,14 +37,20 @@ static int debug; | |||
36 | module_param(debug, int, 0644); | 37 | module_param(debug, int, 0644); |
37 | MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); | 38 | MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); |
38 | 39 | ||
40 | static int no_poweroff; | ||
41 | module_param(no_poweroff, int, 0644); | ||
42 | MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n" | ||
43 | "\t\t1 keep device energized and with tuner ready all the times.\n" | ||
44 | "\t\tFaster, but consumes more power and keeps the device hotter"); | ||
45 | |||
39 | static DEFINE_MUTEX(xc5000_list_mutex); | 46 | static DEFINE_MUTEX(xc5000_list_mutex); |
40 | static LIST_HEAD(hybrid_tuner_instance_list); | 47 | static LIST_HEAD(hybrid_tuner_instance_list); |
41 | 48 | ||
42 | #define dprintk(level, fmt, arg...) if (debug >= level) \ | 49 | #define dprintk(level, fmt, arg...) if (debug >= level) \ |
43 | printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) | 50 | printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) |
44 | 51 | ||
45 | #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw" | 52 | #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw" |
46 | #define XC5000_DEFAULT_FIRMWARE_SIZE 12332 | 53 | #define XC5000_DEFAULT_FIRMWARE_SIZE 12401 |
47 | 54 | ||
48 | struct xc5000_priv { | 55 | struct xc5000_priv { |
49 | struct tuner_i2c_props i2c_props; | 56 | struct tuner_i2c_props i2c_props; |
@@ -83,11 +90,11 @@ struct xc5000_priv { | |||
83 | #define XREG_D_CODE 0x04 | 90 | #define XREG_D_CODE 0x04 |
84 | #define XREG_IF_OUT 0x05 | 91 | #define XREG_IF_OUT 0x05 |
85 | #define XREG_SEEK_MODE 0x07 | 92 | #define XREG_SEEK_MODE 0x07 |
86 | #define XREG_POWER_DOWN 0x0A | 93 | #define XREG_POWER_DOWN 0x0A /* Obsolete */ |
87 | #define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */ | 94 | #define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */ |
88 | #define XREG_SMOOTHEDCVBS 0x0E | 95 | #define XREG_SMOOTHEDCVBS 0x0E |
89 | #define XREG_XTALFREQ 0x0F | 96 | #define XREG_XTALFREQ 0x0F |
90 | #define XREG_FINERFFREQ 0x10 | 97 | #define XREG_FINERFREQ 0x10 |
91 | #define XREG_DDIMODE 0x11 | 98 | #define XREG_DDIMODE 0x11 |
92 | 99 | ||
93 | #define XREG_ADC_ENV 0x00 | 100 | #define XREG_ADC_ENV 0x00 |
@@ -100,6 +107,7 @@ struct xc5000_priv { | |||
100 | #define XREG_VERSION 0x07 | 107 | #define XREG_VERSION 0x07 |
101 | #define XREG_PRODUCT_ID 0x08 | 108 | #define XREG_PRODUCT_ID 0x08 |
102 | #define XREG_BUSY 0x09 | 109 | #define XREG_BUSY 0x09 |
110 | #define XREG_BUILD 0x0D | ||
103 | 111 | ||
104 | /* | 112 | /* |
105 | Basic firmware description. This will remain with | 113 | Basic firmware description. This will remain with |
@@ -191,27 +199,36 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { | |||
191 | {"FM Radio-INPUT1", 0x0208, 0x9002} | 199 | {"FM Radio-INPUT1", 0x0208, 0x9002} |
192 | }; | 200 | }; |
193 | 201 | ||
194 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); | 202 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); |
195 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); | 203 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); |
196 | static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); | 204 | static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val); |
197 | static void xc5000_TunerReset(struct dvb_frontend *fe); | 205 | static int xc5000_TunerReset(struct dvb_frontend *fe); |
198 | 206 | ||
199 | static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) | 207 | static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) |
200 | { | 208 | { |
201 | return xc5000_writeregs(priv, buf, len) | 209 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, |
202 | ? XC_RESULT_I2C_WRITE_FAILURE : XC_RESULT_SUCCESS; | 210 | .flags = 0, .buf = buf, .len = len }; |
211 | |||
212 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { | ||
213 | printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len); | ||
214 | return XC_RESULT_I2C_WRITE_FAILURE; | ||
215 | } | ||
216 | return XC_RESULT_SUCCESS; | ||
203 | } | 217 | } |
204 | 218 | ||
219 | /* This routine is never used because the only time we read data from the | ||
220 | i2c bus is when we read registers, and we want that to be an atomic i2c | ||
221 | transaction in case we are on a multi-master bus */ | ||
205 | static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) | 222 | static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) |
206 | { | 223 | { |
207 | return xc5000_readregs(priv, buf, len) | 224 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, |
208 | ? XC_RESULT_I2C_READ_FAILURE : XC_RESULT_SUCCESS; | 225 | .flags = I2C_M_RD, .buf = buf, .len = len }; |
209 | } | ||
210 | 226 | ||
211 | static int xc_reset(struct dvb_frontend *fe) | 227 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { |
212 | { | 228 | printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len); |
213 | xc5000_TunerReset(fe); | 229 | return -EREMOTEIO; |
214 | return XC_RESULT_SUCCESS; | 230 | } |
231 | return 0; | ||
215 | } | 232 | } |
216 | 233 | ||
217 | static void xc_wait(int wait_ms) | 234 | static void xc_wait(int wait_ms) |
@@ -219,7 +236,7 @@ static void xc_wait(int wait_ms) | |||
219 | msleep(wait_ms); | 236 | msleep(wait_ms); |
220 | } | 237 | } |
221 | 238 | ||
222 | static void xc5000_TunerReset(struct dvb_frontend *fe) | 239 | static int xc5000_TunerReset(struct dvb_frontend *fe) |
223 | { | 240 | { |
224 | struct xc5000_priv *priv = fe->tuner_priv; | 241 | struct xc5000_priv *priv = fe->tuner_priv; |
225 | int ret; | 242 | int ret; |
@@ -232,16 +249,21 @@ static void xc5000_TunerReset(struct dvb_frontend *fe) | |||
232 | priv->i2c_props.adap->algo_data, | 249 | priv->i2c_props.adap->algo_data, |
233 | DVB_FRONTEND_COMPONENT_TUNER, | 250 | DVB_FRONTEND_COMPONENT_TUNER, |
234 | XC5000_TUNER_RESET, 0); | 251 | XC5000_TUNER_RESET, 0); |
235 | if (ret) | 252 | if (ret) { |
236 | printk(KERN_ERR "xc5000: reset failed\n"); | 253 | printk(KERN_ERR "xc5000: reset failed\n"); |
237 | } else | 254 | return XC_RESULT_RESET_FAILURE; |
255 | } | ||
256 | } else { | ||
238 | printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n"); | 257 | printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n"); |
258 | return XC_RESULT_RESET_FAILURE; | ||
259 | } | ||
260 | return XC_RESULT_SUCCESS; | ||
239 | } | 261 | } |
240 | 262 | ||
241 | static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) | 263 | static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) |
242 | { | 264 | { |
243 | u8 buf[4]; | 265 | u8 buf[4]; |
244 | int WatchDogTimer = 5; | 266 | int WatchDogTimer = 100; |
245 | int result; | 267 | int result; |
246 | 268 | ||
247 | buf[0] = (regAddr >> 8) & 0xFF; | 269 | buf[0] = (regAddr >> 8) & 0xFF; |
@@ -263,7 +285,7 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) | |||
263 | /* busy flag cleared */ | 285 | /* busy flag cleared */ |
264 | break; | 286 | break; |
265 | } else { | 287 | } else { |
266 | xc_wait(100); /* wait 5 ms */ | 288 | xc_wait(5); /* wait 5 ms */ |
267 | WatchDogTimer--; | 289 | WatchDogTimer--; |
268 | } | 290 | } |
269 | } | 291 | } |
@@ -276,25 +298,6 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) | |||
276 | return result; | 298 | return result; |
277 | } | 299 | } |
278 | 300 | ||
279 | static int xc_read_reg(struct xc5000_priv *priv, u16 regAddr, u16 *i2cData) | ||
280 | { | ||
281 | u8 buf[2]; | ||
282 | int result; | ||
283 | |||
284 | buf[0] = (regAddr >> 8) & 0xFF; | ||
285 | buf[1] = regAddr & 0xFF; | ||
286 | result = xc_send_i2c_data(priv, buf, 2); | ||
287 | if (result != XC_RESULT_SUCCESS) | ||
288 | return result; | ||
289 | |||
290 | result = xc_read_i2c_data(priv, buf, 2); | ||
291 | if (result != XC_RESULT_SUCCESS) | ||
292 | return result; | ||
293 | |||
294 | *i2cData = buf[0] * 256 + buf[1]; | ||
295 | return result; | ||
296 | } | ||
297 | |||
298 | static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) | 301 | static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) |
299 | { | 302 | { |
300 | struct xc5000_priv *priv = fe->tuner_priv; | 303 | struct xc5000_priv *priv = fe->tuner_priv; |
@@ -309,7 +312,7 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) | |||
309 | len = i2c_sequence[index] * 256 + i2c_sequence[index+1]; | 312 | len = i2c_sequence[index] * 256 + i2c_sequence[index+1]; |
310 | if (len == 0x0000) { | 313 | if (len == 0x0000) { |
311 | /* RESET command */ | 314 | /* RESET command */ |
312 | result = xc_reset(fe); | 315 | result = xc5000_TunerReset(fe); |
313 | index += 2; | 316 | index += 2; |
314 | if (result != XC_RESULT_SUCCESS) | 317 | if (result != XC_RESULT_SUCCESS) |
315 | return result; | 318 | return result; |
@@ -371,15 +374,6 @@ static int xc_SetTVStandard(struct xc5000_priv *priv, | |||
371 | return ret; | 374 | return ret; |
372 | } | 375 | } |
373 | 376 | ||
374 | static int xc_shutdown(struct xc5000_priv *priv) | ||
375 | { | ||
376 | return XC_RESULT_SUCCESS; | ||
377 | /* Fixme: cannot bring tuner back alive once shutdown | ||
378 | * without reloading the driver modules. | ||
379 | * return xc_write_reg(priv, XREG_POWER_DOWN, 0); | ||
380 | */ | ||
381 | } | ||
382 | |||
383 | static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) | 377 | static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) |
384 | { | 378 | { |
385 | dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, | 379 | dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, |
@@ -408,7 +402,10 @@ static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz) | |||
408 | 402 | ||
409 | freq_code = (u16)(freq_hz / 15625); | 403 | freq_code = (u16)(freq_hz / 15625); |
410 | 404 | ||
411 | return xc_write_reg(priv, XREG_RF_FREQ, freq_code); | 405 | /* Starting in firmware version 1.1.44, Xceive recommends using the |
406 | FINERFREQ for all normal tuning (the doc indicates reg 0x03 should | ||
407 | only be used for fast scanning for channel lock) */ | ||
408 | return xc_write_reg(priv, XREG_FINERFREQ, freq_code); | ||
412 | } | 409 | } |
413 | 410 | ||
414 | 411 | ||
@@ -424,7 +421,7 @@ static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz) | |||
424 | 421 | ||
425 | static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope) | 422 | static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope) |
426 | { | 423 | { |
427 | return xc_read_reg(priv, XREG_ADC_ENV, adc_envelope); | 424 | return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope); |
428 | } | 425 | } |
429 | 426 | ||
430 | static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) | 427 | static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) |
@@ -433,8 +430,8 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) | |||
433 | u16 regData; | 430 | u16 regData; |
434 | u32 tmp; | 431 | u32 tmp; |
435 | 432 | ||
436 | result = xc_read_reg(priv, XREG_FREQ_ERROR, ®Data); | 433 | result = xc5000_readreg(priv, XREG_FREQ_ERROR, ®Data); |
437 | if (result) | 434 | if (result != XC_RESULT_SUCCESS) |
438 | return result; | 435 | return result; |
439 | 436 | ||
440 | tmp = (u32)regData; | 437 | tmp = (u32)regData; |
@@ -444,7 +441,7 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) | |||
444 | 441 | ||
445 | static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status) | 442 | static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status) |
446 | { | 443 | { |
447 | return xc_read_reg(priv, XREG_LOCK, lock_status); | 444 | return xc5000_readreg(priv, XREG_LOCK, lock_status); |
448 | } | 445 | } |
449 | 446 | ||
450 | static int xc_get_version(struct xc5000_priv *priv, | 447 | static int xc_get_version(struct xc5000_priv *priv, |
@@ -454,8 +451,8 @@ static int xc_get_version(struct xc5000_priv *priv, | |||
454 | u16 data; | 451 | u16 data; |
455 | int result; | 452 | int result; |
456 | 453 | ||
457 | result = xc_read_reg(priv, XREG_VERSION, &data); | 454 | result = xc5000_readreg(priv, XREG_VERSION, &data); |
458 | if (result) | 455 | if (result != XC_RESULT_SUCCESS) |
459 | return result; | 456 | return result; |
460 | 457 | ||
461 | (*hw_majorversion) = (data >> 12) & 0x0F; | 458 | (*hw_majorversion) = (data >> 12) & 0x0F; |
@@ -466,13 +463,18 @@ static int xc_get_version(struct xc5000_priv *priv, | |||
466 | return 0; | 463 | return 0; |
467 | } | 464 | } |
468 | 465 | ||
466 | static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev) | ||
467 | { | ||
468 | return xc5000_readreg(priv, XREG_BUILD, buildrev); | ||
469 | } | ||
470 | |||
469 | static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) | 471 | static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) |
470 | { | 472 | { |
471 | u16 regData; | 473 | u16 regData; |
472 | int result; | 474 | int result; |
473 | 475 | ||
474 | result = xc_read_reg(priv, XREG_HSYNC_FREQ, ®Data); | 476 | result = xc5000_readreg(priv, XREG_HSYNC_FREQ, ®Data); |
475 | if (result) | 477 | if (result != XC_RESULT_SUCCESS) |
476 | return result; | 478 | return result; |
477 | 479 | ||
478 | (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100; | 480 | (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100; |
@@ -481,12 +483,12 @@ static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) | |||
481 | 483 | ||
482 | static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines) | 484 | static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines) |
483 | { | 485 | { |
484 | return xc_read_reg(priv, XREG_FRAME_LINES, frame_lines); | 486 | return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines); |
485 | } | 487 | } |
486 | 488 | ||
487 | static int xc_get_quality(struct xc5000_priv *priv, u16 *quality) | 489 | static int xc_get_quality(struct xc5000_priv *priv, u16 *quality) |
488 | { | 490 | { |
489 | return xc_read_reg(priv, XREG_QUALITY, quality); | 491 | return xc5000_readreg(priv, XREG_QUALITY, quality); |
490 | } | 492 | } |
491 | 493 | ||
492 | static u16 WaitForLock(struct xc5000_priv *priv) | 494 | static u16 WaitForLock(struct xc5000_priv *priv) |
@@ -504,7 +506,9 @@ static u16 WaitForLock(struct xc5000_priv *priv) | |||
504 | return lockState; | 506 | return lockState; |
505 | } | 507 | } |
506 | 508 | ||
507 | static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz) | 509 | #define XC_TUNE_ANALOG 0 |
510 | #define XC_TUNE_DIGITAL 1 | ||
511 | static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode) | ||
508 | { | 512 | { |
509 | int found = 0; | 513 | int found = 0; |
510 | 514 | ||
@@ -513,8 +517,10 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz) | |||
513 | if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) | 517 | if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) |
514 | return 0; | 518 | return 0; |
515 | 519 | ||
516 | if (WaitForLock(priv) == 1) | 520 | if (mode == XC_TUNE_ANALOG) { |
517 | found = 1; | 521 | if (WaitForLock(priv) == 1) |
522 | found = 1; | ||
523 | } | ||
518 | 524 | ||
519 | return found; | 525 | return found; |
520 | } | 526 | } |
@@ -536,32 +542,7 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val) | |||
536 | } | 542 | } |
537 | 543 | ||
538 | *val = (bval[0] << 8) | bval[1]; | 544 | *val = (bval[0] << 8) | bval[1]; |
539 | return 0; | 545 | return XC_RESULT_SUCCESS; |
540 | } | ||
541 | |||
542 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) | ||
543 | { | ||
544 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, | ||
545 | .flags = 0, .buf = buf, .len = len }; | ||
546 | |||
547 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { | ||
548 | printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", | ||
549 | (int)len); | ||
550 | return -EREMOTEIO; | ||
551 | } | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len) | ||
556 | { | ||
557 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, | ||
558 | .flags = I2C_M_RD, .buf = buf, .len = len }; | ||
559 | |||
560 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { | ||
561 | printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", (int)len); | ||
562 | return -EREMOTEIO; | ||
563 | } | ||
564 | return 0; | ||
565 | } | 546 | } |
566 | 547 | ||
567 | static int xc5000_fwupload(struct dvb_frontend *fe) | 548 | static int xc5000_fwupload(struct dvb_frontend *fe) |
@@ -575,13 +556,13 @@ static int xc5000_fwupload(struct dvb_frontend *fe) | |||
575 | XC5000_DEFAULT_FIRMWARE); | 556 | XC5000_DEFAULT_FIRMWARE); |
576 | 557 | ||
577 | ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, | 558 | ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, |
578 | &priv->i2c_props.adap->dev); | 559 | priv->i2c_props.adap->dev.parent); |
579 | if (ret) { | 560 | if (ret) { |
580 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); | 561 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); |
581 | ret = XC_RESULT_RESET_FAILURE; | 562 | ret = XC_RESULT_RESET_FAILURE; |
582 | goto out; | 563 | goto out; |
583 | } else { | 564 | } else { |
584 | printk(KERN_INFO "xc5000: firmware read %Zu bytes.\n", | 565 | printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n", |
585 | fw->size); | 566 | fw->size); |
586 | ret = XC_RESULT_SUCCESS; | 567 | ret = XC_RESULT_SUCCESS; |
587 | } | 568 | } |
@@ -590,8 +571,9 @@ static int xc5000_fwupload(struct dvb_frontend *fe) | |||
590 | printk(KERN_ERR "xc5000: firmware incorrect size\n"); | 571 | printk(KERN_ERR "xc5000: firmware incorrect size\n"); |
591 | ret = XC_RESULT_RESET_FAILURE; | 572 | ret = XC_RESULT_RESET_FAILURE; |
592 | } else { | 573 | } else { |
593 | printk(KERN_INFO "xc5000: firmware upload\n"); | 574 | printk(KERN_INFO "xc5000: firmware uploading...\n"); |
594 | ret = xc_load_i2c_sequence(fe, fw->data); | 575 | ret = xc_load_i2c_sequence(fe, fw->data); |
576 | printk(KERN_INFO "xc5000: firmware upload complete...\n"); | ||
595 | } | 577 | } |
596 | 578 | ||
597 | out: | 579 | out: |
@@ -609,6 +591,7 @@ static void xc_debug_dump(struct xc5000_priv *priv) | |||
609 | u16 quality; | 591 | u16 quality; |
610 | u8 hw_majorversion = 0, hw_minorversion = 0; | 592 | u8 hw_majorversion = 0, hw_minorversion = 0; |
611 | u8 fw_majorversion = 0, fw_minorversion = 0; | 593 | u8 fw_majorversion = 0, fw_minorversion = 0; |
594 | u16 fw_buildversion = 0; | ||
612 | 595 | ||
613 | /* Wait for stats to stabilize. | 596 | /* Wait for stats to stabilize. |
614 | * Frame Lines needs two frame times after initial lock | 597 | * Frame Lines needs two frame times after initial lock |
@@ -628,9 +611,10 @@ static void xc_debug_dump(struct xc5000_priv *priv) | |||
628 | 611 | ||
629 | xc_get_version(priv, &hw_majorversion, &hw_minorversion, | 612 | xc_get_version(priv, &hw_majorversion, &hw_minorversion, |
630 | &fw_majorversion, &fw_minorversion); | 613 | &fw_majorversion, &fw_minorversion); |
631 | dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n", | 614 | xc_get_buildversion(priv, &fw_buildversion); |
615 | dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n", | ||
632 | hw_majorversion, hw_minorversion, | 616 | hw_majorversion, hw_minorversion, |
633 | fw_majorversion, fw_minorversion); | 617 | fw_majorversion, fw_minorversion, fw_buildversion); |
634 | 618 | ||
635 | xc_get_hsync_freq(priv, &hsync_freq_hz); | 619 | xc_get_hsync_freq(priv, &hsync_freq_hz); |
636 | dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz); | 620 | dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz); |
@@ -648,27 +632,57 @@ static int xc5000_set_params(struct dvb_frontend *fe, | |||
648 | struct xc5000_priv *priv = fe->tuner_priv; | 632 | struct xc5000_priv *priv = fe->tuner_priv; |
649 | int ret; | 633 | int ret; |
650 | 634 | ||
635 | if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) | ||
636 | xc_load_fw_and_init_tuner(fe); | ||
637 | |||
651 | dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); | 638 | dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); |
652 | 639 | ||
653 | switch (params->u.vsb.modulation) { | 640 | if (fe->ops.info.type == FE_ATSC) { |
654 | case VSB_8: | 641 | dprintk(1, "%s() ATSC\n", __func__); |
655 | case VSB_16: | 642 | switch (params->u.vsb.modulation) { |
656 | dprintk(1, "%s() VSB modulation\n", __func__); | 643 | case VSB_8: |
644 | case VSB_16: | ||
645 | dprintk(1, "%s() VSB modulation\n", __func__); | ||
646 | priv->rf_mode = XC_RF_MODE_AIR; | ||
647 | priv->freq_hz = params->frequency - 1750000; | ||
648 | priv->bandwidth = BANDWIDTH_6_MHZ; | ||
649 | priv->video_standard = DTV6; | ||
650 | break; | ||
651 | case QAM_64: | ||
652 | case QAM_256: | ||
653 | case QAM_AUTO: | ||
654 | dprintk(1, "%s() QAM modulation\n", __func__); | ||
655 | priv->rf_mode = XC_RF_MODE_CABLE; | ||
656 | priv->freq_hz = params->frequency - 1750000; | ||
657 | priv->bandwidth = BANDWIDTH_6_MHZ; | ||
658 | priv->video_standard = DTV6; | ||
659 | break; | ||
660 | default: | ||
661 | return -EINVAL; | ||
662 | } | ||
663 | } else if (fe->ops.info.type == FE_OFDM) { | ||
664 | dprintk(1, "%s() OFDM\n", __func__); | ||
665 | switch (params->u.ofdm.bandwidth) { | ||
666 | case BANDWIDTH_6_MHZ: | ||
667 | priv->bandwidth = BANDWIDTH_6_MHZ; | ||
668 | priv->video_standard = DTV6; | ||
669 | priv->freq_hz = params->frequency - 1750000; | ||
670 | break; | ||
671 | case BANDWIDTH_7_MHZ: | ||
672 | printk(KERN_ERR "xc5000 bandwidth 7MHz not supported\n"); | ||
673 | return -EINVAL; | ||
674 | case BANDWIDTH_8_MHZ: | ||
675 | priv->bandwidth = BANDWIDTH_8_MHZ; | ||
676 | priv->video_standard = DTV8; | ||
677 | priv->freq_hz = params->frequency - 2750000; | ||
678 | break; | ||
679 | default: | ||
680 | printk(KERN_ERR "xc5000 bandwidth not set!\n"); | ||
681 | return -EINVAL; | ||
682 | } | ||
657 | priv->rf_mode = XC_RF_MODE_AIR; | 683 | priv->rf_mode = XC_RF_MODE_AIR; |
658 | priv->freq_hz = params->frequency - 1750000; | 684 | } else { |
659 | priv->bandwidth = BANDWIDTH_6_MHZ; | 685 | printk(KERN_ERR "xc5000 modulation type not supported!\n"); |
660 | priv->video_standard = DTV6; | ||
661 | break; | ||
662 | case QAM_64: | ||
663 | case QAM_256: | ||
664 | case QAM_AUTO: | ||
665 | dprintk(1, "%s() QAM modulation\n", __func__); | ||
666 | priv->rf_mode = XC_RF_MODE_CABLE; | ||
667 | priv->freq_hz = params->frequency - 1750000; | ||
668 | priv->bandwidth = BANDWIDTH_6_MHZ; | ||
669 | priv->video_standard = DTV6; | ||
670 | break; | ||
671 | default: | ||
672 | return -EINVAL; | 686 | return -EINVAL; |
673 | } | 687 | } |
674 | 688 | ||
@@ -698,7 +712,7 @@ static int xc5000_set_params(struct dvb_frontend *fe, | |||
698 | return -EIO; | 712 | return -EIO; |
699 | } | 713 | } |
700 | 714 | ||
701 | xc_tune_channel(priv, priv->freq_hz); | 715 | xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL); |
702 | 716 | ||
703 | if (debug) | 717 | if (debug) |
704 | xc_debug_dump(priv); | 718 | xc_debug_dump(priv); |
@@ -725,8 +739,6 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe) | |||
725 | return ret; | 739 | return ret; |
726 | } | 740 | } |
727 | 741 | ||
728 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); | ||
729 | |||
730 | static int xc5000_set_analog_params(struct dvb_frontend *fe, | 742 | static int xc5000_set_analog_params(struct dvb_frontend *fe, |
731 | struct analog_parameters *params) | 743 | struct analog_parameters *params) |
732 | { | 744 | { |
@@ -807,7 +819,7 @@ tune_channel: | |||
807 | return -EREMOTEIO; | 819 | return -EREMOTEIO; |
808 | } | 820 | } |
809 | 821 | ||
810 | xc_tune_channel(priv, priv->freq_hz); | 822 | xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); |
811 | 823 | ||
812 | if (debug) | 824 | if (debug) |
813 | xc_debug_dump(priv); | 825 | xc_debug_dump(priv); |
@@ -875,18 +887,18 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) | |||
875 | 887 | ||
876 | static int xc5000_sleep(struct dvb_frontend *fe) | 888 | static int xc5000_sleep(struct dvb_frontend *fe) |
877 | { | 889 | { |
878 | struct xc5000_priv *priv = fe->tuner_priv; | ||
879 | int ret; | 890 | int ret; |
880 | 891 | ||
881 | dprintk(1, "%s()\n", __func__); | 892 | dprintk(1, "%s()\n", __func__); |
882 | 893 | ||
883 | /* On Pinnacle PCTV HD 800i, the tuner cannot be reinitialized | 894 | /* Avoid firmware reload on slow devices */ |
884 | * once shutdown without reloading the driver. Maybe I am not | 895 | if (no_poweroff) |
885 | * doing something right. | 896 | return 0; |
886 | * | ||
887 | */ | ||
888 | 897 | ||
889 | ret = xc_shutdown(priv); | 898 | /* According to Xceive technical support, the "powerdown" register |
899 | was removed in newer versions of the firmware. The "supported" | ||
900 | way to sleep the tuner is to pull the reset pin low for 10ms */ | ||
901 | ret = xc5000_TunerReset(fe); | ||
890 | if (ret != XC_RESULT_SUCCESS) { | 902 | if (ret != XC_RESULT_SUCCESS) { |
891 | printk(KERN_ERR | 903 | printk(KERN_ERR |
892 | "xc5000: %s() unable to shutdown tuner\n", | 904 | "xc5000: %s() unable to shutdown tuner\n", |
@@ -991,7 +1003,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
991 | /* Check if firmware has been loaded. It is possible that another | 1003 | /* Check if firmware has been loaded. It is possible that another |
992 | instance of the driver has loaded the firmware. | 1004 | instance of the driver has loaded the firmware. |
993 | */ | 1005 | */ |
994 | if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) | 1006 | if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS) |
995 | goto fail; | 1007 | goto fail; |
996 | 1008 | ||
997 | switch (id) { | 1009 | switch (id) { |
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h index 3e1c472092ab..9e2148a19967 100644 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ b/drivers/media/dvb/b2c2/flexcop-common.h | |||
@@ -1,9 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | 2 | * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III |
3 | * | 3 | * flexcop-common.h - common header file for device-specific source files |
4 | * flexcop-common.h - common header file for device-specific source files also. | 4 | * see flexcop.c for copyright information |
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | 5 | */ |
8 | #ifndef __FLEXCOP_COMMON_H__ | 6 | #ifndef __FLEXCOP_COMMON_H__ |
9 | #define __FLEXCOP_COMMON_H__ | 7 | #define __FLEXCOP_COMMON_H__ |
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index f7afab5944cf..efb4a6c2b57a 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -1,34 +1,27 @@ | |||
1 | /* | 1 | /* |
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | 2 | * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III |
3 | * | 3 | * flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling |
4 | * flexcop-fe-tuner.c - methods for attaching a frontend and controlling DiSEqC. | 4 | * see flexcop.c for copyright information |
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | 5 | */ |
8 | #include <media/tuner.h> | 6 | #include <media/tuner.h> |
9 | |||
10 | #include "flexcop.h" | 7 | #include "flexcop.h" |
11 | |||
12 | #include "stv0299.h" | ||
13 | #include "mt352.h" | ||
14 | #include "nxt200x.h" | ||
15 | #include "bcm3510.h" | ||
16 | #include "stv0297.h" | ||
17 | #include "mt312.h" | 8 | #include "mt312.h" |
18 | #include "lgdt330x.h" | 9 | #include "stv0299.h" |
19 | #include "dvb-pll.h" | ||
20 | #include "tuner-simple.h" | ||
21 | |||
22 | #include "s5h1420.h" | 10 | #include "s5h1420.h" |
23 | #include "itd1000.h" | 11 | #include "itd1000.h" |
24 | |||
25 | #include "cx24123.h" | ||
26 | #include "cx24113.h" | 12 | #include "cx24113.h" |
27 | 13 | #include "cx24123.h" | |
28 | #include "isl6421.h" | 14 | #include "isl6421.h" |
15 | #include "mt352.h" | ||
16 | #include "bcm3510.h" | ||
17 | #include "nxt200x.h" | ||
18 | #include "dvb-pll.h" | ||
19 | #include "lgdt330x.h" | ||
20 | #include "tuner-simple.h" | ||
21 | #include "stv0297.h" | ||
29 | 22 | ||
30 | /* lnb control */ | 23 | /* lnb control */ |
31 | 24 | #if defined(CONFIG_DVB_MT312_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) | |
32 | static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 25 | static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
33 | { | 26 | { |
34 | struct flexcop_device *fc = fe->dvb->priv; | 27 | struct flexcop_device *fc = fe->dvb->priv; |
@@ -37,65 +30,62 @@ static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage | |||
37 | 30 | ||
38 | v = fc->read_ibi_reg(fc, misc_204); | 31 | v = fc->read_ibi_reg(fc, misc_204); |
39 | switch (voltage) { | 32 | switch (voltage) { |
40 | case SEC_VOLTAGE_OFF: | 33 | case SEC_VOLTAGE_OFF: |
41 | v.misc_204.ACPI1_sig = 1; | 34 | v.misc_204.ACPI1_sig = 1; |
42 | break; | 35 | break; |
43 | case SEC_VOLTAGE_13: | 36 | case SEC_VOLTAGE_13: |
44 | v.misc_204.ACPI1_sig = 0; | 37 | v.misc_204.ACPI1_sig = 0; |
45 | v.misc_204.LNB_L_H_sig = 0; | 38 | v.misc_204.LNB_L_H_sig = 0; |
46 | break; | 39 | break; |
47 | case SEC_VOLTAGE_18: | 40 | case SEC_VOLTAGE_18: |
48 | v.misc_204.ACPI1_sig = 0; | 41 | v.misc_204.ACPI1_sig = 0; |
49 | v.misc_204.LNB_L_H_sig = 1; | 42 | v.misc_204.LNB_L_H_sig = 1; |
50 | break; | 43 | break; |
51 | default: | 44 | default: |
52 | err("unknown SEC_VOLTAGE value"); | 45 | err("unknown SEC_VOLTAGE value"); |
53 | return -EINVAL; | 46 | return -EINVAL; |
54 | } | 47 | } |
55 | return fc->write_ibi_reg(fc, misc_204, v); | 48 | return fc->write_ibi_reg(fc, misc_204, v); |
56 | } | 49 | } |
50 | #endif | ||
57 | 51 | ||
52 | #if defined(CONFIG_DVB_S5H1420_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) \ | ||
53 | || defined(CONFIG_DVB_MT312_MODULE) | ||
58 | static int flexcop_sleep(struct dvb_frontend* fe) | 54 | static int flexcop_sleep(struct dvb_frontend* fe) |
59 | { | 55 | { |
60 | struct flexcop_device *fc = fe->dvb->priv; | 56 | struct flexcop_device *fc = fe->dvb->priv; |
61 | /* flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */ | ||
62 | |||
63 | if (fc->fe_sleep) | 57 | if (fc->fe_sleep) |
64 | return fc->fe_sleep(fe); | 58 | return fc->fe_sleep(fe); |
65 | |||
66 | /* v.misc_204.ACPI3_sig = 1; | ||
67 | fc->write_ibi_reg(fc,misc_204,v);*/ | ||
68 | |||
69 | return 0; | 59 | return 0; |
70 | } | 60 | } |
61 | #endif | ||
71 | 62 | ||
63 | /* SkyStar2 DVB-S rev 2.3 */ | ||
64 | #if defined(CONFIG_DVB_MT312_MODULE) | ||
72 | static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | 65 | static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) |
73 | { | 66 | { |
74 | /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ | 67 | /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ |
75 | struct flexcop_device *fc = fe->dvb->priv; | 68 | struct flexcop_device *fc = fe->dvb->priv; |
76 | flexcop_ibi_value v; | 69 | flexcop_ibi_value v; |
77 | u16 ax; | 70 | u16 ax; |
78 | v.raw = 0; | 71 | v.raw = 0; |
79 | |||
80 | deb_tuner("tone = %u\n",tone); | 72 | deb_tuner("tone = %u\n",tone); |
81 | 73 | ||
82 | switch (tone) { | 74 | switch (tone) { |
83 | case SEC_TONE_ON: | 75 | case SEC_TONE_ON: |
84 | ax = 0x01ff; | 76 | ax = 0x01ff; |
85 | break; | 77 | break; |
86 | case SEC_TONE_OFF: | 78 | case SEC_TONE_OFF: |
87 | ax = 0; | 79 | ax = 0; |
88 | break; | 80 | break; |
89 | default: | 81 | default: |
90 | err("unknown SEC_TONE value"); | 82 | err("unknown SEC_TONE value"); |
91 | return -EINVAL; | 83 | return -EINVAL; |
92 | } | 84 | } |
93 | 85 | ||
94 | v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */ | 86 | v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */ |
95 | |||
96 | v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax; | 87 | v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax; |
97 | v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax; | 88 | v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax; |
98 | |||
99 | return fc->write_ibi_reg(fc,lnb_switch_freq_200,v); | 89 | return fc->write_ibi_reg(fc,lnb_switch_freq_200,v); |
100 | } | 90 | } |
101 | 91 | ||
@@ -110,17 +100,16 @@ static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data) | |||
110 | static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data) | 100 | static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data) |
111 | { | 101 | { |
112 | int i, par = 1, d; | 102 | int i, par = 1, d; |
113 | |||
114 | for (i = 7; i >= 0; i--) { | 103 | for (i = 7; i >= 0; i--) { |
115 | d = (data >> i) & 1; | 104 | d = (data >> i) & 1; |
116 | par ^= d; | 105 | par ^= d; |
117 | flexcop_diseqc_send_bit(fe, d); | 106 | flexcop_diseqc_send_bit(fe, d); |
118 | } | 107 | } |
119 | |||
120 | flexcop_diseqc_send_bit(fe, par); | 108 | flexcop_diseqc_send_bit(fe, par); |
121 | } | 109 | } |
122 | 110 | ||
123 | static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst) | 111 | static int flexcop_send_diseqc_msg(struct dvb_frontend *fe, |
112 | int len, u8 *msg, unsigned long burst) | ||
124 | { | 113 | { |
125 | int i; | 114 | int i; |
126 | 115 | ||
@@ -129,7 +118,6 @@ static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, un | |||
129 | 118 | ||
130 | for (i = 0; i < len; i++) | 119 | for (i = 0; i < len; i++) |
131 | flexcop_diseqc_send_byte(fe,msg[i]); | 120 | flexcop_diseqc_send_byte(fe,msg[i]); |
132 | |||
133 | mdelay(16); | 121 | mdelay(16); |
134 | 122 | ||
135 | if (burst != -1) { | 123 | if (burst != -1) { |
@@ -146,50 +134,110 @@ static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, un | |||
146 | return 0; | 134 | return 0; |
147 | } | 135 | } |
148 | 136 | ||
149 | static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) | 137 | static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe, |
138 | struct dvb_diseqc_master_cmd *cmd) | ||
150 | { | 139 | { |
151 | return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0); | 140 | return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0); |
152 | } | 141 | } |
153 | 142 | ||
154 | static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) | 143 | static int flexcop_diseqc_send_burst(struct dvb_frontend *fe, |
144 | fe_sec_mini_cmd_t minicmd) | ||
155 | { | 145 | { |
156 | return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd); | 146 | return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd); |
157 | } | 147 | } |
158 | 148 | ||
159 | /* dvb-s stv0299 */ | 149 | static struct mt312_config skystar23_samsung_tbdu18132_config = { |
160 | static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) | 150 | .demod_address = 0x0e, |
151 | }; | ||
152 | |||
153 | static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend *fe, | ||
154 | struct dvb_frontend_parameters *params) | ||
155 | { | ||
156 | u8 buf[4]; | ||
157 | u32 div; | ||
158 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, | ||
159 | .len = sizeof(buf) }; | ||
160 | struct flexcop_device *fc = fe->dvb->priv; | ||
161 | div = (params->frequency + (125/2)) / 125; | ||
162 | |||
163 | buf[0] = (div >> 8) & 0x7f; | ||
164 | buf[1] = (div >> 0) & 0xff; | ||
165 | buf[2] = 0x84 | ((div >> 10) & 0x60); | ||
166 | buf[3] = 0x80; | ||
167 | |||
168 | if (params->frequency < 1550000) | ||
169 | buf[3] |= 0x02; | ||
170 | |||
171 | if (fe->ops.i2c_gate_ctrl) | ||
172 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
173 | if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1) | ||
174 | return -EIO; | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static int skystar2_rev23_attach(struct flexcop_device *fc, | ||
179 | struct i2c_adapter *i2c) | ||
180 | { | ||
181 | fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c); | ||
182 | if (fc->fe != NULL) { | ||
183 | struct dvb_frontend_ops *ops = &fc->fe->ops; | ||
184 | ops->tuner_ops.set_params = | ||
185 | skystar23_samsung_tbdu18132_tuner_set_params; | ||
186 | ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; | ||
187 | ops->diseqc_send_burst = flexcop_diseqc_send_burst; | ||
188 | ops->set_tone = flexcop_set_tone; | ||
189 | ops->set_voltage = flexcop_set_voltage; | ||
190 | fc->fe_sleep = ops->sleep; | ||
191 | ops->sleep = flexcop_sleep; | ||
192 | return 1; | ||
193 | } | ||
194 | return 0; | ||
195 | } | ||
196 | #endif | ||
197 | |||
198 | /* SkyStar2 DVB-S rev 2.6 */ | ||
199 | #if defined(CONFIG_DVB_STV0299_MODULE) | ||
200 | static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe, | ||
201 | u32 srate, u32 ratio) | ||
161 | { | 202 | { |
162 | u8 aclk = 0; | 203 | u8 aclk = 0; |
163 | u8 bclk = 0; | 204 | u8 bclk = 0; |
164 | 205 | ||
165 | if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } | 206 | if (srate < 1500000) { |
166 | else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } | 207 | aclk = 0xb7; bclk = 0x47; |
167 | else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } | 208 | } else if (srate < 3000000) { |
168 | else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } | 209 | aclk = 0xb7; bclk = 0x4b; |
169 | else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } | 210 | } else if (srate < 7000000) { |
170 | else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } | 211 | aclk = 0xb7; bclk = 0x4f; |
171 | 212 | } else if (srate < 14000000) { | |
172 | stv0299_writereg (fe, 0x13, aclk); | 213 | aclk = 0xb7; bclk = 0x53; |
173 | stv0299_writereg (fe, 0x14, bclk); | 214 | } else if (srate < 30000000) { |
174 | stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); | 215 | aclk = 0xb6; bclk = 0x53; |
175 | stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); | 216 | } else if (srate < 45000000) { |
176 | stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); | 217 | aclk = 0xb4; bclk = 0x51; |
218 | } | ||
177 | 219 | ||
220 | stv0299_writereg(fe, 0x13, aclk); | ||
221 | stv0299_writereg(fe, 0x14, bclk); | ||
222 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
223 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
224 | stv0299_writereg(fe, 0x21, ratio & 0xf0); | ||
178 | return 0; | 225 | return 0; |
179 | } | 226 | } |
180 | 227 | ||
181 | static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) | 228 | static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend *fe, |
229 | struct dvb_frontend_parameters *params) | ||
182 | { | 230 | { |
183 | u8 buf[4]; | 231 | u8 buf[4]; |
184 | u32 div; | 232 | u32 div; |
185 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | 233 | struct i2c_msg msg = { |
234 | .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
186 | struct flexcop_device *fc = fe->dvb->priv; | 235 | struct flexcop_device *fc = fe->dvb->priv; |
187 | |||
188 | div = params->frequency / 125; | 236 | div = params->frequency / 125; |
189 | 237 | ||
190 | buf[0] = (div >> 8) & 0x7f; | 238 | buf[0] = (div >> 8) & 0x7f; |
191 | buf[1] = div & 0xff; | 239 | buf[1] = div & 0xff; |
192 | buf[2] = 0x84; /* 0xC4 */ | 240 | buf[2] = 0x84; /* 0xC4 */ |
193 | buf[3] = 0x08; | 241 | buf[3] = 0x08; |
194 | 242 | ||
195 | if (params->frequency < 1500000) | 243 | if (params->frequency < 1500000) |
@@ -203,48 +251,48 @@ static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dv | |||
203 | } | 251 | } |
204 | 252 | ||
205 | static u8 samsung_tbmu24112_inittab[] = { | 253 | static u8 samsung_tbmu24112_inittab[] = { |
206 | 0x01, 0x15, | 254 | 0x01, 0x15, |
207 | 0x02, 0x30, | 255 | 0x02, 0x30, |
208 | 0x03, 0x00, | 256 | 0x03, 0x00, |
209 | 0x04, 0x7D, | 257 | 0x04, 0x7D, |
210 | 0x05, 0x35, | 258 | 0x05, 0x35, |
211 | 0x06, 0x02, | 259 | 0x06, 0x02, |
212 | 0x07, 0x00, | 260 | 0x07, 0x00, |
213 | 0x08, 0xC3, | 261 | 0x08, 0xC3, |
214 | 0x0C, 0x00, | 262 | 0x0C, 0x00, |
215 | 0x0D, 0x81, | 263 | 0x0D, 0x81, |
216 | 0x0E, 0x23, | 264 | 0x0E, 0x23, |
217 | 0x0F, 0x12, | 265 | 0x0F, 0x12, |
218 | 0x10, 0x7E, | 266 | 0x10, 0x7E, |
219 | 0x11, 0x84, | 267 | 0x11, 0x84, |
220 | 0x12, 0xB9, | 268 | 0x12, 0xB9, |
221 | 0x13, 0x88, | 269 | 0x13, 0x88, |
222 | 0x14, 0x89, | 270 | 0x14, 0x89, |
223 | 0x15, 0xC9, | 271 | 0x15, 0xC9, |
224 | 0x16, 0x00, | 272 | 0x16, 0x00, |
225 | 0x17, 0x5C, | 273 | 0x17, 0x5C, |
226 | 0x18, 0x00, | 274 | 0x18, 0x00, |
227 | 0x19, 0x00, | 275 | 0x19, 0x00, |
228 | 0x1A, 0x00, | 276 | 0x1A, 0x00, |
229 | 0x1C, 0x00, | 277 | 0x1C, 0x00, |
230 | 0x1D, 0x00, | 278 | 0x1D, 0x00, |
231 | 0x1E, 0x00, | 279 | 0x1E, 0x00, |
232 | 0x1F, 0x3A, | 280 | 0x1F, 0x3A, |
233 | 0x20, 0x2E, | 281 | 0x20, 0x2E, |
234 | 0x21, 0x80, | 282 | 0x21, 0x80, |
235 | 0x22, 0xFF, | 283 | 0x22, 0xFF, |
236 | 0x23, 0xC1, | 284 | 0x23, 0xC1, |
237 | 0x28, 0x00, | 285 | 0x28, 0x00, |
238 | 0x29, 0x1E, | 286 | 0x29, 0x1E, |
239 | 0x2A, 0x14, | 287 | 0x2A, 0x14, |
240 | 0x2B, 0x0F, | 288 | 0x2B, 0x0F, |
241 | 0x2C, 0x09, | 289 | 0x2C, 0x09, |
242 | 0x2D, 0x05, | 290 | 0x2D, 0x05, |
243 | 0x31, 0x1F, | 291 | 0x31, 0x1F, |
244 | 0x32, 0x19, | 292 | 0x32, 0x19, |
245 | 0x33, 0xFE, | 293 | 0x33, 0xFE, |
246 | 0x34, 0x93, | 294 | 0x34, 0x93, |
247 | 0xff, 0xff, | 295 | 0xff, 0xff, |
248 | }; | 296 | }; |
249 | 297 | ||
250 | static struct stv0299_config samsung_tbmu24112_config = { | 298 | static struct stv0299_config samsung_tbmu24112_config = { |
@@ -259,27 +307,155 @@ static struct stv0299_config samsung_tbmu24112_config = { | |||
259 | .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, | 307 | .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, |
260 | }; | 308 | }; |
261 | 309 | ||
262 | /* dvb-t mt352 */ | 310 | static int skystar2_rev26_attach(struct flexcop_device *fc, |
263 | static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) | 311 | struct i2c_adapter *i2c) |
312 | { | ||
313 | fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c); | ||
314 | if (fc->fe != NULL) { | ||
315 | struct dvb_frontend_ops *ops = &fc->fe->ops; | ||
316 | ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; | ||
317 | ops->set_voltage = flexcop_set_voltage; | ||
318 | fc->fe_sleep = ops->sleep; | ||
319 | ops->sleep = flexcop_sleep; | ||
320 | return 1; | ||
321 | } | ||
322 | return 0; | ||
323 | } | ||
324 | #endif | ||
325 | |||
326 | /* SkyStar2 DVB-S rev 2.7 */ | ||
327 | #if defined(CONFIG_DVB_S5H1420_MODULE) | ||
328 | static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { | ||
329 | .demod_address = 0x53, | ||
330 | .invert = 1, | ||
331 | .repeated_start_workaround = 1, | ||
332 | .serial_mpeg = 1, | ||
333 | }; | ||
334 | |||
335 | static struct itd1000_config skystar2_rev2_7_itd1000_config = { | ||
336 | .i2c_address = 0x61, | ||
337 | }; | ||
338 | |||
339 | static int skystar2_rev27_attach(struct flexcop_device *fc, | ||
340 | struct i2c_adapter *i2c) | ||
341 | { | ||
342 | flexcop_ibi_value r108; | ||
343 | struct i2c_adapter *i2c_tuner; | ||
344 | |||
345 | /* enable no_base_addr - no repeated start when reading */ | ||
346 | fc->fc_i2c_adap[0].no_base_addr = 1; | ||
347 | fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config, | ||
348 | i2c); | ||
349 | if (!fc->fe) | ||
350 | goto fail; | ||
351 | |||
352 | i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe); | ||
353 | if (!i2c_tuner) | ||
354 | goto fail; | ||
355 | |||
356 | fc->fe_sleep = fc->fe->ops.sleep; | ||
357 | fc->fe->ops.sleep = flexcop_sleep; | ||
358 | |||
359 | /* enable no_base_addr - no repeated start when reading */ | ||
360 | fc->fc_i2c_adap[2].no_base_addr = 1; | ||
361 | if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, | ||
362 | 0x08, 1, 1)) { | ||
363 | err("ISL6421 could NOT be attached"); | ||
364 | goto fail_isl; | ||
365 | } | ||
366 | info("ISL6421 successfully attached"); | ||
367 | |||
368 | /* the ITD1000 requires a lower i2c clock - is it a problem ? */ | ||
369 | r108.raw = 0x00000506; | ||
370 | fc->write_ibi_reg(fc, tw_sm_c_108, r108); | ||
371 | if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner, | ||
372 | &skystar2_rev2_7_itd1000_config)) { | ||
373 | err("ITD1000 could NOT be attached"); | ||
374 | /* Should i2c clock be restored? */ | ||
375 | goto fail_isl; | ||
376 | } | ||
377 | info("ITD1000 successfully attached"); | ||
378 | |||
379 | return 1; | ||
380 | |||
381 | fail_isl: | ||
382 | fc->fc_i2c_adap[2].no_base_addr = 0; | ||
383 | fail: | ||
384 | /* for the next devices we need it again */ | ||
385 | fc->fc_i2c_adap[0].no_base_addr = 0; | ||
386 | return 0; | ||
387 | } | ||
388 | #endif | ||
389 | |||
390 | /* SkyStar2 rev 2.8 */ | ||
391 | #if defined(CONFIG_DVB_CX24123_MODULE) | ||
392 | static struct cx24123_config skystar2_rev2_8_cx24123_config = { | ||
393 | .demod_address = 0x55, | ||
394 | .dont_use_pll = 1, | ||
395 | .agc_callback = cx24113_agc_callback, | ||
396 | }; | ||
397 | |||
398 | static const struct cx24113_config skystar2_rev2_8_cx24113_config = { | ||
399 | .i2c_addr = 0x54, | ||
400 | .xtal_khz = 10111, | ||
401 | }; | ||
402 | |||
403 | static int skystar2_rev28_attach(struct flexcop_device *fc, | ||
404 | struct i2c_adapter *i2c) | ||
405 | { | ||
406 | struct i2c_adapter *i2c_tuner; | ||
407 | |||
408 | fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config, | ||
409 | i2c); | ||
410 | if (!fc->fe) | ||
411 | return 0; | ||
412 | |||
413 | i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);; | ||
414 | if (!i2c_tuner) | ||
415 | return 0; | ||
416 | |||
417 | if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config, | ||
418 | i2c_tuner)) { | ||
419 | err("CX24113 could NOT be attached"); | ||
420 | return 0; | ||
421 | } | ||
422 | info("CX24113 successfully attached"); | ||
423 | |||
424 | fc->fc_i2c_adap[2].no_base_addr = 1; | ||
425 | if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, | ||
426 | 0x08, 0, 0)) { | ||
427 | err("ISL6421 could NOT be attached"); | ||
428 | fc->fc_i2c_adap[2].no_base_addr = 0; | ||
429 | return 0; | ||
430 | } | ||
431 | info("ISL6421 successfully attached"); | ||
432 | /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an | ||
433 | * IR-receiver (PIC16F818) - but the card has no input for that ??? */ | ||
434 | return 1; | ||
435 | } | ||
436 | #endif | ||
437 | |||
438 | /* AirStar DVB-T */ | ||
439 | #if defined(CONFIG_DVB_MT352_MODULE) | ||
440 | static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe) | ||
264 | { | 441 | { |
265 | static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d }; | 442 | static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d }; |
266 | static u8 mt352_reset [] = { 0x50, 0x80 }; | 443 | static u8 mt352_reset[] = { 0x50, 0x80 }; |
267 | static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | 444 | static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 }; |
268 | static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 }; | 445 | static u8 mt352_agc_cfg[] = { 0x67, 0x28, 0xa1 }; |
269 | static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; | 446 | static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; |
270 | 447 | ||
271 | mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); | 448 | mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); |
272 | udelay(2000); | 449 | udelay(2000); |
273 | mt352_write(fe, mt352_reset, sizeof(mt352_reset)); | 450 | mt352_write(fe, mt352_reset, sizeof(mt352_reset)); |
274 | mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); | 451 | mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); |
275 | |||
276 | mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); | 452 | mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); |
277 | mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); | 453 | mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); |
278 | |||
279 | return 0; | 454 | return 0; |
280 | } | 455 | } |
281 | 456 | ||
282 | static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) | 457 | static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend *fe, |
458 | struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) | ||
283 | { | 459 | { |
284 | u32 div; | 460 | u32 div; |
285 | unsigned char bs = 0; | 461 | unsigned char bs = 0; |
@@ -287,19 +463,20 @@ static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_fro | |||
287 | if (buf_len < 5) | 463 | if (buf_len < 5) |
288 | return -EINVAL; | 464 | return -EINVAL; |
289 | 465 | ||
290 | #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ | 466 | #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ |
291 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | 467 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; |
292 | 468 | if (params->frequency >= 48000000 && params->frequency <= 154000000) \ | |
293 | if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09; | 469 | bs = 0x09; |
294 | if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; | 470 | if (params->frequency >= 161000000 && params->frequency <= 439000000) \ |
295 | if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; | 471 | bs = 0x0a; |
472 | if (params->frequency >= 447000000 && params->frequency <= 863000000) \ | ||
473 | bs = 0x08; | ||
296 | 474 | ||
297 | pllbuf[0] = 0x61; | 475 | pllbuf[0] = 0x61; |
298 | pllbuf[1] = div >> 8; | 476 | pllbuf[1] = div >> 8; |
299 | pllbuf[2] = div & 0xff; | 477 | pllbuf[2] = div & 0xff; |
300 | pllbuf[3] = 0xcc; | 478 | pllbuf[3] = 0xcc; |
301 | pllbuf[4] = bs; | 479 | pllbuf[4] = bs; |
302 | |||
303 | return 5; | 480 | return 5; |
304 | } | 481 | } |
305 | 482 | ||
@@ -308,70 +485,95 @@ static struct mt352_config samsung_tdtc9251dh0_config = { | |||
308 | .demod_init = samsung_tdtc9251dh0_demod_init, | 485 | .demod_init = samsung_tdtc9251dh0_demod_init, |
309 | }; | 486 | }; |
310 | 487 | ||
311 | static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) | 488 | static int airstar_dvbt_attach(struct flexcop_device *fc, |
489 | struct i2c_adapter *i2c) | ||
490 | { | ||
491 | fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c); | ||
492 | if (fc->fe != NULL) { | ||
493 | fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; | ||
494 | return 1; | ||
495 | } | ||
496 | return 0; | ||
497 | } | ||
498 | #endif | ||
499 | |||
500 | /* AirStar ATSC 1st generation */ | ||
501 | #if defined(CONFIG_DVB_BCM3510_MODULE) | ||
502 | static int flexcop_fe_request_firmware(struct dvb_frontend *fe, | ||
503 | const struct firmware **fw, char* name) | ||
312 | { | 504 | { |
313 | struct flexcop_device *fc = fe->dvb->priv; | 505 | struct flexcop_device *fc = fe->dvb->priv; |
314 | return request_firmware(fw, name, fc->dev); | 506 | return request_firmware(fw, name, fc->dev); |
315 | } | 507 | } |
316 | 508 | ||
317 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { | ||
318 | .demod_address = 0x59, | ||
319 | .demod_chip = LGDT3303, | ||
320 | .serial_mpeg = 0x04, | ||
321 | .clock_polarity_flip = 1, | ||
322 | }; | ||
323 | |||
324 | static struct nxt200x_config samsung_tbmv_config = { | ||
325 | .demod_address = 0x0a, | ||
326 | }; | ||
327 | |||
328 | static struct bcm3510_config air2pc_atsc_first_gen_config = { | 509 | static struct bcm3510_config air2pc_atsc_first_gen_config = { |
329 | .demod_address = 0x0f, | 510 | .demod_address = 0x0f, |
330 | .request_firmware = flexcop_fe_request_firmware, | 511 | .request_firmware = flexcop_fe_request_firmware, |
331 | }; | 512 | }; |
332 | 513 | ||
333 | static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) | 514 | static int airstar_atsc1_attach(struct flexcop_device *fc, |
515 | struct i2c_adapter *i2c) | ||
334 | { | 516 | { |
335 | u8 buf[4]; | 517 | fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); |
336 | u32 div; | 518 | return fc->fe != NULL; |
337 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | 519 | } |
338 | struct flexcop_device *fc = fe->dvb->priv; | 520 | #endif |
339 | |||
340 | div = (params->frequency + (125/2)) / 125; | ||
341 | 521 | ||
342 | buf[0] = (div >> 8) & 0x7f; | 522 | /* AirStar ATSC 2nd generation */ |
343 | buf[1] = (div >> 0) & 0xff; | 523 | #if defined(CONFIG_DVB_NXT200X_MODULE) |
344 | buf[2] = 0x84 | ((div >> 10) & 0x60); | 524 | static struct nxt200x_config samsung_tbmv_config = { |
345 | buf[3] = 0x80; | 525 | .demod_address = 0x0a, |
526 | }; | ||
346 | 527 | ||
347 | if (params->frequency < 1550000) | 528 | static int airstar_atsc2_attach(struct flexcop_device *fc, |
348 | buf[3] |= 0x02; | 529 | struct i2c_adapter *i2c) |
530 | { | ||
531 | fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c); | ||
532 | if (!fc->fe) | ||
533 | return 0; | ||
349 | 534 | ||
350 | if (fe->ops.i2c_gate_ctrl) | 535 | return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, |
351 | fe->ops.i2c_gate_ctrl(fe, 1); | 536 | DVB_PLL_SAMSUNG_TBMV); |
352 | if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1) | ||
353 | return -EIO; | ||
354 | return 0; | ||
355 | } | 537 | } |
538 | #endif | ||
356 | 539 | ||
357 | static struct mt312_config skystar23_samsung_tbdu18132_config = { | 540 | /* AirStar ATSC 3rd generation */ |
358 | 541 | #if defined(CONFIG_DVB_LGDT330X_MODULE) | |
359 | .demod_address = 0x0e, | 542 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { |
543 | .demod_address = 0x59, | ||
544 | .demod_chip = LGDT3303, | ||
545 | .serial_mpeg = 0x04, | ||
546 | .clock_polarity_flip = 1, | ||
360 | }; | 547 | }; |
361 | 548 | ||
549 | static int airstar_atsc3_attach(struct flexcop_device *fc, | ||
550 | struct i2c_adapter *i2c) | ||
551 | { | ||
552 | fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c); | ||
553 | if (!fc->fe) | ||
554 | return 0; | ||
555 | |||
556 | return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, | ||
557 | TUNER_LG_TDVS_H06XF); | ||
558 | } | ||
559 | #endif | ||
560 | |||
561 | /* CableStar2 DVB-C */ | ||
562 | #if defined(CONFIG_DVB_STV0297_MODULE) | ||
362 | static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, | 563 | static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, |
363 | struct dvb_frontend_parameters *fep) | 564 | struct dvb_frontend_parameters *fep) |
364 | { | 565 | { |
365 | struct flexcop_device *fc = fe->dvb->priv; | 566 | struct flexcop_device *fc = fe->dvb->priv; |
366 | u8 buf[4]; | 567 | u8 buf[4]; |
367 | u16 div; | 568 | u16 div; |
368 | int ret; | 569 | int ret; |
369 | 570 | ||
370 | /* 62.5 kHz * 10 */ | 571 | /* 62.5 kHz * 10 */ |
371 | #define REF_FREQ 625 | 572 | #define REF_FREQ 625 |
372 | #define FREQ_OFFSET 36125 | 573 | #define FREQ_OFFSET 36125 |
373 | 574 | ||
374 | div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz | 575 | div = ((fep->frequency/1000 + FREQ_OFFSET) * 10) / REF_FREQ; |
576 | /* 4 MHz = 4000 KHz */ | ||
375 | 577 | ||
376 | buf[0] = (u8)( div >> 8) & 0x7f; | 578 | buf[0] = (u8)( div >> 8) & 0x7f; |
377 | buf[1] = (u8) div & 0xff; | 579 | buf[1] = (u8) div & 0xff; |
@@ -384,11 +586,11 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, | |||
384 | * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */ | 586 | * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */ |
385 | buf[2] = 0x95; | 587 | buf[2] = 0x95; |
386 | 588 | ||
387 | // Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5 | 589 | /* Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5 |
388 | // 47 - 153 0 * 0 0 0 0 0 1 0x01 | 590 | * 47 - 153 0 * 0 0 0 0 0 1 0x01 |
389 | // 153 - 430 0 * 0 0 0 0 1 0 0x02 | 591 | * 153 - 430 0 * 0 0 0 0 1 0 0x02 |
390 | // 430 - 822 0 * 0 0 1 0 0 0 0x08 | 592 | * 430 - 822 0 * 0 0 1 0 0 0 0x08 |
391 | // 822 - 862 1 * 0 0 1 0 0 0 0x88 | 593 | * 822 - 862 1 * 0 0 1 0 0 0 0x88 */ |
392 | 594 | ||
393 | if (fep->frequency <= 153000000) buf[3] = 0x01; | 595 | if (fep->frequency <= 153000000) buf[3] = 0x01; |
394 | else if (fep->frequency <= 430000000) buf[3] = 0x02; | 596 | else if (fep->frequency <= 430000000) buf[3] = 0x02; |
@@ -397,11 +599,11 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, | |||
397 | 599 | ||
398 | if (fe->ops.i2c_gate_ctrl) | 600 | if (fe->ops.i2c_gate_ctrl) |
399 | fe->ops.i2c_gate_ctrl(fe, 0); | 601 | fe->ops.i2c_gate_ctrl(fe, 0); |
400 | deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]); | 602 | deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n", fep->frequency, |
603 | buf[0], buf[1], buf[2], buf[3]); | ||
401 | ret = fc->i2c_request(&fc->fc_i2c_adap[2], | 604 | ret = fc->i2c_request(&fc->fc_i2c_adap[2], |
402 | FC_WRITE, 0x61, buf[0], &buf[1], 3); | 605 | FC_WRITE, 0x61, buf[0], &buf[1], 3); |
403 | deb_tuner("tuner write returned: %d\n",ret); | 606 | deb_tuner("tuner write returned: %d\n",ret); |
404 | |||
405 | return ret; | 607 | return ret; |
406 | } | 608 | } |
407 | 609 | ||
@@ -481,182 +683,73 @@ static u8 alps_tdee4_stv0297_inittab[] = { | |||
481 | static struct stv0297_config alps_tdee4_stv0297_config = { | 683 | static struct stv0297_config alps_tdee4_stv0297_config = { |
482 | .demod_address = 0x1c, | 684 | .demod_address = 0x1c, |
483 | .inittab = alps_tdee4_stv0297_inittab, | 685 | .inittab = alps_tdee4_stv0297_inittab, |
484 | // .invert = 1, | ||
485 | // .pll_set = alps_tdee4_stv0297_pll_set, | ||
486 | }; | ||
487 | |||
488 | |||
489 | /* SkyStar2 rev2.7 (a/u) */ | ||
490 | static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { | ||
491 | .demod_address = 0x53, | ||
492 | .invert = 1, | ||
493 | .repeated_start_workaround = 1, | ||
494 | .serial_mpeg = 1, | ||
495 | }; | ||
496 | |||
497 | static struct itd1000_config skystar2_rev2_7_itd1000_config = { | ||
498 | .i2c_address = 0x61, | ||
499 | }; | 686 | }; |
500 | 687 | ||
501 | /* SkyStar2 rev2.8 */ | 688 | static int cablestar2_attach(struct flexcop_device *fc, |
502 | static struct cx24123_config skystar2_rev2_8_cx24123_config = { | 689 | struct i2c_adapter *i2c) |
503 | .demod_address = 0x55, | ||
504 | .dont_use_pll = 1, | ||
505 | .agc_callback = cx24113_agc_callback, | ||
506 | }; | ||
507 | |||
508 | static const struct cx24113_config skystar2_rev2_8_cx24113_config = { | ||
509 | .i2c_addr = 0x54, | ||
510 | .xtal_khz = 10111, | ||
511 | }; | ||
512 | |||
513 | /* try to figure out the frontend, each card/box can have on of the following list */ | ||
514 | int flexcop_frontend_init(struct flexcop_device *fc) | ||
515 | { | 690 | { |
516 | struct dvb_frontend_ops *ops; | ||
517 | struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap; | ||
518 | struct i2c_adapter *i2c_tuner; | ||
519 | |||
520 | /* enable no_base_addr - no repeated start when reading */ | ||
521 | fc->fc_i2c_adap[0].no_base_addr = 1; | ||
522 | fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config, i2c); | ||
523 | if (fc->fe != NULL) { | ||
524 | flexcop_ibi_value r108; | ||
525 | i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe); | ||
526 | ops = &fc->fe->ops; | ||
527 | |||
528 | fc->fe_sleep = ops->sleep; | ||
529 | ops->sleep = flexcop_sleep; | ||
530 | |||
531 | fc->dev_type = FC_SKY_REV27; | ||
532 | |||
533 | /* enable no_base_addr - no repeated start when reading */ | ||
534 | fc->fc_i2c_adap[2].no_base_addr = 1; | ||
535 | if (dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL) | ||
536 | err("ISL6421 could NOT be attached"); | ||
537 | else | ||
538 | info("ISL6421 successfully attached"); | ||
539 | |||
540 | /* the ITD1000 requires a lower i2c clock - it slows down the stuff for everyone - but is it a problem ? */ | ||
541 | r108.raw = 0x00000506; | ||
542 | fc->write_ibi_reg(fc, tw_sm_c_108, r108); | ||
543 | if (i2c_tuner) { | ||
544 | if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, &skystar2_rev2_7_itd1000_config) == NULL) | ||
545 | err("ITD1000 could NOT be attached"); | ||
546 | else | ||
547 | info("ITD1000 successfully attached"); | ||
548 | } | ||
549 | goto fe_found; | ||
550 | } | ||
551 | fc->fc_i2c_adap[0].no_base_addr = 0; /* for the next devices we need it again */ | ||
552 | |||
553 | /* try the sky v2.8 (cx24123, isl6421) */ | ||
554 | fc->fe = dvb_attach(cx24123_attach, | ||
555 | &skystar2_rev2_8_cx24123_config, i2c); | ||
556 | if (fc->fe != NULL) { | ||
557 | i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe); | ||
558 | if (i2c_tuner != NULL) { | ||
559 | if (dvb_attach(cx24113_attach, fc->fe, | ||
560 | &skystar2_rev2_8_cx24113_config, | ||
561 | i2c_tuner) == NULL) | ||
562 | err("CX24113 could NOT be attached"); | ||
563 | else | ||
564 | info("CX24113 successfully attached"); | ||
565 | } | ||
566 | |||
567 | fc->dev_type = FC_SKY_REV28; | ||
568 | |||
569 | fc->fc_i2c_adap[2].no_base_addr = 1; | ||
570 | if (dvb_attach(isl6421_attach, fc->fe, | ||
571 | &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL) | ||
572 | err("ISL6421 could NOT be attached"); | ||
573 | else | ||
574 | info("ISL6421 successfully attached"); | ||
575 | |||
576 | /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an | ||
577 | * IR-receiver (PIC16F818) - but the card has no input for | ||
578 | * that ??? */ | ||
579 | |||
580 | goto fe_found; | ||
581 | } | ||
582 | |||
583 | /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ | ||
584 | fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c); | ||
585 | if (fc->fe != NULL) { | ||
586 | ops = &fc->fe->ops; | ||
587 | |||
588 | ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; | ||
589 | |||
590 | ops->set_voltage = flexcop_set_voltage; | ||
591 | |||
592 | fc->fe_sleep = ops->sleep; | ||
593 | ops->sleep = flexcop_sleep; | ||
594 | |||
595 | fc->dev_type = FC_SKY_REV26; | ||
596 | goto fe_found; | ||
597 | } | ||
598 | |||
599 | /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ | ||
600 | fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c); | ||
601 | if (fc->fe != NULL) { | ||
602 | fc->dev_type = FC_AIR_DVBT; | ||
603 | fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; | ||
604 | goto fe_found; | ||
605 | } | ||
606 | |||
607 | /* try the air atsc 2nd generation (nxt2002) */ | ||
608 | fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c); | ||
609 | if (fc->fe != NULL) { | ||
610 | fc->dev_type = FC_AIR_ATSC2; | ||
611 | dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV); | ||
612 | goto fe_found; | ||
613 | } | ||
614 | |||
615 | fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c); | ||
616 | if (fc->fe != NULL) { | ||
617 | fc->dev_type = FC_AIR_ATSC3; | ||
618 | dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, | ||
619 | TUNER_LG_TDVS_H06XF); | ||
620 | goto fe_found; | ||
621 | } | ||
622 | |||
623 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ | ||
624 | fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); | ||
625 | if (fc->fe != NULL) { | ||
626 | fc->dev_type = FC_AIR_ATSC1; | ||
627 | goto fe_found; | ||
628 | } | ||
629 | |||
630 | /* try the cable dvb (stv0297) */ | ||
631 | fc->fc_i2c_adap[0].no_base_addr = 1; | 691 | fc->fc_i2c_adap[0].no_base_addr = 1; |
632 | fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c); | 692 | fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c); |
633 | if (fc->fe != NULL) { | 693 | if (!fc->fe) { |
634 | fc->dev_type = FC_CABLE; | 694 | /* Reset for next frontend to try */ |
635 | fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; | 695 | fc->fc_i2c_adap[0].no_base_addr = 0; |
636 | goto fe_found; | 696 | return 0; |
637 | } | 697 | } |
638 | fc->fc_i2c_adap[0].no_base_addr = 0; | 698 | fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; |
639 | 699 | return 1; | |
640 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ | 700 | } |
641 | fc->fe = dvb_attach(mt312_attach, | 701 | #endif |
642 | &skystar23_samsung_tbdu18132_config, i2c); | 702 | |
643 | if (fc->fe != NULL) { | 703 | static struct { |
644 | ops = &fc->fe->ops; | 704 | flexcop_device_type_t type; |
645 | 705 | int (*attach)(struct flexcop_device *, struct i2c_adapter *); | |
646 | ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params; | 706 | } flexcop_frontends[] = { |
647 | 707 | #if defined(CONFIG_DVB_S5H1420_MODULE) | |
648 | ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; | 708 | { FC_SKY_REV27, skystar2_rev27_attach }, |
649 | ops->diseqc_send_burst = flexcop_diseqc_send_burst; | 709 | #endif |
650 | ops->set_tone = flexcop_set_tone; | 710 | #if defined(CONFIG_DVB_CX24123_MODULE) |
651 | ops->set_voltage = flexcop_set_voltage; | 711 | { FC_SKY_REV28, skystar2_rev28_attach }, |
652 | 712 | #endif | |
653 | fc->fe_sleep = ops->sleep; | 713 | #if defined(CONFIG_DVB_STV0299_MODULE) |
654 | ops->sleep = flexcop_sleep; | 714 | { FC_SKY_REV26, skystar2_rev26_attach }, |
715 | #endif | ||
716 | #if defined(CONFIG_DVB_MT352_MODULE) | ||
717 | { FC_AIR_DVBT, airstar_dvbt_attach }, | ||
718 | #endif | ||
719 | #if defined(CONFIG_DVB_NXT200X_MODULE) | ||
720 | { FC_AIR_ATSC2, airstar_atsc2_attach }, | ||
721 | #endif | ||
722 | #if defined(CONFIG_DVB_LGDT330X_MODULE) | ||
723 | { FC_AIR_ATSC3, airstar_atsc3_attach }, | ||
724 | #endif | ||
725 | #if defined(CONFIG_DVB_BCM3510_MODULE) | ||
726 | { FC_AIR_ATSC1, airstar_atsc1_attach }, | ||
727 | #endif | ||
728 | #if defined(CONFIG_DVB_STV0297_MODULE) | ||
729 | { FC_CABLE, cablestar2_attach }, | ||
730 | #endif | ||
731 | #if defined(CONFIG_DVB_MT312_MODULE) | ||
732 | { FC_SKY_REV23, skystar2_rev23_attach }, | ||
733 | #endif | ||
734 | }; | ||
655 | 735 | ||
656 | fc->dev_type = FC_SKY_REV23; | 736 | /* try to figure out the frontend */ |
657 | goto fe_found; | 737 | int flexcop_frontend_init(struct flexcop_device *fc) |
738 | { | ||
739 | int i; | ||
740 | for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) { | ||
741 | /* type needs to be set before, because of some workarounds | ||
742 | * done based on the probed card type */ | ||
743 | fc->dev_type = flexcop_frontends[i].type; | ||
744 | if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap)) | ||
745 | goto fe_found; | ||
746 | /* Clean up partially attached frontend */ | ||
747 | if (fc->fe) { | ||
748 | dvb_frontend_detach(fc->fe); | ||
749 | fc->fe = NULL; | ||
750 | } | ||
658 | } | 751 | } |
659 | 752 | fc->dev_type = FC_UNK; | |
660 | err("no frontend driver found for this B2C2/FlexCop adapter"); | 753 | err("no frontend driver found for this B2C2/FlexCop adapter"); |
661 | return -ENODEV; | 754 | return -ENODEV; |
662 | 755 | ||
@@ -664,9 +757,7 @@ fe_found: | |||
664 | info("found '%s' .", fc->fe->ops.info.name); | 757 | info("found '%s' .", fc->fe->ops.info.name); |
665 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { | 758 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { |
666 | err("frontend registration failed!"); | 759 | err("frontend registration failed!"); |
667 | ops = &fc->fe->ops; | 760 | dvb_frontend_detach(fc->fe); |
668 | if (ops->release != NULL) | ||
669 | ops->release(fc->fe); | ||
670 | fc->fe = NULL; | 761 | fc->fe = NULL; |
671 | return -EINVAL; | 762 | return -EINVAL; |
672 | } | 763 | } |
@@ -680,6 +771,5 @@ void flexcop_frontend_exit(struct flexcop_device *fc) | |||
680 | dvb_unregister_frontend(fc->fe); | 771 | dvb_unregister_frontend(fc->fe); |
681 | dvb_frontend_detach(fc->fe); | 772 | dvb_frontend_detach(fc->fe); |
682 | } | 773 | } |
683 | |||
684 | fc->init_state &= ~FC_STATE_FE_INIT; | 774 | fc->init_state &= ~FC_STATE_FE_INIT; |
685 | } | 775 | } |
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index e2bed5076485..fd1df2352764 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c | |||
@@ -200,7 +200,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, | |||
200 | msgs[i].buf[0], &msgs[i].buf[1], | 200 | msgs[i].buf[0], &msgs[i].buf[1], |
201 | msgs[i].len - 1); | 201 | msgs[i].len - 1); |
202 | if (ret < 0) { | 202 | if (ret < 0) { |
203 | err("i2c master_xfer failed"); | 203 | deb_i2c("i2c master_xfer failed"); |
204 | break; | 204 | break; |
205 | } | 205 | } |
206 | } | 206 | } |
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c index e56627d2f0f4..f06f3a9070f5 100644 --- a/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/drivers/media/dvb/b2c2/flexcop-misc.c | |||
@@ -46,16 +46,16 @@ static const char *flexcop_revision_names[] = { | |||
46 | }; | 46 | }; |
47 | 47 | ||
48 | static const char *flexcop_device_names[] = { | 48 | static const char *flexcop_device_names[] = { |
49 | "Unknown device", | 49 | [FC_UNK] = "Unknown device", |
50 | "Air2PC/AirStar 2 DVB-T", | 50 | [FC_CABLE] = "Cable2PC/CableStar 2 DVB-C", |
51 | "Air2PC/AirStar 2 ATSC 1st generation", | 51 | [FC_AIR_DVBT] = "Air2PC/AirStar 2 DVB-T", |
52 | "Air2PC/AirStar 2 ATSC 2nd generation", | 52 | [FC_AIR_ATSC1] = "Air2PC/AirStar 2 ATSC 1st generation", |
53 | "Sky2PC/SkyStar 2 DVB-S", | 53 | [FC_AIR_ATSC2] = "Air2PC/AirStar 2 ATSC 2nd generation", |
54 | "Sky2PC/SkyStar 2 DVB-S (old version)", | 54 | [FC_AIR_ATSC3] = "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", |
55 | "Cable2PC/CableStar 2 DVB-C", | 55 | [FC_SKY_REV23] = "Sky2PC/SkyStar 2 DVB-S rev 2.3 (old version)", |
56 | "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", | 56 | [FC_SKY_REV26] = "Sky2PC/SkyStar 2 DVB-S rev 2.6", |
57 | "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", | 57 | [FC_SKY_REV27] = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", |
58 | "Sky2PC/SkyStar 2 DVB-S rev 2.8", | 58 | [FC_SKY_REV28] = "Sky2PC/SkyStar 2 DVB-S rev 2.8", |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static const char *flexcop_bus_names[] = { | 61 | static const char *flexcop_bus_names[] = { |
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index 56d8fab688bb..a24c125331f0 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c | |||
@@ -508,12 +508,6 @@ static int __devinit bt878_probe(struct pci_dev *dev, | |||
508 | pci_set_master(dev); | 508 | pci_set_master(dev); |
509 | pci_set_drvdata(dev, bt); | 509 | pci_set_drvdata(dev, bt); |
510 | 510 | ||
511 | /* if(init_bt878(btv) < 0) { | ||
512 | bt878_remove(dev); | ||
513 | return -EIO; | ||
514 | } | ||
515 | */ | ||
516 | |||
517 | if ((result = bt878_mem_alloc(bt))) { | 511 | if ((result = bt878_mem_alloc(bt))) { |
518 | printk(KERN_ERR "bt878: failed to allocate memory!\n"); | 512 | printk(KERN_ERR "bt878: failed to allocate memory!\n"); |
519 | goto fail2; | 513 | goto fail2; |
@@ -579,7 +573,7 @@ static struct pci_driver bt878_pci_driver = { | |||
579 | .name = "bt878", | 573 | .name = "bt878", |
580 | .id_table = bt878_pci_tbl, | 574 | .id_table = bt878_pci_tbl, |
581 | .probe = bt878_probe, | 575 | .probe = bt878_probe, |
582 | .remove = bt878_remove, | 576 | .remove = __devexit_p(bt878_remove), |
583 | }; | 577 | }; |
584 | 578 | ||
585 | static int bt878_pci_driver_registered; | 579 | static int bt878_pci_driver_registered; |
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 971a8b18f6dd..4dbd7d4185af 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c | |||
@@ -51,6 +51,9 @@ | |||
51 | #ifndef PCI_VENDOR_ID_TRIGEM | 51 | #ifndef PCI_VENDOR_ID_TRIGEM |
52 | #define PCI_VENDOR_ID_TRIGEM 0x109f | 52 | #define PCI_VENDOR_ID_TRIGEM 0x109f |
53 | #endif | 53 | #endif |
54 | #ifndef PCI_VENDOR_ID_AXESS | ||
55 | #define PCI_VENDOR_ID_AXESS 0x195d | ||
56 | #endif | ||
54 | #ifndef PCI_DEVICE_ID_DM1105 | 57 | #ifndef PCI_DEVICE_ID_DM1105 |
55 | #define PCI_DEVICE_ID_DM1105 0x036f | 58 | #define PCI_DEVICE_ID_DM1105 0x036f |
56 | #endif | 59 | #endif |
@@ -60,6 +63,9 @@ | |||
60 | #ifndef PCI_DEVICE_ID_DW2004 | 63 | #ifndef PCI_DEVICE_ID_DW2004 |
61 | #define PCI_DEVICE_ID_DW2004 0x2004 | 64 | #define PCI_DEVICE_ID_DW2004 0x2004 |
62 | #endif | 65 | #endif |
66 | #ifndef PCI_DEVICE_ID_DM05 | ||
67 | #define PCI_DEVICE_ID_DM05 0x1105 | ||
68 | #endif | ||
63 | /* ----------------------------------------------- */ | 69 | /* ----------------------------------------------- */ |
64 | /* sdmc dm1105 registers */ | 70 | /* sdmc dm1105 registers */ |
65 | 71 | ||
@@ -150,6 +156,11 @@ | |||
150 | #define DM1105_LNB_13V 0x00010100 | 156 | #define DM1105_LNB_13V 0x00010100 |
151 | #define DM1105_LNB_18V 0x00000100 | 157 | #define DM1105_LNB_18V 0x00000100 |
152 | 158 | ||
159 | /* GPIO's for LNB power control for Axess DM05 */ | ||
160 | #define DM05_LNB_MASK 0x00000000 | ||
161 | #define DM05_LNB_13V 0x00020000 | ||
162 | #define DM05_LNB_18V 0x00030000 | ||
163 | |||
153 | static int ir_debug; | 164 | static int ir_debug; |
154 | module_param(ir_debug, int, 0644); | 165 | module_param(ir_debug, int, 0644); |
155 | MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); | 166 | MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); |
@@ -188,6 +199,8 @@ struct dm1105dvb { | |||
188 | 199 | ||
189 | /* irq */ | 200 | /* irq */ |
190 | struct work_struct work; | 201 | struct work_struct work; |
202 | struct workqueue_struct *wq; | ||
203 | char wqn[16]; | ||
191 | 204 | ||
192 | /* dma */ | 205 | /* dma */ |
193 | dma_addr_t dma_addr; | 206 | dma_addr_t dma_addr; |
@@ -313,15 +326,25 @@ static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe) | |||
313 | static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 326 | static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
314 | { | 327 | { |
315 | struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); | 328 | struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); |
329 | u32 lnb_mask, lnb_13v, lnb_18v; | ||
316 | 330 | ||
317 | if (voltage == SEC_VOLTAGE_18) { | 331 | switch (dm1105dvb->pdev->subsystem_device) { |
318 | outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR)); | 332 | case PCI_DEVICE_ID_DM05: |
319 | outl(DM1105_LNB_18V, dm_io_mem(DM1105_GPIOVAL)); | 333 | lnb_mask = DM05_LNB_MASK; |
320 | } else { | 334 | lnb_13v = DM05_LNB_13V; |
321 | /*LNB ON-13V by default!*/ | 335 | lnb_18v = DM05_LNB_18V; |
322 | outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR)); | 336 | break; |
323 | outl(DM1105_LNB_13V, dm_io_mem(DM1105_GPIOVAL)); | 337 | default: |
324 | } | 338 | lnb_mask = DM1105_LNB_MASK; |
339 | lnb_13v = DM1105_LNB_13V; | ||
340 | lnb_18v = DM1105_LNB_18V; | ||
341 | } | ||
342 | |||
343 | outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR)); | ||
344 | if (voltage == SEC_VOLTAGE_18) | ||
345 | outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL)); | ||
346 | else | ||
347 | outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL)); | ||
325 | 348 | ||
326 | return 0; | 349 | return 0; |
327 | } | 350 | } |
@@ -440,7 +463,7 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) | |||
440 | case (INTSTS_TSIRQ | INTSTS_IR): | 463 | case (INTSTS_TSIRQ | INTSTS_IR): |
441 | dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) - | 464 | dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) - |
442 | inl(dm_io_mem(DM1105_STADR)); | 465 | inl(dm_io_mem(DM1105_STADR)); |
443 | schedule_work(&dm1105dvb->work); | 466 | queue_work(dm1105dvb->wq, &dm1105dvb->work); |
444 | break; | 467 | break; |
445 | case INTSTS_IR: | 468 | case INTSTS_IR: |
446 | dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE)); | 469 | dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE)); |
@@ -567,46 +590,44 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb) | |||
567 | int ret; | 590 | int ret; |
568 | 591 | ||
569 | switch (dm1105dvb->pdev->subsystem_device) { | 592 | switch (dm1105dvb->pdev->subsystem_device) { |
570 | case PCI_DEVICE_ID_DW2002: | 593 | case PCI_DEVICE_ID_DW2004: |
571 | dm1105dvb->fe = dvb_attach( | 594 | dm1105dvb->fe = dvb_attach( |
572 | stv0299_attach, &sharp_z0194a_config, | 595 | cx24116_attach, &serit_sp2633_config, |
573 | &dm1105dvb->i2c_adap); | 596 | &dm1105dvb->i2c_adap); |
597 | if (dm1105dvb->fe) | ||
598 | dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; | ||
574 | 599 | ||
600 | break; | ||
601 | default: | ||
602 | dm1105dvb->fe = dvb_attach( | ||
603 | stv0299_attach, &sharp_z0194a_config, | ||
604 | &dm1105dvb->i2c_adap); | ||
575 | if (dm1105dvb->fe) { | 605 | if (dm1105dvb->fe) { |
576 | dm1105dvb->fe->ops.set_voltage = | 606 | dm1105dvb->fe->ops.set_voltage = |
577 | dm1105dvb_set_voltage; | 607 | dm1105dvb_set_voltage; |
578 | dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60, | 608 | dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60, |
579 | &dm1105dvb->i2c_adap, DVB_PLL_OPERA1); | 609 | &dm1105dvb->i2c_adap, DVB_PLL_OPERA1); |
610 | break; | ||
580 | } | 611 | } |
581 | 612 | ||
582 | if (!dm1105dvb->fe) { | 613 | dm1105dvb->fe = dvb_attach( |
583 | dm1105dvb->fe = dvb_attach( | 614 | stv0288_attach, &earda_config, |
584 | stv0288_attach, &earda_config, | 615 | &dm1105dvb->i2c_adap); |
585 | &dm1105dvb->i2c_adap); | 616 | if (dm1105dvb->fe) { |
586 | if (dm1105dvb->fe) { | 617 | dm1105dvb->fe->ops.set_voltage = |
587 | dm1105dvb->fe->ops.set_voltage = | 618 | dm1105dvb_set_voltage; |
588 | dm1105dvb_set_voltage; | 619 | dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61, |
589 | dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61, | 620 | &dm1105dvb->i2c_adap); |
590 | &dm1105dvb->i2c_adap); | 621 | break; |
591 | } | ||
592 | } | 622 | } |
593 | 623 | ||
594 | if (!dm1105dvb->fe) { | ||
595 | dm1105dvb->fe = dvb_attach( | ||
596 | si21xx_attach, &serit_config, | ||
597 | &dm1105dvb->i2c_adap); | ||
598 | if (dm1105dvb->fe) | ||
599 | dm1105dvb->fe->ops.set_voltage = | ||
600 | dm1105dvb_set_voltage; | ||
601 | } | ||
602 | break; | ||
603 | case PCI_DEVICE_ID_DW2004: | ||
604 | dm1105dvb->fe = dvb_attach( | 624 | dm1105dvb->fe = dvb_attach( |
605 | cx24116_attach, &serit_sp2633_config, | 625 | si21xx_attach, &serit_config, |
606 | &dm1105dvb->i2c_adap); | 626 | &dm1105dvb->i2c_adap); |
607 | if (dm1105dvb->fe) | 627 | if (dm1105dvb->fe) |
608 | dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; | 628 | dm1105dvb->fe->ops.set_voltage = |
609 | break; | 629 | dm1105dvb_set_voltage; |
630 | |||
610 | } | 631 | } |
611 | 632 | ||
612 | if (!dm1105dvb->fe) { | 633 | if (!dm1105dvb->fe) { |
@@ -630,10 +651,17 @@ static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac) | |||
630 | static u8 command[1] = { 0x28 }; | 651 | static u8 command[1] = { 0x28 }; |
631 | 652 | ||
632 | struct i2c_msg msg[] = { | 653 | struct i2c_msg msg[] = { |
633 | { .addr = IIC_24C01_addr >> 1, .flags = 0, | 654 | { |
634 | .buf = command, .len = 1 }, | 655 | .addr = IIC_24C01_addr >> 1, |
635 | { .addr = IIC_24C01_addr >> 1, .flags = I2C_M_RD, | 656 | .flags = 0, |
636 | .buf = mac, .len = 6 }, | 657 | .buf = command, |
658 | .len = 1 | ||
659 | }, { | ||
660 | .addr = IIC_24C01_addr >> 1, | ||
661 | .flags = I2C_M_RD, | ||
662 | .buf = mac, | ||
663 | .len = 6 | ||
664 | }, | ||
637 | }; | 665 | }; |
638 | 666 | ||
639 | dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2); | 667 | dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2); |
@@ -752,14 +780,22 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, | |||
752 | dm1105_ir_init(dm1105dvb); | 780 | dm1105_ir_init(dm1105dvb); |
753 | 781 | ||
754 | INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer); | 782 | INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer); |
783 | sprintf(dm1105dvb->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num); | ||
784 | dm1105dvb->wq = create_singlethread_workqueue(dm1105dvb->wqn); | ||
785 | if (!dm1105dvb->wq) | ||
786 | goto err_dvb_net; | ||
755 | 787 | ||
756 | ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, | 788 | ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, |
757 | DRIVER_NAME, dm1105dvb); | 789 | DRIVER_NAME, dm1105dvb); |
758 | if (ret < 0) | 790 | if (ret < 0) |
759 | goto err_free_irq; | 791 | goto err_workqueue; |
760 | 792 | ||
761 | return 0; | 793 | return 0; |
762 | 794 | ||
795 | err_workqueue: | ||
796 | destroy_workqueue(dm1105dvb->wq); | ||
797 | err_dvb_net: | ||
798 | dvb_net_release(&dm1105dvb->dvbnet); | ||
763 | err_disconnect_frontend: | 799 | err_disconnect_frontend: |
764 | dmx->disconnect_frontend(dmx); | 800 | dmx->disconnect_frontend(dmx); |
765 | err_remove_mem_frontend: | 801 | err_remove_mem_frontend: |
@@ -776,8 +812,6 @@ err_i2c_del_adapter: | |||
776 | i2c_del_adapter(&dm1105dvb->i2c_adap); | 812 | i2c_del_adapter(&dm1105dvb->i2c_adap); |
777 | err_dm1105dvb_hw_exit: | 813 | err_dm1105dvb_hw_exit: |
778 | dm1105dvb_hw_exit(dm1105dvb); | 814 | dm1105dvb_hw_exit(dm1105dvb); |
779 | err_free_irq: | ||
780 | free_irq(pdev->irq, dm1105dvb); | ||
781 | err_pci_iounmap: | 815 | err_pci_iounmap: |
782 | pci_iounmap(pdev, dm1105dvb->io_mem); | 816 | pci_iounmap(pdev, dm1105dvb->io_mem); |
783 | err_pci_release_regions: | 817 | err_pci_release_regions: |
@@ -834,6 +868,11 @@ static struct pci_device_id dm1105_id_table[] __devinitdata = { | |||
834 | .subvendor = PCI_ANY_ID, | 868 | .subvendor = PCI_ANY_ID, |
835 | .subdevice = PCI_DEVICE_ID_DW2004, | 869 | .subdevice = PCI_DEVICE_ID_DW2004, |
836 | }, { | 870 | }, { |
871 | .vendor = PCI_VENDOR_ID_AXESS, | ||
872 | .device = PCI_DEVICE_ID_DM05, | ||
873 | .subvendor = PCI_VENDOR_ID_AXESS, | ||
874 | .subdevice = PCI_DEVICE_ID_DM05, | ||
875 | }, { | ||
837 | /* empty */ | 876 | /* empty */ |
838 | }, | 877 | }, |
839 | }; | 878 | }; |
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index c35fbb8d8f4a..6d6121eb5d59 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c | |||
@@ -244,19 +244,13 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, | |||
244 | { | 244 | { |
245 | struct dvb_device *dvbdev = file->private_data; | 245 | struct dvb_device *dvbdev = file->private_data; |
246 | struct dmxdev *dmxdev = dvbdev->priv; | 246 | struct dmxdev *dmxdev = dvbdev->priv; |
247 | int ret; | ||
248 | 247 | ||
249 | if (dmxdev->exit) { | 248 | if (dmxdev->exit) |
250 | mutex_unlock(&dmxdev->mutex); | ||
251 | return -ENODEV; | 249 | return -ENODEV; |
252 | } | ||
253 | 250 | ||
254 | //mutex_lock(&dmxdev->mutex); | 251 | return dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, |
255 | ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, | 252 | file->f_flags & O_NONBLOCK, |
256 | file->f_flags & O_NONBLOCK, | 253 | buf, count, ppos); |
257 | buf, count, ppos); | ||
258 | //mutex_unlock(&dmxdev->mutex); | ||
259 | return ret; | ||
260 | } | 254 | } |
261 | 255 | ||
262 | static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev, | 256 | static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev, |
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index e2eca0b1fe7c..cfe2768d24af 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c | |||
@@ -38,6 +38,16 @@ | |||
38 | */ | 38 | */ |
39 | // #define DVB_DEMUX_SECTION_LOSS_LOG | 39 | // #define DVB_DEMUX_SECTION_LOSS_LOG |
40 | 40 | ||
41 | static int dvb_demux_tscheck; | ||
42 | module_param(dvb_demux_tscheck, int, 0644); | ||
43 | MODULE_PARM_DESC(dvb_demux_tscheck, | ||
44 | "enable transport stream continuity and TEI check"); | ||
45 | |||
46 | #define dprintk_tscheck(x...) do { \ | ||
47 | if (dvb_demux_tscheck && printk_ratelimit()) \ | ||
48 | printk(x); \ | ||
49 | } while (0) | ||
50 | |||
41 | /****************************************************************************** | 51 | /****************************************************************************** |
42 | * static inlined helper functions | 52 | * static inlined helper functions |
43 | ******************************************************************************/ | 53 | ******************************************************************************/ |
@@ -376,6 +386,36 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) | |||
376 | u16 pid = ts_pid(buf); | 386 | u16 pid = ts_pid(buf); |
377 | int dvr_done = 0; | 387 | int dvr_done = 0; |
378 | 388 | ||
389 | if (dvb_demux_tscheck) { | ||
390 | if (!demux->cnt_storage) | ||
391 | demux->cnt_storage = vmalloc(MAX_PID + 1); | ||
392 | |||
393 | if (!demux->cnt_storage) { | ||
394 | printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n"); | ||
395 | dvb_demux_tscheck = 0; | ||
396 | goto no_dvb_demux_tscheck; | ||
397 | } | ||
398 | |||
399 | /* check pkt counter */ | ||
400 | if (pid < MAX_PID) { | ||
401 | if (buf[1] & 0x80) | ||
402 | dprintk_tscheck("TEI detected. " | ||
403 | "PID=0x%x data1=0x%x\n", | ||
404 | pid, buf[1]); | ||
405 | |||
406 | if ((buf[3] & 0xf) != demux->cnt_storage[pid]) | ||
407 | dprintk_tscheck("TS packet counter mismatch. " | ||
408 | "PID=0x%x expected 0x%x " | ||
409 | "got 0x%x\n", | ||
410 | pid, demux->cnt_storage[pid], | ||
411 | buf[3] & 0xf); | ||
412 | |||
413 | demux->cnt_storage[pid] = ((buf[3] & 0xf) + 1)&0xf; | ||
414 | }; | ||
415 | /* end check */ | ||
416 | }; | ||
417 | no_dvb_demux_tscheck: | ||
418 | |||
379 | list_for_each_entry(feed, &demux->feed_list, list_head) { | 419 | list_for_each_entry(feed, &demux->feed_list, list_head) { |
380 | if ((feed->pid != pid) && (feed->pid != 0x2000)) | 420 | if ((feed->pid != pid) && (feed->pid != 0x2000)) |
381 | continue; | 421 | continue; |
@@ -1160,6 +1200,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) | |||
1160 | int i; | 1200 | int i; |
1161 | struct dmx_demux *dmx = &dvbdemux->dmx; | 1201 | struct dmx_demux *dmx = &dvbdemux->dmx; |
1162 | 1202 | ||
1203 | dvbdemux->cnt_storage = NULL; | ||
1163 | dvbdemux->users = 0; | 1204 | dvbdemux->users = 0; |
1164 | dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter)); | 1205 | dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter)); |
1165 | 1206 | ||
@@ -1226,6 +1267,7 @@ EXPORT_SYMBOL(dvb_dmx_init); | |||
1226 | 1267 | ||
1227 | void dvb_dmx_release(struct dvb_demux *dvbdemux) | 1268 | void dvb_dmx_release(struct dvb_demux *dvbdemux) |
1228 | { | 1269 | { |
1270 | vfree(dvbdemux->cnt_storage); | ||
1229 | vfree(dvbdemux->filter); | 1271 | vfree(dvbdemux->filter); |
1230 | vfree(dvbdemux->feed); | 1272 | vfree(dvbdemux->feed); |
1231 | } | 1273 | } |
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h index 2c5f915329ca..2fe05d03240d 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.h +++ b/drivers/media/dvb/dvb-core/dvb_demux.h | |||
@@ -42,6 +42,8 @@ | |||
42 | 42 | ||
43 | #define DVB_DEMUX_MASK_MAX 18 | 43 | #define DVB_DEMUX_MASK_MAX 18 |
44 | 44 | ||
45 | #define MAX_PID 0x1fff | ||
46 | |||
45 | struct dvb_demux_filter { | 47 | struct dvb_demux_filter { |
46 | struct dmx_section_filter filter; | 48 | struct dmx_section_filter filter; |
47 | u8 maskandmode[DMX_MAX_FILTER_SIZE]; | 49 | u8 maskandmode[DMX_MAX_FILTER_SIZE]; |
@@ -127,6 +129,8 @@ struct dvb_demux { | |||
127 | 129 | ||
128 | struct mutex mutex; | 130 | struct mutex mutex; |
129 | spinlock_t lock; | 131 | spinlock_t lock; |
132 | |||
133 | uint8_t *cnt_storage; /* for TS continuity check */ | ||
130 | }; | 134 | }; |
131 | 135 | ||
132 | int dvb_dmx_init(struct dvb_demux *dvbdemux); | 136 | int dvb_dmx_init(struct dvb_demux *dvbdemux); |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index ebc78157b9b8..f50ca7292a7d 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -543,6 +543,7 @@ restart: | |||
543 | 543 | ||
544 | if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { | 544 | if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { |
545 | /* got signal or quitting */ | 545 | /* got signal or quitting */ |
546 | fepriv->exit = 1; | ||
546 | break; | 547 | break; |
547 | } | 548 | } |
548 | 549 | ||
@@ -656,6 +657,7 @@ restart: | |||
656 | } | 657 | } |
657 | 658 | ||
658 | fepriv->thread = NULL; | 659 | fepriv->thread = NULL; |
660 | fepriv->exit = 0; | ||
659 | mb(); | 661 | mb(); |
660 | 662 | ||
661 | dvb_frontend_wakeup(fe); | 663 | dvb_frontend_wakeup(fe); |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 1bb66e1ed5a7..496c1a37034c 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -261,6 +261,7 @@ config DVB_USB_DW2102 | |||
261 | select DVB_STB6000 if !DVB_FE_CUSTOMISE | 261 | select DVB_STB6000 if !DVB_FE_CUSTOMISE |
262 | select DVB_CX24116 if !DVB_FE_CUSTOMISE | 262 | select DVB_CX24116 if !DVB_FE_CUSTOMISE |
263 | select DVB_SI21XX if !DVB_FE_CUSTOMISE | 263 | select DVB_SI21XX if !DVB_FE_CUSTOMISE |
264 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE | ||
264 | help | 265 | help |
265 | Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers | 266 | Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers |
266 | and the TeVii S650. | 267 | and the TeVii S650. |
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 53bfc8e42fb9..4cb31e7c13c2 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c | |||
@@ -40,7 +40,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |||
40 | static DEFINE_MUTEX(af9015_usb_mutex); | 40 | static DEFINE_MUTEX(af9015_usb_mutex); |
41 | 41 | ||
42 | static struct af9015_config af9015_config; | 42 | static struct af9015_config af9015_config; |
43 | static struct dvb_usb_device_properties af9015_properties[2]; | 43 | static struct dvb_usb_device_properties af9015_properties[3]; |
44 | static int af9015_properties_count = ARRAY_SIZE(af9015_properties); | 44 | static int af9015_properties_count = ARRAY_SIZE(af9015_properties); |
45 | 45 | ||
46 | static struct af9013_config af9015_af9013_config[] = { | 46 | static struct af9013_config af9015_af9013_config[] = { |
@@ -538,7 +538,7 @@ exit: | |||
538 | /* dump eeprom */ | 538 | /* dump eeprom */ |
539 | static int af9015_eeprom_dump(struct dvb_usb_device *d) | 539 | static int af9015_eeprom_dump(struct dvb_usb_device *d) |
540 | { | 540 | { |
541 | char buf[52], buf2[4]; | 541 | char buf[4+3*16+1], buf2[4]; |
542 | u8 reg, val; | 542 | u8 reg, val; |
543 | 543 | ||
544 | for (reg = 0; ; reg++) { | 544 | for (reg = 0; ; reg++) { |
@@ -1261,7 +1261,11 @@ static struct usb_device_id af9015_usb_table[] = { | |||
1261 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, | 1261 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, |
1262 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)}, | 1262 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)}, |
1263 | {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)}, | 1263 | {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)}, |
1264 | {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, | 1264 | /* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, |
1265 | {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)}, | ||
1266 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)}, | ||
1267 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, | ||
1268 | {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, | ||
1265 | {0}, | 1269 | {0}, |
1266 | }; | 1270 | }; |
1267 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); | 1271 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); |
@@ -1321,7 +1325,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1321 | 1325 | ||
1322 | .i2c_algo = &af9015_i2c_algo, | 1326 | .i2c_algo = &af9015_i2c_algo, |
1323 | 1327 | ||
1324 | .num_device_descs = 9, | 1328 | .num_device_descs = 9, /* max 9 */ |
1325 | .devices = { | 1329 | .devices = { |
1326 | { | 1330 | { |
1327 | .name = "Afatech AF9015 DVB-T USB2.0 stick", | 1331 | .name = "Afatech AF9015 DVB-T USB2.0 stick", |
@@ -1426,7 +1430,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1426 | 1430 | ||
1427 | .i2c_algo = &af9015_i2c_algo, | 1431 | .i2c_algo = &af9015_i2c_algo, |
1428 | 1432 | ||
1429 | .num_device_descs = 9, | 1433 | .num_device_descs = 9, /* max 9 */ |
1430 | .devices = { | 1434 | .devices = { |
1431 | { | 1435 | { |
1432 | .name = "Xtensions XD-380", | 1436 | .name = "Xtensions XD-380", |
@@ -1478,7 +1482,85 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1478 | .warm_ids = {NULL}, | 1482 | .warm_ids = {NULL}, |
1479 | }, | 1483 | }, |
1480 | } | 1484 | } |
1481 | } | 1485 | }, { |
1486 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
1487 | |||
1488 | .usb_ctrl = DEVICE_SPECIFIC, | ||
1489 | .download_firmware = af9015_download_firmware, | ||
1490 | .firmware = "dvb-usb-af9015.fw", | ||
1491 | .no_reconnect = 1, | ||
1492 | |||
1493 | .size_of_priv = sizeof(struct af9015_state), \ | ||
1494 | |||
1495 | .num_adapters = 2, | ||
1496 | .adapter = { | ||
1497 | { | ||
1498 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
1499 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
1500 | |||
1501 | .pid_filter_count = 32, | ||
1502 | .pid_filter = af9015_pid_filter, | ||
1503 | .pid_filter_ctrl = af9015_pid_filter_ctrl, | ||
1504 | |||
1505 | .frontend_attach = | ||
1506 | af9015_af9013_frontend_attach, | ||
1507 | .tuner_attach = af9015_tuner_attach, | ||
1508 | .stream = { | ||
1509 | .type = USB_BULK, | ||
1510 | .count = 6, | ||
1511 | .endpoint = 0x84, | ||
1512 | }, | ||
1513 | }, | ||
1514 | { | ||
1515 | .frontend_attach = | ||
1516 | af9015_af9013_frontend_attach, | ||
1517 | .tuner_attach = af9015_tuner_attach, | ||
1518 | .stream = { | ||
1519 | .type = USB_BULK, | ||
1520 | .count = 6, | ||
1521 | .endpoint = 0x85, | ||
1522 | .u = { | ||
1523 | .bulk = { | ||
1524 | .buffersize = | ||
1525 | TS_USB20_MAX_PACKET_SIZE, | ||
1526 | } | ||
1527 | } | ||
1528 | }, | ||
1529 | } | ||
1530 | }, | ||
1531 | |||
1532 | .identify_state = af9015_identify_state, | ||
1533 | |||
1534 | .rc_query = af9015_rc_query, | ||
1535 | .rc_interval = 150, | ||
1536 | |||
1537 | .i2c_algo = &af9015_i2c_algo, | ||
1538 | |||
1539 | .num_device_descs = 4, /* max 9 */ | ||
1540 | .devices = { | ||
1541 | { | ||
1542 | .name = "AverMedia AVerTV Volar GPS 805 (A805)", | ||
1543 | .cold_ids = {&af9015_usb_table[21], NULL}, | ||
1544 | .warm_ids = {NULL}, | ||
1545 | }, | ||
1546 | { | ||
1547 | .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \ | ||
1548 | "V3.0", | ||
1549 | .cold_ids = {&af9015_usb_table[22], NULL}, | ||
1550 | .warm_ids = {NULL}, | ||
1551 | }, | ||
1552 | { | ||
1553 | .name = "KWorld Digial MC-810", | ||
1554 | .cold_ids = {&af9015_usb_table[23], NULL}, | ||
1555 | .warm_ids = {NULL}, | ||
1556 | }, | ||
1557 | { | ||
1558 | .name = "Genius TVGo DVB-T03", | ||
1559 | .cold_ids = {&af9015_usb_table[24], NULL}, | ||
1560 | .warm_ids = {NULL}, | ||
1561 | }, | ||
1562 | } | ||
1563 | }, | ||
1482 | }; | 1564 | }; |
1483 | 1565 | ||
1484 | static int af9015_usb_probe(struct usb_interface *intf, | 1566 | static int af9015_usb_probe(struct usb_interface *intf, |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 8ddbadf62194..818b2ab584bf 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
@@ -1346,9 +1346,9 @@ static int dib0700_xc5000_tuner_callback(void *priv, int component, | |||
1346 | if (command == XC5000_TUNER_RESET) { | 1346 | if (command == XC5000_TUNER_RESET) { |
1347 | /* Reset the tuner */ | 1347 | /* Reset the tuner */ |
1348 | dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0); | 1348 | dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0); |
1349 | msleep(330); /* from Windows USB trace */ | 1349 | msleep(10); |
1350 | dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1); | 1350 | dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1); |
1351 | msleep(330); /* from Windows USB trace */ | 1351 | msleep(10); |
1352 | } else { | 1352 | } else { |
1353 | err("xc5000: unknown tuner callback command: %d\n", command); | 1353 | err("xc5000: unknown tuner callback command: %d\n", command); |
1354 | return -EINVAL; | 1354 | return -EINVAL; |
@@ -1493,6 +1493,10 @@ struct usb_device_id dib0700_usb_id_table[] = { | |||
1493 | { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) }, | 1493 | { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) }, |
1494 | { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) }, | 1494 | { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) }, |
1495 | { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) }, | 1495 | { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) }, |
1496 | /* 50 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_Dlx) }, | ||
1497 | { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_H) }, | ||
1498 | { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) }, | ||
1499 | { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) }, | ||
1496 | { 0 } /* Terminating entry */ | 1500 | { 0 } /* Terminating entry */ |
1497 | }; | 1501 | }; |
1498 | MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); | 1502 | MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); |
@@ -1692,7 +1696,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
1692 | }, | 1696 | }, |
1693 | }, | 1697 | }, |
1694 | 1698 | ||
1695 | .num_device_descs = 11, | 1699 | .num_device_descs = 12, |
1696 | .devices = { | 1700 | .devices = { |
1697 | { "DiBcom STK7070P reference design", | 1701 | { "DiBcom STK7070P reference design", |
1698 | { &dib0700_usb_id_table[15], NULL }, | 1702 | { &dib0700_usb_id_table[15], NULL }, |
@@ -1726,8 +1730,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
1726 | { &dib0700_usb_id_table[30], NULL }, | 1730 | { &dib0700_usb_id_table[30], NULL }, |
1727 | { NULL }, | 1731 | { NULL }, |
1728 | }, | 1732 | }, |
1729 | { "Terratec Cinergy T USB XXS", | 1733 | { "Terratec Cinergy T USB XXS/ T3", |
1730 | { &dib0700_usb_id_table[33], NULL }, | 1734 | { &dib0700_usb_id_table[33], |
1735 | &dib0700_usb_id_table[52], NULL }, | ||
1731 | { NULL }, | 1736 | { NULL }, |
1732 | }, | 1737 | }, |
1733 | { "Elgato EyeTV DTT", | 1738 | { "Elgato EyeTV DTT", |
@@ -1738,6 +1743,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
1738 | { &dib0700_usb_id_table[45], NULL }, | 1743 | { &dib0700_usb_id_table[45], NULL }, |
1739 | { NULL }, | 1744 | { NULL }, |
1740 | }, | 1745 | }, |
1746 | { "Elgato EyeTV Dtt Dlx PD378S", | ||
1747 | { &dib0700_usb_id_table[50], NULL }, | ||
1748 | { NULL }, | ||
1749 | }, | ||
1741 | }, | 1750 | }, |
1742 | 1751 | ||
1743 | .rc_interval = DEFAULT_RC_INTERVAL, | 1752 | .rc_interval = DEFAULT_RC_INTERVAL, |
@@ -1784,8 +1793,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
1784 | { &dib0700_usb_id_table[36], NULL }, | 1793 | { &dib0700_usb_id_table[36], NULL }, |
1785 | { NULL }, | 1794 | { NULL }, |
1786 | }, | 1795 | }, |
1787 | { "Terratec Cinergy DT USB XS Diversity", | 1796 | { "Terratec Cinergy DT USB XS Diversity/ T5", |
1788 | { &dib0700_usb_id_table[43], NULL }, | 1797 | { &dib0700_usb_id_table[43], |
1798 | &dib0700_usb_id_table[53], NULL}, | ||
1789 | { NULL }, | 1799 | { NULL }, |
1790 | }, | 1800 | }, |
1791 | { "Sony PlayTV", | 1801 | { "Sony PlayTV", |
@@ -1812,7 +1822,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
1812 | }, | 1822 | }, |
1813 | }, | 1823 | }, |
1814 | 1824 | ||
1815 | .num_device_descs = 7, | 1825 | .num_device_descs = 8, |
1816 | .devices = { | 1826 | .devices = { |
1817 | { "Terratec Cinergy HT USB XE", | 1827 | { "Terratec Cinergy HT USB XE", |
1818 | { &dib0700_usb_id_table[27], NULL }, | 1828 | { &dib0700_usb_id_table[27], NULL }, |
@@ -1842,6 +1852,11 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
1842 | { &dib0700_usb_id_table[48], NULL }, | 1852 | { &dib0700_usb_id_table[48], NULL }, |
1843 | { NULL }, | 1853 | { NULL }, |
1844 | }, | 1854 | }, |
1855 | { "Leadtek WinFast DTV Dongle H", | ||
1856 | { &dib0700_usb_id_table[51], NULL }, | ||
1857 | { NULL }, | ||
1858 | }, | ||
1859 | |||
1845 | }, | 1860 | }, |
1846 | .rc_interval = DEFAULT_RC_INTERVAL, | 1861 | .rc_interval = DEFAULT_RC_INTERVAL, |
1847 | .rc_key_map = dib0700_rc_keys, | 1862 | .rc_key_map = dib0700_rc_keys, |
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 8ee6cd4da9e7..8dbad1ec53c4 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c | |||
@@ -133,14 +133,17 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num | |||
133 | 133 | ||
134 | for (i = 0; i < num; i++) { | 134 | for (i = 0; i < num; i++) { |
135 | /* write/read request */ | 135 | /* write/read request */ |
136 | if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { | 136 | if (i+1 < num && (msg[i].flags & I2C_M_RD) == 0 |
137 | && (msg[i+1].flags & I2C_M_RD)) { | ||
137 | if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len, | 138 | if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len, |
138 | msg[i+1].buf,msg[i+1].len) < 0) | 139 | msg[i+1].buf,msg[i+1].len) < 0) |
139 | break; | 140 | break; |
140 | i++; | 141 | i++; |
141 | } else | 142 | } else if ((msg[i].flags & I2C_M_RD) == 0) { |
142 | if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) | 143 | if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) |
143 | break; | 144 | break; |
145 | } else | ||
146 | break; | ||
144 | } | 147 | } |
145 | 148 | ||
146 | mutex_unlock(&d->i2c_mutex); | 149 | mutex_unlock(&d->i2c_mutex); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index f506c74119f3..9593b7289994 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -80,6 +80,7 @@ | |||
80 | #define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d | 80 | #define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d |
81 | #define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78 | 81 | #define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78 |
82 | #define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80 | 82 | #define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80 |
83 | #define USB_PID_CONCEPTRONIC_CTVDIGRCU 0xe397 | ||
83 | #define USB_PID_CONEXANT_D680_DMB 0x86d6 | 84 | #define USB_PID_CONEXANT_D680_DMB 0x86d6 |
84 | #define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 | 85 | #define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 |
85 | #define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 | 86 | #define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 |
@@ -97,6 +98,7 @@ | |||
97 | #define USB_PID_DPOSH_M9206_COLD 0x9206 | 98 | #define USB_PID_DPOSH_M9206_COLD 0x9206 |
98 | #define USB_PID_DPOSH_M9206_WARM 0xa090 | 99 | #define USB_PID_DPOSH_M9206_WARM 0xa090 |
99 | #define USB_PID_UNIWILL_STK7700P 0x6003 | 100 | #define USB_PID_UNIWILL_STK7700P 0x6003 |
101 | #define USB_PID_GENIUS_TVGO_DVB_T03 0x4012 | ||
100 | #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 | 102 | #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 |
101 | #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 | 103 | #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 |
102 | #define USB_PID_INTEL_CE9500 0x9500 | 104 | #define USB_PID_INTEL_CE9500 0x9500 |
@@ -104,6 +106,7 @@ | |||
104 | #define USB_PID_KWORLD_395U 0xe396 | 106 | #define USB_PID_KWORLD_395U 0xe396 |
105 | #define USB_PID_KWORLD_395U_2 0xe39b | 107 | #define USB_PID_KWORLD_395U_2 0xe39b |
106 | #define USB_PID_KWORLD_395U_3 0xe395 | 108 | #define USB_PID_KWORLD_395U_3 0xe395 |
109 | #define USB_PID_KWORLD_MC810 0xc810 | ||
107 | #define USB_PID_KWORLD_PC160_2T 0xc160 | 110 | #define USB_PID_KWORLD_PC160_2T 0xc160 |
108 | #define USB_PID_KWORLD_VSTREAM_COLD 0x17de | 111 | #define USB_PID_KWORLD_VSTREAM_COLD 0x17de |
109 | #define USB_PID_KWORLD_VSTREAM_WARM 0x17df | 112 | #define USB_PID_KWORLD_VSTREAM_WARM 0x17df |
@@ -171,6 +174,7 @@ | |||
171 | #define USB_PID_AVERMEDIA_A309 0xa309 | 174 | #define USB_PID_AVERMEDIA_A309 0xa309 |
172 | #define USB_PID_AVERMEDIA_A310 0xa310 | 175 | #define USB_PID_AVERMEDIA_A310 0xa310 |
173 | #define USB_PID_AVERMEDIA_A850 0x850a | 176 | #define USB_PID_AVERMEDIA_A850 0x850a |
177 | #define USB_PID_AVERMEDIA_A805 0xa805 | ||
174 | #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 | 178 | #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 |
175 | #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a | 179 | #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a |
176 | #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 | 180 | #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 |
@@ -178,6 +182,8 @@ | |||
178 | #define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060 | 182 | #define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060 |
179 | #define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 | 183 | #define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 |
180 | #define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 | 184 | #define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 |
185 | #define USB_PID_TERRATEC_T3 0x10a0 | ||
186 | #define USB_PID_TERRATEC_T5 0x10a1 | ||
181 | #define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e | 187 | #define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e |
182 | #define USB_PID_PINNACLE_PCTV2000E 0x022c | 188 | #define USB_PID_PINNACLE_PCTV2000E 0x022c |
183 | #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 | 189 | #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 |
@@ -222,6 +228,7 @@ | |||
222 | #define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 | 228 | #define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 |
223 | #define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 | 229 | #define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 |
224 | #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 | 230 | #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 |
231 | #define USB_PID_WINFAST_DTV_DONGLE_H 0x60f6 | ||
225 | #define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01 | 232 | #define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01 |
226 | #define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029 | 233 | #define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029 |
227 | #define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200 | 234 | #define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200 |
@@ -251,5 +258,6 @@ | |||
251 | #define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 | 258 | #define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 |
252 | #define USB_PID_SONY_PLAYTV 0x0003 | 259 | #define USB_PID_SONY_PLAYTV 0x0003 |
253 | #define USB_PID_ELGATO_EYETV_DTT 0x0021 | 260 | #define USB_PID_ELGATO_EYETV_DTT 0x0021 |
261 | #define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 | ||
254 | 262 | ||
255 | #endif | 263 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index b5157518a300..e441d274e6c1 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
@@ -223,7 +223,7 @@ struct dvb_usb_device_properties { | |||
223 | int generic_bulk_ctrl_endpoint; | 223 | int generic_bulk_ctrl_endpoint; |
224 | 224 | ||
225 | int num_device_descs; | 225 | int num_device_descs; |
226 | struct dvb_usb_device_description devices[11]; | 226 | struct dvb_usb_device_description devices[12]; |
227 | }; | 227 | }; |
228 | 228 | ||
229 | /** | 229 | /** |
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index c65f273ff313..75de49c0d943 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* DVB USB framework compliant Linux driver for the | 1 | /* DVB USB framework compliant Linux driver for the |
2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104 Card | 2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, |
3 | * | 3 | * TeVii S600, S650 Cards |
4 | * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) | 4 | * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
@@ -17,6 +17,7 @@ | |||
17 | #include "stb6000.h" | 17 | #include "stb6000.h" |
18 | #include "eds1547.h" | 18 | #include "eds1547.h" |
19 | #include "cx24116.h" | 19 | #include "cx24116.h" |
20 | #include "tda1002x.h" | ||
20 | 21 | ||
21 | #ifndef USB_PID_DW2102 | 22 | #ifndef USB_PID_DW2102 |
22 | #define USB_PID_DW2102 0x2102 | 23 | #define USB_PID_DW2102 0x2102 |
@@ -26,10 +27,18 @@ | |||
26 | #define USB_PID_DW2104 0x2104 | 27 | #define USB_PID_DW2104 0x2104 |
27 | #endif | 28 | #endif |
28 | 29 | ||
30 | #ifndef USB_PID_DW3101 | ||
31 | #define USB_PID_DW3101 0x3101 | ||
32 | #endif | ||
33 | |||
29 | #ifndef USB_PID_CINERGY_S | 34 | #ifndef USB_PID_CINERGY_S |
30 | #define USB_PID_CINERGY_S 0x0064 | 35 | #define USB_PID_CINERGY_S 0x0064 |
31 | #endif | 36 | #endif |
32 | 37 | ||
38 | #ifndef USB_PID_TEVII_S650 | ||
39 | #define USB_PID_TEVII_S650 0xd650 | ||
40 | #endif | ||
41 | |||
33 | #define DW210X_READ_MSG 0 | 42 | #define DW210X_READ_MSG 0 |
34 | #define DW210X_WRITE_MSG 1 | 43 | #define DW210X_WRITE_MSG 1 |
35 | 44 | ||
@@ -40,18 +49,21 @@ | |||
40 | #define DW2102_VOLTAGE_CTRL (0x1800) | 49 | #define DW2102_VOLTAGE_CTRL (0x1800) |
41 | #define DW2102_RC_QUERY (0x1a00) | 50 | #define DW2102_RC_QUERY (0x1a00) |
42 | 51 | ||
43 | struct dw210x_state { | 52 | struct dvb_usb_rc_keys_table { |
44 | u32 last_key_pressed; | 53 | struct dvb_usb_rc_key *rc_keys; |
45 | }; | 54 | int rc_keys_size; |
46 | struct dw210x_rc_keys { | ||
47 | u32 keycode; | ||
48 | u32 event; | ||
49 | }; | 55 | }; |
50 | 56 | ||
51 | /* debug */ | 57 | /* debug */ |
52 | static int dvb_usb_dw2102_debug; | 58 | static int dvb_usb_dw2102_debug; |
53 | module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); | 59 | module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); |
54 | MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); | 60 | MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." |
61 | DVB_USB_DEBUG_STATUS); | ||
62 | |||
63 | /* keymaps */ | ||
64 | static int ir_keymap; | ||
65 | module_param_named(keymap, ir_keymap, int, 0644); | ||
66 | MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); | ||
55 | 67 | ||
56 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 68 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
57 | 69 | ||
@@ -79,7 +91,7 @@ static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, | |||
79 | static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | 91 | static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], |
80 | int num) | 92 | int num) |
81 | { | 93 | { |
82 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 94 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
83 | int i = 0, ret = 0; | 95 | int i = 0, ret = 0; |
84 | u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; | 96 | u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; |
85 | u16 value; | 97 | u16 value; |
@@ -205,6 +217,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, | |||
205 | mutex_unlock(&d->i2c_mutex); | 217 | mutex_unlock(&d->i2c_mutex); |
206 | return num; | 218 | return num; |
207 | } | 219 | } |
220 | |||
208 | static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) | 221 | static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) |
209 | { | 222 | { |
210 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 223 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
@@ -219,7 +232,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms | |||
219 | case 2: { | 232 | case 2: { |
220 | /* read */ | 233 | /* read */ |
221 | /* first write first register number */ | 234 | /* first write first register number */ |
222 | u8 ibuf [msg[1].len + 2], obuf[3]; | 235 | u8 ibuf[msg[1].len + 2], obuf[3]; |
223 | obuf[0] = 0xd0; | 236 | obuf[0] = 0xd0; |
224 | obuf[1] = msg[0].len; | 237 | obuf[1] = msg[0].len; |
225 | obuf[2] = msg[0].buf[0]; | 238 | obuf[2] = msg[0].buf[0]; |
@@ -293,7 +306,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i | |||
293 | case 2: { | 306 | case 2: { |
294 | /* read */ | 307 | /* read */ |
295 | /* first write first register number */ | 308 | /* first write first register number */ |
296 | u8 ibuf [msg[1].len + 2], obuf[3]; | 309 | u8 ibuf[msg[1].len + 2], obuf[3]; |
297 | obuf[0] = 0xaa; | 310 | obuf[0] = 0xaa; |
298 | obuf[1] = msg[0].len; | 311 | obuf[1] = msg[0].len; |
299 | obuf[2] = msg[0].buf[0]; | 312 | obuf[2] = msg[0].buf[0]; |
@@ -360,6 +373,69 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i | |||
360 | return num; | 373 | return num; |
361 | } | 374 | } |
362 | 375 | ||
376 | static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||
377 | int num) | ||
378 | { | ||
379 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||
380 | int ret = 0, i; | ||
381 | |||
382 | if (!d) | ||
383 | return -ENODEV; | ||
384 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
385 | return -EAGAIN; | ||
386 | |||
387 | switch (num) { | ||
388 | case 2: { | ||
389 | /* read */ | ||
390 | /* first write first register number */ | ||
391 | u8 ibuf[msg[1].len + 2], obuf[3]; | ||
392 | obuf[0] = msg[0].addr << 1; | ||
393 | obuf[1] = msg[0].len; | ||
394 | obuf[2] = msg[0].buf[0]; | ||
395 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
396 | obuf, msg[0].len + 2, DW210X_WRITE_MSG); | ||
397 | /* second read registers */ | ||
398 | ret = dw210x_op_rw(d->udev, 0xc3, 0x19 , 0, | ||
399 | ibuf, msg[1].len + 2, DW210X_READ_MSG); | ||
400 | memcpy(msg[1].buf, ibuf + 2, msg[1].len); | ||
401 | |||
402 | break; | ||
403 | } | ||
404 | case 1: | ||
405 | switch (msg[0].addr) { | ||
406 | case 0x60: | ||
407 | case 0x0c: { | ||
408 | /* write to register */ | ||
409 | u8 obuf[msg[0].len + 2]; | ||
410 | obuf[0] = msg[0].addr << 1; | ||
411 | obuf[1] = msg[0].len; | ||
412 | memcpy(obuf + 2, msg[0].buf, msg[0].len); | ||
413 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
414 | obuf, msg[0].len + 2, DW210X_WRITE_MSG); | ||
415 | break; | ||
416 | } | ||
417 | case(DW2102_RC_QUERY): { | ||
418 | u8 ibuf[2]; | ||
419 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, | ||
420 | ibuf, 2, DW210X_READ_MSG); | ||
421 | memcpy(msg[0].buf, ibuf , 2); | ||
422 | break; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | break; | ||
427 | } | ||
428 | |||
429 | for (i = 0; i < num; i++) { | ||
430 | deb_xfer("%02x:%02x: %s ", i, msg[i].addr, | ||
431 | msg[i].flags == 0 ? ">>>" : "<<<"); | ||
432 | debug_dump(msg[i].buf, msg[i].len, deb_xfer); | ||
433 | } | ||
434 | |||
435 | mutex_unlock(&d->i2c_mutex); | ||
436 | return num; | ||
437 | } | ||
438 | |||
363 | static u32 dw210x_i2c_func(struct i2c_adapter *adapter) | 439 | static u32 dw210x_i2c_func(struct i2c_adapter *adapter) |
364 | { | 440 | { |
365 | return I2C_FUNC_I2C; | 441 | return I2C_FUNC_I2C; |
@@ -385,6 +461,11 @@ static struct i2c_algorithm dw2104_i2c_algo = { | |||
385 | .functionality = dw210x_i2c_func, | 461 | .functionality = dw210x_i2c_func, |
386 | }; | 462 | }; |
387 | 463 | ||
464 | static struct i2c_algorithm dw3101_i2c_algo = { | ||
465 | .master_xfer = dw3101_i2c_transfer, | ||
466 | .functionality = dw210x_i2c_func, | ||
467 | }; | ||
468 | |||
388 | static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | 469 | static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) |
389 | { | 470 | { |
390 | int i; | 471 | int i; |
@@ -404,6 +485,7 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | |||
404 | debug_dump(eepromline, 16, deb_xfer); | 485 | debug_dump(eepromline, 16, deb_xfer); |
405 | } | 486 | } |
406 | } | 487 | } |
488 | |||
407 | memcpy(mac, eeprom + 8, 6); | 489 | memcpy(mac, eeprom + 8, 6); |
408 | return 0; | 490 | return 0; |
409 | }; | 491 | }; |
@@ -448,6 +530,11 @@ static struct si21xx_config serit_sp1511lhb_config = { | |||
448 | 530 | ||
449 | }; | 531 | }; |
450 | 532 | ||
533 | static struct tda10023_config dw3101_tda10023_config = { | ||
534 | .demod_address = 0x0c, | ||
535 | .invert = 1, | ||
536 | }; | ||
537 | |||
451 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | 538 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) |
452 | { | 539 | { |
453 | if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, | 540 | if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, |
@@ -460,6 +547,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | |||
460 | } | 547 | } |
461 | 548 | ||
462 | static struct dvb_usb_device_properties dw2102_properties; | 549 | static struct dvb_usb_device_properties dw2102_properties; |
550 | static struct dvb_usb_device_properties dw2104_properties; | ||
463 | 551 | ||
464 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) | 552 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) |
465 | { | 553 | { |
@@ -497,6 +585,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) | |||
497 | return -EIO; | 585 | return -EIO; |
498 | } | 586 | } |
499 | 587 | ||
588 | static int dw3101_frontend_attach(struct dvb_usb_adapter *d) | ||
589 | { | ||
590 | d->fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config, | ||
591 | &d->dev->i2c_adap, 0x48); | ||
592 | if (d->fe != NULL) { | ||
593 | info("Attached tda10023!\n"); | ||
594 | return 0; | ||
595 | } | ||
596 | return -EIO; | ||
597 | } | ||
598 | |||
500 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) | 599 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) |
501 | { | 600 | { |
502 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, | 601 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, |
@@ -512,6 +611,14 @@ static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap) | |||
512 | return 0; | 611 | return 0; |
513 | } | 612 | } |
514 | 613 | ||
614 | static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) | ||
615 | { | ||
616 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, | ||
617 | &adap->dev->i2c_adap, DVB_PLL_TUA6034); | ||
618 | |||
619 | return 0; | ||
620 | } | ||
621 | |||
515 | static struct dvb_usb_rc_key dw210x_rc_keys[] = { | 622 | static struct dvb_usb_rc_key dw210x_rc_keys[] = { |
516 | { 0xf8, 0x0a, KEY_Q }, /*power*/ | 623 | { 0xf8, 0x0a, KEY_Q }, /*power*/ |
517 | { 0xf8, 0x0c, KEY_M }, /*mute*/ | 624 | { 0xf8, 0x0c, KEY_M }, /*mute*/ |
@@ -544,44 +651,147 @@ static struct dvb_usb_rc_key dw210x_rc_keys[] = { | |||
544 | { 0xf8, 0x40, KEY_F }, /*full*/ | 651 | { 0xf8, 0x40, KEY_F }, /*full*/ |
545 | { 0xf8, 0x1e, KEY_W }, /*tvmode*/ | 652 | { 0xf8, 0x1e, KEY_W }, /*tvmode*/ |
546 | { 0xf8, 0x1b, KEY_B }, /*recall*/ | 653 | { 0xf8, 0x1b, KEY_B }, /*recall*/ |
654 | }; | ||
547 | 655 | ||
656 | static struct dvb_usb_rc_key tevii_rc_keys[] = { | ||
657 | { 0xf8, 0x0a, KEY_POWER }, | ||
658 | { 0xf8, 0x0c, KEY_MUTE }, | ||
659 | { 0xf8, 0x11, KEY_1 }, | ||
660 | { 0xf8, 0x12, KEY_2 }, | ||
661 | { 0xf8, 0x13, KEY_3 }, | ||
662 | { 0xf8, 0x14, KEY_4 }, | ||
663 | { 0xf8, 0x15, KEY_5 }, | ||
664 | { 0xf8, 0x16, KEY_6 }, | ||
665 | { 0xf8, 0x17, KEY_7 }, | ||
666 | { 0xf8, 0x18, KEY_8 }, | ||
667 | { 0xf8, 0x19, KEY_9 }, | ||
668 | { 0xf8, 0x10, KEY_0 }, | ||
669 | { 0xf8, 0x1c, KEY_MENU }, | ||
670 | { 0xf8, 0x0f, KEY_VOLUMEDOWN }, | ||
671 | { 0xf8, 0x1a, KEY_LAST }, | ||
672 | { 0xf8, 0x0e, KEY_OPEN }, | ||
673 | { 0xf8, 0x04, KEY_RECORD }, | ||
674 | { 0xf8, 0x09, KEY_VOLUMEUP }, | ||
675 | { 0xf8, 0x08, KEY_CHANNELUP }, | ||
676 | { 0xf8, 0x07, KEY_PVR }, | ||
677 | { 0xf8, 0x0b, KEY_TIME }, | ||
678 | { 0xf8, 0x02, KEY_RIGHT }, | ||
679 | { 0xf8, 0x03, KEY_LEFT }, | ||
680 | { 0xf8, 0x00, KEY_UP }, | ||
681 | { 0xf8, 0x1f, KEY_OK }, | ||
682 | { 0xf8, 0x01, KEY_DOWN }, | ||
683 | { 0xf8, 0x05, KEY_TUNER }, | ||
684 | { 0xf8, 0x06, KEY_CHANNELDOWN }, | ||
685 | { 0xf8, 0x40, KEY_PLAYPAUSE }, | ||
686 | { 0xf8, 0x1e, KEY_REWIND }, | ||
687 | { 0xf8, 0x1b, KEY_FAVORITES }, | ||
688 | { 0xf8, 0x1d, KEY_BACK }, | ||
689 | { 0xf8, 0x4d, KEY_FASTFORWARD }, | ||
690 | { 0xf8, 0x44, KEY_EPG }, | ||
691 | { 0xf8, 0x4c, KEY_INFO }, | ||
692 | { 0xf8, 0x41, KEY_AB }, | ||
693 | { 0xf8, 0x43, KEY_AUDIO }, | ||
694 | { 0xf8, 0x45, KEY_SUBTITLE }, | ||
695 | { 0xf8, 0x4a, KEY_LIST }, | ||
696 | { 0xf8, 0x46, KEY_F1 }, | ||
697 | { 0xf8, 0x47, KEY_F2 }, | ||
698 | { 0xf8, 0x5e, KEY_F3 }, | ||
699 | { 0xf8, 0x5c, KEY_F4 }, | ||
700 | { 0xf8, 0x52, KEY_F5 }, | ||
701 | { 0xf8, 0x5a, KEY_F6 }, | ||
702 | { 0xf8, 0x56, KEY_MODE }, | ||
703 | { 0xf8, 0x58, KEY_SWITCHVIDEOMODE }, | ||
548 | }; | 704 | }; |
549 | 705 | ||
706 | static struct dvb_usb_rc_key tbs_rc_keys[] = { | ||
707 | { 0xf8, 0x84, KEY_POWER }, | ||
708 | { 0xf8, 0x94, KEY_MUTE }, | ||
709 | { 0xf8, 0x87, KEY_1 }, | ||
710 | { 0xf8, 0x86, KEY_2 }, | ||
711 | { 0xf8, 0x85, KEY_3 }, | ||
712 | { 0xf8, 0x8b, KEY_4 }, | ||
713 | { 0xf8, 0x8a, KEY_5 }, | ||
714 | { 0xf8, 0x89, KEY_6 }, | ||
715 | { 0xf8, 0x8f, KEY_7 }, | ||
716 | { 0xf8, 0x8e, KEY_8 }, | ||
717 | { 0xf8, 0x8d, KEY_9 }, | ||
718 | { 0xf8, 0x92, KEY_0 }, | ||
719 | { 0xf8, 0x96, KEY_CHANNELUP }, | ||
720 | { 0xf8, 0x91, KEY_CHANNELDOWN }, | ||
721 | { 0xf8, 0x93, KEY_VOLUMEUP }, | ||
722 | { 0xf8, 0x8c, KEY_VOLUMEDOWN }, | ||
723 | { 0xf8, 0x83, KEY_RECORD }, | ||
724 | { 0xf8, 0x98, KEY_PAUSE }, | ||
725 | { 0xf8, 0x99, KEY_OK }, | ||
726 | { 0xf8, 0x9a, KEY_SHUFFLE }, | ||
727 | { 0xf8, 0x81, KEY_UP }, | ||
728 | { 0xf8, 0x90, KEY_LEFT }, | ||
729 | { 0xf8, 0x82, KEY_RIGHT }, | ||
730 | { 0xf8, 0x88, KEY_DOWN }, | ||
731 | { 0xf8, 0x95, KEY_FAVORITES }, | ||
732 | { 0xf8, 0x97, KEY_SUBTITLE }, | ||
733 | { 0xf8, 0x9d, KEY_ZOOM }, | ||
734 | { 0xf8, 0x9f, KEY_EXIT }, | ||
735 | { 0xf8, 0x9e, KEY_MENU }, | ||
736 | { 0xf8, 0x9c, KEY_EPG }, | ||
737 | { 0xf8, 0x80, KEY_PREVIOUS }, | ||
738 | { 0xf8, 0x9b, KEY_MODE } | ||
739 | }; | ||
550 | 740 | ||
741 | static struct dvb_usb_rc_keys_table keys_tables[] = { | ||
742 | { dw210x_rc_keys, ARRAY_SIZE(dw210x_rc_keys) }, | ||
743 | { tevii_rc_keys, ARRAY_SIZE(tevii_rc_keys) }, | ||
744 | { tbs_rc_keys, ARRAY_SIZE(tbs_rc_keys) }, | ||
745 | }; | ||
551 | 746 | ||
552 | static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 747 | static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) |
553 | { | 748 | { |
554 | struct dw210x_state *st = d->priv; | 749 | struct dvb_usb_rc_key *keymap = d->props.rc_key_map; |
750 | int keymap_size = d->props.rc_key_map_size; | ||
555 | u8 key[2]; | 751 | u8 key[2]; |
556 | struct i2c_msg msg[] = { | 752 | struct i2c_msg msg = { |
557 | {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key, | 753 | .addr = DW2102_RC_QUERY, |
558 | .len = 2}, | 754 | .flags = I2C_M_RD, |
755 | .buf = key, | ||
756 | .len = 2 | ||
559 | }; | 757 | }; |
560 | int i; | 758 | int i; |
759 | /* override keymap */ | ||
760 | if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) { | ||
761 | keymap = keys_tables[ir_keymap - 1].rc_keys ; | ||
762 | keymap_size = keys_tables[ir_keymap - 1].rc_keys_size; | ||
763 | } | ||
561 | 764 | ||
562 | *state = REMOTE_NO_KEY_PRESSED; | 765 | *state = REMOTE_NO_KEY_PRESSED; |
563 | if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { | 766 | if (dw2102_i2c_transfer(&d->i2c_adap, &msg, 1) == 1) { |
564 | for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) { | 767 | for (i = 0; i < keymap_size ; i++) { |
565 | if (dw210x_rc_keys[i].data == msg[0].buf[0]) { | 768 | if (keymap[i].data == msg.buf[0]) { |
566 | *state = REMOTE_KEY_PRESSED; | 769 | *state = REMOTE_KEY_PRESSED; |
567 | *event = dw210x_rc_keys[i].event; | 770 | *event = keymap[i].event; |
568 | st->last_key_pressed = | ||
569 | dw210x_rc_keys[i].event; | ||
570 | break; | 771 | break; |
571 | } | 772 | } |
572 | st->last_key_pressed = 0; | 773 | |
573 | } | 774 | } |
775 | |||
776 | if ((*state) == REMOTE_KEY_PRESSED) | ||
777 | deb_rc("%s: found rc key: %x, %x, event: %x\n", | ||
778 | __func__, key[0], key[1], (*event)); | ||
779 | else if (key[0] != 0xff) | ||
780 | deb_rc("%s: unknown rc key: %x, %x\n", | ||
781 | __func__, key[0], key[1]); | ||
782 | |||
574 | } | 783 | } |
575 | /* info("key: %x %x\n",key[0],key[1]); */ | 784 | |
576 | return 0; | 785 | return 0; |
577 | } | 786 | } |
578 | 787 | ||
579 | static struct usb_device_id dw2102_table[] = { | 788 | static struct usb_device_id dw2102_table[] = { |
580 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, | 789 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, |
581 | {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, | 790 | {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, |
582 | {USB_DEVICE(USB_VID_CYPRESS, 0x2104)}, | 791 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)}, |
583 | {USB_DEVICE(0x9022, 0xd650)}, | 792 | {USB_DEVICE(0x9022, USB_PID_TEVII_S650)}, |
584 | {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, | 793 | {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, |
794 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, | ||
585 | { } | 795 | { } |
586 | }; | 796 | }; |
587 | 797 | ||
@@ -642,11 +852,16 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
642 | } | 852 | } |
643 | /* init registers */ | 853 | /* init registers */ |
644 | switch (dev->descriptor.idProduct) { | 854 | switch (dev->descriptor.idProduct) { |
855 | case USB_PID_TEVII_S650: | ||
856 | dw2104_properties.rc_key_map = tevii_rc_keys; | ||
857 | dw2104_properties.rc_key_map_size = | ||
858 | ARRAY_SIZE(tevii_rc_keys); | ||
645 | case USB_PID_DW2104: | 859 | case USB_PID_DW2104: |
646 | case 0xd650: | ||
647 | reset = 1; | 860 | reset = 1; |
648 | dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, | 861 | dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, |
649 | DW210X_WRITE_MSG); | 862 | DW210X_WRITE_MSG); |
863 | /* break omitted intentionally */ | ||
864 | case USB_PID_DW3101: | ||
650 | reset = 0; | 865 | reset = 0; |
651 | dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, | 866 | dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, |
652 | DW210X_WRITE_MSG); | 867 | DW210X_WRITE_MSG); |
@@ -690,6 +905,7 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
690 | DW210X_READ_MSG); | 905 | DW210X_READ_MSG); |
691 | break; | 906 | break; |
692 | } | 907 | } |
908 | |||
693 | msleep(100); | 909 | msleep(100); |
694 | kfree(p); | 910 | kfree(p); |
695 | } | 911 | } |
@@ -700,7 +916,6 @@ static struct dvb_usb_device_properties dw2102_properties = { | |||
700 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 916 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
701 | .usb_ctrl = DEVICE_SPECIFIC, | 917 | .usb_ctrl = DEVICE_SPECIFIC, |
702 | .firmware = "dvb-usb-dw2102.fw", | 918 | .firmware = "dvb-usb-dw2102.fw", |
703 | .size_of_priv = sizeof(struct dw210x_state), | ||
704 | .no_reconnect = 1, | 919 | .no_reconnect = 1, |
705 | 920 | ||
706 | .i2c_algo = &dw2102_serit_i2c_algo, | 921 | .i2c_algo = &dw2102_serit_i2c_algo, |
@@ -714,7 +929,7 @@ static struct dvb_usb_device_properties dw2102_properties = { | |||
714 | .num_adapters = 1, | 929 | .num_adapters = 1, |
715 | .download_firmware = dw2102_load_firmware, | 930 | .download_firmware = dw2102_load_firmware, |
716 | .read_mac_address = dw210x_read_mac_address, | 931 | .read_mac_address = dw210x_read_mac_address, |
717 | .adapter = { | 932 | .adapter = { |
718 | { | 933 | { |
719 | .frontend_attach = dw2102_frontend_attach, | 934 | .frontend_attach = dw2102_frontend_attach, |
720 | .streaming_ctrl = NULL, | 935 | .streaming_ctrl = NULL, |
@@ -752,7 +967,6 @@ static struct dvb_usb_device_properties dw2104_properties = { | |||
752 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 967 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
753 | .usb_ctrl = DEVICE_SPECIFIC, | 968 | .usb_ctrl = DEVICE_SPECIFIC, |
754 | .firmware = "dvb-usb-dw2104.fw", | 969 | .firmware = "dvb-usb-dw2104.fw", |
755 | .size_of_priv = sizeof(struct dw210x_state), | ||
756 | .no_reconnect = 1, | 970 | .no_reconnect = 1, |
757 | 971 | ||
758 | .i2c_algo = &dw2104_i2c_algo, | 972 | .i2c_algo = &dw2104_i2c_algo, |
@@ -796,12 +1010,57 @@ static struct dvb_usb_device_properties dw2104_properties = { | |||
796 | } | 1010 | } |
797 | }; | 1011 | }; |
798 | 1012 | ||
1013 | static struct dvb_usb_device_properties dw3101_properties = { | ||
1014 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
1015 | .usb_ctrl = DEVICE_SPECIFIC, | ||
1016 | .firmware = "dvb-usb-dw3101.fw", | ||
1017 | .no_reconnect = 1, | ||
1018 | |||
1019 | .i2c_algo = &dw3101_i2c_algo, | ||
1020 | .rc_key_map = dw210x_rc_keys, | ||
1021 | .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys), | ||
1022 | .rc_interval = 150, | ||
1023 | .rc_query = dw2102_rc_query, | ||
1024 | |||
1025 | .generic_bulk_ctrl_endpoint = 0x81, | ||
1026 | /* parameter for the MPEG2-data transfer */ | ||
1027 | .num_adapters = 1, | ||
1028 | .download_firmware = dw2102_load_firmware, | ||
1029 | .read_mac_address = dw210x_read_mac_address, | ||
1030 | .adapter = { | ||
1031 | { | ||
1032 | .frontend_attach = dw3101_frontend_attach, | ||
1033 | .streaming_ctrl = NULL, | ||
1034 | .tuner_attach = dw3101_tuner_attach, | ||
1035 | .stream = { | ||
1036 | .type = USB_BULK, | ||
1037 | .count = 8, | ||
1038 | .endpoint = 0x82, | ||
1039 | .u = { | ||
1040 | .bulk = { | ||
1041 | .buffersize = 4096, | ||
1042 | } | ||
1043 | } | ||
1044 | }, | ||
1045 | } | ||
1046 | }, | ||
1047 | .num_device_descs = 1, | ||
1048 | .devices = { | ||
1049 | { "DVBWorld DVB-C 3101 USB2.0", | ||
1050 | {&dw2102_table[5], NULL}, | ||
1051 | {NULL}, | ||
1052 | }, | ||
1053 | } | ||
1054 | }; | ||
1055 | |||
799 | static int dw2102_probe(struct usb_interface *intf, | 1056 | static int dw2102_probe(struct usb_interface *intf, |
800 | const struct usb_device_id *id) | 1057 | const struct usb_device_id *id) |
801 | { | 1058 | { |
802 | if (0 == dvb_usb_device_init(intf, &dw2102_properties, | 1059 | if (0 == dvb_usb_device_init(intf, &dw2102_properties, |
803 | THIS_MODULE, NULL, adapter_nr) || | 1060 | THIS_MODULE, NULL, adapter_nr) || |
804 | 0 == dvb_usb_device_init(intf, &dw2104_properties, | 1061 | 0 == dvb_usb_device_init(intf, &dw2104_properties, |
1062 | THIS_MODULE, NULL, adapter_nr) || | ||
1063 | 0 == dvb_usb_device_init(intf, &dw3101_properties, | ||
805 | THIS_MODULE, NULL, adapter_nr)) { | 1064 | THIS_MODULE, NULL, adapter_nr)) { |
806 | return 0; | 1065 | return 0; |
807 | } | 1066 | } |
@@ -833,6 +1092,8 @@ module_init(dw2102_module_init); | |||
833 | module_exit(dw2102_module_exit); | 1092 | module_exit(dw2102_module_exit); |
834 | 1093 | ||
835 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | 1094 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); |
836 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device"); | 1095 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," |
1096 | " DVB-C 3101 USB2.0," | ||
1097 | " TeVii S600, S650 USB2.0 devices"); | ||
837 | MODULE_VERSION("0.1"); | 1098 | MODULE_VERSION("0.1"); |
838 | MODULE_LICENSE("GPL"); | 1099 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h index e3370734e95a..5cd0b0eb6ce1 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.h +++ b/drivers/media/dvb/dvb-usb/dw2102.h | |||
@@ -5,4 +5,5 @@ | |||
5 | #include "dvb-usb.h" | 5 | #include "dvb-usb.h" |
6 | 6 | ||
7 | #define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) | 7 | #define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) |
8 | #define deb_rc(args...) dprintk(dvb_usb_dw2102_debug, 0x04, args) | ||
8 | #endif | 9 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c index 3dd6843864ed..afb444db43ad 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/drivers/media/dvb/dvb-usb/gp8psk.c | |||
@@ -223,7 +223,7 @@ static struct usb_device_id gp8psk_usb_table [] = { | |||
223 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) }, | 223 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) }, |
224 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) }, | 224 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) }, |
225 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) }, | 225 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) }, |
226 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, | 226 | /* { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */ |
227 | { 0 }, | 227 | { 0 }, |
228 | }; | 228 | }; |
229 | MODULE_DEVICE_TABLE(usb, gp8psk_usb_table); | 229 | MODULE_DEVICE_TABLE(usb, gp8psk_usb_table); |
@@ -254,7 +254,7 @@ static struct dvb_usb_device_properties gp8psk_properties = { | |||
254 | 254 | ||
255 | .generic_bulk_ctrl_endpoint = 0x01, | 255 | .generic_bulk_ctrl_endpoint = 0x01, |
256 | 256 | ||
257 | .num_device_descs = 4, | 257 | .num_device_descs = 3, |
258 | .devices = { | 258 | .devices = { |
259 | { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver", | 259 | { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver", |
260 | .cold_ids = { &gp8psk_usb_table[0], NULL }, | 260 | .cold_ids = { &gp8psk_usb_table[0], NULL }, |
@@ -268,10 +268,6 @@ static struct dvb_usb_device_properties gp8psk_properties = { | |||
268 | .cold_ids = { NULL }, | 268 | .cold_ids = { NULL }, |
269 | .warm_ids = { &gp8psk_usb_table[3], NULL }, | 269 | .warm_ids = { &gp8psk_usb_table[3], NULL }, |
270 | }, | 270 | }, |
271 | { .name = "Genpix SkyWalker-CW3K DVB-S receiver", | ||
272 | .cold_ids = { NULL }, | ||
273 | .warm_ids = { &gp8psk_usb_table[4], NULL }, | ||
274 | }, | ||
275 | { NULL }, | 271 | { NULL }, |
276 | } | 272 | } |
277 | }; | 273 | }; |
diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c index 46a6324d7b73..27bca2e283df 100644 --- a/drivers/media/dvb/firewire/firedtv-rc.c +++ b/drivers/media/dvb/firewire/firedtv-rc.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include "firedtv.h" | 18 | #include "firedtv.h" |
19 | 19 | ||
20 | /* fixed table with older keycodes, geared towards MythTV */ | 20 | /* fixed table with older keycodes, geared towards MythTV */ |
21 | const static u16 oldtable[] = { | 21 | static const u16 oldtable[] = { |
22 | 22 | ||
23 | /* code from device: 0x4501...0x451f */ | 23 | /* code from device: 0x4501...0x451f */ |
24 | 24 | ||
@@ -62,7 +62,7 @@ const static u16 oldtable[] = { | |||
62 | }; | 62 | }; |
63 | 63 | ||
64 | /* user-modifiable table for a remote as sold in 2008 */ | 64 | /* user-modifiable table for a remote as sold in 2008 */ |
65 | const static u16 keytable[] = { | 65 | static const u16 keytable[] = { |
66 | 66 | ||
67 | /* code from device: 0x0300...0x031f */ | 67 | /* code from device: 0x0300...0x031f */ |
68 | 68 | ||
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 23e4cffeba38..be967ac09a39 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -35,6 +35,21 @@ config DVB_STB6100 | |||
35 | A Silicon tuner from ST used in conjunction with the STB0899 | 35 | A Silicon tuner from ST used in conjunction with the STB0899 |
36 | demodulator. Say Y when you want to support this tuner. | 36 | demodulator. Say Y when you want to support this tuner. |
37 | 37 | ||
38 | config DVB_STV090x | ||
39 | tristate "STV0900/STV0903(A/B) based" | ||
40 | depends on DVB_CORE && I2C | ||
41 | default m if DVB_FE_CUSTOMISE | ||
42 | help | ||
43 | DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators. | ||
44 | Say Y when you want to support these frontends. | ||
45 | |||
46 | config DVB_STV6110x | ||
47 | tristate "STV6110/(A) based tuners" | ||
48 | depends on DVB_CORE && I2C | ||
49 | default m if DVB_FE_CUSTOMISE | ||
50 | help | ||
51 | A Silicon tuner that supports DVB-S and DVB-S2 modes | ||
52 | |||
38 | comment "DVB-S (satellite) frontends" | 53 | comment "DVB-S (satellite) frontends" |
39 | depends on DVB_CORE | 54 | depends on DVB_CORE |
40 | 55 | ||
@@ -506,6 +521,13 @@ config DVB_ISL6421 | |||
506 | help | 521 | help |
507 | An SEC control chip. | 522 | An SEC control chip. |
508 | 523 | ||
524 | config DVB_ISL6423 | ||
525 | tristate "ISL6423 SEC controller" | ||
526 | depends on DVB_CORE && I2C | ||
527 | default m if DVB_FE_CUSTOMISE | ||
528 | help | ||
529 | A SEC controller chip from Intersil | ||
530 | |||
509 | config DVB_LGS8GL5 | 531 | config DVB_LGS8GL5 |
510 | tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" | 532 | tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" |
511 | depends on DVB_CORE && I2C | 533 | depends on DVB_CORE && I2C |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index bc2b00abd106..832473c1e512 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -71,4 +71,6 @@ obj-$(CONFIG_DVB_STB6000) += stb6000.o | |||
71 | obj-$(CONFIG_DVB_S921) += s921.o | 71 | obj-$(CONFIG_DVB_S921) += s921.o |
72 | obj-$(CONFIG_DVB_STV6110) += stv6110.o | 72 | obj-$(CONFIG_DVB_STV6110) += stv6110.o |
73 | obj-$(CONFIG_DVB_STV0900) += stv0900.o | 73 | obj-$(CONFIG_DVB_STV0900) += stv0900.o |
74 | 74 | obj-$(CONFIG_DVB_STV090x) += stv090x.o | |
75 | obj-$(CONFIG_DVB_STV6110x) += stv6110x.o | ||
76 | obj-$(CONFIG_DVB_ISL6423) += isl6423.o | ||
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index b2b50fb4cfd3..136c5863d81b 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c | |||
@@ -1455,7 +1455,7 @@ static int af9013_download_firmware(struct af9013_state *state) | |||
1455 | af9013_ops.info.name); | 1455 | af9013_ops.info.name); |
1456 | 1456 | ||
1457 | /* request the firmware, this will block and timeout */ | 1457 | /* request the firmware, this will block and timeout */ |
1458 | ret = request_firmware(&fw, fw_file, &state->i2c->dev); | 1458 | ret = request_firmware(&fw, fw_file, state->i2c->dev.parent); |
1459 | if (ret) { | 1459 | if (ret) { |
1460 | err("did not find the firmware file. (%s) " | 1460 | err("did not find the firmware file. (%s) " |
1461 | "Please see linux/Documentation/dvb/ for more details" \ | 1461 | "Please see linux/Documentation/dvb/ for more details" \ |
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 35731258bb0a..956b80f4979c 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c | |||
@@ -367,11 +367,90 @@ static struct { | |||
367 | { 0x8231, 0x13 }, | 367 | { 0x8231, 0x13 }, |
368 | }; | 368 | }; |
369 | 369 | ||
370 | /* QAM Modulation table */ | 370 | /* QAM64 Modulation table */ |
371 | static struct { | 371 | static struct { |
372 | u16 reg; | 372 | u16 reg; |
373 | u16 data; | 373 | u16 data; |
374 | } QAM_mod_tab[] = { | 374 | } QAM64_mod_tab[] = { |
375 | { 0x00a3, 0x09 }, | ||
376 | { 0x00a4, 0x00 }, | ||
377 | { 0x0081, 0xc4 }, | ||
378 | { 0x00a5, 0x40 }, | ||
379 | { 0x00aa, 0x77 }, | ||
380 | { 0x00ad, 0x77 }, | ||
381 | { 0x00a6, 0x67 }, | ||
382 | { 0x0262, 0x20 }, | ||
383 | { 0x021c, 0x30 }, | ||
384 | { 0x00b8, 0x3e }, | ||
385 | { 0x00b9, 0xf0 }, | ||
386 | { 0x00ba, 0x01 }, | ||
387 | { 0x00bb, 0x18 }, | ||
388 | { 0x00bc, 0x50 }, | ||
389 | { 0x00bd, 0x00 }, | ||
390 | { 0x00be, 0xea }, | ||
391 | { 0x00bf, 0xef }, | ||
392 | { 0x00c0, 0xfc }, | ||
393 | { 0x00c1, 0xbd }, | ||
394 | { 0x00c2, 0x1f }, | ||
395 | { 0x00c3, 0xfc }, | ||
396 | { 0x00c4, 0xdd }, | ||
397 | { 0x00c5, 0xaf }, | ||
398 | { 0x00c6, 0x00 }, | ||
399 | { 0x00c7, 0x38 }, | ||
400 | { 0x00c8, 0x30 }, | ||
401 | { 0x00c9, 0x05 }, | ||
402 | { 0x00ca, 0x4a }, | ||
403 | { 0x00cb, 0xd0 }, | ||
404 | { 0x00cc, 0x01 }, | ||
405 | { 0x00cd, 0xd9 }, | ||
406 | { 0x00ce, 0x6f }, | ||
407 | { 0x00cf, 0xf9 }, | ||
408 | { 0x00d0, 0x70 }, | ||
409 | { 0x00d1, 0xdf }, | ||
410 | { 0x00d2, 0xf7 }, | ||
411 | { 0x00d3, 0xc2 }, | ||
412 | { 0x00d4, 0xdf }, | ||
413 | { 0x00d5, 0x02 }, | ||
414 | { 0x00d6, 0x9a }, | ||
415 | { 0x00d7, 0xd0 }, | ||
416 | { 0x0250, 0x0d }, | ||
417 | { 0x0251, 0xcd }, | ||
418 | { 0x0252, 0xe0 }, | ||
419 | { 0x0253, 0x05 }, | ||
420 | { 0x0254, 0xa7 }, | ||
421 | { 0x0255, 0xff }, | ||
422 | { 0x0256, 0xed }, | ||
423 | { 0x0257, 0x5b }, | ||
424 | { 0x0258, 0xae }, | ||
425 | { 0x0259, 0xe6 }, | ||
426 | { 0x025a, 0x3d }, | ||
427 | { 0x025b, 0x0f }, | ||
428 | { 0x025c, 0x0d }, | ||
429 | { 0x025d, 0xea }, | ||
430 | { 0x025e, 0xf2 }, | ||
431 | { 0x025f, 0x51 }, | ||
432 | { 0x0260, 0xf5 }, | ||
433 | { 0x0261, 0x06 }, | ||
434 | { 0x021a, 0x00 }, | ||
435 | { 0x0546, 0x40 }, | ||
436 | { 0x0210, 0xc7 }, | ||
437 | { 0x0211, 0xaa }, | ||
438 | { 0x0212, 0xab }, | ||
439 | { 0x0213, 0x02 }, | ||
440 | { 0x0502, 0x00 }, | ||
441 | { 0x0121, 0x04 }, | ||
442 | { 0x0122, 0x04 }, | ||
443 | { 0x052e, 0x10 }, | ||
444 | { 0x00a4, 0xca }, | ||
445 | { 0x00a7, 0x40 }, | ||
446 | { 0x0526, 0x01 }, | ||
447 | }; | ||
448 | |||
449 | /* QAM256 Modulation table */ | ||
450 | static struct { | ||
451 | u16 reg; | ||
452 | u16 data; | ||
453 | } QAM256_mod_tab[] = { | ||
375 | { 0x80a3, 0x09 }, | 454 | { 0x80a3, 0x09 }, |
376 | { 0x80a4, 0x00 }, | 455 | { 0x80a4, 0x00 }, |
377 | { 0x8081, 0xc4 }, | 456 | { 0x8081, 0xc4 }, |
@@ -464,12 +543,19 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, | |||
464 | au8522_set_if(fe, state->config->vsb_if); | 543 | au8522_set_if(fe, state->config->vsb_if); |
465 | break; | 544 | break; |
466 | case QAM_64: | 545 | case QAM_64: |
546 | dprintk("%s() QAM 64\n", __func__); | ||
547 | for (i = 0; i < ARRAY_SIZE(QAM64_mod_tab); i++) | ||
548 | au8522_writereg(state, | ||
549 | QAM64_mod_tab[i].reg, | ||
550 | QAM64_mod_tab[i].data); | ||
551 | au8522_set_if(fe, state->config->qam_if); | ||
552 | break; | ||
467 | case QAM_256: | 553 | case QAM_256: |
468 | dprintk("%s() QAM 64/256\n", __func__); | 554 | dprintk("%s() QAM 256\n", __func__); |
469 | for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++) | 555 | for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++) |
470 | au8522_writereg(state, | 556 | au8522_writereg(state, |
471 | QAM_mod_tab[i].reg, | 557 | QAM256_mod_tab[i].reg, |
472 | QAM_mod_tab[i].data); | 558 | QAM256_mod_tab[i].data); |
473 | au8522_set_if(fe, state->config->qam_if); | 559 | au8522_set_if(fe, state->config->qam_if); |
474 | break; | 560 | break; |
475 | default: | 561 | default: |
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index 9b9f57264cef..2410d8b59b6b 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c | |||
@@ -492,7 +492,7 @@ static int cx24116_firmware_ondemand(struct dvb_frontend *fe) | |||
492 | printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", | 492 | printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", |
493 | __func__, CX24116_DEFAULT_FIRMWARE); | 493 | __func__, CX24116_DEFAULT_FIRMWARE); |
494 | ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, | 494 | ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, |
495 | &state->i2c->dev); | 495 | state->i2c->dev.parent); |
496 | printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", | 496 | printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", |
497 | __func__); | 497 | __func__); |
498 | if (ret) { | 498 | if (ret) { |
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c index 172f1f928f02..010075535221 100644 --- a/drivers/media/dvb/frontends/drx397xD.c +++ b/drivers/media/dvb/frontends/drx397xD.c | |||
@@ -123,10 +123,10 @@ static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix) | |||
123 | } | 123 | } |
124 | memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); | 124 | memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); |
125 | 125 | ||
126 | if (request_firmware(&fw[ix].file, fw[ix].name, &s->i2c->dev) != 0) { | 126 | rc = request_firmware(&fw[ix].file, fw[ix].name, s->i2c->dev.parent); |
127 | if (rc != 0) { | ||
127 | printk(KERN_ERR "%s: Firmware \"%s\" not available\n", | 128 | printk(KERN_ERR "%s: Firmware \"%s\" not available\n", |
128 | mod_name, fw[ix].name); | 129 | mod_name, fw[ix].name); |
129 | rc = -ENOENT; | ||
130 | goto exit_err; | 130 | goto exit_err; |
131 | } | 131 | } |
132 | 132 | ||
diff --git a/drivers/media/dvb/frontends/isl6423.c b/drivers/media/dvb/frontends/isl6423.c new file mode 100644 index 000000000000..dca5bebfeeb5 --- /dev/null +++ b/drivers/media/dvb/frontends/isl6423.c | |||
@@ -0,0 +1,308 @@ | |||
1 | /* | ||
2 | Intersil ISL6423 SEC and LNB Power supply controller | ||
3 | |||
4 | Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||
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 | #include <linux/delay.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/string.h> | ||
27 | #include <linux/slab.h> | ||
28 | |||
29 | #include "dvb_frontend.h" | ||
30 | #include "isl6423.h" | ||
31 | |||
32 | static unsigned int verbose; | ||
33 | module_param(verbose, int, 0644); | ||
34 | MODULE_PARM_DESC(verbose, "Set Verbosity level"); | ||
35 | |||
36 | #define FE_ERROR 0 | ||
37 | #define FE_NOTICE 1 | ||
38 | #define FE_INFO 2 | ||
39 | #define FE_DEBUG 3 | ||
40 | #define FE_DEBUGREG 4 | ||
41 | |||
42 | #define dprintk(__y, __z, format, arg...) do { \ | ||
43 | if (__z) { \ | ||
44 | if ((verbose > FE_ERROR) && (verbose > __y)) \ | ||
45 | printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ | ||
46 | else if ((verbose > FE_NOTICE) && (verbose > __y)) \ | ||
47 | printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ | ||
48 | else if ((verbose > FE_INFO) && (verbose > __y)) \ | ||
49 | printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ | ||
50 | else if ((verbose > FE_DEBUG) && (verbose > __y)) \ | ||
51 | printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ | ||
52 | } else { \ | ||
53 | if (verbose > __y) \ | ||
54 | printk(format, ##arg); \ | ||
55 | } \ | ||
56 | } while (0) | ||
57 | |||
58 | struct isl6423_dev { | ||
59 | const struct isl6423_config *config; | ||
60 | struct i2c_adapter *i2c; | ||
61 | |||
62 | u8 reg_3; | ||
63 | u8 reg_4; | ||
64 | |||
65 | unsigned int verbose; | ||
66 | }; | ||
67 | |||
68 | static int isl6423_write(struct isl6423_dev *isl6423, u8 reg) | ||
69 | { | ||
70 | struct i2c_adapter *i2c = isl6423->i2c; | ||
71 | u8 addr = isl6423->config->addr; | ||
72 | int err = 0; | ||
73 | |||
74 | struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = ®, .len = 1 }; | ||
75 | |||
76 | dprintk(FE_DEBUG, 1, "write reg %02X", reg); | ||
77 | err = i2c_transfer(i2c, &msg, 1); | ||
78 | if (err < 0) | ||
79 | goto exit; | ||
80 | return 0; | ||
81 | |||
82 | exit: | ||
83 | dprintk(FE_ERROR, 1, "I/O error <%d>", err); | ||
84 | return err; | ||
85 | } | ||
86 | |||
87 | static int isl6423_set_modulation(struct dvb_frontend *fe) | ||
88 | { | ||
89 | struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv; | ||
90 | const struct isl6423_config *config = isl6423->config; | ||
91 | int err = 0; | ||
92 | u8 reg_2 = 0; | ||
93 | |||
94 | reg_2 = 0x01 << 5; | ||
95 | |||
96 | if (config->mod_extern) | ||
97 | reg_2 |= (1 << 3); | ||
98 | else | ||
99 | reg_2 |= (1 << 4); | ||
100 | |||
101 | err = isl6423_write(isl6423, reg_2); | ||
102 | if (err < 0) | ||
103 | goto exit; | ||
104 | return 0; | ||
105 | |||
106 | exit: | ||
107 | dprintk(FE_ERROR, 1, "I/O error <%d>", err); | ||
108 | return err; | ||
109 | } | ||
110 | |||
111 | static int isl6423_voltage_boost(struct dvb_frontend *fe, long arg) | ||
112 | { | ||
113 | struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv; | ||
114 | u8 reg_3 = isl6423->reg_3; | ||
115 | u8 reg_4 = isl6423->reg_4; | ||
116 | int err = 0; | ||
117 | |||
118 | if (arg) { | ||
119 | /* EN = 1, VSPEN = 1, VBOT = 1 */ | ||
120 | reg_4 |= (1 << 4); | ||
121 | reg_4 |= 0x1; | ||
122 | reg_3 |= (1 << 3); | ||
123 | } else { | ||
124 | /* EN = 1, VSPEN = 1, VBOT = 0 */ | ||
125 | reg_4 |= (1 << 4); | ||
126 | reg_4 &= ~0x1; | ||
127 | reg_3 |= (1 << 3); | ||
128 | } | ||
129 | err = isl6423_write(isl6423, reg_3); | ||
130 | if (err < 0) | ||
131 | goto exit; | ||
132 | |||
133 | err = isl6423_write(isl6423, reg_4); | ||
134 | if (err < 0) | ||
135 | goto exit; | ||
136 | |||
137 | isl6423->reg_3 = reg_3; | ||
138 | isl6423->reg_4 = reg_4; | ||
139 | |||
140 | return 0; | ||
141 | exit: | ||
142 | dprintk(FE_ERROR, 1, "I/O error <%d>", err); | ||
143 | return err; | ||
144 | } | ||
145 | |||
146 | |||
147 | static int isl6423_set_voltage(struct dvb_frontend *fe, | ||
148 | enum fe_sec_voltage voltage) | ||
149 | { | ||
150 | struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv; | ||
151 | u8 reg_3 = isl6423->reg_3; | ||
152 | u8 reg_4 = isl6423->reg_4; | ||
153 | int err = 0; | ||
154 | |||
155 | switch (voltage) { | ||
156 | case SEC_VOLTAGE_OFF: | ||
157 | /* EN = 0 */ | ||
158 | reg_4 &= ~(1 << 4); | ||
159 | break; | ||
160 | |||
161 | case SEC_VOLTAGE_13: | ||
162 | /* EN = 1, VSPEN = 1, VTOP = 0, VBOT = 0 */ | ||
163 | reg_4 |= (1 << 4); | ||
164 | reg_4 &= ~0x3; | ||
165 | reg_3 |= (1 << 3); | ||
166 | break; | ||
167 | |||
168 | case SEC_VOLTAGE_18: | ||
169 | /* EN = 1, VSPEN = 1, VTOP = 1, VBOT = 0 */ | ||
170 | reg_4 |= (1 << 4); | ||
171 | reg_4 |= 0x2; | ||
172 | reg_4 &= ~0x1; | ||
173 | reg_3 |= (1 << 3); | ||
174 | break; | ||
175 | |||
176 | default: | ||
177 | break; | ||
178 | } | ||
179 | err = isl6423_write(isl6423, reg_3); | ||
180 | if (err < 0) | ||
181 | goto exit; | ||
182 | |||
183 | err = isl6423_write(isl6423, reg_4); | ||
184 | if (err < 0) | ||
185 | goto exit; | ||
186 | |||
187 | isl6423->reg_3 = reg_3; | ||
188 | isl6423->reg_4 = reg_4; | ||
189 | |||
190 | return 0; | ||
191 | exit: | ||
192 | dprintk(FE_ERROR, 1, "I/O error <%d>", err); | ||
193 | return err; | ||
194 | } | ||
195 | |||
196 | static int isl6423_set_current(struct dvb_frontend *fe) | ||
197 | { | ||
198 | struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv; | ||
199 | u8 reg_3 = isl6423->reg_3; | ||
200 | const struct isl6423_config *config = isl6423->config; | ||
201 | int err = 0; | ||
202 | |||
203 | switch (config->current_max) { | ||
204 | case SEC_CURRENT_275m: | ||
205 | /* 275mA */ | ||
206 | /* ISELH = 0, ISELL = 0 */ | ||
207 | reg_3 &= ~0x3; | ||
208 | break; | ||
209 | |||
210 | case SEC_CURRENT_515m: | ||
211 | /* 515mA */ | ||
212 | /* ISELH = 0, ISELL = 1 */ | ||
213 | reg_3 &= ~0x2; | ||
214 | reg_3 |= 0x1; | ||
215 | break; | ||
216 | |||
217 | case SEC_CURRENT_635m: | ||
218 | /* 635mA */ | ||
219 | /* ISELH = 1, ISELL = 0 */ | ||
220 | reg_3 &= ~0x1; | ||
221 | reg_3 |= 0x2; | ||
222 | break; | ||
223 | |||
224 | case SEC_CURRENT_800m: | ||
225 | /* 800mA */ | ||
226 | /* ISELH = 1, ISELL = 1 */ | ||
227 | reg_3 |= 0x3; | ||
228 | break; | ||
229 | } | ||
230 | |||
231 | err = isl6423_write(isl6423, reg_3); | ||
232 | if (err < 0) | ||
233 | goto exit; | ||
234 | |||
235 | switch (config->curlim) { | ||
236 | case SEC_CURRENT_LIM_ON: | ||
237 | /* DCL = 0 */ | ||
238 | reg_3 &= ~0x10; | ||
239 | break; | ||
240 | |||
241 | case SEC_CURRENT_LIM_OFF: | ||
242 | /* DCL = 1 */ | ||
243 | reg_3 |= 0x10; | ||
244 | break; | ||
245 | } | ||
246 | |||
247 | err = isl6423_write(isl6423, reg_3); | ||
248 | if (err < 0) | ||
249 | goto exit; | ||
250 | |||
251 | isl6423->reg_3 = reg_3; | ||
252 | |||
253 | return 0; | ||
254 | exit: | ||
255 | dprintk(FE_ERROR, 1, "I/O error <%d>", err); | ||
256 | return err; | ||
257 | } | ||
258 | |||
259 | static void isl6423_release(struct dvb_frontend *fe) | ||
260 | { | ||
261 | isl6423_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
262 | |||
263 | kfree(fe->sec_priv); | ||
264 | fe->sec_priv = NULL; | ||
265 | } | ||
266 | |||
267 | struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe, | ||
268 | struct i2c_adapter *i2c, | ||
269 | const struct isl6423_config *config) | ||
270 | { | ||
271 | struct isl6423_dev *isl6423; | ||
272 | |||
273 | isl6423 = kzalloc(sizeof(struct isl6423_dev), GFP_KERNEL); | ||
274 | if (!isl6423) | ||
275 | return NULL; | ||
276 | |||
277 | isl6423->config = config; | ||
278 | isl6423->i2c = i2c; | ||
279 | fe->sec_priv = isl6423; | ||
280 | |||
281 | /* SR3H = 0, SR3M = 1, SR3L = 0 */ | ||
282 | isl6423->reg_3 = 0x02 << 5; | ||
283 | /* SR4H = 0, SR4M = 1, SR4L = 1 */ | ||
284 | isl6423->reg_4 = 0x03 << 5; | ||
285 | |||
286 | if (isl6423_set_current(fe)) | ||
287 | goto exit; | ||
288 | |||
289 | if (isl6423_set_modulation(fe)) | ||
290 | goto exit; | ||
291 | |||
292 | fe->ops.release_sec = isl6423_release; | ||
293 | fe->ops.set_voltage = isl6423_set_voltage; | ||
294 | fe->ops.enable_high_lnb_voltage = isl6423_voltage_boost; | ||
295 | isl6423->verbose = verbose; | ||
296 | |||
297 | return fe; | ||
298 | |||
299 | exit: | ||
300 | kfree(isl6423); | ||
301 | fe->sec_priv = NULL; | ||
302 | return NULL; | ||
303 | } | ||
304 | EXPORT_SYMBOL(isl6423_attach); | ||
305 | |||
306 | MODULE_DESCRIPTION("ISL6423 SEC"); | ||
307 | MODULE_AUTHOR("Manu Abraham"); | ||
308 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/isl6423.h b/drivers/media/dvb/frontends/isl6423.h new file mode 100644 index 000000000000..e1a37fba01ca --- /dev/null +++ b/drivers/media/dvb/frontends/isl6423.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | Intersil ISL6423 SEC and LNB Power supply controller | ||
3 | |||
4 | Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||
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 | #ifndef __ISL_6423_H | ||
22 | #define __ISL_6423_H | ||
23 | |||
24 | #include <linux/dvb/frontend.h> | ||
25 | |||
26 | enum isl6423_current { | ||
27 | SEC_CURRENT_275m = 0, | ||
28 | SEC_CURRENT_515m, | ||
29 | SEC_CURRENT_635m, | ||
30 | SEC_CURRENT_800m, | ||
31 | }; | ||
32 | |||
33 | enum isl6423_curlim { | ||
34 | SEC_CURRENT_LIM_ON = 1, | ||
35 | SEC_CURRENT_LIM_OFF | ||
36 | }; | ||
37 | |||
38 | struct isl6423_config { | ||
39 | enum isl6423_current current_max; | ||
40 | enum isl6423_curlim curlim; | ||
41 | u8 addr; | ||
42 | u8 mod_extern; | ||
43 | }; | ||
44 | |||
45 | #if defined(CONFIG_DVB_ISL6423) || (defined(CONFIG_DVB_ISL6423_MODULE) && defined(MODULE)) | ||
46 | |||
47 | |||
48 | extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe, | ||
49 | struct i2c_adapter *i2c, | ||
50 | const struct isl6423_config *config); | ||
51 | |||
52 | #else | ||
53 | static inline struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe, | ||
54 | struct i2c_adapter *i2c, | ||
55 | const struct isl6423_config *config) | ||
56 | { | ||
57 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
58 | return NULL; | ||
59 | } | ||
60 | |||
61 | #endif /* CONFIG_DVB_ISL6423 */ | ||
62 | |||
63 | #endif /* __ISL_6423_H */ | ||
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c index d92d0557a80b..fde8c59700fb 100644 --- a/drivers/media/dvb/frontends/lgdt3305.c +++ b/drivers/media/dvb/frontends/lgdt3305.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <asm/div64.h> | ||
22 | #include <linux/dvb/frontend.h> | 23 | #include <linux/dvb/frontend.h> |
23 | #include "dvb_math.h" | 24 | #include "dvb_math.h" |
24 | #include "lgdt3305.h" | 25 | #include "lgdt3305.h" |
@@ -496,27 +497,15 @@ static int lgdt3305_set_if(struct lgdt3305_state *state, | |||
496 | 497 | ||
497 | nco = if_freq_khz / 10; | 498 | nco = if_freq_khz / 10; |
498 | 499 | ||
499 | #define LGDT3305_64BIT_DIVISION_ENABLED 0 | ||
500 | /* FIXME: 64bit division disabled to avoid linking error: | ||
501 | * WARNING: "__udivdi3" [lgdt3305.ko] undefined! | ||
502 | */ | ||
503 | switch (param->u.vsb.modulation) { | 500 | switch (param->u.vsb.modulation) { |
504 | case VSB_8: | 501 | case VSB_8: |
505 | #if LGDT3305_64BIT_DIVISION_ENABLED | ||
506 | nco <<= 24; | 502 | nco <<= 24; |
507 | nco /= 625; | 503 | do_div(nco, 625); |
508 | #else | ||
509 | nco *= ((1 << 24) / 625); | ||
510 | #endif | ||
511 | break; | 504 | break; |
512 | case QAM_64: | 505 | case QAM_64: |
513 | case QAM_256: | 506 | case QAM_256: |
514 | #if LGDT3305_64BIT_DIVISION_ENABLED | ||
515 | nco <<= 28; | 507 | nco <<= 28; |
516 | nco /= 625; | 508 | do_div(nco, 625); |
517 | #else | ||
518 | nco *= ((1 << 28) / 625); | ||
519 | #endif | ||
520 | break; | 509 | break; |
521 | default: | 510 | default: |
522 | return -EINVAL; | 511 | return -EINVAL; |
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c index f9785dfe735b..fde27645bbed 100644 --- a/drivers/media/dvb/frontends/lgs8gxx.c +++ b/drivers/media/dvb/frontends/lgs8gxx.c | |||
@@ -37,14 +37,14 @@ | |||
37 | } while (0) | 37 | } while (0) |
38 | 38 | ||
39 | static int debug; | 39 | static int debug; |
40 | static int fake_signal_str; | 40 | static int fake_signal_str = 1; |
41 | 41 | ||
42 | module_param(debug, int, 0644); | 42 | module_param(debug, int, 0644); |
43 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | 43 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); |
44 | 44 | ||
45 | module_param(fake_signal_str, int, 0644); | 45 | module_param(fake_signal_str, int, 0644); |
46 | MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913." | 46 | MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913." |
47 | "Signal strength calculation is slow.(default:off)."); | 47 | "Signal strength calculation is slow.(default:on)."); |
48 | 48 | ||
49 | /* LGS8GXX internal helper functions */ | 49 | /* LGS8GXX internal helper functions */ |
50 | 50 | ||
@@ -610,7 +610,7 @@ static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal) | |||
610 | else | 610 | else |
611 | cat = 0; | 611 | cat = 0; |
612 | 612 | ||
613 | *signal = cat; | 613 | *signal = cat * 65535 / 5; |
614 | 614 | ||
615 | return 0; | 615 | return 0; |
616 | } | 616 | } |
@@ -630,8 +630,8 @@ static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal) | |||
630 | 630 | ||
631 | if (fake_signal_str) { | 631 | if (fake_signal_str) { |
632 | if ((t & 0xC0) == 0xC0) { | 632 | if ((t & 0xC0) == 0xC0) { |
633 | dprintk("Fake signal strength as 50\n"); | 633 | dprintk("Fake signal strength\n"); |
634 | *signal = 0x32; | 634 | *signal = 0x7FFF; |
635 | } else | 635 | } else |
636 | *signal = 0; | 636 | *signal = 0; |
637 | return 0; | 637 | return 0; |
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c index 1dcc56f32bff..71f607fe8fc7 100644 --- a/drivers/media/dvb/frontends/lnbp21.c +++ b/drivers/media/dvb/frontends/lnbp21.c | |||
@@ -133,7 +133,7 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe, | |||
133 | /* override frontend ops */ | 133 | /* override frontend ops */ |
134 | fe->ops.set_voltage = lnbp21_set_voltage; | 134 | fe->ops.set_voltage = lnbp21_set_voltage; |
135 | fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | 135 | fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; |
136 | printk(KERN_INFO "LNBx2x attached on addr=%x", lnbp21->i2c_addr); | 136 | printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr); |
137 | 137 | ||
138 | return fe; | 138 | return fe; |
139 | } | 139 | } |
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c index 5ac9b15920f8..a621f727935f 100644 --- a/drivers/media/dvb/frontends/mt312.c +++ b/drivers/media/dvb/frontends/mt312.c | |||
@@ -77,7 +77,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg, | |||
77 | ret = i2c_transfer(state->i2c, msg, 2); | 77 | ret = i2c_transfer(state->i2c, msg, 2); |
78 | 78 | ||
79 | if (ret != 2) { | 79 | if (ret != 2) { |
80 | printk(KERN_ERR "%s: ret == %d\n", __func__, ret); | 80 | printk(KERN_DEBUG "%s: ret == %d\n", __func__, ret); |
81 | return -EREMOTEIO; | 81 | return -EREMOTEIO; |
82 | } | 82 | } |
83 | 83 | ||
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c index a8429ebfa8a2..eac20650499f 100644 --- a/drivers/media/dvb/frontends/nxt200x.c +++ b/drivers/media/dvb/frontends/nxt200x.c | |||
@@ -879,7 +879,8 @@ static int nxt2002_init(struct dvb_frontend* fe) | |||
879 | 879 | ||
880 | /* request the firmware, this will block until someone uploads it */ | 880 | /* request the firmware, this will block until someone uploads it */ |
881 | printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE); | 881 | printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE); |
882 | ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev); | 882 | ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, |
883 | state->i2c->dev.parent); | ||
883 | printk("nxt2002: Waiting for firmware upload(2)...\n"); | 884 | printk("nxt2002: Waiting for firmware upload(2)...\n"); |
884 | if (ret) { | 885 | if (ret) { |
885 | printk("nxt2002: No firmware uploaded (timeout or file not found?)\n"); | 886 | printk("nxt2002: No firmware uploaded (timeout or file not found?)\n"); |
@@ -943,7 +944,8 @@ static int nxt2004_init(struct dvb_frontend* fe) | |||
943 | 944 | ||
944 | /* request the firmware, this will block until someone uploads it */ | 945 | /* request the firmware, this will block until someone uploads it */ |
945 | printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE); | 946 | printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE); |
946 | ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev); | 947 | ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, |
948 | state->i2c->dev.parent); | ||
947 | printk("nxt2004: Waiting for firmware upload(2)...\n"); | 949 | printk("nxt2004: Waiting for firmware upload(2)...\n"); |
948 | if (ret) { | 950 | if (ret) { |
949 | printk("nxt2004: No firmware uploaded (timeout or file not found?)\n"); | 951 | printk("nxt2004: No firmware uploaded (timeout or file not found?)\n"); |
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index 5ed32544de39..8133ea3cddd7 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c | |||
@@ -340,7 +340,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe, | |||
340 | } | 340 | } |
341 | printk("or51132: Waiting for firmware upload(%s)...\n", | 341 | printk("or51132: Waiting for firmware upload(%s)...\n", |
342 | fwname); | 342 | fwname); |
343 | ret = request_firmware(&fw, fwname, &state->i2c->dev); | 343 | ret = request_firmware(&fw, fwname, state->i2c->dev.parent); |
344 | if (ret) { | 344 | if (ret) { |
345 | printk(KERN_WARNING "or51132: No firmware up" | 345 | printk(KERN_WARNING "or51132: No firmware up" |
346 | "loaded(timeout or file not found?)\n"); | 346 | "loaded(timeout or file not found?)\n"); |
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h index 762d5af62d7a..67dc8ec634e2 100644 --- a/drivers/media/dvb/frontends/stv0900_priv.h +++ b/drivers/media/dvb/frontends/stv0900_priv.h | |||
@@ -60,8 +60,6 @@ | |||
60 | } \ | 60 | } \ |
61 | } while (0) | 61 | } while (0) |
62 | 62 | ||
63 | #define dmd_choose(a, b) (demod = STV0900_DEMOD_2 ? b : a)) | ||
64 | |||
65 | static int stvdebug; | 63 | static int stvdebug; |
66 | 64 | ||
67 | #define dprintk(args...) \ | 65 | #define dprintk(args...) \ |
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c new file mode 100644 index 000000000000..96ef745a2e4e --- /dev/null +++ b/drivers/media/dvb/frontends/stv090x.c | |||
@@ -0,0 +1,4299 @@ | |||
1 | /* | ||
2 | STV0900/0903 Multistandard Broadcast Frontend driver | ||
3 | Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||
4 | |||
5 | Copyright (C) ST Microelectronics | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (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 General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/string.h> | ||
26 | #include <linux/mutex.h> | ||
27 | |||
28 | #include <linux/dvb/frontend.h> | ||
29 | #include "dvb_frontend.h" | ||
30 | |||
31 | #include "stv6110x.h" /* for demodulator internal modes */ | ||
32 | |||
33 | #include "stv090x_reg.h" | ||
34 | #include "stv090x.h" | ||
35 | #include "stv090x_priv.h" | ||
36 | |||
37 | static unsigned int verbose; | ||
38 | module_param(verbose, int, 0644); | ||
39 | |||
40 | struct mutex demod_lock; | ||
41 | |||
42 | /* DVBS1 and DSS C/N Lookup table */ | ||
43 | static const struct stv090x_tab stv090x_s1cn_tab[] = { | ||
44 | { 0, 8917 }, /* 0.0dB */ | ||
45 | { 5, 8801 }, /* 0.5dB */ | ||
46 | { 10, 8667 }, /* 1.0dB */ | ||
47 | { 15, 8522 }, /* 1.5dB */ | ||
48 | { 20, 8355 }, /* 2.0dB */ | ||
49 | { 25, 8175 }, /* 2.5dB */ | ||
50 | { 30, 7979 }, /* 3.0dB */ | ||
51 | { 35, 7763 }, /* 3.5dB */ | ||
52 | { 40, 7530 }, /* 4.0dB */ | ||
53 | { 45, 7282 }, /* 4.5dB */ | ||
54 | { 50, 7026 }, /* 5.0dB */ | ||
55 | { 55, 6781 }, /* 5.5dB */ | ||
56 | { 60, 6514 }, /* 6.0dB */ | ||
57 | { 65, 6241 }, /* 6.5dB */ | ||
58 | { 70, 5965 }, /* 7.0dB */ | ||
59 | { 75, 5690 }, /* 7.5dB */ | ||
60 | { 80, 5424 }, /* 8.0dB */ | ||
61 | { 85, 5161 }, /* 8.5dB */ | ||
62 | { 90, 4902 }, /* 9.0dB */ | ||
63 | { 95, 4654 }, /* 9.5dB */ | ||
64 | { 100, 4417 }, /* 10.0dB */ | ||
65 | { 105, 4186 }, /* 10.5dB */ | ||
66 | { 110, 3968 }, /* 11.0dB */ | ||
67 | { 115, 3757 }, /* 11.5dB */ | ||
68 | { 120, 3558 }, /* 12.0dB */ | ||
69 | { 125, 3366 }, /* 12.5dB */ | ||
70 | { 130, 3185 }, /* 13.0dB */ | ||
71 | { 135, 3012 }, /* 13.5dB */ | ||
72 | { 140, 2850 }, /* 14.0dB */ | ||
73 | { 145, 2698 }, /* 14.5dB */ | ||
74 | { 150, 2550 }, /* 15.0dB */ | ||
75 | { 160, 2283 }, /* 16.0dB */ | ||
76 | { 170, 2042 }, /* 17.0dB */ | ||
77 | { 180, 1827 }, /* 18.0dB */ | ||
78 | { 190, 1636 }, /* 19.0dB */ | ||
79 | { 200, 1466 }, /* 20.0dB */ | ||
80 | { 210, 1315 }, /* 21.0dB */ | ||
81 | { 220, 1181 }, /* 22.0dB */ | ||
82 | { 230, 1064 }, /* 23.0dB */ | ||
83 | { 240, 960 }, /* 24.0dB */ | ||
84 | { 250, 869 }, /* 25.0dB */ | ||
85 | { 260, 792 }, /* 26.0dB */ | ||
86 | { 270, 724 }, /* 27.0dB */ | ||
87 | { 280, 665 }, /* 28.0dB */ | ||
88 | { 290, 616 }, /* 29.0dB */ | ||
89 | { 300, 573 }, /* 30.0dB */ | ||
90 | { 310, 537 }, /* 31.0dB */ | ||
91 | { 320, 507 }, /* 32.0dB */ | ||
92 | { 330, 483 }, /* 33.0dB */ | ||
93 | { 400, 398 }, /* 40.0dB */ | ||
94 | { 450, 381 }, /* 45.0dB */ | ||
95 | { 500, 377 } /* 50.0dB */ | ||
96 | }; | ||
97 | |||
98 | /* DVBS2 C/N Lookup table */ | ||
99 | static const struct stv090x_tab stv090x_s2cn_tab[] = { | ||
100 | { -30, 13348 }, /* -3.0dB */ | ||
101 | { -20, 12640 }, /* -2d.0B */ | ||
102 | { -10, 11883 }, /* -1.0dB */ | ||
103 | { 0, 11101 }, /* -0.0dB */ | ||
104 | { 5, 10718 }, /* 0.5dB */ | ||
105 | { 10, 10339 }, /* 1.0dB */ | ||
106 | { 15, 9947 }, /* 1.5dB */ | ||
107 | { 20, 9552 }, /* 2.0dB */ | ||
108 | { 25, 9183 }, /* 2.5dB */ | ||
109 | { 30, 8799 }, /* 3.0dB */ | ||
110 | { 35, 8422 }, /* 3.5dB */ | ||
111 | { 40, 8062 }, /* 4.0dB */ | ||
112 | { 45, 7707 }, /* 4.5dB */ | ||
113 | { 50, 7353 }, /* 5.0dB */ | ||
114 | { 55, 7025 }, /* 5.5dB */ | ||
115 | { 60, 6684 }, /* 6.0dB */ | ||
116 | { 65, 6331 }, /* 6.5dB */ | ||
117 | { 70, 6036 }, /* 7.0dB */ | ||
118 | { 75, 5727 }, /* 7.5dB */ | ||
119 | { 80, 5437 }, /* 8.0dB */ | ||
120 | { 85, 5164 }, /* 8.5dB */ | ||
121 | { 90, 4902 }, /* 9.0dB */ | ||
122 | { 95, 4653 }, /* 9.5dB */ | ||
123 | { 100, 4408 }, /* 10.0dB */ | ||
124 | { 105, 4187 }, /* 10.5dB */ | ||
125 | { 110, 3961 }, /* 11.0dB */ | ||
126 | { 115, 3751 }, /* 11.5dB */ | ||
127 | { 120, 3558 }, /* 12.0dB */ | ||
128 | { 125, 3368 }, /* 12.5dB */ | ||
129 | { 130, 3191 }, /* 13.0dB */ | ||
130 | { 135, 3017 }, /* 13.5dB */ | ||
131 | { 140, 2862 }, /* 14.0dB */ | ||
132 | { 145, 2710 }, /* 14.5dB */ | ||
133 | { 150, 2565 }, /* 15.0dB */ | ||
134 | { 160, 2300 }, /* 16.0dB */ | ||
135 | { 170, 2058 }, /* 17.0dB */ | ||
136 | { 180, 1849 }, /* 18.0dB */ | ||
137 | { 190, 1663 }, /* 19.0dB */ | ||
138 | { 200, 1495 }, /* 20.0dB */ | ||
139 | { 210, 1349 }, /* 21.0dB */ | ||
140 | { 220, 1222 }, /* 22.0dB */ | ||
141 | { 230, 1110 }, /* 23.0dB */ | ||
142 | { 240, 1011 }, /* 24.0dB */ | ||
143 | { 250, 925 }, /* 25.0dB */ | ||
144 | { 260, 853 }, /* 26.0dB */ | ||
145 | { 270, 789 }, /* 27.0dB */ | ||
146 | { 280, 734 }, /* 28.0dB */ | ||
147 | { 290, 690 }, /* 29.0dB */ | ||
148 | { 300, 650 }, /* 30.0dB */ | ||
149 | { 310, 619 }, /* 31.0dB */ | ||
150 | { 320, 593 }, /* 32.0dB */ | ||
151 | { 330, 571 }, /* 33.0dB */ | ||
152 | { 400, 498 }, /* 40.0dB */ | ||
153 | { 450, 484 }, /* 45.0dB */ | ||
154 | { 500, 481 } /* 50.0dB */ | ||
155 | }; | ||
156 | |||
157 | /* RF level C/N lookup table */ | ||
158 | static const struct stv090x_tab stv090x_rf_tab[] = { | ||
159 | { -5, 0xcaa1 }, /* -5dBm */ | ||
160 | { -10, 0xc229 }, /* -10dBm */ | ||
161 | { -15, 0xbb08 }, /* -15dBm */ | ||
162 | { -20, 0xb4bc }, /* -20dBm */ | ||
163 | { -25, 0xad5a }, /* -25dBm */ | ||
164 | { -30, 0xa298 }, /* -30dBm */ | ||
165 | { -35, 0x98a8 }, /* -35dBm */ | ||
166 | { -40, 0x8389 }, /* -40dBm */ | ||
167 | { -45, 0x59be }, /* -45dBm */ | ||
168 | { -50, 0x3a14 }, /* -50dBm */ | ||
169 | { -55, 0x2d11 }, /* -55dBm */ | ||
170 | { -60, 0x210d }, /* -60dBm */ | ||
171 | { -65, 0xa14f }, /* -65dBm */ | ||
172 | { -70, 0x07aa } /* -70dBm */ | ||
173 | }; | ||
174 | |||
175 | |||
176 | static struct stv090x_reg stv0900_initval[] = { | ||
177 | |||
178 | { STV090x_OUTCFG, 0x00 }, | ||
179 | { STV090x_MODECFG, 0xff }, | ||
180 | { STV090x_AGCRF1CFG, 0x11 }, | ||
181 | { STV090x_AGCRF2CFG, 0x13 }, | ||
182 | { STV090x_TSGENERAL1X, 0x14 }, | ||
183 | { STV090x_TSTTNR2, 0x21 }, | ||
184 | { STV090x_TSTTNR4, 0x21 }, | ||
185 | { STV090x_P2_DISTXCTL, 0x22 }, | ||
186 | { STV090x_P2_F22TX, 0xc0 }, | ||
187 | { STV090x_P2_F22RX, 0xc0 }, | ||
188 | { STV090x_P2_DISRXCTL, 0x00 }, | ||
189 | { STV090x_P2_DMDCFGMD, 0xF9 }, | ||
190 | { STV090x_P2_DEMOD, 0x08 }, | ||
191 | { STV090x_P2_DMDCFG3, 0xc4 }, | ||
192 | { STV090x_P2_CARFREQ, 0xed }, | ||
193 | { STV090x_P2_LDT, 0xd0 }, | ||
194 | { STV090x_P2_LDT2, 0xb8 }, | ||
195 | { STV090x_P2_TMGCFG, 0xd2 }, | ||
196 | { STV090x_P2_TMGTHRISE, 0x20 }, | ||
197 | { STV090x_P1_TMGCFG, 0xd2 }, | ||
198 | |||
199 | { STV090x_P2_TMGTHFALL, 0x00 }, | ||
200 | { STV090x_P2_FECSPY, 0x88 }, | ||
201 | { STV090x_P2_FSPYDATA, 0x3a }, | ||
202 | { STV090x_P2_FBERCPT4, 0x00 }, | ||
203 | { STV090x_P2_FSPYBER, 0x10 }, | ||
204 | { STV090x_P2_ERRCTRL1, 0x35 }, | ||
205 | { STV090x_P2_ERRCTRL2, 0xc1 }, | ||
206 | { STV090x_P2_CFRICFG, 0xf8 }, | ||
207 | { STV090x_P2_NOSCFG, 0x1c }, | ||
208 | { STV090x_P2_DMDTOM, 0x20 }, | ||
209 | { STV090x_P2_CORRELMANT, 0x70 }, | ||
210 | { STV090x_P2_CORRELABS, 0x88 }, | ||
211 | { STV090x_P2_AGC2O, 0x5b }, | ||
212 | { STV090x_P2_AGC2REF, 0x38 }, | ||
213 | { STV090x_P2_CARCFG, 0xe4 }, | ||
214 | { STV090x_P2_ACLC, 0x1A }, | ||
215 | { STV090x_P2_BCLC, 0x09 }, | ||
216 | { STV090x_P2_CARHDR, 0x08 }, | ||
217 | { STV090x_P2_KREFTMG, 0xc1 }, | ||
218 | { STV090x_P2_SFRUPRATIO, 0xf0 }, | ||
219 | { STV090x_P2_SFRLOWRATIO, 0x70 }, | ||
220 | { STV090x_P2_SFRSTEP, 0x58 }, | ||
221 | { STV090x_P2_TMGCFG2, 0x01 }, | ||
222 | { STV090x_P2_CAR2CFG, 0x26 }, | ||
223 | { STV090x_P2_BCLC2S2Q, 0x86 }, | ||
224 | { STV090x_P2_BCLC2S28, 0x86 }, | ||
225 | { STV090x_P2_SMAPCOEF7, 0x77 }, | ||
226 | { STV090x_P2_SMAPCOEF6, 0x85 }, | ||
227 | { STV090x_P2_SMAPCOEF5, 0x77 }, | ||
228 | { STV090x_P2_TSCFGL, 0x20 }, | ||
229 | { STV090x_P2_DMDCFG2, 0x3b }, | ||
230 | { STV090x_P2_MODCODLST0, 0xff }, | ||
231 | { STV090x_P2_MODCODLST1, 0xff }, | ||
232 | { STV090x_P2_MODCODLST2, 0xff }, | ||
233 | { STV090x_P2_MODCODLST3, 0xff }, | ||
234 | { STV090x_P2_MODCODLST4, 0xff }, | ||
235 | { STV090x_P2_MODCODLST5, 0xff }, | ||
236 | { STV090x_P2_MODCODLST6, 0xff }, | ||
237 | { STV090x_P2_MODCODLST7, 0xcc }, | ||
238 | { STV090x_P2_MODCODLST8, 0xcc }, | ||
239 | { STV090x_P2_MODCODLST9, 0xcc }, | ||
240 | { STV090x_P2_MODCODLSTA, 0xcc }, | ||
241 | { STV090x_P2_MODCODLSTB, 0xcc }, | ||
242 | { STV090x_P2_MODCODLSTC, 0xcc }, | ||
243 | { STV090x_P2_MODCODLSTD, 0xcc }, | ||
244 | { STV090x_P2_MODCODLSTE, 0xcc }, | ||
245 | { STV090x_P2_MODCODLSTF, 0xcf }, | ||
246 | { STV090x_P1_DISTXCTL, 0x22 }, | ||
247 | { STV090x_P1_F22TX, 0xc0 }, | ||
248 | { STV090x_P1_F22RX, 0xc0 }, | ||
249 | { STV090x_P1_DISRXCTL, 0x00 }, | ||
250 | { STV090x_P1_DMDCFGMD, 0xf9 }, | ||
251 | { STV090x_P1_DEMOD, 0x08 }, | ||
252 | { STV090x_P1_DMDCFG3, 0xc4 }, | ||
253 | { STV090x_P1_DMDTOM, 0x20 }, | ||
254 | { STV090x_P1_CARFREQ, 0xed }, | ||
255 | { STV090x_P1_LDT, 0xd0 }, | ||
256 | { STV090x_P1_LDT2, 0xb8 }, | ||
257 | { STV090x_P1_TMGCFG, 0xd2 }, | ||
258 | { STV090x_P1_TMGTHRISE, 0x20 }, | ||
259 | { STV090x_P1_TMGTHFALL, 0x00 }, | ||
260 | { STV090x_P1_SFRUPRATIO, 0xf0 }, | ||
261 | { STV090x_P1_SFRLOWRATIO, 0x70 }, | ||
262 | { STV090x_P1_TSCFGL, 0x20 }, | ||
263 | { STV090x_P1_FECSPY, 0x88 }, | ||
264 | { STV090x_P1_FSPYDATA, 0x3a }, | ||
265 | { STV090x_P1_FBERCPT4, 0x00 }, | ||
266 | { STV090x_P1_FSPYBER, 0x10 }, | ||
267 | { STV090x_P1_ERRCTRL1, 0x35 }, | ||
268 | { STV090x_P1_ERRCTRL2, 0xc1 }, | ||
269 | { STV090x_P1_CFRICFG, 0xf8 }, | ||
270 | { STV090x_P1_NOSCFG, 0x1c }, | ||
271 | { STV090x_P1_CORRELMANT, 0x70 }, | ||
272 | { STV090x_P1_CORRELABS, 0x88 }, | ||
273 | { STV090x_P1_AGC2O, 0x5b }, | ||
274 | { STV090x_P1_AGC2REF, 0x38 }, | ||
275 | { STV090x_P1_CARCFG, 0xe4 }, | ||
276 | { STV090x_P1_ACLC, 0x1A }, | ||
277 | { STV090x_P1_BCLC, 0x09 }, | ||
278 | { STV090x_P1_CARHDR, 0x08 }, | ||
279 | { STV090x_P1_KREFTMG, 0xc1 }, | ||
280 | { STV090x_P1_SFRSTEP, 0x58 }, | ||
281 | { STV090x_P1_TMGCFG2, 0x01 }, | ||
282 | { STV090x_P1_CAR2CFG, 0x26 }, | ||
283 | { STV090x_P1_BCLC2S2Q, 0x86 }, | ||
284 | { STV090x_P1_BCLC2S28, 0x86 }, | ||
285 | { STV090x_P1_SMAPCOEF7, 0x77 }, | ||
286 | { STV090x_P1_SMAPCOEF6, 0x85 }, | ||
287 | { STV090x_P1_SMAPCOEF5, 0x77 }, | ||
288 | { STV090x_P1_DMDCFG2, 0x3b }, | ||
289 | { STV090x_P1_MODCODLST0, 0xff }, | ||
290 | { STV090x_P1_MODCODLST1, 0xff }, | ||
291 | { STV090x_P1_MODCODLST2, 0xff }, | ||
292 | { STV090x_P1_MODCODLST3, 0xff }, | ||
293 | { STV090x_P1_MODCODLST4, 0xff }, | ||
294 | { STV090x_P1_MODCODLST5, 0xff }, | ||
295 | { STV090x_P1_MODCODLST6, 0xff }, | ||
296 | { STV090x_P1_MODCODLST7, 0xcc }, | ||
297 | { STV090x_P1_MODCODLST8, 0xcc }, | ||
298 | { STV090x_P1_MODCODLST9, 0xcc }, | ||
299 | { STV090x_P1_MODCODLSTA, 0xcc }, | ||
300 | { STV090x_P1_MODCODLSTB, 0xcc }, | ||
301 | { STV090x_P1_MODCODLSTC, 0xcc }, | ||
302 | { STV090x_P1_MODCODLSTD, 0xcc }, | ||
303 | { STV090x_P1_MODCODLSTE, 0xcc }, | ||
304 | { STV090x_P1_MODCODLSTF, 0xcf }, | ||
305 | { STV090x_GENCFG, 0x1d }, | ||
306 | { STV090x_NBITER_NF4, 0x37 }, | ||
307 | { STV090x_NBITER_NF5, 0x29 }, | ||
308 | { STV090x_NBITER_NF6, 0x37 }, | ||
309 | { STV090x_NBITER_NF7, 0x33 }, | ||
310 | { STV090x_NBITER_NF8, 0x31 }, | ||
311 | { STV090x_NBITER_NF9, 0x2f }, | ||
312 | { STV090x_NBITER_NF10, 0x39 }, | ||
313 | { STV090x_NBITER_NF11, 0x3a }, | ||
314 | { STV090x_NBITER_NF12, 0x29 }, | ||
315 | { STV090x_NBITER_NF13, 0x37 }, | ||
316 | { STV090x_NBITER_NF14, 0x33 }, | ||
317 | { STV090x_NBITER_NF15, 0x2f }, | ||
318 | { STV090x_NBITER_NF16, 0x39 }, | ||
319 | { STV090x_NBITER_NF17, 0x3a }, | ||
320 | { STV090x_NBITERNOERR, 0x04 }, | ||
321 | { STV090x_GAINLLR_NF4, 0x0C }, | ||
322 | { STV090x_GAINLLR_NF5, 0x0F }, | ||
323 | { STV090x_GAINLLR_NF6, 0x11 }, | ||
324 | { STV090x_GAINLLR_NF7, 0x14 }, | ||
325 | { STV090x_GAINLLR_NF8, 0x17 }, | ||
326 | { STV090x_GAINLLR_NF9, 0x19 }, | ||
327 | { STV090x_GAINLLR_NF10, 0x20 }, | ||
328 | { STV090x_GAINLLR_NF11, 0x21 }, | ||
329 | { STV090x_GAINLLR_NF12, 0x0D }, | ||
330 | { STV090x_GAINLLR_NF13, 0x0F }, | ||
331 | { STV090x_GAINLLR_NF14, 0x13 }, | ||
332 | { STV090x_GAINLLR_NF15, 0x1A }, | ||
333 | { STV090x_GAINLLR_NF16, 0x1F }, | ||
334 | { STV090x_GAINLLR_NF17, 0x21 }, | ||
335 | { STV090x_RCCFGH, 0x20 }, | ||
336 | { STV090x_P1_FECM, 0x01 }, /* disable DSS modes */ | ||
337 | { STV090x_P2_FECM, 0x01 }, /* disable DSS modes */ | ||
338 | { STV090x_P1_PRVIT, 0x2F }, /* disable PR 6/7 */ | ||
339 | { STV090x_P2_PRVIT, 0x2F }, /* disable PR 6/7 */ | ||
340 | }; | ||
341 | |||
342 | static struct stv090x_reg stv0903_initval[] = { | ||
343 | { STV090x_OUTCFG, 0x00 }, | ||
344 | { STV090x_AGCRF1CFG, 0x11 }, | ||
345 | { STV090x_STOPCLK1, 0x48 }, | ||
346 | { STV090x_STOPCLK2, 0x14 }, | ||
347 | { STV090x_TSTTNR1, 0x27 }, | ||
348 | { STV090x_TSTTNR2, 0x21 }, | ||
349 | { STV090x_P1_DISTXCTL, 0x22 }, | ||
350 | { STV090x_P1_F22TX, 0xc0 }, | ||
351 | { STV090x_P1_F22RX, 0xc0 }, | ||
352 | { STV090x_P1_DISRXCTL, 0x00 }, | ||
353 | { STV090x_P1_DMDCFGMD, 0xF9 }, | ||
354 | { STV090x_P1_DEMOD, 0x08 }, | ||
355 | { STV090x_P1_DMDCFG3, 0xc4 }, | ||
356 | { STV090x_P1_CARFREQ, 0xed }, | ||
357 | { STV090x_P1_TNRCFG2, 0x82 }, | ||
358 | { STV090x_P1_LDT, 0xd0 }, | ||
359 | { STV090x_P1_LDT2, 0xb8 }, | ||
360 | { STV090x_P1_TMGCFG, 0xd2 }, | ||
361 | { STV090x_P1_TMGTHRISE, 0x20 }, | ||
362 | { STV090x_P1_TMGTHFALL, 0x00 }, | ||
363 | { STV090x_P1_SFRUPRATIO, 0xf0 }, | ||
364 | { STV090x_P1_SFRLOWRATIO, 0x70 }, | ||
365 | { STV090x_P1_TSCFGL, 0x20 }, | ||
366 | { STV090x_P1_FECSPY, 0x88 }, | ||
367 | { STV090x_P1_FSPYDATA, 0x3a }, | ||
368 | { STV090x_P1_FBERCPT4, 0x00 }, | ||
369 | { STV090x_P1_FSPYBER, 0x10 }, | ||
370 | { STV090x_P1_ERRCTRL1, 0x35 }, | ||
371 | { STV090x_P1_ERRCTRL2, 0xc1 }, | ||
372 | { STV090x_P1_CFRICFG, 0xf8 }, | ||
373 | { STV090x_P1_NOSCFG, 0x1c }, | ||
374 | { STV090x_P1_DMDTOM, 0x20 }, | ||
375 | { STV090x_P1_CORRELMANT, 0x70 }, | ||
376 | { STV090x_P1_CORRELABS, 0x88 }, | ||
377 | { STV090x_P1_AGC2O, 0x5b }, | ||
378 | { STV090x_P1_AGC2REF, 0x38 }, | ||
379 | { STV090x_P1_CARCFG, 0xe4 }, | ||
380 | { STV090x_P1_ACLC, 0x1A }, | ||
381 | { STV090x_P1_BCLC, 0x09 }, | ||
382 | { STV090x_P1_CARHDR, 0x08 }, | ||
383 | { STV090x_P1_KREFTMG, 0xc1 }, | ||
384 | { STV090x_P1_SFRSTEP, 0x58 }, | ||
385 | { STV090x_P1_TMGCFG2, 0x01 }, | ||
386 | { STV090x_P1_CAR2CFG, 0x26 }, | ||
387 | { STV090x_P1_BCLC2S2Q, 0x86 }, | ||
388 | { STV090x_P1_BCLC2S28, 0x86 }, | ||
389 | { STV090x_P1_SMAPCOEF7, 0x77 }, | ||
390 | { STV090x_P1_SMAPCOEF6, 0x85 }, | ||
391 | { STV090x_P1_SMAPCOEF5, 0x77 }, | ||
392 | { STV090x_P1_DMDCFG2, 0x3b }, | ||
393 | { STV090x_P1_MODCODLST0, 0xff }, | ||
394 | { STV090x_P1_MODCODLST1, 0xff }, | ||
395 | { STV090x_P1_MODCODLST2, 0xff }, | ||
396 | { STV090x_P1_MODCODLST3, 0xff }, | ||
397 | { STV090x_P1_MODCODLST4, 0xff }, | ||
398 | { STV090x_P1_MODCODLST5, 0xff }, | ||
399 | { STV090x_P1_MODCODLST6, 0xff }, | ||
400 | { STV090x_P1_MODCODLST7, 0xcc }, | ||
401 | { STV090x_P1_MODCODLST8, 0xcc }, | ||
402 | { STV090x_P1_MODCODLST9, 0xcc }, | ||
403 | { STV090x_P1_MODCODLSTA, 0xcc }, | ||
404 | { STV090x_P1_MODCODLSTB, 0xcc }, | ||
405 | { STV090x_P1_MODCODLSTC, 0xcc }, | ||
406 | { STV090x_P1_MODCODLSTD, 0xcc }, | ||
407 | { STV090x_P1_MODCODLSTE, 0xcc }, | ||
408 | { STV090x_P1_MODCODLSTF, 0xcf }, | ||
409 | { STV090x_GENCFG, 0x1c }, | ||
410 | { STV090x_NBITER_NF4, 0x37 }, | ||
411 | { STV090x_NBITER_NF5, 0x29 }, | ||
412 | { STV090x_NBITER_NF6, 0x37 }, | ||
413 | { STV090x_NBITER_NF7, 0x33 }, | ||
414 | { STV090x_NBITER_NF8, 0x31 }, | ||
415 | { STV090x_NBITER_NF9, 0x2f }, | ||
416 | { STV090x_NBITER_NF10, 0x39 }, | ||
417 | { STV090x_NBITER_NF11, 0x3a }, | ||
418 | { STV090x_NBITER_NF12, 0x29 }, | ||
419 | { STV090x_NBITER_NF13, 0x37 }, | ||
420 | { STV090x_NBITER_NF14, 0x33 }, | ||
421 | { STV090x_NBITER_NF15, 0x2f }, | ||
422 | { STV090x_NBITER_NF16, 0x39 }, | ||
423 | { STV090x_NBITER_NF17, 0x3a }, | ||
424 | { STV090x_NBITERNOERR, 0x04 }, | ||
425 | { STV090x_GAINLLR_NF4, 0x0C }, | ||
426 | { STV090x_GAINLLR_NF5, 0x0F }, | ||
427 | { STV090x_GAINLLR_NF6, 0x11 }, | ||
428 | { STV090x_GAINLLR_NF7, 0x14 }, | ||
429 | { STV090x_GAINLLR_NF8, 0x17 }, | ||
430 | { STV090x_GAINLLR_NF9, 0x19 }, | ||
431 | { STV090x_GAINLLR_NF10, 0x20 }, | ||
432 | { STV090x_GAINLLR_NF11, 0x21 }, | ||
433 | { STV090x_GAINLLR_NF12, 0x0D }, | ||
434 | { STV090x_GAINLLR_NF13, 0x0F }, | ||
435 | { STV090x_GAINLLR_NF14, 0x13 }, | ||
436 | { STV090x_GAINLLR_NF15, 0x1A }, | ||
437 | { STV090x_GAINLLR_NF16, 0x1F }, | ||
438 | { STV090x_GAINLLR_NF17, 0x21 }, | ||
439 | { STV090x_RCCFGH, 0x20 }, | ||
440 | { STV090x_P1_FECM, 0x01 }, /*disable the DSS mode */ | ||
441 | { STV090x_P1_PRVIT, 0x2f } /*disable puncture rate 6/7*/ | ||
442 | }; | ||
443 | |||
444 | static struct stv090x_reg stv0900_cut20_val[] = { | ||
445 | |||
446 | { STV090x_P2_DMDCFG3, 0xe8 }, | ||
447 | { STV090x_P2_DMDCFG4, 0x10 }, | ||
448 | { STV090x_P2_CARFREQ, 0x38 }, | ||
449 | { STV090x_P2_CARHDR, 0x20 }, | ||
450 | { STV090x_P2_KREFTMG, 0x5a }, | ||
451 | { STV090x_P2_SMAPCOEF7, 0x06 }, | ||
452 | { STV090x_P2_SMAPCOEF6, 0x00 }, | ||
453 | { STV090x_P2_SMAPCOEF5, 0x04 }, | ||
454 | { STV090x_P2_NOSCFG, 0x0c }, | ||
455 | { STV090x_P1_DMDCFG3, 0xe8 }, | ||
456 | { STV090x_P1_DMDCFG4, 0x10 }, | ||
457 | { STV090x_P1_CARFREQ, 0x38 }, | ||
458 | { STV090x_P1_CARHDR, 0x20 }, | ||
459 | { STV090x_P1_KREFTMG, 0x5a }, | ||
460 | { STV090x_P1_SMAPCOEF7, 0x06 }, | ||
461 | { STV090x_P1_SMAPCOEF6, 0x00 }, | ||
462 | { STV090x_P1_SMAPCOEF5, 0x04 }, | ||
463 | { STV090x_P1_NOSCFG, 0x0c }, | ||
464 | { STV090x_GAINLLR_NF4, 0x21 }, | ||
465 | { STV090x_GAINLLR_NF5, 0x21 }, | ||
466 | { STV090x_GAINLLR_NF6, 0x20 }, | ||
467 | { STV090x_GAINLLR_NF7, 0x1F }, | ||
468 | { STV090x_GAINLLR_NF8, 0x1E }, | ||
469 | { STV090x_GAINLLR_NF9, 0x1E }, | ||
470 | { STV090x_GAINLLR_NF10, 0x1D }, | ||
471 | { STV090x_GAINLLR_NF11, 0x1B }, | ||
472 | { STV090x_GAINLLR_NF12, 0x20 }, | ||
473 | { STV090x_GAINLLR_NF13, 0x20 }, | ||
474 | { STV090x_GAINLLR_NF14, 0x20 }, | ||
475 | { STV090x_GAINLLR_NF15, 0x20 }, | ||
476 | { STV090x_GAINLLR_NF16, 0x20 }, | ||
477 | { STV090x_GAINLLR_NF17, 0x21 }, | ||
478 | }; | ||
479 | |||
480 | static struct stv090x_reg stv0903_cut20_val[] = { | ||
481 | { STV090x_P1_DMDCFG3, 0xe8 }, | ||
482 | { STV090x_P1_DMDCFG4, 0x10 }, | ||
483 | { STV090x_P1_CARFREQ, 0x38 }, | ||
484 | { STV090x_P1_CARHDR, 0x20 }, | ||
485 | { STV090x_P1_KREFTMG, 0x5a }, | ||
486 | { STV090x_P1_SMAPCOEF7, 0x06 }, | ||
487 | { STV090x_P1_SMAPCOEF6, 0x00 }, | ||
488 | { STV090x_P1_SMAPCOEF5, 0x04 }, | ||
489 | { STV090x_P1_NOSCFG, 0x0c }, | ||
490 | { STV090x_GAINLLR_NF4, 0x21 }, | ||
491 | { STV090x_GAINLLR_NF5, 0x21 }, | ||
492 | { STV090x_GAINLLR_NF6, 0x20 }, | ||
493 | { STV090x_GAINLLR_NF7, 0x1F }, | ||
494 | { STV090x_GAINLLR_NF8, 0x1E }, | ||
495 | { STV090x_GAINLLR_NF9, 0x1E }, | ||
496 | { STV090x_GAINLLR_NF10, 0x1D }, | ||
497 | { STV090x_GAINLLR_NF11, 0x1B }, | ||
498 | { STV090x_GAINLLR_NF12, 0x20 }, | ||
499 | { STV090x_GAINLLR_NF13, 0x20 }, | ||
500 | { STV090x_GAINLLR_NF14, 0x20 }, | ||
501 | { STV090x_GAINLLR_NF15, 0x20 }, | ||
502 | { STV090x_GAINLLR_NF16, 0x20 }, | ||
503 | { STV090x_GAINLLR_NF17, 0x21 } | ||
504 | }; | ||
505 | |||
506 | /* Cut 2.0 Long Frame Tracking CR loop */ | ||
507 | static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = { | ||
508 | /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ | ||
509 | { STV090x_QPSK_12, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x1e }, | ||
510 | { STV090x_QPSK_35, 0x2f, 0x3f, 0x2e, 0x2f, 0x3d, 0x0f, 0x0e, 0x2e, 0x3d, 0x0e }, | ||
511 | { STV090x_QPSK_23, 0x2f, 0x3f, 0x2e, 0x2f, 0x0e, 0x0f, 0x0e, 0x1e, 0x3d, 0x3d }, | ||
512 | { STV090x_QPSK_34, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, | ||
513 | { STV090x_QPSK_45, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, | ||
514 | { STV090x_QPSK_56, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, | ||
515 | { STV090x_QPSK_89, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, | ||
516 | { STV090x_QPSK_910, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, | ||
517 | { STV090x_8PSK_35, 0x3c, 0x3e, 0x1c, 0x2e, 0x0c, 0x1e, 0x2b, 0x2d, 0x1b, 0x1d }, | ||
518 | { STV090x_8PSK_23, 0x1d, 0x3e, 0x3c, 0x2e, 0x2c, 0x1e, 0x0c, 0x2d, 0x2b, 0x1d }, | ||
519 | { STV090x_8PSK_34, 0x0e, 0x3e, 0x3d, 0x2e, 0x0d, 0x1e, 0x2c, 0x2d, 0x0c, 0x1d }, | ||
520 | { STV090x_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d }, | ||
521 | { STV090x_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d }, | ||
522 | { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d } | ||
523 | }; | ||
524 | |||
525 | /* Cut 3.0 Long Frame Tracking CR loop */ | ||
526 | static struct stv090x_long_frame_crloop stv090x_s2_crl_cut30[] = { | ||
527 | /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ | ||
528 | { STV090x_QPSK_12, 0x3c, 0x2c, 0x0c, 0x2c, 0x1b, 0x2c, 0x1b, 0x1c, 0x0b, 0x3b }, | ||
529 | { STV090x_QPSK_35, 0x0d, 0x0d, 0x0c, 0x0d, 0x1b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b }, | ||
530 | { STV090x_QPSK_23, 0x1d, 0x0d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b }, | ||
531 | { STV090x_QPSK_34, 0x1d, 0x1d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b }, | ||
532 | { STV090x_QPSK_45, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, | ||
533 | { STV090x_QPSK_56, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, | ||
534 | { STV090x_QPSK_89, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, | ||
535 | { STV090x_QPSK_910, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, | ||
536 | { STV090x_8PSK_35, 0x39, 0x29, 0x39, 0x19, 0x19, 0x19, 0x19, 0x19, 0x09, 0x19 }, | ||
537 | { STV090x_8PSK_23, 0x2a, 0x39, 0x1a, 0x0a, 0x39, 0x0a, 0x29, 0x39, 0x29, 0x0a }, | ||
538 | { STV090x_8PSK_34, 0x2b, 0x3a, 0x1b, 0x1b, 0x3a, 0x1b, 0x1a, 0x0b, 0x1a, 0x3a }, | ||
539 | { STV090x_8PSK_56, 0x0c, 0x1b, 0x3b, 0x3b, 0x1b, 0x3b, 0x3a, 0x3b, 0x3a, 0x1b }, | ||
540 | { STV090x_8PSK_89, 0x0d, 0x3c, 0x2c, 0x2c, 0x2b, 0x0c, 0x0b, 0x3b, 0x0b, 0x1b }, | ||
541 | { STV090x_8PSK_910, 0x0d, 0x0d, 0x2c, 0x3c, 0x3b, 0x1c, 0x0b, 0x3b, 0x0b, 0x1b } | ||
542 | }; | ||
543 | |||
544 | /* Cut 2.0 Long Frame Tracking CR Loop */ | ||
545 | static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = { | ||
546 | /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ | ||
547 | { STV090x_16APSK_23, 0x0c, 0x0c, 0x0c, 0x0c, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x0c }, | ||
548 | { STV090x_16APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0c, 0x2d, 0x0c, 0x1d, 0x0c }, | ||
549 | { STV090x_16APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c }, | ||
550 | { STV090x_16APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c }, | ||
551 | { STV090x_16APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c }, | ||
552 | { STV090x_16APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c }, | ||
553 | { STV090x_32APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, | ||
554 | { STV090x_32APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, | ||
555 | { STV090x_32APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, | ||
556 | { STV090x_32APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, | ||
557 | { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c } | ||
558 | }; | ||
559 | |||
560 | /* Cut 3.0 Long Frame Tracking CR Loop */ | ||
561 | static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut30[] = { | ||
562 | /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ | ||
563 | { STV090x_16APSK_23, 0x0a, 0x0a, 0x0a, 0x0a, 0x1a, 0x0a, 0x3a, 0x0a, 0x2a, 0x0a }, | ||
564 | { STV090x_16APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x3b, 0x0a, 0x1b, 0x0a }, | ||
565 | { STV090x_16APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a }, | ||
566 | { STV090x_16APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a }, | ||
567 | { STV090x_16APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a }, | ||
568 | { STV090x_16APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a }, | ||
569 | { STV090x_32APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, | ||
570 | { STV090x_32APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, | ||
571 | { STV090x_32APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, | ||
572 | { STV090x_32APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, | ||
573 | { STV090x_32APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } | ||
574 | }; | ||
575 | |||
576 | static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = { | ||
577 | /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ | ||
578 | { STV090x_QPSK_14, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x2d, 0x1f, 0x3d, 0x3e }, | ||
579 | { STV090x_QPSK_13, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x3d, 0x0f, 0x3d, 0x2e }, | ||
580 | { STV090x_QPSK_25, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x2e } | ||
581 | }; | ||
582 | |||
583 | static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut30[] = { | ||
584 | /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ | ||
585 | { STV090x_QPSK_14, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x2a, 0x1c, 0x3a, 0x3b }, | ||
586 | { STV090x_QPSK_13, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b }, | ||
587 | { STV090x_QPSK_25, 0x1c, 0x3c, 0x1b, 0x3c, 0x3a, 0x1c, 0x3a, 0x3b, 0x3a, 0x2b } | ||
588 | }; | ||
589 | |||
590 | /* Cut 2.0 Short Frame Tracking CR Loop */ | ||
591 | static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = { | ||
592 | /* MODCOD 2M 5M 10M 20M 30M */ | ||
593 | { STV090x_QPSK, 0x2f, 0x2e, 0x0e, 0x0e, 0x3d }, | ||
594 | { STV090x_8PSK, 0x3e, 0x0e, 0x2d, 0x0d, 0x3c }, | ||
595 | { STV090x_16APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d }, | ||
596 | { STV090x_32APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d } | ||
597 | }; | ||
598 | |||
599 | /* Cut 3.0 Short Frame Tracking CR Loop */ | ||
600 | static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = { | ||
601 | /* MODCOD 2M 5M 10M 20M 30M */ | ||
602 | { STV090x_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A }, | ||
603 | { STV090x_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 }, | ||
604 | { STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A }, | ||
605 | { STV090x_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A } | ||
606 | }; | ||
607 | |||
608 | static inline s32 comp2(s32 __x, s32 __width) | ||
609 | { | ||
610 | if (__width == 32) | ||
611 | return __x; | ||
612 | else | ||
613 | return (__x >= (1 << (__width - 1))) ? (__x - (1 << __width)) : __x; | ||
614 | } | ||
615 | |||
616 | static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg) | ||
617 | { | ||
618 | const struct stv090x_config *config = state->config; | ||
619 | int ret; | ||
620 | |||
621 | u8 b0[] = { reg >> 8, reg & 0xff }; | ||
622 | u8 buf; | ||
623 | |||
624 | struct i2c_msg msg[] = { | ||
625 | { .addr = config->address, .flags = 0, .buf = b0, .len = 2 }, | ||
626 | { .addr = config->address, .flags = I2C_M_RD, .buf = &buf, .len = 1 } | ||
627 | }; | ||
628 | |||
629 | ret = i2c_transfer(state->i2c, msg, 2); | ||
630 | if (ret != 2) { | ||
631 | if (ret != -ERESTARTSYS) | ||
632 | dprintk(FE_ERROR, 1, | ||
633 | "Read error, Reg=[0x%02x], Status=%d", | ||
634 | reg, ret); | ||
635 | |||
636 | return ret < 0 ? ret : -EREMOTEIO; | ||
637 | } | ||
638 | if (unlikely(*state->verbose >= FE_DEBUGREG)) | ||
639 | dprintk(FE_ERROR, 1, "Reg=[0x%02x], data=%02x", | ||
640 | reg, buf); | ||
641 | |||
642 | return (unsigned int) buf; | ||
643 | } | ||
644 | |||
645 | static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 *data, u32 count) | ||
646 | { | ||
647 | const struct stv090x_config *config = state->config; | ||
648 | int ret; | ||
649 | u8 buf[2 + count]; | ||
650 | struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count }; | ||
651 | |||
652 | buf[0] = reg >> 8; | ||
653 | buf[1] = reg & 0xff; | ||
654 | memcpy(&buf[2], data, count); | ||
655 | |||
656 | if (unlikely(*state->verbose >= FE_DEBUGREG)) { | ||
657 | int i; | ||
658 | |||
659 | printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); | ||
660 | for (i = 0; i < count; i++) | ||
661 | printk(" %02x", data[i]); | ||
662 | printk("\n"); | ||
663 | } | ||
664 | |||
665 | ret = i2c_transfer(state->i2c, &i2c_msg, 1); | ||
666 | if (ret != 1) { | ||
667 | if (ret != -ERESTARTSYS) | ||
668 | dprintk(FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d", | ||
669 | reg, data[0], count, ret); | ||
670 | return ret < 0 ? ret : -EREMOTEIO; | ||
671 | } | ||
672 | |||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data) | ||
677 | { | ||
678 | return stv090x_write_regs(state, reg, &data, 1); | ||
679 | } | ||
680 | |||
681 | static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
682 | { | ||
683 | struct stv090x_state *state = fe->demodulator_priv; | ||
684 | u32 reg; | ||
685 | |||
686 | reg = STV090x_READ_DEMOD(state, I2CRPT); | ||
687 | if (enable) { | ||
688 | dprintk(FE_DEBUG, 1, "Enable Gate"); | ||
689 | STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1); | ||
690 | if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) | ||
691 | goto err; | ||
692 | |||
693 | } else { | ||
694 | dprintk(FE_DEBUG, 1, "Disable Gate"); | ||
695 | STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 0); | ||
696 | if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0) | ||
697 | goto err; | ||
698 | } | ||
699 | return 0; | ||
700 | err: | ||
701 | dprintk(FE_ERROR, 1, "I/O error"); | ||
702 | return -1; | ||
703 | } | ||
704 | |||
705 | static void stv090x_get_lock_tmg(struct stv090x_state *state) | ||
706 | { | ||
707 | switch (state->algo) { | ||
708 | case STV090x_BLIND_SEARCH: | ||
709 | dprintk(FE_DEBUG, 1, "Blind Search"); | ||
710 | if (state->srate <= 1500000) { /*10Msps< SR <=15Msps*/ | ||
711 | state->DemodTimeout = 1500; | ||
712 | state->FecTimeout = 400; | ||
713 | } else if (state->srate <= 5000000) { /*10Msps< SR <=15Msps*/ | ||
714 | state->DemodTimeout = 1000; | ||
715 | state->FecTimeout = 300; | ||
716 | } else { /*SR >20Msps*/ | ||
717 | state->DemodTimeout = 700; | ||
718 | state->FecTimeout = 100; | ||
719 | } | ||
720 | break; | ||
721 | |||
722 | case STV090x_COLD_SEARCH: | ||
723 | case STV090x_WARM_SEARCH: | ||
724 | default: | ||
725 | dprintk(FE_DEBUG, 1, "Normal Search"); | ||
726 | if (state->srate <= 1000000) { /*SR <=1Msps*/ | ||
727 | state->DemodTimeout = 4500; | ||
728 | state->FecTimeout = 1700; | ||
729 | } else if (state->srate <= 2000000) { /*1Msps < SR <= 2Msps */ | ||
730 | state->DemodTimeout = 2500; | ||
731 | state->FecTimeout = 1100; | ||
732 | } else if (state->srate <= 5000000) { /*2Msps < SR <= 5Msps */ | ||
733 | state->DemodTimeout = 1000; | ||
734 | state->FecTimeout = 550; | ||
735 | } else if (state->srate <= 10000000) { /*5Msps < SR <= 10Msps */ | ||
736 | state->DemodTimeout = 700; | ||
737 | state->FecTimeout = 250; | ||
738 | } else if (state->srate <= 20000000) { /*10Msps < SR <= 20Msps */ | ||
739 | state->DemodTimeout = 400; | ||
740 | state->FecTimeout = 130; | ||
741 | } else { /*SR >20Msps*/ | ||
742 | state->DemodTimeout = 300; | ||
743 | state->FecTimeout = 100; | ||
744 | } | ||
745 | break; | ||
746 | } | ||
747 | |||
748 | if (state->algo == STV090x_WARM_SEARCH) | ||
749 | state->DemodTimeout /= 2; | ||
750 | } | ||
751 | |||
752 | static int stv090x_set_srate(struct stv090x_state *state, u32 srate) | ||
753 | { | ||
754 | u32 sym; | ||
755 | |||
756 | if (srate > 60000000) { | ||
757 | sym = (srate << 4); /* SR * 2^16 / master_clk */ | ||
758 | sym /= (state->mclk >> 12); | ||
759 | } else if (srate > 6000000) { | ||
760 | sym = (srate << 6); | ||
761 | sym /= (state->mclk >> 10); | ||
762 | } else { | ||
763 | sym = (srate << 9); | ||
764 | sym /= (state->mclk >> 7); | ||
765 | } | ||
766 | |||
767 | if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */ | ||
768 | goto err; | ||
769 | if (STV090x_WRITE_DEMOD(state, SFRINIT0, (sym & 0xff)) < 0) /* LSB */ | ||
770 | goto err; | ||
771 | |||
772 | return 0; | ||
773 | err: | ||
774 | dprintk(FE_ERROR, 1, "I/O error"); | ||
775 | return -1; | ||
776 | } | ||
777 | |||
778 | static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate) | ||
779 | { | ||
780 | u32 sym; | ||
781 | |||
782 | srate = 105 * (srate / 100); | ||
783 | if (srate > 60000000) { | ||
784 | sym = (srate << 4); /* SR * 2^16 / master_clk */ | ||
785 | sym /= (state->mclk >> 12); | ||
786 | } else if (srate > 6000000) { | ||
787 | sym = (srate << 6); | ||
788 | sym /= (state->mclk >> 10); | ||
789 | } else { | ||
790 | sym = (srate << 9); | ||
791 | sym /= (state->mclk >> 7); | ||
792 | } | ||
793 | |||
794 | if (sym < 0x7fff) { | ||
795 | if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */ | ||
796 | goto err; | ||
797 | if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */ | ||
798 | goto err; | ||
799 | } else { | ||
800 | if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x7f) < 0) /* MSB */ | ||
801 | goto err; | ||
802 | if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xff) < 0) /* LSB */ | ||
803 | goto err; | ||
804 | } | ||
805 | |||
806 | return 0; | ||
807 | err: | ||
808 | dprintk(FE_ERROR, 1, "I/O error"); | ||
809 | return -1; | ||
810 | } | ||
811 | |||
812 | static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate) | ||
813 | { | ||
814 | u32 sym; | ||
815 | |||
816 | srate = 95 * (srate / 100); | ||
817 | if (srate > 60000000) { | ||
818 | sym = (srate << 4); /* SR * 2^16 / master_clk */ | ||
819 | sym /= (state->mclk >> 12); | ||
820 | } else if (srate > 6000000) { | ||
821 | sym = (srate << 6); | ||
822 | sym /= (state->mclk >> 10); | ||
823 | } else { | ||
824 | sym = (srate << 9); | ||
825 | sym /= (state->mclk >> 7); | ||
826 | } | ||
827 | |||
828 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0xff)) < 0) /* MSB */ | ||
829 | goto err; | ||
830 | if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */ | ||
831 | goto err; | ||
832 | return 0; | ||
833 | err: | ||
834 | dprintk(FE_ERROR, 1, "I/O error"); | ||
835 | return -1; | ||
836 | } | ||
837 | |||
838 | static u32 stv090x_car_width(u32 srate, enum stv090x_rolloff rolloff) | ||
839 | { | ||
840 | u32 ro; | ||
841 | |||
842 | switch (rolloff) { | ||
843 | case STV090x_RO_20: | ||
844 | ro = 20; | ||
845 | break; | ||
846 | case STV090x_RO_25: | ||
847 | ro = 25; | ||
848 | break; | ||
849 | case STV090x_RO_35: | ||
850 | default: | ||
851 | ro = 35; | ||
852 | break; | ||
853 | } | ||
854 | |||
855 | return srate + (srate * ro) / 100; | ||
856 | } | ||
857 | |||
858 | static int stv090x_set_vit_thacq(struct stv090x_state *state) | ||
859 | { | ||
860 | if (STV090x_WRITE_DEMOD(state, VTH12, 0x96) < 0) | ||
861 | goto err; | ||
862 | if (STV090x_WRITE_DEMOD(state, VTH23, 0x64) < 0) | ||
863 | goto err; | ||
864 | if (STV090x_WRITE_DEMOD(state, VTH34, 0x36) < 0) | ||
865 | goto err; | ||
866 | if (STV090x_WRITE_DEMOD(state, VTH56, 0x23) < 0) | ||
867 | goto err; | ||
868 | if (STV090x_WRITE_DEMOD(state, VTH67, 0x1e) < 0) | ||
869 | goto err; | ||
870 | if (STV090x_WRITE_DEMOD(state, VTH78, 0x19) < 0) | ||
871 | goto err; | ||
872 | return 0; | ||
873 | err: | ||
874 | dprintk(FE_ERROR, 1, "I/O error"); | ||
875 | return -1; | ||
876 | } | ||
877 | |||
878 | static int stv090x_set_vit_thtracq(struct stv090x_state *state) | ||
879 | { | ||
880 | if (STV090x_WRITE_DEMOD(state, VTH12, 0xd0) < 0) | ||
881 | goto err; | ||
882 | if (STV090x_WRITE_DEMOD(state, VTH23, 0x7d) < 0) | ||
883 | goto err; | ||
884 | if (STV090x_WRITE_DEMOD(state, VTH34, 0x53) < 0) | ||
885 | goto err; | ||
886 | if (STV090x_WRITE_DEMOD(state, VTH56, 0x2f) < 0) | ||
887 | goto err; | ||
888 | if (STV090x_WRITE_DEMOD(state, VTH67, 0x24) < 0) | ||
889 | goto err; | ||
890 | if (STV090x_WRITE_DEMOD(state, VTH78, 0x1f) < 0) | ||
891 | goto err; | ||
892 | return 0; | ||
893 | err: | ||
894 | dprintk(FE_ERROR, 1, "I/O error"); | ||
895 | return -1; | ||
896 | } | ||
897 | |||
898 | static int stv090x_set_viterbi(struct stv090x_state *state) | ||
899 | { | ||
900 | switch (state->search_mode) { | ||
901 | case STV090x_SEARCH_AUTO: | ||
902 | if (STV090x_WRITE_DEMOD(state, FECM, 0x10) < 0) /* DVB-S and DVB-S2 */ | ||
903 | goto err; | ||
904 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x3f) < 0) /* all puncture rate */ | ||
905 | goto err; | ||
906 | break; | ||
907 | case STV090x_SEARCH_DVBS1: | ||
908 | if (STV090x_WRITE_DEMOD(state, FECM, 0x00) < 0) /* disable DSS */ | ||
909 | goto err; | ||
910 | switch (state->fec) { | ||
911 | case STV090x_PR12: | ||
912 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0) | ||
913 | goto err; | ||
914 | break; | ||
915 | |||
916 | case STV090x_PR23: | ||
917 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0) | ||
918 | goto err; | ||
919 | break; | ||
920 | |||
921 | case STV090x_PR34: | ||
922 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x04) < 0) | ||
923 | goto err; | ||
924 | break; | ||
925 | |||
926 | case STV090x_PR56: | ||
927 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x08) < 0) | ||
928 | goto err; | ||
929 | break; | ||
930 | |||
931 | case STV090x_PR78: | ||
932 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x20) < 0) | ||
933 | goto err; | ||
934 | break; | ||
935 | |||
936 | default: | ||
937 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x2f) < 0) /* all */ | ||
938 | goto err; | ||
939 | break; | ||
940 | } | ||
941 | break; | ||
942 | case STV090x_SEARCH_DSS: | ||
943 | if (STV090x_WRITE_DEMOD(state, FECM, 0x80) < 0) | ||
944 | goto err; | ||
945 | switch (state->fec) { | ||
946 | case STV090x_PR12: | ||
947 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0) | ||
948 | goto err; | ||
949 | break; | ||
950 | |||
951 | case STV090x_PR23: | ||
952 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0) | ||
953 | goto err; | ||
954 | break; | ||
955 | |||
956 | case STV090x_PR67: | ||
957 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x10) < 0) | ||
958 | goto err; | ||
959 | break; | ||
960 | |||
961 | default: | ||
962 | if (STV090x_WRITE_DEMOD(state, PRVIT, 0x13) < 0) /* 1/2, 2/3, 6/7 */ | ||
963 | goto err; | ||
964 | break; | ||
965 | } | ||
966 | break; | ||
967 | default: | ||
968 | break; | ||
969 | } | ||
970 | return 0; | ||
971 | err: | ||
972 | dprintk(FE_ERROR, 1, "I/O error"); | ||
973 | return -1; | ||
974 | } | ||
975 | |||
976 | static int stv090x_stop_modcod(struct stv090x_state *state) | ||
977 | { | ||
978 | if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) | ||
979 | goto err; | ||
980 | if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0) | ||
981 | goto err; | ||
982 | if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0) | ||
983 | goto err; | ||
984 | if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0) | ||
985 | goto err; | ||
986 | if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0) | ||
987 | goto err; | ||
988 | if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0) | ||
989 | goto err; | ||
990 | if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0) | ||
991 | goto err; | ||
992 | if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xff) < 0) | ||
993 | goto err; | ||
994 | if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xff) < 0) | ||
995 | goto err; | ||
996 | if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xff) < 0) | ||
997 | goto err; | ||
998 | if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xff) < 0) | ||
999 | goto err; | ||
1000 | if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xff) < 0) | ||
1001 | goto err; | ||
1002 | if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xff) < 0) | ||
1003 | goto err; | ||
1004 | if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xff) < 0) | ||
1005 | goto err; | ||
1006 | if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0) | ||
1007 | goto err; | ||
1008 | if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xff) < 0) | ||
1009 | goto err; | ||
1010 | return 0; | ||
1011 | err: | ||
1012 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1013 | return -1; | ||
1014 | } | ||
1015 | |||
1016 | static int stv090x_activate_modcod(struct stv090x_state *state) | ||
1017 | { | ||
1018 | if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) | ||
1019 | goto err; | ||
1020 | if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0) | ||
1021 | goto err; | ||
1022 | if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0) | ||
1023 | goto err; | ||
1024 | if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0) | ||
1025 | goto err; | ||
1026 | if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0) | ||
1027 | goto err; | ||
1028 | if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0) | ||
1029 | goto err; | ||
1030 | if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0) | ||
1031 | goto err; | ||
1032 | if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0) | ||
1033 | goto err; | ||
1034 | if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0) | ||
1035 | goto err; | ||
1036 | if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0) | ||
1037 | goto err; | ||
1038 | if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0) | ||
1039 | goto err; | ||
1040 | if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0) | ||
1041 | goto err; | ||
1042 | if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0) | ||
1043 | goto err; | ||
1044 | if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0) | ||
1045 | goto err; | ||
1046 | if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0) | ||
1047 | goto err; | ||
1048 | if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0) | ||
1049 | goto err; | ||
1050 | |||
1051 | return 0; | ||
1052 | err: | ||
1053 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1054 | return -1; | ||
1055 | } | ||
1056 | |||
1057 | static int stv090x_activate_modcod_single(struct stv090x_state *state) | ||
1058 | { | ||
1059 | |||
1060 | if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) | ||
1061 | goto err; | ||
1062 | if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xf0) < 0) | ||
1063 | goto err; | ||
1064 | if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0x00) < 0) | ||
1065 | goto err; | ||
1066 | if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0x00) < 0) | ||
1067 | goto err; | ||
1068 | if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0x00) < 0) | ||
1069 | goto err; | ||
1070 | if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0x00) < 0) | ||
1071 | goto err; | ||
1072 | if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0x00) < 0) | ||
1073 | goto err; | ||
1074 | if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0x00) < 0) | ||
1075 | goto err; | ||
1076 | if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0x00) < 0) | ||
1077 | goto err; | ||
1078 | if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0x00) < 0) | ||
1079 | goto err; | ||
1080 | if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0x00) < 0) | ||
1081 | goto err; | ||
1082 | if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0x00) < 0) | ||
1083 | goto err; | ||
1084 | if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0x00) < 0) | ||
1085 | goto err; | ||
1086 | if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0x00) < 0) | ||
1087 | goto err; | ||
1088 | if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0x00) < 0) | ||
1089 | goto err; | ||
1090 | if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0x0f) < 0) | ||
1091 | goto err; | ||
1092 | |||
1093 | return 0; | ||
1094 | |||
1095 | err: | ||
1096 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1097 | return -1; | ||
1098 | } | ||
1099 | |||
1100 | static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable) | ||
1101 | { | ||
1102 | u32 reg; | ||
1103 | |||
1104 | switch (state->demod) { | ||
1105 | case STV090x_DEMODULATOR_0: | ||
1106 | mutex_lock(&demod_lock); | ||
1107 | reg = stv090x_read_reg(state, STV090x_STOPCLK2); | ||
1108 | STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable); | ||
1109 | if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) | ||
1110 | goto err; | ||
1111 | mutex_unlock(&demod_lock); | ||
1112 | break; | ||
1113 | |||
1114 | case STV090x_DEMODULATOR_1: | ||
1115 | mutex_lock(&demod_lock); | ||
1116 | reg = stv090x_read_reg(state, STV090x_STOPCLK2); | ||
1117 | STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable); | ||
1118 | if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) | ||
1119 | goto err; | ||
1120 | mutex_unlock(&demod_lock); | ||
1121 | break; | ||
1122 | |||
1123 | default: | ||
1124 | dprintk(FE_ERROR, 1, "Wrong demodulator!"); | ||
1125 | break; | ||
1126 | } | ||
1127 | return 0; | ||
1128 | err: | ||
1129 | mutex_unlock(&demod_lock); | ||
1130 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1131 | return -1; | ||
1132 | } | ||
1133 | |||
1134 | static int stv090x_dvbs_track_crl(struct stv090x_state *state) | ||
1135 | { | ||
1136 | if (state->dev_ver >= 0x30) { | ||
1137 | /* Set ACLC BCLC optimised value vs SR */ | ||
1138 | if (state->srate >= 15000000) { | ||
1139 | if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0) | ||
1140 | goto err; | ||
1141 | if (STV090x_WRITE_DEMOD(state, BCLC, 0x1a) < 0) | ||
1142 | goto err; | ||
1143 | } else if ((state->srate >= 7000000) && (15000000 > state->srate)) { | ||
1144 | if (STV090x_WRITE_DEMOD(state, ACLC, 0x0c) < 0) | ||
1145 | goto err; | ||
1146 | if (STV090x_WRITE_DEMOD(state, BCLC, 0x1b) < 0) | ||
1147 | goto err; | ||
1148 | } else if (state->srate < 7000000) { | ||
1149 | if (STV090x_WRITE_DEMOD(state, ACLC, 0x2c) < 0) | ||
1150 | goto err; | ||
1151 | if (STV090x_WRITE_DEMOD(state, BCLC, 0x1c) < 0) | ||
1152 | goto err; | ||
1153 | } | ||
1154 | |||
1155 | } else { | ||
1156 | /* Cut 2.0 */ | ||
1157 | if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) | ||
1158 | goto err; | ||
1159 | if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) | ||
1160 | goto err; | ||
1161 | } | ||
1162 | return 0; | ||
1163 | err: | ||
1164 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1165 | return -1; | ||
1166 | } | ||
1167 | |||
1168 | static int stv090x_delivery_search(struct stv090x_state *state) | ||
1169 | { | ||
1170 | u32 reg; | ||
1171 | |||
1172 | switch (state->search_mode) { | ||
1173 | case STV090x_SEARCH_DVBS1: | ||
1174 | case STV090x_SEARCH_DSS: | ||
1175 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
1176 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); | ||
1177 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); | ||
1178 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
1179 | goto err; | ||
1180 | |||
1181 | /* Activate Viterbi decoder in legacy search, | ||
1182 | * do not use FRESVIT1, might impact VITERBI2 | ||
1183 | */ | ||
1184 | if (stv090x_vitclk_ctl(state, 0) < 0) | ||
1185 | goto err; | ||
1186 | |||
1187 | if (stv090x_dvbs_track_crl(state) < 0) | ||
1188 | goto err; | ||
1189 | |||
1190 | if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x22) < 0) /* disable DVB-S2 */ | ||
1191 | goto err; | ||
1192 | |||
1193 | if (stv090x_set_vit_thacq(state) < 0) | ||
1194 | goto err; | ||
1195 | if (stv090x_set_viterbi(state) < 0) | ||
1196 | goto err; | ||
1197 | break; | ||
1198 | |||
1199 | case STV090x_SEARCH_DVBS2: | ||
1200 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
1201 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); | ||
1202 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); | ||
1203 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
1204 | goto err; | ||
1205 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); | ||
1206 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); | ||
1207 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
1208 | goto err; | ||
1209 | |||
1210 | if (stv090x_vitclk_ctl(state, 1) < 0) | ||
1211 | goto err; | ||
1212 | |||
1213 | if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) /* stop DVB-S CR loop */ | ||
1214 | goto err; | ||
1215 | if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) | ||
1216 | goto err; | ||
1217 | |||
1218 | if (state->dev_ver <= 0x20) { | ||
1219 | /* enable S2 carrier loop */ | ||
1220 | if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) | ||
1221 | goto err; | ||
1222 | } else { | ||
1223 | /* > Cut 3: Stop carrier 3 */ | ||
1224 | if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0) | ||
1225 | goto err; | ||
1226 | } | ||
1227 | |||
1228 | if (state->demod_mode != STV090x_SINGLE) { | ||
1229 | /* Cut 2: enable link during search */ | ||
1230 | if (stv090x_activate_modcod(state) < 0) | ||
1231 | goto err; | ||
1232 | } else { | ||
1233 | /* Single demodulator | ||
1234 | * Authorize SHORT and LONG frames, | ||
1235 | * QPSK, 8PSK, 16APSK and 32APSK | ||
1236 | */ | ||
1237 | if (stv090x_activate_modcod_single(state) < 0) | ||
1238 | goto err; | ||
1239 | } | ||
1240 | |||
1241 | break; | ||
1242 | |||
1243 | case STV090x_SEARCH_AUTO: | ||
1244 | default: | ||
1245 | /* enable DVB-S2 and DVB-S2 in Auto MODE */ | ||
1246 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
1247 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); | ||
1248 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); | ||
1249 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
1250 | goto err; | ||
1251 | |||
1252 | if (stv090x_vitclk_ctl(state, 0) < 0) | ||
1253 | goto err; | ||
1254 | |||
1255 | if (stv090x_dvbs_track_crl(state) < 0) | ||
1256 | goto err; | ||
1257 | |||
1258 | if (state->dev_ver <= 0x20) { | ||
1259 | /* enable S2 carrier loop */ | ||
1260 | if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) | ||
1261 | goto err; | ||
1262 | } else { | ||
1263 | /* > Cut 3: Stop carrier 3 */ | ||
1264 | if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0) | ||
1265 | goto err; | ||
1266 | } | ||
1267 | |||
1268 | if (state->demod_mode != STV090x_SINGLE) { | ||
1269 | /* Cut 2: enable link during search */ | ||
1270 | if (stv090x_activate_modcod(state) < 0) | ||
1271 | goto err; | ||
1272 | } else { | ||
1273 | /* Single demodulator | ||
1274 | * Authorize SHORT and LONG frames, | ||
1275 | * QPSK, 8PSK, 16APSK and 32APSK | ||
1276 | */ | ||
1277 | if (stv090x_activate_modcod_single(state) < 0) | ||
1278 | goto err; | ||
1279 | } | ||
1280 | |||
1281 | if (state->srate >= 2000000) { | ||
1282 | /* Srate >= 2MSPS, Viterbi threshold to acquire */ | ||
1283 | if (stv090x_set_vit_thacq(state) < 0) | ||
1284 | goto err; | ||
1285 | } else { | ||
1286 | /* Srate < 2MSPS, Reset Viterbi thresholdto track | ||
1287 | * and then re-acquire | ||
1288 | */ | ||
1289 | if (stv090x_set_vit_thtracq(state) < 0) | ||
1290 | goto err; | ||
1291 | } | ||
1292 | |||
1293 | if (stv090x_set_viterbi(state) < 0) | ||
1294 | goto err; | ||
1295 | break; | ||
1296 | } | ||
1297 | return 0; | ||
1298 | err: | ||
1299 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1300 | return -1; | ||
1301 | } | ||
1302 | |||
1303 | static int stv090x_start_search(struct stv090x_state *state) | ||
1304 | { | ||
1305 | u32 reg, freq_abs; | ||
1306 | s16 freq; | ||
1307 | |||
1308 | /* Reset demodulator */ | ||
1309 | reg = STV090x_READ_DEMOD(state, DMDISTATE); | ||
1310 | STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); | ||
1311 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) | ||
1312 | goto err; | ||
1313 | |||
1314 | if (state->dev_ver <= 0x20) { | ||
1315 | if (state->srate <= 5000000) { | ||
1316 | if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0) | ||
1317 | goto err; | ||
1318 | if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0) | ||
1319 | goto err; | ||
1320 | if (STV090x_WRITE_DEMOD(state, CFRUP1, 0xff) < 0) | ||
1321 | goto err; | ||
1322 | if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0) | ||
1323 | goto err; | ||
1324 | if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0) | ||
1325 | goto err; | ||
1326 | |||
1327 | /*enlarge the timing bandwith for Low SR*/ | ||
1328 | if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) | ||
1329 | goto err; | ||
1330 | } else { | ||
1331 | /* If the symbol rate is >5 Msps | ||
1332 | Set The carrier search up and low to auto mode */ | ||
1333 | if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) | ||
1334 | goto err; | ||
1335 | /*reduce the timing bandwith for high SR*/ | ||
1336 | if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) | ||
1337 | goto err; | ||
1338 | } | ||
1339 | } else { | ||
1340 | /* >= Cut 3 */ | ||
1341 | if (state->srate <= 5000000) { | ||
1342 | /* enlarge the timing bandwith for Low SR */ | ||
1343 | STV090x_WRITE_DEMOD(state, RTCS2, 0x68); | ||
1344 | } else { | ||
1345 | /* reduce timing bandwith for high SR */ | ||
1346 | STV090x_WRITE_DEMOD(state, RTCS2, 0x44); | ||
1347 | } | ||
1348 | |||
1349 | /* Set CFR min and max to manual mode */ | ||
1350 | STV090x_WRITE_DEMOD(state, CARCFG, 0x46); | ||
1351 | |||
1352 | if (state->algo == STV090x_WARM_SEARCH) { | ||
1353 | /* WARM Start | ||
1354 | * CFR min = -1MHz, | ||
1355 | * CFR max = +1MHz | ||
1356 | */ | ||
1357 | freq_abs = 1000 << 16; | ||
1358 | freq_abs /= (state->mclk / 1000); | ||
1359 | freq = (s16) freq_abs; | ||
1360 | } else { | ||
1361 | /* COLD Start | ||
1362 | * CFR min =- (SearchRange / 2 + 600KHz) | ||
1363 | * CFR max = +(SearchRange / 2 + 600KHz) | ||
1364 | * (600KHz for the tuner step size) | ||
1365 | */ | ||
1366 | freq_abs = (state->search_range / 2000) + 600; | ||
1367 | freq_abs = freq_abs << 16; | ||
1368 | freq_abs /= (state->mclk / 1000); | ||
1369 | freq = (s16) freq_abs; | ||
1370 | } | ||
1371 | |||
1372 | if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0) | ||
1373 | goto err; | ||
1374 | if (STV090x_WRITE_DEMOD(state, CFRUP1, LSB(freq)) < 0) | ||
1375 | goto err; | ||
1376 | |||
1377 | freq *= -1; | ||
1378 | |||
1379 | if (STV090x_WRITE_DEMOD(state, CFRLOW1, MSB(freq)) < 0) | ||
1380 | goto err; | ||
1381 | if (STV090x_WRITE_DEMOD(state, CFRLOW0, LSB(freq)) < 0) | ||
1382 | goto err; | ||
1383 | |||
1384 | } | ||
1385 | |||
1386 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0) < 0) | ||
1387 | goto err; | ||
1388 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0) | ||
1389 | goto err; | ||
1390 | |||
1391 | if (state->dev_ver >= 0x20) { | ||
1392 | if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) | ||
1393 | goto err; | ||
1394 | if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) | ||
1395 | goto err; | ||
1396 | |||
1397 | if ((state->search_mode == STV090x_DVBS1) || | ||
1398 | (state->search_mode == STV090x_DSS) || | ||
1399 | (state->search_mode == STV090x_SEARCH_AUTO)) { | ||
1400 | |||
1401 | if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0) | ||
1402 | goto err; | ||
1403 | if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) | ||
1404 | goto err; | ||
1405 | } | ||
1406 | } | ||
1407 | |||
1408 | if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00) < 0) | ||
1409 | goto err; | ||
1410 | if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xe0) < 0) | ||
1411 | goto err; | ||
1412 | if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xc0) < 0) | ||
1413 | goto err; | ||
1414 | |||
1415 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
1416 | STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0); | ||
1417 | STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0); | ||
1418 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
1419 | goto err; | ||
1420 | reg = STV090x_READ_DEMOD(state, DMDCFG2); | ||
1421 | STV090x_SETFIELD_Px(reg, S1S2_SEQUENTIAL_FIELD, 0x0); | ||
1422 | if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0) | ||
1423 | goto err; | ||
1424 | |||
1425 | if (state->dev_ver >= 0x20) { | ||
1426 | /*Frequency offset detector setting*/ | ||
1427 | if (state->srate < 2000000) { | ||
1428 | if (state->dev_ver <= 0x20) { | ||
1429 | /* Cut 2 */ | ||
1430 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0) | ||
1431 | goto err; | ||
1432 | } else { | ||
1433 | /* Cut 2 */ | ||
1434 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0) | ||
1435 | goto err; | ||
1436 | } | ||
1437 | if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0) | ||
1438 | goto err; | ||
1439 | } | ||
1440 | |||
1441 | if (state->srate < 10000000) { | ||
1442 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0) | ||
1443 | goto err; | ||
1444 | } else { | ||
1445 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0) | ||
1446 | goto err; | ||
1447 | } | ||
1448 | } else { | ||
1449 | if (state->srate < 10000000) { | ||
1450 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0) | ||
1451 | goto err; | ||
1452 | } else { | ||
1453 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0) | ||
1454 | goto err; | ||
1455 | } | ||
1456 | } | ||
1457 | |||
1458 | switch (state->algo) { | ||
1459 | case STV090x_WARM_SEARCH: | ||
1460 | /* The symbol rate and the exact | ||
1461 | * carrier Frequency are known | ||
1462 | */ | ||
1463 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) | ||
1464 | goto err; | ||
1465 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) | ||
1466 | goto err; | ||
1467 | break; | ||
1468 | |||
1469 | case STV090x_COLD_SEARCH: | ||
1470 | /* The symbol rate is known */ | ||
1471 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) | ||
1472 | goto err; | ||
1473 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) | ||
1474 | goto err; | ||
1475 | break; | ||
1476 | |||
1477 | default: | ||
1478 | break; | ||
1479 | } | ||
1480 | return 0; | ||
1481 | err: | ||
1482 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1483 | return -1; | ||
1484 | } | ||
1485 | |||
1486 | static int stv090x_get_agc2_min_level(struct stv090x_state *state) | ||
1487 | { | ||
1488 | u32 agc2_min = 0, agc2 = 0, freq_init, freq_step, reg; | ||
1489 | s32 i, j, steps, dir; | ||
1490 | |||
1491 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) | ||
1492 | goto err; | ||
1493 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
1494 | STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1); | ||
1495 | STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1); | ||
1496 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
1497 | goto err; | ||
1498 | |||
1499 | if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) /* SR = 65 Msps Max */ | ||
1500 | goto err; | ||
1501 | if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0) | ||
1502 | goto err; | ||
1503 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) /* SR= 400 ksps Min */ | ||
1504 | goto err; | ||
1505 | if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0) | ||
1506 | goto err; | ||
1507 | if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) /* stop acq @ coarse carrier state */ | ||
1508 | goto err; | ||
1509 | if (stv090x_set_srate(state, 1000000) < 0) | ||
1510 | goto err; | ||
1511 | |||
1512 | steps = -1 + state->search_range / 1000000; | ||
1513 | steps /= 2; | ||
1514 | steps = (2 * steps) + 1; | ||
1515 | if (steps < 0) | ||
1516 | steps = 1; | ||
1517 | |||
1518 | dir = 1; | ||
1519 | freq_step = (1000000 * 256) / (state->mclk / 256); | ||
1520 | freq_init = 0; | ||
1521 | |||
1522 | for (i = 0; i < steps; i++) { | ||
1523 | if (dir > 0) | ||
1524 | freq_init = freq_init + (freq_step * i); | ||
1525 | else | ||
1526 | freq_init = freq_init - (freq_step * i); | ||
1527 | |||
1528 | dir = -1; | ||
1529 | |||
1530 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */ | ||
1531 | goto err; | ||
1532 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_init >> 8) & 0xff) < 0) | ||
1533 | goto err; | ||
1534 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_init & 0xff) < 0) | ||
1535 | goto err; | ||
1536 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */ | ||
1537 | goto err; | ||
1538 | msleep(10); | ||
1539 | for (j = 0; j < 10; j++) { | ||
1540 | agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8; | ||
1541 | agc2 |= STV090x_READ_DEMOD(state, AGC2I0); | ||
1542 | } | ||
1543 | agc2 /= 10; | ||
1544 | agc2_min = 0xffff; | ||
1545 | if (agc2 < 0xffff) | ||
1546 | agc2_min = agc2; | ||
1547 | } | ||
1548 | |||
1549 | return agc2_min; | ||
1550 | err: | ||
1551 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1552 | return -1; | ||
1553 | } | ||
1554 | |||
1555 | static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk) | ||
1556 | { | ||
1557 | u8 r3, r2, r1, r0; | ||
1558 | s32 srate, int_1, int_2, tmp_1, tmp_2; | ||
1559 | |||
1560 | r3 = STV090x_READ_DEMOD(state, SFR3); | ||
1561 | r2 = STV090x_READ_DEMOD(state, SFR2); | ||
1562 | r1 = STV090x_READ_DEMOD(state, SFR1); | ||
1563 | r0 = STV090x_READ_DEMOD(state, SFR0); | ||
1564 | |||
1565 | srate = ((r3 << 24) | (r2 << 16) | (r1 << 8) | r0); | ||
1566 | |||
1567 | int_1 = clk >> 16; | ||
1568 | int_2 = srate >> 16; | ||
1569 | |||
1570 | tmp_1 = clk % 0x10000; | ||
1571 | tmp_2 = srate % 0x10000; | ||
1572 | |||
1573 | srate = (int_1 * int_2) + | ||
1574 | ((int_1 * tmp_2) >> 16) + | ||
1575 | ((int_2 * tmp_1) >> 16); | ||
1576 | |||
1577 | return srate; | ||
1578 | } | ||
1579 | |||
1580 | static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) | ||
1581 | { | ||
1582 | struct dvb_frontend *fe = &state->frontend; | ||
1583 | |||
1584 | int tmg_lock = 0, i; | ||
1585 | s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq; | ||
1586 | u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg; | ||
1587 | |||
1588 | reg = STV090x_READ_DEMOD(state, DMDISTATE); | ||
1589 | STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */ | ||
1590 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) | ||
1591 | goto err; | ||
1592 | if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0) | ||
1593 | goto err; | ||
1594 | if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0) | ||
1595 | goto err; | ||
1596 | if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0) | ||
1597 | goto err; | ||
1598 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
1599 | STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1); | ||
1600 | STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1); | ||
1601 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
1602 | goto err; | ||
1603 | |||
1604 | if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) | ||
1605 | goto err; | ||
1606 | if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0) | ||
1607 | goto err; | ||
1608 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) | ||
1609 | goto err; | ||
1610 | if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0) | ||
1611 | goto err; | ||
1612 | if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) | ||
1613 | goto err; | ||
1614 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0) | ||
1615 | goto err; | ||
1616 | |||
1617 | if (state->dev_ver >= 0x30) { | ||
1618 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0) | ||
1619 | goto err; | ||
1620 | if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) | ||
1621 | goto err; | ||
1622 | |||
1623 | } else if (state->dev_ver >= 0x20) { | ||
1624 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0) | ||
1625 | goto err; | ||
1626 | if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) | ||
1627 | goto err; | ||
1628 | } | ||
1629 | |||
1630 | if (state->srate <= 2000000) | ||
1631 | car_step = 1000; | ||
1632 | else if (state->srate <= 5000000) | ||
1633 | car_step = 2000; | ||
1634 | else if (state->srate <= 12000000) | ||
1635 | car_step = 3000; | ||
1636 | else | ||
1637 | car_step = 5000; | ||
1638 | |||
1639 | steps = -1 + ((state->search_range / 1000) / car_step); | ||
1640 | steps /= 2; | ||
1641 | steps = (2 * steps) + 1; | ||
1642 | if (steps < 0) | ||
1643 | steps = 1; | ||
1644 | else if (steps > 10) { | ||
1645 | steps = 11; | ||
1646 | car_step = (state->search_range / 1000) / 10; | ||
1647 | } | ||
1648 | cur_step = 0; | ||
1649 | dir = 1; | ||
1650 | freq = state->frequency; | ||
1651 | |||
1652 | while ((!tmg_lock) && (cur_step < steps)) { | ||
1653 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */ | ||
1654 | goto err; | ||
1655 | reg = STV090x_READ_DEMOD(state, DMDISTATE); | ||
1656 | STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x00); /* trigger acquisition */ | ||
1657 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) | ||
1658 | goto err; | ||
1659 | msleep(50); | ||
1660 | for (i = 0; i < 10; i++) { | ||
1661 | reg = STV090x_READ_DEMOD(state, DSTATUS); | ||
1662 | if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2) | ||
1663 | tmg_cpt++; | ||
1664 | agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8; | ||
1665 | agc2 |= STV090x_READ_DEMOD(state, AGC2I0); | ||
1666 | } | ||
1667 | agc2 /= 10; | ||
1668 | srate_coarse = stv090x_get_srate(state, state->mclk); | ||
1669 | cur_step++; | ||
1670 | dir *= -1; | ||
1671 | if ((tmg_cpt >= 5) && (agc2 < 0x1f00) && (srate_coarse < 55000000) && (srate_coarse > 850000)) | ||
1672 | tmg_lock = 1; | ||
1673 | else if (cur_step < steps) { | ||
1674 | if (dir > 0) | ||
1675 | freq += cur_step * car_step; | ||
1676 | else | ||
1677 | freq -= cur_step * car_step; | ||
1678 | |||
1679 | /* Setup tuner */ | ||
1680 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
1681 | goto err; | ||
1682 | |||
1683 | if (state->config->tuner_set_frequency) { | ||
1684 | if (state->config->tuner_set_frequency(fe, state->frequency) < 0) | ||
1685 | goto err; | ||
1686 | } | ||
1687 | |||
1688 | if (state->config->tuner_set_bandwidth) { | ||
1689 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) | ||
1690 | goto err; | ||
1691 | } | ||
1692 | |||
1693 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
1694 | goto err; | ||
1695 | |||
1696 | msleep(50); | ||
1697 | |||
1698 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
1699 | goto err; | ||
1700 | |||
1701 | if (state->config->tuner_get_status) { | ||
1702 | if (state->config->tuner_get_status(fe, ®) < 0) | ||
1703 | goto err; | ||
1704 | } | ||
1705 | |||
1706 | if (reg) | ||
1707 | dprintk(FE_DEBUG, 1, "Tuner phase locked"); | ||
1708 | else | ||
1709 | dprintk(FE_DEBUG, 1, "Tuner unlocked"); | ||
1710 | |||
1711 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
1712 | goto err; | ||
1713 | |||
1714 | } | ||
1715 | } | ||
1716 | if (!tmg_lock) | ||
1717 | srate_coarse = 0; | ||
1718 | else | ||
1719 | srate_coarse = stv090x_get_srate(state, state->mclk); | ||
1720 | |||
1721 | return srate_coarse; | ||
1722 | err: | ||
1723 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1724 | return -1; | ||
1725 | } | ||
1726 | |||
1727 | static u32 stv090x_srate_srch_fine(struct stv090x_state *state) | ||
1728 | { | ||
1729 | u32 srate_coarse, freq_coarse, sym, reg; | ||
1730 | |||
1731 | srate_coarse = stv090x_get_srate(state, state->mclk); | ||
1732 | freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8; | ||
1733 | freq_coarse |= STV090x_READ_DEMOD(state, CFR1); | ||
1734 | sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ | ||
1735 | |||
1736 | if (sym < state->srate) | ||
1737 | srate_coarse = 0; | ||
1738 | else { | ||
1739 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */ | ||
1740 | goto err; | ||
1741 | if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0) | ||
1742 | goto err; | ||
1743 | if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0) | ||
1744 | goto err; | ||
1745 | if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0) | ||
1746 | goto err; | ||
1747 | if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0) | ||
1748 | goto err; | ||
1749 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
1750 | STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); | ||
1751 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
1752 | goto err; | ||
1753 | |||
1754 | if (state->dev_ver >= 0x30) { | ||
1755 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0) | ||
1756 | goto err; | ||
1757 | } else if (state->dev_ver >= 0x20) { | ||
1758 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) | ||
1759 | goto err; | ||
1760 | } | ||
1761 | |||
1762 | if (srate_coarse > 3000000) { | ||
1763 | sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ | ||
1764 | sym = (sym / 1000) * 65536; | ||
1765 | sym /= (state->mclk / 1000); | ||
1766 | if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) | ||
1767 | goto err; | ||
1768 | if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) | ||
1769 | goto err; | ||
1770 | sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */ | ||
1771 | sym = (sym / 1000) * 65536; | ||
1772 | sym /= (state->mclk / 1000); | ||
1773 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) | ||
1774 | goto err; | ||
1775 | if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) | ||
1776 | goto err; | ||
1777 | sym = (srate_coarse / 1000) * 65536; | ||
1778 | sym /= (state->mclk / 1000); | ||
1779 | if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) | ||
1780 | goto err; | ||
1781 | if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) | ||
1782 | goto err; | ||
1783 | } else { | ||
1784 | sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ | ||
1785 | sym = (sym / 100) * 65536; | ||
1786 | sym /= (state->mclk / 100); | ||
1787 | if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) | ||
1788 | goto err; | ||
1789 | if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) | ||
1790 | goto err; | ||
1791 | sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */ | ||
1792 | sym = (sym / 100) * 65536; | ||
1793 | sym /= (state->mclk / 100); | ||
1794 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) | ||
1795 | goto err; | ||
1796 | if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) | ||
1797 | goto err; | ||
1798 | sym = (srate_coarse / 100) * 65536; | ||
1799 | sym /= (state->mclk / 100); | ||
1800 | if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) | ||
1801 | goto err; | ||
1802 | if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) | ||
1803 | goto err; | ||
1804 | } | ||
1805 | if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0) | ||
1806 | goto err; | ||
1807 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_coarse >> 8) & 0xff) < 0) | ||
1808 | goto err; | ||
1809 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_coarse & 0xff) < 0) | ||
1810 | goto err; | ||
1811 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) /* trigger acquisition */ | ||
1812 | goto err; | ||
1813 | } | ||
1814 | |||
1815 | return srate_coarse; | ||
1816 | |||
1817 | err: | ||
1818 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1819 | return -1; | ||
1820 | } | ||
1821 | |||
1822 | static int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout) | ||
1823 | { | ||
1824 | s32 timer = 0, lock = 0; | ||
1825 | u32 reg; | ||
1826 | u8 stat; | ||
1827 | |||
1828 | while ((timer < timeout) && (!lock)) { | ||
1829 | reg = STV090x_READ_DEMOD(state, DMDSTATE); | ||
1830 | stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); | ||
1831 | |||
1832 | switch (stat) { | ||
1833 | case 0: /* searching */ | ||
1834 | case 1: /* first PLH detected */ | ||
1835 | default: | ||
1836 | dprintk(FE_DEBUG, 1, "Demodulator searching .."); | ||
1837 | lock = 0; | ||
1838 | break; | ||
1839 | case 2: /* DVB-S2 mode */ | ||
1840 | case 3: /* DVB-S1/legacy mode */ | ||
1841 | reg = STV090x_READ_DEMOD(state, DSTATUS); | ||
1842 | lock = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD); | ||
1843 | break; | ||
1844 | } | ||
1845 | |||
1846 | if (!lock) | ||
1847 | msleep(10); | ||
1848 | else | ||
1849 | dprintk(FE_DEBUG, 1, "Demodulator acquired LOCK"); | ||
1850 | |||
1851 | timer += 10; | ||
1852 | } | ||
1853 | return lock; | ||
1854 | } | ||
1855 | |||
1856 | static int stv090x_blind_search(struct stv090x_state *state) | ||
1857 | { | ||
1858 | u32 agc2, reg, srate_coarse; | ||
1859 | s32 timeout_dmd = 500, cpt_fail, agc2_ovflw, i; | ||
1860 | u8 k_ref, k_max, k_min; | ||
1861 | int coarse_fail, lock; | ||
1862 | |||
1863 | k_max = 120; | ||
1864 | k_min = 30; | ||
1865 | |||
1866 | agc2 = stv090x_get_agc2_min_level(state); | ||
1867 | |||
1868 | if (agc2 > STV090x_SEARCH_AGC2_TH(state->dev_ver)) { | ||
1869 | lock = 0; | ||
1870 | } else { | ||
1871 | |||
1872 | if (state->dev_ver <= 0x20) { | ||
1873 | if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) | ||
1874 | goto err; | ||
1875 | } else { | ||
1876 | /* > Cut 3 */ | ||
1877 | if (STV090x_WRITE_DEMOD(state, CARCFG, 0x06) < 0) | ||
1878 | goto err; | ||
1879 | } | ||
1880 | |||
1881 | if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) | ||
1882 | goto err; | ||
1883 | |||
1884 | if (state->dev_ver >= 0x20) { | ||
1885 | if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) | ||
1886 | goto err; | ||
1887 | if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) | ||
1888 | goto err; | ||
1889 | if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0) | ||
1890 | goto err; | ||
1891 | if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) /* set viterbi hysteresis */ | ||
1892 | goto err; | ||
1893 | } | ||
1894 | |||
1895 | k_ref = k_max; | ||
1896 | do { | ||
1897 | if (STV090x_WRITE_DEMOD(state, KREFTMG, k_ref) < 0) | ||
1898 | goto err; | ||
1899 | if (stv090x_srate_srch_coarse(state) != 0) { | ||
1900 | srate_coarse = stv090x_srate_srch_fine(state); | ||
1901 | if (srate_coarse != 0) { | ||
1902 | stv090x_get_lock_tmg(state); | ||
1903 | lock = stv090x_get_dmdlock(state, timeout_dmd); | ||
1904 | } else { | ||
1905 | lock = 0; | ||
1906 | } | ||
1907 | } else { | ||
1908 | cpt_fail = 0; | ||
1909 | agc2_ovflw = 0; | ||
1910 | for (i = 0; i < 10; i++) { | ||
1911 | agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8; | ||
1912 | agc2 |= STV090x_READ_DEMOD(state, AGC2I0); | ||
1913 | if (agc2 >= 0xff00) | ||
1914 | agc2_ovflw++; | ||
1915 | reg = STV090x_READ_DEMOD(state, DSTATUS2); | ||
1916 | if ((STV090x_GETFIELD_Px(reg, CFR_OVERFLOW_FIELD) == 0x01) && | ||
1917 | (STV090x_GETFIELD_Px(reg, DEMOD_DELOCK_FIELD) == 0x01)) | ||
1918 | |||
1919 | cpt_fail++; | ||
1920 | } | ||
1921 | if ((cpt_fail > 7) || (agc2_ovflw > 7)) | ||
1922 | coarse_fail = 1; | ||
1923 | |||
1924 | lock = 0; | ||
1925 | } | ||
1926 | k_ref -= 30; | ||
1927 | } while ((k_ref >= k_min) && (!lock) && (!coarse_fail)); | ||
1928 | } | ||
1929 | |||
1930 | return lock; | ||
1931 | |||
1932 | err: | ||
1933 | dprintk(FE_ERROR, 1, "I/O error"); | ||
1934 | return -1; | ||
1935 | } | ||
1936 | |||
1937 | static int stv090x_chk_tmg(struct stv090x_state *state) | ||
1938 | { | ||
1939 | u32 reg; | ||
1940 | s32 tmg_cpt = 0, i; | ||
1941 | u8 freq, tmg_thh, tmg_thl; | ||
1942 | int tmg_lock; | ||
1943 | |||
1944 | freq = STV090x_READ_DEMOD(state, CARFREQ); | ||
1945 | tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE); | ||
1946 | tmg_thl = STV090x_READ_DEMOD(state, TMGTHFALL); | ||
1947 | if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0) | ||
1948 | goto err; | ||
1949 | if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0) | ||
1950 | goto err; | ||
1951 | |||
1952 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
1953 | STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); /* stop carrier offset search */ | ||
1954 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
1955 | goto err; | ||
1956 | if (STV090x_WRITE_DEMOD(state, RTC, 0x80) < 0) | ||
1957 | goto err; | ||
1958 | |||
1959 | if (STV090x_WRITE_DEMOD(state, RTCS2, 0x40) < 0) | ||
1960 | goto err; | ||
1961 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x00) < 0) | ||
1962 | goto err; | ||
1963 | |||
1964 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) /* set car ofset to 0 */ | ||
1965 | goto err; | ||
1966 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) | ||
1967 | goto err; | ||
1968 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x65) < 0) | ||
1969 | goto err; | ||
1970 | |||
1971 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* trigger acquisition */ | ||
1972 | goto err; | ||
1973 | msleep(10); | ||
1974 | |||
1975 | for (i = 0; i < 10; i++) { | ||
1976 | reg = STV090x_READ_DEMOD(state, DSTATUS); | ||
1977 | if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2) | ||
1978 | tmg_cpt++; | ||
1979 | msleep(1); | ||
1980 | } | ||
1981 | if (tmg_cpt >= 3) | ||
1982 | tmg_lock = 1; | ||
1983 | |||
1984 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) | ||
1985 | goto err; | ||
1986 | if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) /* DVB-S1 timing */ | ||
1987 | goto err; | ||
1988 | if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) /* DVB-S2 timing */ | ||
1989 | goto err; | ||
1990 | |||
1991 | if (STV090x_WRITE_DEMOD(state, CARFREQ, freq) < 0) | ||
1992 | goto err; | ||
1993 | if (STV090x_WRITE_DEMOD(state, TMGTHRISE, tmg_thh) < 0) | ||
1994 | goto err; | ||
1995 | if (STV090x_WRITE_DEMOD(state, TMGTHFALL, tmg_thl) < 0) | ||
1996 | goto err; | ||
1997 | |||
1998 | return tmg_lock; | ||
1999 | |||
2000 | err: | ||
2001 | dprintk(FE_ERROR, 1, "I/O error"); | ||
2002 | return -1; | ||
2003 | } | ||
2004 | |||
2005 | static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) | ||
2006 | { | ||
2007 | struct dvb_frontend *fe = &state->frontend; | ||
2008 | |||
2009 | u32 reg; | ||
2010 | s32 car_step, steps, cur_step, dir, freq, timeout_lock; | ||
2011 | int lock = 0; | ||
2012 | |||
2013 | if (state->srate >= 10000000) | ||
2014 | timeout_lock = timeout_dmd / 3; | ||
2015 | else | ||
2016 | timeout_lock = timeout_dmd / 2; | ||
2017 | |||
2018 | lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */ | ||
2019 | if (!lock) { | ||
2020 | if (state->srate >= 10000000) { | ||
2021 | if (stv090x_chk_tmg(state)) { | ||
2022 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) | ||
2023 | goto err; | ||
2024 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) | ||
2025 | goto err; | ||
2026 | lock = stv090x_get_dmdlock(state, timeout_dmd); | ||
2027 | } else { | ||
2028 | lock = 0; | ||
2029 | } | ||
2030 | } else { | ||
2031 | if (state->srate <= 4000000) | ||
2032 | car_step = 1000; | ||
2033 | else if (state->srate <= 7000000) | ||
2034 | car_step = 2000; | ||
2035 | else if (state->srate <= 10000000) | ||
2036 | car_step = 3000; | ||
2037 | else | ||
2038 | car_step = 5000; | ||
2039 | |||
2040 | steps = (state->search_range / 1000) / car_step; | ||
2041 | steps /= 2; | ||
2042 | steps = 2 * (steps + 1); | ||
2043 | if (steps < 0) | ||
2044 | steps = 2; | ||
2045 | else if (steps > 12) | ||
2046 | steps = 12; | ||
2047 | |||
2048 | cur_step = 1; | ||
2049 | dir = 1; | ||
2050 | |||
2051 | if (!lock) { | ||
2052 | freq = state->frequency; | ||
2053 | state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate; | ||
2054 | while ((cur_step <= steps) && (!lock)) { | ||
2055 | if (dir > 0) | ||
2056 | freq += cur_step * car_step; | ||
2057 | else | ||
2058 | freq -= cur_step * car_step; | ||
2059 | |||
2060 | /* Setup tuner */ | ||
2061 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
2062 | goto err; | ||
2063 | |||
2064 | if (state->config->tuner_set_frequency) { | ||
2065 | if (state->config->tuner_set_frequency(fe, state->frequency) < 0) | ||
2066 | goto err; | ||
2067 | } | ||
2068 | |||
2069 | if (state->config->tuner_set_bandwidth) { | ||
2070 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) | ||
2071 | goto err; | ||
2072 | } | ||
2073 | |||
2074 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
2075 | goto err; | ||
2076 | |||
2077 | msleep(50); | ||
2078 | |||
2079 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
2080 | goto err; | ||
2081 | |||
2082 | if (state->config->tuner_get_status) { | ||
2083 | if (state->config->tuner_get_status(fe, ®) < 0) | ||
2084 | goto err; | ||
2085 | } | ||
2086 | |||
2087 | if (reg) | ||
2088 | dprintk(FE_DEBUG, 1, "Tuner phase locked"); | ||
2089 | else | ||
2090 | dprintk(FE_DEBUG, 1, "Tuner unlocked"); | ||
2091 | |||
2092 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
2093 | goto err; | ||
2094 | |||
2095 | STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); | ||
2096 | if (state->delsys == STV090x_DVBS2) { | ||
2097 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
2098 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); | ||
2099 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); | ||
2100 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
2101 | goto err; | ||
2102 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); | ||
2103 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); | ||
2104 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
2105 | goto err; | ||
2106 | } | ||
2107 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) | ||
2108 | goto err; | ||
2109 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) | ||
2110 | goto err; | ||
2111 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) | ||
2112 | goto err; | ||
2113 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) | ||
2114 | goto err; | ||
2115 | lock = stv090x_get_dmdlock(state, (timeout_dmd / 3)); | ||
2116 | |||
2117 | dir *= -1; | ||
2118 | cur_step++; | ||
2119 | } | ||
2120 | } | ||
2121 | } | ||
2122 | } | ||
2123 | |||
2124 | return lock; | ||
2125 | |||
2126 | err: | ||
2127 | dprintk(FE_ERROR, 1, "I/O error"); | ||
2128 | return -1; | ||
2129 | } | ||
2130 | |||
2131 | static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s32 *timeout_sw, s32 *steps) | ||
2132 | { | ||
2133 | s32 timeout, inc, steps_max, srate, car_max; | ||
2134 | |||
2135 | srate = state->srate; | ||
2136 | car_max = state->search_range / 1000; | ||
2137 | car_max += car_max / 10; | ||
2138 | car_max = 65536 * (car_max / 2); | ||
2139 | car_max /= (state->mclk / 1000); | ||
2140 | |||
2141 | if (car_max > 0x4000) | ||
2142 | car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */ | ||
2143 | |||
2144 | inc = srate; | ||
2145 | inc /= state->mclk / 1000; | ||
2146 | inc *= 256; | ||
2147 | inc *= 256; | ||
2148 | inc /= 1000; | ||
2149 | |||
2150 | switch (state->search_mode) { | ||
2151 | case STV090x_SEARCH_DVBS1: | ||
2152 | case STV090x_SEARCH_DSS: | ||
2153 | inc *= 3; /* freq step = 3% of srate */ | ||
2154 | timeout = 20; | ||
2155 | break; | ||
2156 | |||
2157 | case STV090x_SEARCH_DVBS2: | ||
2158 | inc *= 4; | ||
2159 | timeout = 25; | ||
2160 | break; | ||
2161 | |||
2162 | case STV090x_SEARCH_AUTO: | ||
2163 | default: | ||
2164 | inc *= 3; | ||
2165 | timeout = 25; | ||
2166 | break; | ||
2167 | } | ||
2168 | inc /= 100; | ||
2169 | if ((inc > car_max) || (inc < 0)) | ||
2170 | inc = car_max / 2; /* increment <= 1/8 Mclk */ | ||
2171 | |||
2172 | timeout *= 27500; /* 27.5 Msps reference */ | ||
2173 | if (srate > 0) | ||
2174 | timeout /= (srate / 1000); | ||
2175 | |||
2176 | if ((timeout > 100) || (timeout < 0)) | ||
2177 | timeout = 100; | ||
2178 | |||
2179 | steps_max = (car_max / inc) + 1; /* min steps = 3 */ | ||
2180 | if ((steps_max > 100) || (steps_max < 0)) { | ||
2181 | steps_max = 100; /* max steps <= 100 */ | ||
2182 | inc = car_max / steps_max; | ||
2183 | } | ||
2184 | *freq_inc = inc; | ||
2185 | *timeout_sw = timeout; | ||
2186 | *steps = steps_max; | ||
2187 | |||
2188 | return 0; | ||
2189 | } | ||
2190 | |||
2191 | static int stv090x_chk_signal(struct stv090x_state *state) | ||
2192 | { | ||
2193 | s32 offst_car, agc2, car_max; | ||
2194 | int no_signal; | ||
2195 | |||
2196 | offst_car = STV090x_READ_DEMOD(state, CFR2) << 8; | ||
2197 | offst_car |= STV090x_READ_DEMOD(state, CFR1); | ||
2198 | offst_car = comp2(offst_car, 16); | ||
2199 | |||
2200 | agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8; | ||
2201 | agc2 |= STV090x_READ_DEMOD(state, AGC2I0); | ||
2202 | car_max = state->search_range / 1000; | ||
2203 | |||
2204 | car_max += (car_max / 10); /* 10% margin */ | ||
2205 | car_max = (65536 * car_max / 2); | ||
2206 | car_max /= state->mclk / 1000; | ||
2207 | |||
2208 | if (car_max > 0x4000) | ||
2209 | car_max = 0x4000; | ||
2210 | |||
2211 | if ((agc2 > 0x2000) || (offst_car > 2 * car_max) || (offst_car < -2 * car_max)) { | ||
2212 | no_signal = 1; | ||
2213 | dprintk(FE_DEBUG, 1, "No Signal"); | ||
2214 | } else { | ||
2215 | no_signal = 0; | ||
2216 | dprintk(FE_DEBUG, 1, "Found Signal"); | ||
2217 | } | ||
2218 | |||
2219 | return no_signal; | ||
2220 | } | ||
2221 | |||
2222 | static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 timeout, int zigzag, s32 steps_max) | ||
2223 | { | ||
2224 | int no_signal, lock = 0; | ||
2225 | s32 cpt_step = 0, offst_freq, car_max; | ||
2226 | u32 reg; | ||
2227 | |||
2228 | car_max = state->search_range / 1000; | ||
2229 | car_max += (car_max / 10); | ||
2230 | car_max = (65536 * car_max / 2); | ||
2231 | car_max /= (state->mclk / 1000); | ||
2232 | if (car_max > 0x4000) | ||
2233 | car_max = 0x4000; | ||
2234 | |||
2235 | if (zigzag) | ||
2236 | offst_freq = 0; | ||
2237 | else | ||
2238 | offst_freq = -car_max + inc; | ||
2239 | |||
2240 | do { | ||
2241 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0) | ||
2242 | goto err; | ||
2243 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, ((offst_freq / 256) & 0xff)) < 0) | ||
2244 | goto err; | ||
2245 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, offst_freq & 0xff) < 0) | ||
2246 | goto err; | ||
2247 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) | ||
2248 | goto err; | ||
2249 | |||
2250 | reg = STV090x_READ_DEMOD(state, PDELCTRL1); | ||
2251 | STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x1); /* stop DVB-S2 packet delin */ | ||
2252 | if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) | ||
2253 | goto err; | ||
2254 | |||
2255 | if (zigzag) { | ||
2256 | if (offst_freq >= 0) | ||
2257 | offst_freq = -offst_freq - 2 * inc; | ||
2258 | else | ||
2259 | offst_freq = -offst_freq; | ||
2260 | } else { | ||
2261 | offst_freq += 2 * inc; | ||
2262 | } | ||
2263 | |||
2264 | cpt_step++; | ||
2265 | |||
2266 | lock = stv090x_get_dmdlock(state, timeout); | ||
2267 | no_signal = stv090x_chk_signal(state); | ||
2268 | |||
2269 | } while ((!lock) && | ||
2270 | (!no_signal) && | ||
2271 | ((offst_freq - inc) < car_max) && | ||
2272 | ((offst_freq + inc) > -car_max) && | ||
2273 | (cpt_step < steps_max)); | ||
2274 | |||
2275 | reg = STV090x_READ_DEMOD(state, PDELCTRL1); | ||
2276 | STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0); | ||
2277 | if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) | ||
2278 | goto err; | ||
2279 | |||
2280 | return lock; | ||
2281 | err: | ||
2282 | dprintk(FE_ERROR, 1, "I/O error"); | ||
2283 | return -1; | ||
2284 | } | ||
2285 | |||
2286 | static int stv090x_sw_algo(struct stv090x_state *state) | ||
2287 | { | ||
2288 | int no_signal, zigzag, lock = 0; | ||
2289 | u32 reg; | ||
2290 | |||
2291 | s32 dvbs2_fly_wheel; | ||
2292 | s32 inc, timeout_step, trials, steps_max; | ||
2293 | |||
2294 | /* get params */ | ||
2295 | stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max); | ||
2296 | |||
2297 | switch (state->search_mode) { | ||
2298 | case STV090x_SEARCH_DVBS1: | ||
2299 | case STV090x_SEARCH_DSS: | ||
2300 | /* accelerate the frequency detector */ | ||
2301 | if (state->dev_ver >= 0x20) { | ||
2302 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0) | ||
2303 | goto err; | ||
2304 | } | ||
2305 | |||
2306 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x49) < 0) | ||
2307 | goto err; | ||
2308 | zigzag = 0; | ||
2309 | break; | ||
2310 | |||
2311 | case STV090x_SEARCH_DVBS2: | ||
2312 | if (state->dev_ver >= 0x20) { | ||
2313 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) | ||
2314 | goto err; | ||
2315 | } | ||
2316 | |||
2317 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0) | ||
2318 | goto err; | ||
2319 | zigzag = 1; | ||
2320 | break; | ||
2321 | |||
2322 | case STV090x_SEARCH_AUTO: | ||
2323 | default: | ||
2324 | /* accelerate the frequency detector */ | ||
2325 | if (state->dev_ver >= 0x20) { | ||
2326 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0) | ||
2327 | goto err; | ||
2328 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) | ||
2329 | goto err; | ||
2330 | } | ||
2331 | |||
2332 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0xc9) < 0) | ||
2333 | goto err; | ||
2334 | zigzag = 0; | ||
2335 | break; | ||
2336 | } | ||
2337 | |||
2338 | trials = 0; | ||
2339 | do { | ||
2340 | lock = stv090x_search_car_loop(state, inc, timeout_step, zigzag, steps_max); | ||
2341 | no_signal = stv090x_chk_signal(state); | ||
2342 | trials++; | ||
2343 | |||
2344 | /*run the SW search 2 times maximum*/ | ||
2345 | if (lock || no_signal || (trials == 2)) { | ||
2346 | /*Check if the demod is not losing lock in DVBS2*/ | ||
2347 | if (state->dev_ver >= 0x20) { | ||
2348 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) | ||
2349 | goto err; | ||
2350 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) | ||
2351 | goto err; | ||
2352 | } | ||
2353 | |||
2354 | reg = STV090x_READ_DEMOD(state, DMDSTATE); | ||
2355 | if ((lock) && (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == STV090x_DVBS2)) { | ||
2356 | /*Check if the demod is not losing lock in DVBS2*/ | ||
2357 | msleep(timeout_step); | ||
2358 | reg = STV090x_READ_DEMOD(state, DMDFLYW); | ||
2359 | dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD); | ||
2360 | if (dvbs2_fly_wheel < 0xd) { /*if correct frames is decrementing */ | ||
2361 | msleep(timeout_step); | ||
2362 | reg = STV090x_READ_DEMOD(state, DMDFLYW); | ||
2363 | dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD); | ||
2364 | } | ||
2365 | if (dvbs2_fly_wheel < 0xd) { | ||
2366 | /*FALSE lock, The demod is loosing lock */ | ||
2367 | lock = 0; | ||
2368 | if (trials < 2) { | ||
2369 | if (state->dev_ver >= 0x20) { | ||
2370 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) | ||
2371 | goto err; | ||
2372 | } | ||
2373 | |||
2374 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0) | ||
2375 | goto err; | ||
2376 | } | ||
2377 | } | ||
2378 | } | ||
2379 | } | ||
2380 | } while ((!lock) && (trials < 2) && (!no_signal)); | ||
2381 | |||
2382 | return lock; | ||
2383 | err: | ||
2384 | dprintk(FE_ERROR, 1, "I/O error"); | ||
2385 | return -1; | ||
2386 | } | ||
2387 | |||
2388 | static enum stv090x_delsys stv090x_get_std(struct stv090x_state *state) | ||
2389 | { | ||
2390 | u32 reg; | ||
2391 | enum stv090x_delsys delsys; | ||
2392 | |||
2393 | reg = STV090x_READ_DEMOD(state, DMDSTATE); | ||
2394 | if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 2) | ||
2395 | delsys = STV090x_DVBS2; | ||
2396 | else if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) { | ||
2397 | reg = STV090x_READ_DEMOD(state, FECM); | ||
2398 | if (STV090x_GETFIELD_Px(reg, DSS_DVB_FIELD) == 1) | ||
2399 | delsys = STV090x_DSS; | ||
2400 | else | ||
2401 | delsys = STV090x_DVBS1; | ||
2402 | } else { | ||
2403 | delsys = STV090x_ERROR; | ||
2404 | } | ||
2405 | |||
2406 | return delsys; | ||
2407 | } | ||
2408 | |||
2409 | /* in Hz */ | ||
2410 | static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk) | ||
2411 | { | ||
2412 | s32 derot, int_1, int_2, tmp_1, tmp_2; | ||
2413 | |||
2414 | derot = STV090x_READ_DEMOD(state, CFR2) << 16; | ||
2415 | derot |= STV090x_READ_DEMOD(state, CFR1) << 8; | ||
2416 | derot |= STV090x_READ_DEMOD(state, CFR0); | ||
2417 | |||
2418 | derot = comp2(derot, 24); | ||
2419 | int_1 = state->mclk >> 12; | ||
2420 | int_2 = derot >> 12; | ||
2421 | |||
2422 | /* carrier_frequency = MasterClock * Reg / 2^24 */ | ||
2423 | tmp_1 = state->mclk % 0x1000; | ||
2424 | tmp_2 = derot % 0x1000; | ||
2425 | |||
2426 | derot = (int_1 * int_2) + | ||
2427 | ((int_1 * tmp_2) >> 12) + | ||
2428 | ((int_1 * tmp_1) >> 12); | ||
2429 | |||
2430 | return derot; | ||
2431 | } | ||
2432 | |||
2433 | static int stv090x_get_viterbi(struct stv090x_state *state) | ||
2434 | { | ||
2435 | u32 reg, rate; | ||
2436 | |||
2437 | reg = STV090x_READ_DEMOD(state, VITCURPUN); | ||
2438 | rate = STV090x_GETFIELD_Px(reg, VIT_CURPUN_FIELD); | ||
2439 | |||
2440 | switch (rate) { | ||
2441 | case 13: | ||
2442 | state->fec = STV090x_PR12; | ||
2443 | break; | ||
2444 | |||
2445 | case 18: | ||
2446 | state->fec = STV090x_PR23; | ||
2447 | break; | ||
2448 | |||
2449 | case 21: | ||
2450 | state->fec = STV090x_PR34; | ||
2451 | break; | ||
2452 | |||
2453 | case 24: | ||
2454 | state->fec = STV090x_PR56; | ||
2455 | break; | ||
2456 | |||
2457 | case 25: | ||
2458 | state->fec = STV090x_PR67; | ||
2459 | break; | ||
2460 | |||
2461 | case 26: | ||
2462 | state->fec = STV090x_PR78; | ||
2463 | break; | ||
2464 | |||
2465 | default: | ||
2466 | state->fec = STV090x_PRERR; | ||
2467 | break; | ||
2468 | } | ||
2469 | |||
2470 | return 0; | ||
2471 | } | ||
2472 | |||
2473 | static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state) | ||
2474 | { | ||
2475 | struct dvb_frontend *fe = &state->frontend; | ||
2476 | |||
2477 | u8 tmg; | ||
2478 | u32 reg; | ||
2479 | s32 i = 0, offst_freq; | ||
2480 | |||
2481 | msleep(5); | ||
2482 | |||
2483 | if (state->algo == STV090x_BLIND_SEARCH) { | ||
2484 | tmg = STV090x_READ_DEMOD(state, TMGREG2); | ||
2485 | STV090x_WRITE_DEMOD(state, SFRSTEP, 0x5c); | ||
2486 | while ((i <= 50) && (tmg != 0) && (tmg != 0xff)) { | ||
2487 | tmg = STV090x_READ_DEMOD(state, TMGREG2); | ||
2488 | msleep(5); | ||
2489 | i += 5; | ||
2490 | } | ||
2491 | } | ||
2492 | state->delsys = stv090x_get_std(state); | ||
2493 | |||
2494 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
2495 | goto err; | ||
2496 | |||
2497 | if (state->config->tuner_get_frequency) { | ||
2498 | if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) | ||
2499 | goto err; | ||
2500 | } | ||
2501 | |||
2502 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
2503 | goto err; | ||
2504 | |||
2505 | offst_freq = stv090x_get_car_freq(state, state->mclk) / 1000; | ||
2506 | state->frequency += offst_freq; | ||
2507 | |||
2508 | if (stv090x_get_viterbi(state) < 0) | ||
2509 | goto err; | ||
2510 | |||
2511 | reg = STV090x_READ_DEMOD(state, DMDMODCOD); | ||
2512 | state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); | ||
2513 | state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01; | ||
2514 | state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1; | ||
2515 | reg = STV090x_READ_DEMOD(state, TMGOBS); | ||
2516 | state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD); | ||
2517 | reg = STV090x_READ_DEMOD(state, FECM); | ||
2518 | state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD); | ||
2519 | |||
2520 | if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) { | ||
2521 | |||
2522 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
2523 | goto err; | ||
2524 | |||
2525 | if (state->config->tuner_get_frequency) { | ||
2526 | if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) | ||
2527 | goto err; | ||
2528 | } | ||
2529 | |||
2530 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
2531 | goto err; | ||
2532 | |||
2533 | if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) | ||
2534 | return STV090x_RANGEOK; | ||
2535 | else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000)) | ||
2536 | return STV090x_RANGEOK; | ||
2537 | else | ||
2538 | return STV090x_OUTOFRANGE; /* Out of Range */ | ||
2539 | } else { | ||
2540 | if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) | ||
2541 | return STV090x_RANGEOK; | ||
2542 | else | ||
2543 | return STV090x_OUTOFRANGE; | ||
2544 | } | ||
2545 | |||
2546 | return STV090x_OUTOFRANGE; | ||
2547 | err: | ||
2548 | dprintk(FE_ERROR, 1, "I/O error"); | ||
2549 | return -1; | ||
2550 | } | ||
2551 | |||
2552 | static u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate) | ||
2553 | { | ||
2554 | s32 offst_tmg; | ||
2555 | |||
2556 | offst_tmg = STV090x_READ_DEMOD(state, TMGREG2) << 16; | ||
2557 | offst_tmg |= STV090x_READ_DEMOD(state, TMGREG1) << 8; | ||
2558 | offst_tmg |= STV090x_READ_DEMOD(state, TMGREG0); | ||
2559 | |||
2560 | offst_tmg = comp2(offst_tmg, 24); /* 2's complement */ | ||
2561 | if (!offst_tmg) | ||
2562 | offst_tmg = 1; | ||
2563 | |||
2564 | offst_tmg = ((s32) srate * 10) / ((s32) 0x1000000 / offst_tmg); | ||
2565 | offst_tmg /= 320; | ||
2566 | |||
2567 | return offst_tmg; | ||
2568 | } | ||
2569 | |||
2570 | static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_modcod modcod, s32 pilots) | ||
2571 | { | ||
2572 | u8 aclc = 0x29; | ||
2573 | s32 i; | ||
2574 | struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low; | ||
2575 | |||
2576 | if (state->dev_ver == 0x20) { | ||
2577 | car_loop = stv090x_s2_crl_cut20; | ||
2578 | car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20; | ||
2579 | car_loop_apsk_low = stv090x_s2_apsk_crl_cut20; | ||
2580 | } else { | ||
2581 | /* >= Cut 3 */ | ||
2582 | car_loop = stv090x_s2_crl_cut30; | ||
2583 | car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut30; | ||
2584 | car_loop_apsk_low = stv090x_s2_apsk_crl_cut30; | ||
2585 | } | ||
2586 | |||
2587 | if (modcod < STV090x_QPSK_12) { | ||
2588 | i = 0; | ||
2589 | while ((i < 3) && (modcod != car_loop_qpsk_low[i].modcod)) | ||
2590 | i++; | ||
2591 | |||
2592 | if (i >= 3) | ||
2593 | i = 2; | ||
2594 | |||
2595 | } else { | ||
2596 | i = 0; | ||
2597 | while ((i < 14) && (modcod != car_loop[i].modcod)) | ||
2598 | i++; | ||
2599 | |||
2600 | if (i >= 14) { | ||
2601 | i = 0; | ||
2602 | while ((i < 11) && (modcod != car_loop_apsk_low[i].modcod)) | ||
2603 | i++; | ||
2604 | |||
2605 | if (i >= 11) | ||
2606 | i = 10; | ||
2607 | } | ||
2608 | } | ||
2609 | |||
2610 | if (modcod <= STV090x_QPSK_25) { | ||
2611 | if (pilots) { | ||
2612 | if (state->srate <= 3000000) | ||
2613 | aclc = car_loop_qpsk_low[i].crl_pilots_on_2; | ||
2614 | else if (state->srate <= 7000000) | ||
2615 | aclc = car_loop_qpsk_low[i].crl_pilots_on_5; | ||
2616 | else if (state->srate <= 15000000) | ||
2617 | aclc = car_loop_qpsk_low[i].crl_pilots_on_10; | ||
2618 | else if (state->srate <= 25000000) | ||
2619 | aclc = car_loop_qpsk_low[i].crl_pilots_on_20; | ||
2620 | else | ||
2621 | aclc = car_loop_qpsk_low[i].crl_pilots_on_30; | ||
2622 | } else { | ||
2623 | if (state->srate <= 3000000) | ||
2624 | aclc = car_loop_qpsk_low[i].crl_pilots_off_2; | ||
2625 | else if (state->srate <= 7000000) | ||
2626 | aclc = car_loop_qpsk_low[i].crl_pilots_off_5; | ||
2627 | else if (state->srate <= 15000000) | ||
2628 | aclc = car_loop_qpsk_low[i].crl_pilots_off_10; | ||
2629 | else if (state->srate <= 25000000) | ||
2630 | aclc = car_loop_qpsk_low[i].crl_pilots_off_20; | ||
2631 | else | ||
2632 | aclc = car_loop_qpsk_low[i].crl_pilots_off_30; | ||
2633 | } | ||
2634 | |||
2635 | } else if (modcod <= STV090x_8PSK_910) { | ||
2636 | if (pilots) { | ||
2637 | if (state->srate <= 3000000) | ||
2638 | aclc = car_loop[i].crl_pilots_on_2; | ||
2639 | else if (state->srate <= 7000000) | ||
2640 | aclc = car_loop[i].crl_pilots_on_5; | ||
2641 | else if (state->srate <= 15000000) | ||
2642 | aclc = car_loop[i].crl_pilots_on_10; | ||
2643 | else if (state->srate <= 25000000) | ||
2644 | aclc = car_loop[i].crl_pilots_on_20; | ||
2645 | else | ||
2646 | aclc = car_loop[i].crl_pilots_on_30; | ||
2647 | } else { | ||
2648 | if (state->srate <= 3000000) | ||
2649 | aclc = car_loop[i].crl_pilots_off_2; | ||
2650 | else if (state->srate <= 7000000) | ||
2651 | aclc = car_loop[i].crl_pilots_off_5; | ||
2652 | else if (state->srate <= 15000000) | ||
2653 | aclc = car_loop[i].crl_pilots_off_10; | ||
2654 | else if (state->srate <= 25000000) | ||
2655 | aclc = car_loop[i].crl_pilots_off_20; | ||
2656 | else | ||
2657 | aclc = car_loop[i].crl_pilots_off_30; | ||
2658 | } | ||
2659 | } else { /* 16APSK and 32APSK */ | ||
2660 | if (state->srate <= 3000000) | ||
2661 | aclc = car_loop_apsk_low[i].crl_pilots_on_2; | ||
2662 | else if (state->srate <= 7000000) | ||
2663 | aclc = car_loop_apsk_low[i].crl_pilots_on_5; | ||
2664 | else if (state->srate <= 15000000) | ||
2665 | aclc = car_loop_apsk_low[i].crl_pilots_on_10; | ||
2666 | else if (state->srate <= 25000000) | ||
2667 | aclc = car_loop_apsk_low[i].crl_pilots_on_20; | ||
2668 | else | ||
2669 | aclc = car_loop_apsk_low[i].crl_pilots_on_30; | ||
2670 | } | ||
2671 | |||
2672 | return aclc; | ||
2673 | } | ||
2674 | |||
2675 | static u8 stv090x_optimize_carloop_short(struct stv090x_state *state) | ||
2676 | { | ||
2677 | struct stv090x_short_frame_crloop *short_crl; | ||
2678 | s32 index = 0; | ||
2679 | u8 aclc = 0x0b; | ||
2680 | |||
2681 | switch (state->modulation) { | ||
2682 | case STV090x_QPSK: | ||
2683 | default: | ||
2684 | index = 0; | ||
2685 | break; | ||
2686 | case STV090x_8PSK: | ||
2687 | index = 1; | ||
2688 | break; | ||
2689 | case STV090x_16APSK: | ||
2690 | index = 2; | ||
2691 | break; | ||
2692 | case STV090x_32APSK: | ||
2693 | index = 3; | ||
2694 | break; | ||
2695 | } | ||
2696 | |||
2697 | if (state->dev_ver >= 0x30) | ||
2698 | short_crl = stv090x_s2_short_crl_cut20; | ||
2699 | else if (state->dev_ver >= 0x20) | ||
2700 | short_crl = stv090x_s2_short_crl_cut30; | ||
2701 | |||
2702 | if (state->srate <= 3000000) | ||
2703 | aclc = short_crl[index].crl_2; | ||
2704 | else if (state->srate <= 7000000) | ||
2705 | aclc = short_crl[index].crl_5; | ||
2706 | else if (state->srate <= 15000000) | ||
2707 | aclc = short_crl[index].crl_10; | ||
2708 | else if (state->srate <= 25000000) | ||
2709 | aclc = short_crl[index].crl_20; | ||
2710 | else | ||
2711 | aclc = short_crl[index].crl_30; | ||
2712 | |||
2713 | return aclc; | ||
2714 | } | ||
2715 | |||
2716 | static int stv090x_optimize_track(struct stv090x_state *state) | ||
2717 | { | ||
2718 | struct dvb_frontend *fe = &state->frontend; | ||
2719 | |||
2720 | enum stv090x_rolloff rolloff; | ||
2721 | enum stv090x_modcod modcod; | ||
2722 | |||
2723 | s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; | ||
2724 | u32 reg; | ||
2725 | |||
2726 | srate = stv090x_get_srate(state, state->mclk); | ||
2727 | srate += stv090x_get_tmgoffst(state, srate); | ||
2728 | |||
2729 | switch (state->delsys) { | ||
2730 | case STV090x_DVBS1: | ||
2731 | case STV090x_DSS: | ||
2732 | if (state->algo == STV090x_SEARCH_AUTO) { | ||
2733 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
2734 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); | ||
2735 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); | ||
2736 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
2737 | goto err; | ||
2738 | } | ||
2739 | reg = STV090x_READ_DEMOD(state, DEMOD); | ||
2740 | STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff); | ||
2741 | STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x01); | ||
2742 | if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) | ||
2743 | goto err; | ||
2744 | |||
2745 | if (state->dev_ver >= 0x30) { | ||
2746 | if (stv090x_get_viterbi(state) < 0) | ||
2747 | goto err; | ||
2748 | |||
2749 | if (state->fec == STV090x_PR12) { | ||
2750 | if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x98) < 0) | ||
2751 | goto err; | ||
2752 | if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0) | ||
2753 | goto err; | ||
2754 | } else { | ||
2755 | if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x18) < 0) | ||
2756 | goto err; | ||
2757 | if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0) | ||
2758 | goto err; | ||
2759 | } | ||
2760 | } | ||
2761 | |||
2762 | if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0) | ||
2763 | goto err; | ||
2764 | break; | ||
2765 | |||
2766 | case STV090x_DVBS2: | ||
2767 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
2768 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); | ||
2769 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); | ||
2770 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
2771 | goto err; | ||
2772 | if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0) | ||
2773 | goto err; | ||
2774 | if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0) | ||
2775 | goto err; | ||
2776 | if (state->frame_len == STV090x_LONG_FRAME) { | ||
2777 | reg = STV090x_READ_DEMOD(state, DMDMODCOD); | ||
2778 | modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); | ||
2779 | pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01; | ||
2780 | aclc = stv090x_optimize_carloop(state, modcod, pilots); | ||
2781 | if (modcod <= STV090x_QPSK_910) { | ||
2782 | STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc); | ||
2783 | } else if (modcod <= STV090x_8PSK_910) { | ||
2784 | if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) | ||
2785 | goto err; | ||
2786 | if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0) | ||
2787 | goto err; | ||
2788 | } | ||
2789 | if ((state->demod_mode == STV090x_SINGLE) && (modcod > STV090x_8PSK_910)) { | ||
2790 | if (modcod <= STV090x_16APSK_910) { | ||
2791 | if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) | ||
2792 | goto err; | ||
2793 | if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0) | ||
2794 | goto err; | ||
2795 | } else { | ||
2796 | if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) | ||
2797 | goto err; | ||
2798 | if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0) | ||
2799 | goto err; | ||
2800 | } | ||
2801 | } | ||
2802 | } else { | ||
2803 | /*Carrier loop setting for short frame*/ | ||
2804 | aclc = stv090x_optimize_carloop_short(state); | ||
2805 | if (state->modulation == STV090x_QPSK) { | ||
2806 | if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc) < 0) | ||
2807 | goto err; | ||
2808 | } else if (state->modulation == STV090x_8PSK) { | ||
2809 | if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) | ||
2810 | goto err; | ||
2811 | if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0) | ||
2812 | goto err; | ||
2813 | } else if (state->modulation == STV090x_16APSK) { | ||
2814 | if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) | ||
2815 | goto err; | ||
2816 | if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0) | ||
2817 | goto err; | ||
2818 | } else if (state->modulation == STV090x_32APSK) { | ||
2819 | if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) | ||
2820 | goto err; | ||
2821 | if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0) | ||
2822 | goto err; | ||
2823 | } | ||
2824 | } | ||
2825 | |||
2826 | STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */ | ||
2827 | break; | ||
2828 | |||
2829 | case STV090x_UNKNOWN: | ||
2830 | default: | ||
2831 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
2832 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); | ||
2833 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); | ||
2834 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
2835 | goto err; | ||
2836 | break; | ||
2837 | } | ||
2838 | |||
2839 | f_1 = STV090x_READ_DEMOD(state, CFR2); | ||
2840 | f_0 = STV090x_READ_DEMOD(state, CFR1); | ||
2841 | reg = STV090x_READ_DEMOD(state, TMGOBS); | ||
2842 | rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD); | ||
2843 | |||
2844 | if (state->algo == STV090x_BLIND_SEARCH) { | ||
2845 | STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00); | ||
2846 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | ||
2847 | STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0x00); | ||
2848 | STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); | ||
2849 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
2850 | goto err; | ||
2851 | if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) | ||
2852 | goto err; | ||
2853 | |||
2854 | if (stv090x_set_srate(state, srate) < 0) | ||
2855 | goto err; | ||
2856 | blind_tune = 1; | ||
2857 | } | ||
2858 | |||
2859 | if (state->dev_ver >= 0x20) { | ||
2860 | if ((state->search_mode == STV090x_SEARCH_DVBS1) || | ||
2861 | (state->search_mode == STV090x_SEARCH_DSS) || | ||
2862 | (state->search_mode == STV090x_SEARCH_AUTO)) { | ||
2863 | |||
2864 | if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x0a) < 0) | ||
2865 | goto err; | ||
2866 | if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x00) < 0) | ||
2867 | goto err; | ||
2868 | } | ||
2869 | } | ||
2870 | |||
2871 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) | ||
2872 | goto err; | ||
2873 | |||
2874 | /* AUTO tracking MODE */ | ||
2875 | if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x80) < 0) | ||
2876 | goto err; | ||
2877 | /* AUTO tracking MODE */ | ||
2878 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0) | ||
2879 | goto err; | ||
2880 | |||
2881 | if ((state->dev_ver >= 0x20) || (blind_tune == 1) || (state->srate < 10000000)) { | ||
2882 | /* update initial carrier freq with the found freq offset */ | ||
2883 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) | ||
2884 | goto err; | ||
2885 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0) | ||
2886 | goto err; | ||
2887 | state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000; | ||
2888 | |||
2889 | if ((state->dev_ver >= 0x20) || (blind_tune == 1)) { | ||
2890 | |||
2891 | if (state->algo != STV090x_WARM_SEARCH) { | ||
2892 | |||
2893 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
2894 | goto err; | ||
2895 | |||
2896 | if (state->config->tuner_set_bandwidth) { | ||
2897 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) | ||
2898 | goto err; | ||
2899 | } | ||
2900 | |||
2901 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
2902 | goto err; | ||
2903 | |||
2904 | } | ||
2905 | } | ||
2906 | if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) | ||
2907 | msleep(50); /* blind search: wait 50ms for SR stabilization */ | ||
2908 | else | ||
2909 | msleep(5); | ||
2910 | |||
2911 | stv090x_get_lock_tmg(state); | ||
2912 | |||
2913 | if (!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) { | ||
2914 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) | ||
2915 | goto err; | ||
2916 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) | ||
2917 | goto err; | ||
2918 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0) | ||
2919 | goto err; | ||
2920 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) | ||
2921 | goto err; | ||
2922 | |||
2923 | i = 0; | ||
2924 | |||
2925 | while ((!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) && (i <= 2)) { | ||
2926 | |||
2927 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) | ||
2928 | goto err; | ||
2929 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) | ||
2930 | goto err; | ||
2931 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0) | ||
2932 | goto err; | ||
2933 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) | ||
2934 | goto err; | ||
2935 | i++; | ||
2936 | } | ||
2937 | } | ||
2938 | |||
2939 | } | ||
2940 | |||
2941 | if (state->dev_ver >= 0x20) { | ||
2942 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) | ||
2943 | goto err; | ||
2944 | } | ||
2945 | |||
2946 | if ((state->delsys == STV090x_DVBS1) || (state->delsys == STV090x_DSS)) | ||
2947 | stv090x_set_vit_thtracq(state); | ||
2948 | |||
2949 | return 0; | ||
2950 | err: | ||
2951 | dprintk(FE_ERROR, 1, "I/O error"); | ||
2952 | return -1; | ||
2953 | } | ||
2954 | |||
2955 | static int stv090x_get_feclock(struct stv090x_state *state, s32 timeout) | ||
2956 | { | ||
2957 | s32 timer = 0, lock = 0, stat; | ||
2958 | u32 reg; | ||
2959 | |||
2960 | while ((timer < timeout) && (!lock)) { | ||
2961 | reg = STV090x_READ_DEMOD(state, DMDSTATE); | ||
2962 | stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); | ||
2963 | |||
2964 | switch (stat) { | ||
2965 | case 0: /* searching */ | ||
2966 | case 1: /* first PLH detected */ | ||
2967 | default: | ||
2968 | lock = 0; | ||
2969 | break; | ||
2970 | |||
2971 | case 2: /* DVB-S2 mode */ | ||
2972 | reg = STV090x_READ_DEMOD(state, PDELSTATUS1); | ||
2973 | lock = STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD); | ||
2974 | break; | ||
2975 | |||
2976 | case 3: /* DVB-S1/legacy mode */ | ||
2977 | reg = STV090x_READ_DEMOD(state, VSTATUSVIT); | ||
2978 | lock = STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD); | ||
2979 | break; | ||
2980 | } | ||
2981 | if (!lock) { | ||
2982 | msleep(10); | ||
2983 | timer += 10; | ||
2984 | } | ||
2985 | } | ||
2986 | return lock; | ||
2987 | } | ||
2988 | |||
2989 | static int stv090x_get_lock(struct stv090x_state *state, s32 timeout_dmd, s32 timeout_fec) | ||
2990 | { | ||
2991 | u32 reg; | ||
2992 | s32 timer = 0; | ||
2993 | int lock; | ||
2994 | |||
2995 | lock = stv090x_get_dmdlock(state, timeout_dmd); | ||
2996 | if (lock) | ||
2997 | lock = stv090x_get_feclock(state, timeout_fec); | ||
2998 | |||
2999 | if (lock) { | ||
3000 | lock = 0; | ||
3001 | |||
3002 | while ((timer < timeout_fec) && (!lock)) { | ||
3003 | reg = STV090x_READ_DEMOD(state, TSSTATUS); | ||
3004 | lock = STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD); | ||
3005 | msleep(1); | ||
3006 | timer++; | ||
3007 | } | ||
3008 | } | ||
3009 | |||
3010 | return lock; | ||
3011 | } | ||
3012 | |||
3013 | static int stv090x_set_s2rolloff(struct stv090x_state *state) | ||
3014 | { | ||
3015 | u32 reg; | ||
3016 | |||
3017 | if (state->dev_ver <= 0x20) { | ||
3018 | /* rolloff to auto mode if DVBS2 */ | ||
3019 | reg = STV090x_READ_DEMOD(state, DEMOD); | ||
3020 | STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00); | ||
3021 | if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) | ||
3022 | goto err; | ||
3023 | } else { | ||
3024 | /* DVB-S2 rolloff to auto mode if DVBS2 */ | ||
3025 | reg = STV090x_READ_DEMOD(state, DEMOD); | ||
3026 | STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 0x00); | ||
3027 | if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) | ||
3028 | goto err; | ||
3029 | } | ||
3030 | return 0; | ||
3031 | err: | ||
3032 | dprintk(FE_ERROR, 1, "I/O error"); | ||
3033 | return -1; | ||
3034 | } | ||
3035 | |||
3036 | |||
3037 | static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) | ||
3038 | { | ||
3039 | struct dvb_frontend *fe = &state->frontend; | ||
3040 | enum stv090x_signal_state signal_state = STV090x_NOCARRIER; | ||
3041 | u32 reg; | ||
3042 | s32 timeout_dmd = 500, timeout_fec = 50, agc1_power, power_iq = 0, i; | ||
3043 | int lock = 0, low_sr = 0, no_signal = 0; | ||
3044 | |||
3045 | reg = STV090x_READ_DEMOD(state, TSCFGH); | ||
3046 | STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */ | ||
3047 | if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) | ||
3048 | goto err; | ||
3049 | |||
3050 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */ | ||
3051 | goto err; | ||
3052 | |||
3053 | if (state->dev_ver >= 0x20) { | ||
3054 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) /* cut 2.0 */ | ||
3055 | goto err; | ||
3056 | } | ||
3057 | |||
3058 | stv090x_get_lock_tmg(state); | ||
3059 | |||
3060 | if (state->algo == STV090x_BLIND_SEARCH) { | ||
3061 | state->tuner_bw = 2 * 36000000; /* wide bw for unknown srate */ | ||
3062 | if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) /* wider srate scan */ | ||
3063 | goto err; | ||
3064 | if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0) | ||
3065 | goto err; | ||
3066 | if (stv090x_set_srate(state, 1000000) < 0) /* inital srate = 1Msps */ | ||
3067 | goto err; | ||
3068 | } else { | ||
3069 | /* known srate */ | ||
3070 | if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0) | ||
3071 | goto err; | ||
3072 | if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0) | ||
3073 | goto err; | ||
3074 | |||
3075 | if (state->srate < 2000000) { | ||
3076 | /* SR < 2MSPS */ | ||
3077 | if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x63) < 0) | ||
3078 | goto err; | ||
3079 | } else { | ||
3080 | /* SR >= 2Msps */ | ||
3081 | if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0) | ||
3082 | goto err; | ||
3083 | } | ||
3084 | |||
3085 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) | ||
3086 | goto err; | ||
3087 | |||
3088 | if (state->dev_ver >= 0x20) { | ||
3089 | if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0) | ||
3090 | goto err; | ||
3091 | if (state->algo == STV090x_COLD_SEARCH) | ||
3092 | state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10; | ||
3093 | else if (state->algo == STV090x_WARM_SEARCH) | ||
3094 | state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000; | ||
3095 | } | ||
3096 | |||
3097 | /* if cold start or warm (Symbolrate is known) | ||
3098 | * use a Narrow symbol rate scan range | ||
3099 | */ | ||
3100 | if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) /* narrow srate scan */ | ||
3101 | goto err; | ||
3102 | |||
3103 | if (stv090x_set_srate(state, state->srate) < 0) | ||
3104 | goto err; | ||
3105 | |||
3106 | if (stv090x_set_max_srate(state, state->mclk, state->srate) < 0) | ||
3107 | goto err; | ||
3108 | if (stv090x_set_min_srate(state, state->mclk, state->srate) < 0) | ||
3109 | goto err; | ||
3110 | |||
3111 | if (state->srate >= 10000000) | ||
3112 | low_sr = 0; | ||
3113 | else | ||
3114 | low_sr = 1; | ||
3115 | } | ||
3116 | |||
3117 | /* Setup tuner */ | ||
3118 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
3119 | goto err; | ||
3120 | |||
3121 | if (state->config->tuner_set_bbgain) { | ||
3122 | if (state->config->tuner_set_bbgain(fe, 10) < 0) /* 10dB */ | ||
3123 | goto err; | ||
3124 | } | ||
3125 | |||
3126 | if (state->config->tuner_set_frequency) { | ||
3127 | if (state->config->tuner_set_frequency(fe, state->frequency) < 0) | ||
3128 | goto err; | ||
3129 | } | ||
3130 | |||
3131 | if (state->config->tuner_set_bandwidth) { | ||
3132 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) | ||
3133 | goto err; | ||
3134 | } | ||
3135 | |||
3136 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
3137 | goto err; | ||
3138 | |||
3139 | msleep(50); | ||
3140 | |||
3141 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
3142 | goto err; | ||
3143 | |||
3144 | if (state->config->tuner_get_status) { | ||
3145 | if (state->config->tuner_get_status(fe, ®) < 0) | ||
3146 | goto err; | ||
3147 | } | ||
3148 | |||
3149 | if (reg) | ||
3150 | dprintk(FE_DEBUG, 1, "Tuner phase locked"); | ||
3151 | else | ||
3152 | dprintk(FE_DEBUG, 1, "Tuner unlocked"); | ||
3153 | |||
3154 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
3155 | goto err; | ||
3156 | |||
3157 | msleep(10); | ||
3158 | agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1), | ||
3159 | STV090x_READ_DEMOD(state, AGCIQIN0)); | ||
3160 | |||
3161 | if (agc1_power == 0) { | ||
3162 | /* If AGC1 integrator value is 0 | ||
3163 | * then read POWERI, POWERQ | ||
3164 | */ | ||
3165 | for (i = 0; i < 5; i++) { | ||
3166 | power_iq += (STV090x_READ_DEMOD(state, POWERI) + | ||
3167 | STV090x_READ_DEMOD(state, POWERQ)) >> 1; | ||
3168 | } | ||
3169 | power_iq /= 5; | ||
3170 | } | ||
3171 | |||
3172 | if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) { | ||
3173 | dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq); | ||
3174 | lock = 0; | ||
3175 | |||
3176 | } else { | ||
3177 | reg = STV090x_READ_DEMOD(state, DEMOD); | ||
3178 | STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); | ||
3179 | |||
3180 | if (state->dev_ver <= 0x20) { | ||
3181 | /* rolloff to auto mode if DVBS2 */ | ||
3182 | STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1); | ||
3183 | } else { | ||
3184 | /* DVB-S2 rolloff to auto mode if DVBS2 */ | ||
3185 | STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 1); | ||
3186 | } | ||
3187 | if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) | ||
3188 | goto err; | ||
3189 | |||
3190 | if (stv090x_delivery_search(state) < 0) | ||
3191 | goto err; | ||
3192 | |||
3193 | if (state->algo != STV090x_BLIND_SEARCH) { | ||
3194 | if (stv090x_start_search(state) < 0) | ||
3195 | goto err; | ||
3196 | } | ||
3197 | } | ||
3198 | |||
3199 | /* need to check for AGC1 state */ | ||
3200 | |||
3201 | |||
3202 | |||
3203 | if (state->algo == STV090x_BLIND_SEARCH) | ||
3204 | lock = stv090x_blind_search(state); | ||
3205 | |||
3206 | else if (state->algo == STV090x_COLD_SEARCH) | ||
3207 | lock = stv090x_get_coldlock(state, timeout_dmd); | ||
3208 | |||
3209 | else if (state->algo == STV090x_WARM_SEARCH) | ||
3210 | lock = stv090x_get_dmdlock(state, timeout_dmd); | ||
3211 | |||
3212 | if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) { | ||
3213 | if (!low_sr) { | ||
3214 | if (stv090x_chk_tmg(state)) | ||
3215 | lock = stv090x_sw_algo(state); | ||
3216 | } | ||
3217 | } | ||
3218 | |||
3219 | if (lock) | ||
3220 | signal_state = stv090x_get_sig_params(state); | ||
3221 | |||
3222 | if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */ | ||
3223 | stv090x_optimize_track(state); | ||
3224 | |||
3225 | if (state->dev_ver >= 0x20) { | ||
3226 | /* >= Cut 2.0 :release TS reset after | ||
3227 | * demod lock and optimized Tracking | ||
3228 | */ | ||
3229 | reg = STV090x_READ_DEMOD(state, TSCFGH); | ||
3230 | STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ | ||
3231 | if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) | ||
3232 | goto err; | ||
3233 | |||
3234 | msleep(3); | ||
3235 | |||
3236 | STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */ | ||
3237 | if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) | ||
3238 | goto err; | ||
3239 | |||
3240 | STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ | ||
3241 | if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) | ||
3242 | goto err; | ||
3243 | } | ||
3244 | |||
3245 | if (stv090x_get_lock(state, timeout_fec, timeout_fec)) { | ||
3246 | lock = 1; | ||
3247 | if (state->delsys == STV090x_DVBS2) { | ||
3248 | stv090x_set_s2rolloff(state); | ||
3249 | |||
3250 | reg = STV090x_READ_DEMOD(state, PDELCTRL2); | ||
3251 | STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 1); | ||
3252 | if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0) | ||
3253 | goto err; | ||
3254 | /* Reset DVBS2 packet delinator error counter */ | ||
3255 | reg = STV090x_READ_DEMOD(state, PDELCTRL2); | ||
3256 | STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 0); | ||
3257 | if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0) | ||
3258 | goto err; | ||
3259 | |||
3260 | if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67) < 0) /* PER */ | ||
3261 | goto err; | ||
3262 | } else { | ||
3263 | if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0) | ||
3264 | goto err; | ||
3265 | } | ||
3266 | /* Reset the Total packet counter */ | ||
3267 | if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0x00) < 0) | ||
3268 | goto err; | ||
3269 | /* Reset the packet Error counter2 */ | ||
3270 | if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) | ||
3271 | goto err; | ||
3272 | } else { | ||
3273 | lock = 0; | ||
3274 | signal_state = STV090x_NODATA; | ||
3275 | no_signal = stv090x_chk_signal(state); | ||
3276 | } | ||
3277 | } | ||
3278 | return signal_state; | ||
3279 | |||
3280 | err: | ||
3281 | dprintk(FE_ERROR, 1, "I/O error"); | ||
3282 | return -1; | ||
3283 | } | ||
3284 | |||
3285 | static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | ||
3286 | { | ||
3287 | struct stv090x_state *state = fe->demodulator_priv; | ||
3288 | struct dtv_frontend_properties *props = &fe->dtv_property_cache; | ||
3289 | |||
3290 | state->delsys = props->delivery_system; | ||
3291 | state->frequency = p->frequency; | ||
3292 | state->srate = p->u.qpsk.symbol_rate; | ||
3293 | state->search_mode = STV090x_SEARCH_AUTO; | ||
3294 | state->algo = STV090x_COLD_SEARCH; | ||
3295 | state->fec = STV090x_PRERR; | ||
3296 | state->search_range = 2000000; | ||
3297 | |||
3298 | if (stv090x_algo(state) == STV090x_RANGEOK) { | ||
3299 | dprintk(FE_DEBUG, 1, "Search success!"); | ||
3300 | return DVBFE_ALGO_SEARCH_SUCCESS; | ||
3301 | } else { | ||
3302 | dprintk(FE_DEBUG, 1, "Search failed!"); | ||
3303 | return DVBFE_ALGO_SEARCH_FAILED; | ||
3304 | } | ||
3305 | |||
3306 | return DVBFE_ALGO_SEARCH_ERROR; | ||
3307 | } | ||
3308 | |||
3309 | /* FIXME! */ | ||
3310 | static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) | ||
3311 | { | ||
3312 | struct stv090x_state *state = fe->demodulator_priv; | ||
3313 | u32 reg; | ||
3314 | u8 search_state; | ||
3315 | |||
3316 | reg = STV090x_READ_DEMOD(state, DMDSTATE); | ||
3317 | search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); | ||
3318 | |||
3319 | switch (search_state) { | ||
3320 | case 0: /* searching */ | ||
3321 | case 1: /* first PLH detected */ | ||
3322 | default: | ||
3323 | dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)"); | ||
3324 | *status = 0; | ||
3325 | break; | ||
3326 | |||
3327 | case 2: /* DVB-S2 mode */ | ||
3328 | dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2"); | ||
3329 | reg = STV090x_READ_DEMOD(state, DSTATUS); | ||
3330 | if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) { | ||
3331 | reg = STV090x_READ_DEMOD(state, TSSTATUS); | ||
3332 | if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { | ||
3333 | *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
3334 | } | ||
3335 | } | ||
3336 | break; | ||
3337 | |||
3338 | case 3: /* DVB-S1/legacy mode */ | ||
3339 | dprintk(FE_DEBUG, 1, "Delivery system: DVB-S"); | ||
3340 | reg = STV090x_READ_DEMOD(state, DSTATUS); | ||
3341 | if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) { | ||
3342 | reg = STV090x_READ_DEMOD(state, VSTATUSVIT); | ||
3343 | if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { | ||
3344 | reg = STV090x_READ_DEMOD(state, TSSTATUS); | ||
3345 | if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { | ||
3346 | *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
3347 | } | ||
3348 | } | ||
3349 | } | ||
3350 | break; | ||
3351 | } | ||
3352 | |||
3353 | return 0; | ||
3354 | } | ||
3355 | |||
3356 | static int stv090x_read_per(struct dvb_frontend *fe, u32 *per) | ||
3357 | { | ||
3358 | struct stv090x_state *state = fe->demodulator_priv; | ||
3359 | |||
3360 | s32 count_4, count_3, count_2, count_1, count_0, count; | ||
3361 | u32 reg, h, m, l; | ||
3362 | enum fe_status status; | ||
3363 | |||
3364 | stv090x_read_status(fe, &status); | ||
3365 | if (!(status & FE_HAS_LOCK)) { | ||
3366 | *per = 1 << 23; /* Max PER */ | ||
3367 | } else { | ||
3368 | /* Counter 2 */ | ||
3369 | reg = STV090x_READ_DEMOD(state, ERRCNT22); | ||
3370 | h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD); | ||
3371 | |||
3372 | reg = STV090x_READ_DEMOD(state, ERRCNT21); | ||
3373 | m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD); | ||
3374 | |||
3375 | reg = STV090x_READ_DEMOD(state, ERRCNT20); | ||
3376 | l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD); | ||
3377 | |||
3378 | *per = ((h << 16) | (m << 8) | l); | ||
3379 | |||
3380 | count_4 = STV090x_READ_DEMOD(state, FBERCPT4); | ||
3381 | count_3 = STV090x_READ_DEMOD(state, FBERCPT3); | ||
3382 | count_2 = STV090x_READ_DEMOD(state, FBERCPT2); | ||
3383 | count_1 = STV090x_READ_DEMOD(state, FBERCPT1); | ||
3384 | count_0 = STV090x_READ_DEMOD(state, FBERCPT0); | ||
3385 | |||
3386 | if ((!count_4) && (!count_3)) { | ||
3387 | count = (count_2 & 0xff) << 16; | ||
3388 | count |= (count_1 & 0xff) << 8; | ||
3389 | count |= count_0 & 0xff; | ||
3390 | } else { | ||
3391 | count = 1 << 24; | ||
3392 | } | ||
3393 | if (count == 0) | ||
3394 | *per = 1; | ||
3395 | } | ||
3396 | if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0) | ||
3397 | goto err; | ||
3398 | if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) | ||
3399 | goto err; | ||
3400 | |||
3401 | return 0; | ||
3402 | err: | ||
3403 | dprintk(FE_ERROR, 1, "I/O error"); | ||
3404 | return -1; | ||
3405 | } | ||
3406 | |||
3407 | static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) | ||
3408 | { | ||
3409 | int res = 0; | ||
3410 | int min = 0, med; | ||
3411 | |||
3412 | if (val < tab[min].read) | ||
3413 | res = tab[min].real; | ||
3414 | else if (val >= tab[max].read) | ||
3415 | res = tab[max].real; | ||
3416 | else { | ||
3417 | while ((max - min) > 1) { | ||
3418 | med = (max + min) / 2; | ||
3419 | if (val >= tab[min].read && val < tab[med].read) | ||
3420 | max = med; | ||
3421 | else | ||
3422 | min = med; | ||
3423 | } | ||
3424 | res = ((val - tab[min].read) * | ||
3425 | (tab[max].real - tab[min].real) / | ||
3426 | (tab[max].read - tab[min].read)) + | ||
3427 | tab[min].real; | ||
3428 | } | ||
3429 | |||
3430 | return res; | ||
3431 | } | ||
3432 | |||
3433 | static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||
3434 | { | ||
3435 | struct stv090x_state *state = fe->demodulator_priv; | ||
3436 | u32 reg; | ||
3437 | s32 agc; | ||
3438 | |||
3439 | reg = STV090x_READ_DEMOD(state, AGCIQIN1); | ||
3440 | agc = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); | ||
3441 | |||
3442 | *strength = stv090x_table_lookup(stv090x_rf_tab, ARRAY_SIZE(stv090x_rf_tab) - 1, agc); | ||
3443 | if (agc > stv090x_rf_tab[0].read) | ||
3444 | *strength = 5; | ||
3445 | else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read) | ||
3446 | *strength = -100; | ||
3447 | |||
3448 | return 0; | ||
3449 | } | ||
3450 | |||
3451 | static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) | ||
3452 | { | ||
3453 | struct stv090x_state *state = fe->demodulator_priv; | ||
3454 | u32 reg_0, reg_1, reg, i; | ||
3455 | s32 val_0, val_1, val = 0; | ||
3456 | u8 lock_f; | ||
3457 | |||
3458 | switch (state->delsys) { | ||
3459 | case STV090x_DVBS2: | ||
3460 | reg = STV090x_READ_DEMOD(state, DSTATUS); | ||
3461 | lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD); | ||
3462 | if (lock_f) { | ||
3463 | msleep(5); | ||
3464 | for (i = 0; i < 16; i++) { | ||
3465 | reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1); | ||
3466 | val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); | ||
3467 | reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0); | ||
3468 | val_0 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); | ||
3469 | val += MAKEWORD16(val_1, val_0); | ||
3470 | msleep(1); | ||
3471 | } | ||
3472 | val /= 16; | ||
3473 | *cnr = stv090x_table_lookup(stv090x_s2cn_tab, ARRAY_SIZE(stv090x_s2cn_tab) - 1, val); | ||
3474 | if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s2cn_tab) - 1].read) | ||
3475 | *cnr = 1000; | ||
3476 | } | ||
3477 | break; | ||
3478 | |||
3479 | case STV090x_DVBS1: | ||
3480 | case STV090x_DSS: | ||
3481 | reg = STV090x_READ_DEMOD(state, DSTATUS); | ||
3482 | lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD); | ||
3483 | if (lock_f) { | ||
3484 | msleep(5); | ||
3485 | for (i = 0; i < 16; i++) { | ||
3486 | reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1); | ||
3487 | val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); | ||
3488 | reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0); | ||
3489 | val_0 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); | ||
3490 | val += MAKEWORD16(val_1, val_0); | ||
3491 | msleep(1); | ||
3492 | } | ||
3493 | val /= 16; | ||
3494 | *cnr = stv090x_table_lookup(stv090x_s1cn_tab, ARRAY_SIZE(stv090x_s1cn_tab) - 1, val); | ||
3495 | if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s1cn_tab) - 1].read) | ||
3496 | *cnr = 1000; | ||
3497 | } | ||
3498 | break; | ||
3499 | default: | ||
3500 | break; | ||
3501 | } | ||
3502 | |||
3503 | return 0; | ||
3504 | } | ||
3505 | |||
3506 | static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | ||
3507 | { | ||
3508 | struct stv090x_state *state = fe->demodulator_priv; | ||
3509 | u32 reg; | ||
3510 | |||
3511 | reg = STV090x_READ_DEMOD(state, DISTXCTL); | ||
3512 | switch (tone) { | ||
3513 | case SEC_TONE_ON: | ||
3514 | STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0); | ||
3515 | STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); | ||
3516 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3517 | goto err; | ||
3518 | STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0); | ||
3519 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3520 | goto err; | ||
3521 | break; | ||
3522 | |||
3523 | case SEC_TONE_OFF: | ||
3524 | STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0); | ||
3525 | STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); | ||
3526 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3527 | goto err; | ||
3528 | break; | ||
3529 | default: | ||
3530 | return -EINVAL; | ||
3531 | } | ||
3532 | |||
3533 | return 0; | ||
3534 | err: | ||
3535 | dprintk(FE_ERROR, 1, "I/O error"); | ||
3536 | return -1; | ||
3537 | } | ||
3538 | |||
3539 | |||
3540 | static enum dvbfe_algo stv090x_frontend_algo(struct dvb_frontend *fe) | ||
3541 | { | ||
3542 | return DVBFE_ALGO_CUSTOM; | ||
3543 | } | ||
3544 | |||
3545 | static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) | ||
3546 | { | ||
3547 | struct stv090x_state *state = fe->demodulator_priv; | ||
3548 | u32 reg, idle = 0, fifo_full = 1; | ||
3549 | int i; | ||
3550 | |||
3551 | reg = STV090x_READ_DEMOD(state, DISTXCTL); | ||
3552 | |||
3553 | STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 2); | ||
3554 | STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); | ||
3555 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3556 | goto err; | ||
3557 | STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0); | ||
3558 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3559 | goto err; | ||
3560 | |||
3561 | STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1); | ||
3562 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3563 | goto err; | ||
3564 | |||
3565 | for (i = 0; i < cmd->msg_len; i++) { | ||
3566 | |||
3567 | while (fifo_full) { | ||
3568 | reg = STV090x_READ_DEMOD(state, DISTXSTATUS); | ||
3569 | fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD); | ||
3570 | } | ||
3571 | |||
3572 | if (STV090x_WRITE_DEMOD(state, DISTXDATA, cmd->msg[i]) < 0) | ||
3573 | goto err; | ||
3574 | } | ||
3575 | reg = STV090x_READ_DEMOD(state, DISTXCTL); | ||
3576 | STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0); | ||
3577 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3578 | goto err; | ||
3579 | |||
3580 | i = 0; | ||
3581 | |||
3582 | while ((!idle) && (i < 10)) { | ||
3583 | reg = STV090x_READ_DEMOD(state, DISTXSTATUS); | ||
3584 | idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD); | ||
3585 | msleep(10); | ||
3586 | i++; | ||
3587 | } | ||
3588 | |||
3589 | return 0; | ||
3590 | err: | ||
3591 | dprintk(FE_ERROR, 1, "I/O error"); | ||
3592 | return -1; | ||
3593 | } | ||
3594 | |||
3595 | static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) | ||
3596 | { | ||
3597 | struct stv090x_state *state = fe->demodulator_priv; | ||
3598 | u32 reg, idle = 0, fifo_full = 1; | ||
3599 | u8 mode, value; | ||
3600 | int i; | ||
3601 | |||
3602 | reg = STV090x_READ_DEMOD(state, DISTXCTL); | ||
3603 | |||
3604 | if (burst == SEC_MINI_A) { | ||
3605 | mode = 3; | ||
3606 | value = 0x00; | ||
3607 | } else { | ||
3608 | mode = 2; | ||
3609 | value = 0xFF; | ||
3610 | } | ||
3611 | |||
3612 | STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, mode); | ||
3613 | STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); | ||
3614 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3615 | goto err; | ||
3616 | STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0); | ||
3617 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3618 | goto err; | ||
3619 | |||
3620 | STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1); | ||
3621 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3622 | goto err; | ||
3623 | |||
3624 | while (fifo_full) { | ||
3625 | reg = STV090x_READ_DEMOD(state, DISTXSTATUS); | ||
3626 | fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD); | ||
3627 | } | ||
3628 | |||
3629 | if (STV090x_WRITE_DEMOD(state, DISTXDATA, value) < 0) | ||
3630 | goto err; | ||
3631 | |||
3632 | reg = STV090x_READ_DEMOD(state, DISTXCTL); | ||
3633 | STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0); | ||
3634 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | ||
3635 | goto err; | ||
3636 | |||
3637 | i = 0; | ||
3638 | |||
3639 | while ((!idle) && (i < 10)) { | ||
3640 | reg = STV090x_READ_DEMOD(state, DISTXSTATUS); | ||
3641 | idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD); | ||
3642 | msleep(10); | ||
3643 | i++; | ||
3644 | } | ||
3645 | |||
3646 | return 0; | ||
3647 | err: | ||
3648 | dprintk(FE_ERROR, 1, "I/O error"); | ||
3649 | return -1; | ||
3650 | } | ||
3651 | |||
3652 | static int stv090x_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply) | ||
3653 | { | ||
3654 | struct stv090x_state *state = fe->demodulator_priv; | ||
3655 | u32 reg = 0, i = 0, rx_end = 0; | ||
3656 | |||
3657 | while ((rx_end != 1) && (i < 10)) { | ||
3658 | msleep(10); | ||
3659 | i++; | ||
3660 | reg = STV090x_READ_DEMOD(state, DISRX_ST0); | ||
3661 | rx_end = STV090x_GETFIELD_Px(reg, RX_END_FIELD); | ||
3662 | } | ||
3663 | |||
3664 | if (rx_end) { | ||
3665 | reply->msg_len = STV090x_GETFIELD_Px(reg, FIFO_BYTENBR_FIELD); | ||
3666 | for (i = 0; i < reply->msg_len; i++) | ||
3667 | reply->msg[i] = STV090x_READ_DEMOD(state, DISRXDATA); | ||
3668 | } | ||
3669 | |||
3670 | return 0; | ||
3671 | } | ||
3672 | |||
3673 | static int stv090x_sleep(struct dvb_frontend *fe) | ||
3674 | { | ||
3675 | struct stv090x_state *state = fe->demodulator_priv; | ||
3676 | u32 reg; | ||
3677 | |||
3678 | dprintk(FE_DEBUG, 1, "Set %s to sleep", | ||
3679 | state->device == STV0900 ? "STV0900" : "STV0903"); | ||
3680 | |||
3681 | reg = stv090x_read_reg(state, STV090x_SYNTCTRL); | ||
3682 | STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01); | ||
3683 | if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) | ||
3684 | goto err; | ||
3685 | |||
3686 | reg = stv090x_read_reg(state, STV090x_TSTTNR1); | ||
3687 | STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); | ||
3688 | if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) | ||
3689 | goto err; | ||
3690 | |||
3691 | return 0; | ||
3692 | err: | ||
3693 | dprintk(FE_ERROR, 1, "I/O error"); | ||
3694 | return -1; | ||
3695 | } | ||
3696 | |||
3697 | static int stv090x_wakeup(struct dvb_frontend *fe) | ||
3698 | { | ||
3699 | struct stv090x_state *state = fe->demodulator_priv; | ||
3700 | u32 reg; | ||
3701 | |||
3702 | dprintk(FE_DEBUG, 1, "Wake %s from standby", | ||
3703 | state->device == STV0900 ? "STV0900" : "STV0903"); | ||
3704 | |||
3705 | reg = stv090x_read_reg(state, STV090x_SYNTCTRL); | ||
3706 | STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00); | ||
3707 | if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) | ||
3708 | goto err; | ||
3709 | |||
3710 | reg = stv090x_read_reg(state, STV090x_TSTTNR1); | ||
3711 | STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1); | ||
3712 | if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) | ||
3713 | goto err; | ||
3714 | |||
3715 | return 0; | ||
3716 | err: | ||
3717 | dprintk(FE_ERROR, 1, "I/O error"); | ||
3718 | return -1; | ||
3719 | } | ||
3720 | |||
3721 | static void stv090x_release(struct dvb_frontend *fe) | ||
3722 | { | ||
3723 | struct stv090x_state *state = fe->demodulator_priv; | ||
3724 | |||
3725 | kfree(state); | ||
3726 | } | ||
3727 | |||
3728 | static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc_mode) | ||
3729 | { | ||
3730 | u32 reg = 0; | ||
3731 | |||
3732 | switch (ldpc_mode) { | ||
3733 | case STV090x_DUAL: | ||
3734 | default: | ||
3735 | if ((state->demod_mode != STV090x_DUAL) || (STV090x_GETFIELD(reg, DDEMOD_FIELD) != 1)) { | ||
3736 | /* set LDPC to dual mode */ | ||
3737 | if (stv090x_write_reg(state, STV090x_GENCFG, 0x1d) < 0) | ||
3738 | goto err; | ||
3739 | |||
3740 | state->demod_mode = STV090x_DUAL; | ||
3741 | |||
3742 | reg = stv090x_read_reg(state, STV090x_TSTRES0); | ||
3743 | STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1); | ||
3744 | if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) | ||
3745 | goto err; | ||
3746 | STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0); | ||
3747 | if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) | ||
3748 | goto err; | ||
3749 | |||
3750 | if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) | ||
3751 | goto err; | ||
3752 | if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0) | ||
3753 | goto err; | ||
3754 | if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0) | ||
3755 | goto err; | ||
3756 | if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0) | ||
3757 | goto err; | ||
3758 | if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0) | ||
3759 | goto err; | ||
3760 | if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0) | ||
3761 | goto err; | ||
3762 | if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0) | ||
3763 | goto err; | ||
3764 | |||
3765 | if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0) | ||
3766 | goto err; | ||
3767 | if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0) | ||
3768 | goto err; | ||
3769 | if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0) | ||
3770 | goto err; | ||
3771 | if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0) | ||
3772 | goto err; | ||
3773 | if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0) | ||
3774 | goto err; | ||
3775 | if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0) | ||
3776 | goto err; | ||
3777 | if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0) | ||
3778 | goto err; | ||
3779 | |||
3780 | if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0) | ||
3781 | goto err; | ||
3782 | if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0) | ||
3783 | goto err; | ||
3784 | } | ||
3785 | break; | ||
3786 | |||
3787 | case STV090x_SINGLE: | ||
3788 | if (stv090x_stop_modcod(state) < 0) | ||
3789 | goto err; | ||
3790 | if (stv090x_activate_modcod_single(state) < 0) | ||
3791 | goto err; | ||
3792 | |||
3793 | if (state->demod == STV090x_DEMODULATOR_1) { | ||
3794 | if (stv090x_write_reg(state, STV090x_GENCFG, 0x06) < 0) /* path 2 */ | ||
3795 | goto err; | ||
3796 | } else { | ||
3797 | if (stv090x_write_reg(state, STV090x_GENCFG, 0x04) < 0) /* path 1 */ | ||
3798 | goto err; | ||
3799 | } | ||
3800 | |||
3801 | reg = stv090x_read_reg(state, STV090x_TSTRES0); | ||
3802 | STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1); | ||
3803 | if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) | ||
3804 | goto err; | ||
3805 | STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0); | ||
3806 | if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) | ||
3807 | goto err; | ||
3808 | |||
3809 | reg = STV090x_READ_DEMOD(state, PDELCTRL1); | ||
3810 | STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x01); | ||
3811 | if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) | ||
3812 | goto err; | ||
3813 | STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x00); | ||
3814 | if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) | ||
3815 | goto err; | ||
3816 | break; | ||
3817 | } | ||
3818 | |||
3819 | return 0; | ||
3820 | err: | ||
3821 | dprintk(FE_ERROR, 1, "I/O error"); | ||
3822 | return -1; | ||
3823 | } | ||
3824 | |||
3825 | /* return (Hz), clk in Hz*/ | ||
3826 | static u32 stv090x_get_mclk(struct stv090x_state *state) | ||
3827 | { | ||
3828 | const struct stv090x_config *config = state->config; | ||
3829 | u32 div, reg; | ||
3830 | u8 ratio; | ||
3831 | |||
3832 | div = stv090x_read_reg(state, STV090x_NCOARSE); | ||
3833 | reg = stv090x_read_reg(state, STV090x_SYNTCTRL); | ||
3834 | ratio = STV090x_GETFIELD(reg, SELX1RATIO_FIELD) ? 4 : 6; | ||
3835 | |||
3836 | return (div + 1) * config->xtal / ratio; /* kHz */ | ||
3837 | } | ||
3838 | |||
3839 | static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk) | ||
3840 | { | ||
3841 | const struct stv090x_config *config = state->config; | ||
3842 | u32 reg, div, clk_sel; | ||
3843 | |||
3844 | reg = stv090x_read_reg(state, STV090x_SYNTCTRL); | ||
3845 | clk_sel = ((STV090x_GETFIELD(reg, SELX1RATIO_FIELD) == 1) ? 4 : 6); | ||
3846 | |||
3847 | div = ((clk_sel * mclk) / config->xtal) - 1; | ||
3848 | |||
3849 | reg = stv090x_read_reg(state, STV090x_NCOARSE); | ||
3850 | STV090x_SETFIELD(reg, M_DIV_FIELD, div); | ||
3851 | if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0) | ||
3852 | goto err; | ||
3853 | |||
3854 | state->mclk = stv090x_get_mclk(state); | ||
3855 | |||
3856 | /*Set the DiseqC frequency to 22KHz */ | ||
3857 | div = state->mclk / 704000; | ||
3858 | if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0) | ||
3859 | goto err; | ||
3860 | if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0) | ||
3861 | goto err; | ||
3862 | |||
3863 | return 0; | ||
3864 | err: | ||
3865 | dprintk(FE_ERROR, 1, "I/O error"); | ||
3866 | return -1; | ||
3867 | } | ||
3868 | |||
3869 | static int stv090x_set_tspath(struct stv090x_state *state) | ||
3870 | { | ||
3871 | u32 reg; | ||
3872 | |||
3873 | if (state->dev_ver >= 0x20) { | ||
3874 | switch (state->config->ts1_mode) { | ||
3875 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||
3876 | case STV090x_TSMODE_DVBCI: | ||
3877 | switch (state->config->ts2_mode) { | ||
3878 | case STV090x_TSMODE_SERIAL_PUNCTURED: | ||
3879 | case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||
3880 | default: | ||
3881 | stv090x_write_reg(state, STV090x_TSGENERAL, 0x00); | ||
3882 | break; | ||
3883 | |||
3884 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||
3885 | case STV090x_TSMODE_DVBCI: | ||
3886 | if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x06) < 0) /* Mux'd stream mode */ | ||
3887 | goto err; | ||
3888 | reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); | ||
3889 | STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); | ||
3890 | if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) | ||
3891 | goto err; | ||
3892 | reg = stv090x_read_reg(state, STV090x_P2_TSCFGM); | ||
3893 | STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); | ||
3894 | if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0) | ||
3895 | goto err; | ||
3896 | if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0) | ||
3897 | goto err; | ||
3898 | if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0) | ||
3899 | goto err; | ||
3900 | break; | ||
3901 | } | ||
3902 | break; | ||
3903 | |||
3904 | case STV090x_TSMODE_SERIAL_PUNCTURED: | ||
3905 | case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||
3906 | default: | ||
3907 | switch (state->config->ts2_mode) { | ||
3908 | case STV090x_TSMODE_SERIAL_PUNCTURED: | ||
3909 | case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||
3910 | default: | ||
3911 | if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) | ||
3912 | goto err; | ||
3913 | break; | ||
3914 | |||
3915 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||
3916 | case STV090x_TSMODE_DVBCI: | ||
3917 | if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0a) < 0) | ||
3918 | goto err; | ||
3919 | break; | ||
3920 | } | ||
3921 | break; | ||
3922 | } | ||
3923 | } else { | ||
3924 | switch (state->config->ts1_mode) { | ||
3925 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||
3926 | case STV090x_TSMODE_DVBCI: | ||
3927 | switch (state->config->ts2_mode) { | ||
3928 | case STV090x_TSMODE_SERIAL_PUNCTURED: | ||
3929 | case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||
3930 | default: | ||
3931 | stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10); | ||
3932 | break; | ||
3933 | |||
3934 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||
3935 | case STV090x_TSMODE_DVBCI: | ||
3936 | stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16); | ||
3937 | reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); | ||
3938 | STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); | ||
3939 | if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) | ||
3940 | goto err; | ||
3941 | reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); | ||
3942 | STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 0); | ||
3943 | if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) | ||
3944 | goto err; | ||
3945 | if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0) | ||
3946 | goto err; | ||
3947 | if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0) | ||
3948 | goto err; | ||
3949 | break; | ||
3950 | } | ||
3951 | break; | ||
3952 | |||
3953 | case STV090x_TSMODE_SERIAL_PUNCTURED: | ||
3954 | case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||
3955 | default: | ||
3956 | switch (state->config->ts2_mode) { | ||
3957 | case STV090x_TSMODE_SERIAL_PUNCTURED: | ||
3958 | case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||
3959 | default: | ||
3960 | stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14); | ||
3961 | break; | ||
3962 | |||
3963 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||
3964 | case STV090x_TSMODE_DVBCI: | ||
3965 | stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12); | ||
3966 | break; | ||
3967 | } | ||
3968 | break; | ||
3969 | } | ||
3970 | } | ||
3971 | |||
3972 | switch (state->config->ts1_mode) { | ||
3973 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||
3974 | reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); | ||
3975 | STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); | ||
3976 | STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); | ||
3977 | if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||
3978 | goto err; | ||
3979 | break; | ||
3980 | |||
3981 | case STV090x_TSMODE_DVBCI: | ||
3982 | reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); | ||
3983 | STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); | ||
3984 | STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); | ||
3985 | if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||
3986 | goto err; | ||
3987 | break; | ||
3988 | |||
3989 | case STV090x_TSMODE_SERIAL_PUNCTURED: | ||
3990 | reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); | ||
3991 | STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); | ||
3992 | STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); | ||
3993 | if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||
3994 | goto err; | ||
3995 | break; | ||
3996 | |||
3997 | case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||
3998 | reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); | ||
3999 | STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); | ||
4000 | STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); | ||
4001 | if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||
4002 | goto err; | ||
4003 | break; | ||
4004 | |||
4005 | default: | ||
4006 | break; | ||
4007 | } | ||
4008 | |||
4009 | switch (state->config->ts2_mode) { | ||
4010 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||
4011 | reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); | ||
4012 | STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); | ||
4013 | STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); | ||
4014 | if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) | ||
4015 | goto err; | ||
4016 | break; | ||
4017 | |||
4018 | case STV090x_TSMODE_DVBCI: | ||
4019 | reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); | ||
4020 | STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); | ||
4021 | STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); | ||
4022 | if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) | ||
4023 | goto err; | ||
4024 | break; | ||
4025 | |||
4026 | case STV090x_TSMODE_SERIAL_PUNCTURED: | ||
4027 | reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); | ||
4028 | STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); | ||
4029 | STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); | ||
4030 | if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) | ||
4031 | goto err; | ||
4032 | break; | ||
4033 | |||
4034 | case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||
4035 | reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); | ||
4036 | STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); | ||
4037 | STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); | ||
4038 | if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) | ||
4039 | goto err; | ||
4040 | break; | ||
4041 | |||
4042 | default: | ||
4043 | break; | ||
4044 | } | ||
4045 | reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); | ||
4046 | STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); | ||
4047 | if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) | ||
4048 | goto err; | ||
4049 | STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00); | ||
4050 | if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) | ||
4051 | goto err; | ||
4052 | |||
4053 | reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); | ||
4054 | STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); | ||
4055 | if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||
4056 | goto err; | ||
4057 | STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00); | ||
4058 | if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||
4059 | goto err; | ||
4060 | |||
4061 | return 0; | ||
4062 | err: | ||
4063 | dprintk(FE_ERROR, 1, "I/O error"); | ||
4064 | return -1; | ||
4065 | } | ||
4066 | |||
4067 | static int stv090x_init(struct dvb_frontend *fe) | ||
4068 | { | ||
4069 | struct stv090x_state *state = fe->demodulator_priv; | ||
4070 | const struct stv090x_config *config = state->config; | ||
4071 | u32 reg; | ||
4072 | |||
4073 | if (stv090x_wakeup(fe) < 0) { | ||
4074 | dprintk(FE_ERROR, 1, "Error waking device"); | ||
4075 | goto err; | ||
4076 | } | ||
4077 | |||
4078 | if (stv090x_ldpc_mode(state, state->demod_mode) < 0) | ||
4079 | goto err; | ||
4080 | |||
4081 | reg = STV090x_READ_DEMOD(state, TNRCFG2); | ||
4082 | STV090x_SETFIELD_Px(reg, TUN_IQSWAP_FIELD, state->inversion); | ||
4083 | if (STV090x_WRITE_DEMOD(state, TNRCFG2, reg) < 0) | ||
4084 | goto err; | ||
4085 | reg = STV090x_READ_DEMOD(state, DEMOD); | ||
4086 | STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff); | ||
4087 | if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) | ||
4088 | goto err; | ||
4089 | |||
4090 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
4091 | goto err; | ||
4092 | |||
4093 | if (config->tuner_set_mode) { | ||
4094 | if (config->tuner_set_mode(fe, TUNER_WAKE) < 0) | ||
4095 | goto err; | ||
4096 | } | ||
4097 | |||
4098 | if (config->tuner_init) { | ||
4099 | if (config->tuner_init(fe) < 0) | ||
4100 | goto err; | ||
4101 | } | ||
4102 | |||
4103 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
4104 | goto err; | ||
4105 | |||
4106 | if (stv090x_set_tspath(state) < 0) | ||
4107 | goto err; | ||
4108 | |||
4109 | return 0; | ||
4110 | err: | ||
4111 | dprintk(FE_ERROR, 1, "I/O error"); | ||
4112 | return -1; | ||
4113 | } | ||
4114 | |||
4115 | static int stv090x_setup(struct dvb_frontend *fe) | ||
4116 | { | ||
4117 | struct stv090x_state *state = fe->demodulator_priv; | ||
4118 | const struct stv090x_config *config = state->config; | ||
4119 | const struct stv090x_reg *stv090x_initval = NULL; | ||
4120 | const struct stv090x_reg *stv090x_cut20_val = NULL; | ||
4121 | unsigned long t1_size = 0, t2_size = 0; | ||
4122 | u32 reg = 0; | ||
4123 | |||
4124 | int i; | ||
4125 | |||
4126 | if (state->device == STV0900) { | ||
4127 | dprintk(FE_DEBUG, 1, "Initializing STV0900"); | ||
4128 | stv090x_initval = stv0900_initval; | ||
4129 | t1_size = ARRAY_SIZE(stv0900_initval); | ||
4130 | stv090x_cut20_val = stv0900_cut20_val; | ||
4131 | t2_size = ARRAY_SIZE(stv0900_cut20_val); | ||
4132 | } else if (state->device == STV0903) { | ||
4133 | dprintk(FE_DEBUG, 1, "Initializing STV0903"); | ||
4134 | stv090x_initval = stv0903_initval; | ||
4135 | t1_size = ARRAY_SIZE(stv0903_initval); | ||
4136 | stv090x_cut20_val = stv0903_cut20_val; | ||
4137 | t2_size = ARRAY_SIZE(stv0903_cut20_val); | ||
4138 | } | ||
4139 | |||
4140 | /* STV090x init */ | ||
4141 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Stop Demod */ | ||
4142 | goto err; | ||
4143 | |||
4144 | msleep(5); | ||
4145 | |||
4146 | if (STV090x_WRITE_DEMOD(state, TNRCFG, 0x6c) < 0) /* check register ! (No Tuner Mode) */ | ||
4147 | goto err; | ||
4148 | |||
4149 | STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); | ||
4150 | if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) /* repeater OFF */ | ||
4151 | goto err; | ||
4152 | |||
4153 | if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */ | ||
4154 | goto err; | ||
4155 | msleep(5); | ||
4156 | if (stv090x_write_reg(state, STV090x_I2CCFG, 0x08) < 0) /* 1/41 oversampling */ | ||
4157 | goto err; | ||
4158 | if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) /* enable PLL */ | ||
4159 | goto err; | ||
4160 | msleep(5); | ||
4161 | |||
4162 | /* write initval */ | ||
4163 | dprintk(FE_DEBUG, 1, "Setting up initial values"); | ||
4164 | for (i = 0; i < t1_size; i++) { | ||
4165 | if (stv090x_write_reg(state, stv090x_initval[i].addr, stv090x_initval[i].data) < 0) | ||
4166 | goto err; | ||
4167 | } | ||
4168 | |||
4169 | state->dev_ver = stv090x_read_reg(state, STV090x_MID); | ||
4170 | if (state->dev_ver >= 0x20) { | ||
4171 | if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) | ||
4172 | goto err; | ||
4173 | |||
4174 | /* write cut20_val*/ | ||
4175 | dprintk(FE_DEBUG, 1, "Setting up Cut 2.0 initial values"); | ||
4176 | for (i = 0; i < t2_size; i++) { | ||
4177 | if (stv090x_write_reg(state, stv090x_cut20_val[i].addr, stv090x_cut20_val[i].data) < 0) | ||
4178 | goto err; | ||
4179 | } | ||
4180 | |||
4181 | } else if (state->dev_ver < 0x20) { | ||
4182 | dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!", | ||
4183 | state->dev_ver); | ||
4184 | |||
4185 | goto err; | ||
4186 | } else if (state->dev_ver > 0x30) { | ||
4187 | /* we shouldn't bail out from here */ | ||
4188 | dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!", | ||
4189 | state->dev_ver); | ||
4190 | } | ||
4191 | |||
4192 | if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0) | ||
4193 | goto err; | ||
4194 | if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) | ||
4195 | goto err; | ||
4196 | |||
4197 | stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */ | ||
4198 | msleep(5); | ||
4199 | if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) | ||
4200 | goto err; | ||
4201 | stv090x_get_mclk(state); | ||
4202 | |||
4203 | return 0; | ||
4204 | err: | ||
4205 | dprintk(FE_ERROR, 1, "I/O error"); | ||
4206 | return -1; | ||
4207 | } | ||
4208 | |||
4209 | static struct dvb_frontend_ops stv090x_ops = { | ||
4210 | |||
4211 | .info = { | ||
4212 | .name = "STV090x Multistandard", | ||
4213 | .type = FE_QPSK, | ||
4214 | .frequency_min = 950000, | ||
4215 | .frequency_max = 2150000, | ||
4216 | .frequency_stepsize = 0, | ||
4217 | .frequency_tolerance = 0, | ||
4218 | .symbol_rate_min = 1000000, | ||
4219 | .symbol_rate_max = 45000000, | ||
4220 | .caps = FE_CAN_INVERSION_AUTO | | ||
4221 | FE_CAN_FEC_AUTO | | ||
4222 | FE_CAN_QPSK | | ||
4223 | FE_CAN_2G_MODULATION | ||
4224 | }, | ||
4225 | |||
4226 | .release = stv090x_release, | ||
4227 | .init = stv090x_init, | ||
4228 | |||
4229 | .sleep = stv090x_sleep, | ||
4230 | .get_frontend_algo = stv090x_frontend_algo, | ||
4231 | |||
4232 | .i2c_gate_ctrl = stv090x_i2c_gate_ctrl, | ||
4233 | |||
4234 | .diseqc_send_master_cmd = stv090x_send_diseqc_msg, | ||
4235 | .diseqc_send_burst = stv090x_send_diseqc_burst, | ||
4236 | .diseqc_recv_slave_reply = stv090x_recv_slave_reply, | ||
4237 | .set_tone = stv090x_set_tone, | ||
4238 | |||
4239 | .search = stv090x_search, | ||
4240 | .read_status = stv090x_read_status, | ||
4241 | .read_ber = stv090x_read_per, | ||
4242 | .read_signal_strength = stv090x_read_signal_strength, | ||
4243 | .read_snr = stv090x_read_cnr | ||
4244 | }; | ||
4245 | |||
4246 | |||
4247 | struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | ||
4248 | struct i2c_adapter *i2c, | ||
4249 | enum stv090x_demodulator demod) | ||
4250 | { | ||
4251 | struct stv090x_state *state = NULL; | ||
4252 | |||
4253 | state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL); | ||
4254 | if (state == NULL) | ||
4255 | goto error; | ||
4256 | |||
4257 | state->verbose = &verbose; | ||
4258 | state->config = config; | ||
4259 | state->i2c = i2c; | ||
4260 | state->frontend.ops = stv090x_ops; | ||
4261 | state->frontend.demodulator_priv = state; | ||
4262 | state->demod = demod; | ||
4263 | state->demod_mode = config->demod_mode; /* Single or Dual mode */ | ||
4264 | state->device = config->device; | ||
4265 | state->rolloff = STV090x_RO_35; /* default */ | ||
4266 | |||
4267 | if (state->demod == STV090x_DEMODULATOR_0) | ||
4268 | mutex_init(&demod_lock); | ||
4269 | |||
4270 | if (stv090x_sleep(&state->frontend) < 0) { | ||
4271 | dprintk(FE_ERROR, 1, "Error putting device to sleep"); | ||
4272 | goto error; | ||
4273 | } | ||
4274 | |||
4275 | if (stv090x_setup(&state->frontend) < 0) { | ||
4276 | dprintk(FE_ERROR, 1, "Error setting up device"); | ||
4277 | goto error; | ||
4278 | } | ||
4279 | if (stv090x_wakeup(&state->frontend) < 0) { | ||
4280 | dprintk(FE_ERROR, 1, "Error waking device"); | ||
4281 | goto error; | ||
4282 | } | ||
4283 | |||
4284 | dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x\n", | ||
4285 | state->device == STV0900 ? "STV0900" : "STV0903", | ||
4286 | demod, | ||
4287 | state->dev_ver); | ||
4288 | |||
4289 | return &state->frontend; | ||
4290 | |||
4291 | error: | ||
4292 | kfree(state); | ||
4293 | return NULL; | ||
4294 | } | ||
4295 | EXPORT_SYMBOL(stv090x_attach); | ||
4296 | MODULE_PARM_DESC(verbose, "Set Verbosity level"); | ||
4297 | MODULE_AUTHOR("Manu Abraham"); | ||
4298 | MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend"); | ||
4299 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h new file mode 100644 index 000000000000..e968c98bb70f --- /dev/null +++ b/drivers/media/dvb/frontends/stv090x.h | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | STV0900/0903 Multistandard Broadcast Frontend driver | ||
3 | Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||
4 | |||
5 | Copyright (C) ST Microelectronics | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (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 General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __STV090x_H | ||
23 | #define __STV090x_H | ||
24 | |||
25 | enum stv090x_demodulator { | ||
26 | STV090x_DEMODULATOR_0 = 1, | ||
27 | STV090x_DEMODULATOR_1 | ||
28 | }; | ||
29 | |||
30 | enum stv090x_device { | ||
31 | STV0903 = 0, | ||
32 | STV0900, | ||
33 | }; | ||
34 | |||
35 | enum stv090x_mode { | ||
36 | STV090x_DUAL = 0, | ||
37 | STV090x_SINGLE | ||
38 | }; | ||
39 | |||
40 | enum stv090x_tsmode { | ||
41 | STV090x_TSMODE_SERIAL_PUNCTURED = 1, | ||
42 | STV090x_TSMODE_SERIAL_CONTINUOUS, | ||
43 | STV090x_TSMODE_PARALLEL_PUNCTURED, | ||
44 | STV090x_TSMODE_DVBCI | ||
45 | }; | ||
46 | |||
47 | enum stv090x_clkmode { | ||
48 | STV090x_CLK_INT = 0, /* Clk i/p = CLKI */ | ||
49 | STV090x_CLK_EXT = 2 /* Clk i/p = XTALI */ | ||
50 | }; | ||
51 | |||
52 | enum stv090x_i2crpt { | ||
53 | STV090x_RPTLEVEL_256 = 0, | ||
54 | STV090x_RPTLEVEL_128 = 1, | ||
55 | STV090x_RPTLEVEL_64 = 2, | ||
56 | STV090x_RPTLEVEL_32 = 3, | ||
57 | STV090x_RPTLEVEL_16 = 4, | ||
58 | STV090x_RPTLEVEL_8 = 5, | ||
59 | STV090x_RPTLEVEL_4 = 6, | ||
60 | STV090x_RPTLEVEL_2 = 7, | ||
61 | }; | ||
62 | |||
63 | struct stv090x_config { | ||
64 | enum stv090x_device device; | ||
65 | enum stv090x_mode demod_mode; | ||
66 | enum stv090x_clkmode clk_mode; | ||
67 | |||
68 | u32 xtal; /* default: 8000000 */ | ||
69 | u8 address; /* default: 0x68 */ | ||
70 | |||
71 | u32 ref_clk; /* default: 16000000 FIXME to tuner config */ | ||
72 | |||
73 | u8 ts1_mode; | ||
74 | u8 ts2_mode; | ||
75 | |||
76 | enum stv090x_i2crpt repeater_level; | ||
77 | |||
78 | int (*tuner_init) (struct dvb_frontend *fe); | ||
79 | int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); | ||
80 | int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); | ||
81 | int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency); | ||
82 | int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth); | ||
83 | int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth); | ||
84 | int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain); | ||
85 | int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain); | ||
86 | int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk); | ||
87 | int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status); | ||
88 | }; | ||
89 | |||
90 | #if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE)) | ||
91 | |||
92 | extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | ||
93 | struct i2c_adapter *i2c, | ||
94 | enum stv090x_demodulator demod); | ||
95 | #else | ||
96 | |||
97 | static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | ||
98 | struct i2c_adapter *i2c, | ||
99 | enum stv090x_demodulator demod) | ||
100 | { | ||
101 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
102 | return NULL; | ||
103 | } | ||
104 | #endif /* CONFIG_DVB_STV090x */ | ||
105 | |||
106 | #endif /* __STV090x_H */ | ||
diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h new file mode 100644 index 000000000000..5a4a01740d88 --- /dev/null +++ b/drivers/media/dvb/frontends/stv090x_priv.h | |||
@@ -0,0 +1,269 @@ | |||
1 | /* | ||
2 | STV0900/0903 Multistandard Broadcast Frontend driver | ||
3 | Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||
4 | |||
5 | Copyright (C) ST Microelectronics | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (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 General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __STV090x_PRIV_H | ||
23 | #define __STV090x_PRIV_H | ||
24 | |||
25 | #include "dvb_frontend.h" | ||
26 | |||
27 | #define FE_ERROR 0 | ||
28 | #define FE_NOTICE 1 | ||
29 | #define FE_INFO 2 | ||
30 | #define FE_DEBUG 3 | ||
31 | #define FE_DEBUGREG 4 | ||
32 | |||
33 | #define dprintk(__y, __z, format, arg...) do { \ | ||
34 | if (__z) { \ | ||
35 | if ((verbose > FE_ERROR) && (verbose > __y)) \ | ||
36 | printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ | ||
37 | else if ((verbose > FE_NOTICE) && (verbose > __y)) \ | ||
38 | printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ | ||
39 | else if ((verbose > FE_INFO) && (verbose > __y)) \ | ||
40 | printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ | ||
41 | else if ((verbose > FE_DEBUG) && (verbose > __y)) \ | ||
42 | printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ | ||
43 | } else { \ | ||
44 | if (verbose > __y) \ | ||
45 | printk(format, ##arg); \ | ||
46 | } \ | ||
47 | } while (0) | ||
48 | |||
49 | #define STV090x_READ_DEMOD(__state, __reg) (( \ | ||
50 | (__state)->demod == STV090x_DEMODULATOR_1) ? \ | ||
51 | stv090x_read_reg(__state, STV090x_P2_##__reg) : \ | ||
52 | stv090x_read_reg(__state, STV090x_P1_##__reg)) | ||
53 | |||
54 | #define STV090x_WRITE_DEMOD(__state, __reg, __data) (( \ | ||
55 | (__state)->demod == STV090x_DEMODULATOR_1) ? \ | ||
56 | stv090x_write_reg(__state, STV090x_P2_##__reg, __data) :\ | ||
57 | stv090x_write_reg(__state, STV090x_P1_##__reg, __data)) | ||
58 | |||
59 | #define STV090x_ADDR_OFFST(__state, __x) (( \ | ||
60 | (__state->demod) == STV090x_DEMODULATOR_1) ? \ | ||
61 | STV090x_P1_##__x : \ | ||
62 | STV090x_P2_##__x) | ||
63 | |||
64 | |||
65 | #define STV090x_SETFIELD(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_##bitf) - 1) <<\ | ||
66 | STV090x_OFFST_##bitf))) | \ | ||
67 | (val << STV090x_OFFST_##bitf)) | ||
68 | |||
69 | #define STV090x_GETFIELD(val, bitf) ((val >> STV090x_OFFST_##bitf) & ((1 << STV090x_WIDTH_##bitf) - 1)) | ||
70 | |||
71 | |||
72 | #define STV090x_SETFIELD_Px(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_Px_##bitf) - 1) <<\ | ||
73 | STV090x_OFFST_Px_##bitf))) | \ | ||
74 | (val << STV090x_OFFST_Px_##bitf)) | ||
75 | |||
76 | #define STV090x_GETFIELD_Px(val, bitf) ((val >> STV090x_OFFST_Px_##bitf) & ((1 << STV090x_WIDTH_Px_##bitf) - 1)) | ||
77 | |||
78 | #define MAKEWORD16(__a, __b) (((__a) << 8) | (__b)) | ||
79 | |||
80 | #define MSB(__x) ((__x >> 8) & 0xff) | ||
81 | #define LSB(__x) (__x & 0xff) | ||
82 | |||
83 | |||
84 | #define STV090x_IQPOWER_THRESHOLD 30 | ||
85 | #define STV090x_SEARCH_AGC2_TH_CUT20 700 | ||
86 | #define STV090x_SEARCH_AGC2_TH_CUT30 1200 | ||
87 | |||
88 | #define STV090x_SEARCH_AGC2_TH(__ver) \ | ||
89 | ((__ver <= 0x20) ? \ | ||
90 | STV090x_SEARCH_AGC2_TH_CUT20 : \ | ||
91 | STV090x_SEARCH_AGC2_TH_CUT30) | ||
92 | |||
93 | enum stv090x_signal_state { | ||
94 | STV090x_NOCARRIER, | ||
95 | STV090x_NODATA, | ||
96 | STV090x_DATAOK, | ||
97 | STV090x_RANGEOK, | ||
98 | STV090x_OUTOFRANGE | ||
99 | }; | ||
100 | |||
101 | enum stv090x_fec { | ||
102 | STV090x_PR12 = 0, | ||
103 | STV090x_PR23, | ||
104 | STV090x_PR34, | ||
105 | STV090x_PR45, | ||
106 | STV090x_PR56, | ||
107 | STV090x_PR67, | ||
108 | STV090x_PR78, | ||
109 | STV090x_PR89, | ||
110 | STV090x_PR910, | ||
111 | STV090x_PRERR | ||
112 | }; | ||
113 | |||
114 | enum stv090x_modulation { | ||
115 | STV090x_QPSK, | ||
116 | STV090x_8PSK, | ||
117 | STV090x_16APSK, | ||
118 | STV090x_32APSK, | ||
119 | STV090x_UNKNOWN | ||
120 | }; | ||
121 | |||
122 | enum stv090x_frame { | ||
123 | STV090x_LONG_FRAME, | ||
124 | STV090x_SHORT_FRAME | ||
125 | }; | ||
126 | |||
127 | enum stv090x_pilot { | ||
128 | STV090x_PILOTS_OFF, | ||
129 | STV090x_PILOTS_ON | ||
130 | }; | ||
131 | |||
132 | enum stv090x_rolloff { | ||
133 | STV090x_RO_35, | ||
134 | STV090x_RO_25, | ||
135 | STV090x_RO_20 | ||
136 | }; | ||
137 | |||
138 | enum stv090x_inversion { | ||
139 | STV090x_IQ_AUTO, | ||
140 | STV090x_IQ_NORMAL, | ||
141 | STV090x_IQ_SWAP | ||
142 | }; | ||
143 | |||
144 | enum stv090x_modcod { | ||
145 | STV090x_DUMMY_PLF = 0, | ||
146 | STV090x_QPSK_14, | ||
147 | STV090x_QPSK_13, | ||
148 | STV090x_QPSK_25, | ||
149 | STV090x_QPSK_12, | ||
150 | STV090x_QPSK_35, | ||
151 | STV090x_QPSK_23, | ||
152 | STV090x_QPSK_34, | ||
153 | STV090x_QPSK_45, | ||
154 | STV090x_QPSK_56, | ||
155 | STV090x_QPSK_89, | ||
156 | STV090x_QPSK_910, | ||
157 | STV090x_8PSK_35, | ||
158 | STV090x_8PSK_23, | ||
159 | STV090x_8PSK_34, | ||
160 | STV090x_8PSK_56, | ||
161 | STV090x_8PSK_89, | ||
162 | STV090x_8PSK_910, | ||
163 | STV090x_16APSK_23, | ||
164 | STV090x_16APSK_34, | ||
165 | STV090x_16APSK_45, | ||
166 | STV090x_16APSK_56, | ||
167 | STV090x_16APSK_89, | ||
168 | STV090x_16APSK_910, | ||
169 | STV090x_32APSK_34, | ||
170 | STV090x_32APSK_45, | ||
171 | STV090x_32APSK_56, | ||
172 | STV090x_32APSK_89, | ||
173 | STV090x_32APSK_910, | ||
174 | STV090x_MODCODE_UNKNOWN | ||
175 | }; | ||
176 | |||
177 | enum stv090x_search { | ||
178 | STV090x_SEARCH_DSS = 0, | ||
179 | STV090x_SEARCH_DVBS1, | ||
180 | STV090x_SEARCH_DVBS2, | ||
181 | STV090x_SEARCH_AUTO | ||
182 | }; | ||
183 | |||
184 | enum stv090x_algo { | ||
185 | STV090x_BLIND_SEARCH, | ||
186 | STV090x_COLD_SEARCH, | ||
187 | STV090x_WARM_SEARCH | ||
188 | }; | ||
189 | |||
190 | enum stv090x_delsys { | ||
191 | STV090x_ERROR = 0, | ||
192 | STV090x_DVBS1 = 1, | ||
193 | STV090x_DVBS2, | ||
194 | STV090x_DSS | ||
195 | }; | ||
196 | |||
197 | struct stv090x_long_frame_crloop { | ||
198 | enum stv090x_modcod modcod; | ||
199 | |||
200 | u8 crl_pilots_on_2; | ||
201 | u8 crl_pilots_off_2; | ||
202 | u8 crl_pilots_on_5; | ||
203 | u8 crl_pilots_off_5; | ||
204 | u8 crl_pilots_on_10; | ||
205 | u8 crl_pilots_off_10; | ||
206 | u8 crl_pilots_on_20; | ||
207 | u8 crl_pilots_off_20; | ||
208 | u8 crl_pilots_on_30; | ||
209 | u8 crl_pilots_off_30; | ||
210 | }; | ||
211 | |||
212 | struct stv090x_short_frame_crloop { | ||
213 | enum stv090x_modulation modulation; | ||
214 | |||
215 | u8 crl_2; /* SR < 3M */ | ||
216 | u8 crl_5; /* 3 < SR <= 7M */ | ||
217 | u8 crl_10; /* 7 < SR <= 15M */ | ||
218 | u8 crl_20; /* 10 < SR <= 25M */ | ||
219 | u8 crl_30; /* 10 < SR <= 45M */ | ||
220 | }; | ||
221 | |||
222 | struct stv090x_reg { | ||
223 | u16 addr; | ||
224 | u8 data; | ||
225 | }; | ||
226 | |||
227 | struct stv090x_tab { | ||
228 | s32 real; | ||
229 | s32 read; | ||
230 | }; | ||
231 | |||
232 | struct stv090x_state { | ||
233 | enum stv090x_device device; | ||
234 | enum stv090x_demodulator demod; | ||
235 | enum stv090x_mode demod_mode; | ||
236 | u32 dev_ver; | ||
237 | |||
238 | struct i2c_adapter *i2c; | ||
239 | const struct stv090x_config *config; | ||
240 | struct dvb_frontend frontend; | ||
241 | |||
242 | u32 *verbose; /* Cached module verbosity */ | ||
243 | |||
244 | enum stv090x_delsys delsys; | ||
245 | enum stv090x_fec fec; | ||
246 | enum stv090x_modulation modulation; | ||
247 | enum stv090x_modcod modcod; | ||
248 | enum stv090x_search search_mode; | ||
249 | enum stv090x_frame frame_len; | ||
250 | enum stv090x_pilot pilots; | ||
251 | enum stv090x_rolloff rolloff; | ||
252 | enum stv090x_inversion inversion; | ||
253 | enum stv090x_algo algo; | ||
254 | |||
255 | u32 frequency; | ||
256 | u32 srate; | ||
257 | |||
258 | s32 mclk; /* Masterclock Divider factor */ | ||
259 | s32 tuner_bw; | ||
260 | |||
261 | u32 tuner_refclk; | ||
262 | |||
263 | s32 search_range; | ||
264 | |||
265 | s32 DemodTimeout; | ||
266 | s32 FecTimeout; | ||
267 | }; | ||
268 | |||
269 | #endif /* __STV090x_PRIV_H */ | ||
diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h new file mode 100644 index 000000000000..57b6abbbd32d --- /dev/null +++ b/drivers/media/dvb/frontends/stv090x_reg.h | |||
@@ -0,0 +1,2373 @@ | |||
1 | /* | ||
2 | STV0900/0903 Multistandard Broadcast Frontend driver | ||
3 | Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||
4 | |||
5 | Copyright (C) ST Microelectronics | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (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 General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __STV090x_REG_H | ||
23 | #define __STV090x_REG_H | ||
24 | |||
25 | #define STV090x_MID 0xf100 | ||
26 | #define STV090x_OFFST_MCHIP_IDENT_FIELD 4 | ||
27 | #define STV090x_WIDTH_MCHIP_IDENT_FIELD 4 | ||
28 | #define STV090x_OFFST_MRELEASE_FIELD 0 | ||
29 | #define STV090x_WIDTH_MRELEASE_FIELD 4 | ||
30 | |||
31 | #define STV090x_DACR1 0xf113 | ||
32 | #define STV090x_OFFST_DACR1_MODE_FIELD 5 | ||
33 | #define STV090x_WIDTH_DACR1_MODE_FIELD 3 | ||
34 | #define STV090x_OFFST_DACR1_VALUE_FIELD 0 | ||
35 | #define STV090x_WIDTH_DACR1_VALUE_FIELD 4 | ||
36 | |||
37 | #define STV090x_DACR2 0xf114 | ||
38 | #define STV090x_OFFST_DACR2_VALUE_FIELD 0 | ||
39 | #define STV090x_WIDTH_DACR2_VALUE_FIELD 8 | ||
40 | |||
41 | #define STV090x_OUTCFG 0xf11c | ||
42 | #define STV090x_OFFST_OUTSERRS1_HZ_FIELD 6 | ||
43 | #define STV090x_WIDTH_OUTSERRS1_HZ_FIELD 1 | ||
44 | #define STV090x_OFFST_OUTSERRS2_HZ_FIELD 5 | ||
45 | #define STV090x_WIDTH_OUTSERRS2_HZ_FIELD 1 | ||
46 | #define STV090x_OFFST_OUTSERRS3_HZ_FIELD 4 | ||
47 | #define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1 | ||
48 | #define STV090x_OFFST_OUTPARRS3_HZ_FIELD 3 | ||
49 | #define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1 | ||
50 | |||
51 | #define STV090x_MODECFG 0xf11d | ||
52 | |||
53 | #define STV090x_IRQSTATUS3 0xf120 | ||
54 | #define STV090x_OFFST_SPLL_LOCK_FIELD 5 | ||
55 | #define STV090x_WIDTH_SPLL_LOCK_FIELD 1 | ||
56 | #define STV090x_OFFST_SSTREAM_LCK_3_FIELD 4 | ||
57 | #define STV090x_WIDTH_SSTREAM_LCK_3_FIELD 1 | ||
58 | #define STV090x_OFFST_SSTREAM_LCK_2_FIELD 3 | ||
59 | #define STV090x_WIDTH_SSTREAM_LCK_2_FIELD 1 | ||
60 | #define STV090x_OFFST_SSTREAM_LCK_1_FIELD 2 | ||
61 | #define STV090x_WIDTH_SSTREAM_LCK_1_FIELD 1 | ||
62 | #define STV090x_OFFST_SDVBS1_PRF_2_FIELD 1 | ||
63 | #define STV090x_WIDTH_SDVBS1_PRF_2_FIELD 1 | ||
64 | #define STV090x_OFFST_SDVBS1_PRF_1_FIELD 0 | ||
65 | #define STV090x_WIDTH_SDVBS1_PRF_1_FIELD 1 | ||
66 | |||
67 | #define STV090x_IRQSTATUS2 0xf121 | ||
68 | #define STV090x_OFFST_SSPY_ENDSIM_3_FIELD 7 | ||
69 | #define STV090x_WIDTH_SSPY_ENDSIM_3_FIELD 1 | ||
70 | #define STV090x_OFFST_SSPY_ENDSIM_2_FIELD 6 | ||
71 | #define STV090x_WIDTH_SSPY_ENDSIM_2_FIELD 1 | ||
72 | #define STV090x_OFFST_SSPY_ENDSIM_1_FIELD 5 | ||
73 | #define STV090x_WIDTH_SSPY_ENDSIM_1_FIELD 1 | ||
74 | #define STV090x_OFFST_SPKTDEL_ERROR_2_FIELD 4 | ||
75 | #define STV090x_WIDTH_SPKTDEL_ERROR_2_FIELD 1 | ||
76 | #define STV090x_OFFST_SPKTDEL_LOCKB_2_FIELD 3 | ||
77 | #define STV090x_WIDTH_SPKTDEL_LOCKB_2_FIELD 1 | ||
78 | #define STV090x_OFFST_SPKTDEL_LOCK_2_FIELD 2 | ||
79 | #define STV090x_WIDTH_SPKTDEL_LOCK_2_FIELD 1 | ||
80 | #define STV090x_OFFST_SPKTDEL_ERROR_1_FIELD 1 | ||
81 | #define STV090x_WIDTH_SPKTDEL_ERROR_1_FIELD 1 | ||
82 | #define STV090x_OFFST_SPKTDEL_LOCKB_1_FIELD 0 | ||
83 | #define STV090x_WIDTH_SPKTDEL_LOCKB_1_FIELD 1 | ||
84 | |||
85 | #define STV090x_IRQSTATUS1 0xf122 | ||
86 | #define STV090x_OFFST_SPKTDEL_LOCK_1_FIELD 7 | ||
87 | #define STV090x_WIDTH_SPKTDEL_LOCK_1_FIELD 1 | ||
88 | #define STV090x_OFFST_SDEMOD_LOCKB_2_FIELD 2 | ||
89 | #define STV090x_WIDTH_SDEMOD_LOCKB_2_FIELD 1 | ||
90 | #define STV090x_OFFST_SDEMOD_LOCK_2_FIELD 1 | ||
91 | #define STV090x_WIDTH_SDEMOD_LOCK_2_FIELD 1 | ||
92 | #define STV090x_OFFST_SDEMOD_IRQ_2_FIELD 0 | ||
93 | #define STV090x_WIDTH_SDEMOD_IRQ_2_FIELD 1 | ||
94 | |||
95 | #define STV090x_IRQSTATUS0 0xf123 | ||
96 | #define STV090x_OFFST_SDEMOD_LOCKB_1_FIELD 7 | ||
97 | #define STV090x_WIDTH_SDEMOD_LOCKB_1_FIELD 1 | ||
98 | #define STV090x_OFFST_SDEMOD_LOCK_1_FIELD 6 | ||
99 | #define STV090x_WIDTH_SDEMOD_LOCK_1_FIELD 1 | ||
100 | #define STV090x_OFFST_SDEMOD_IRQ_1_FIELD 5 | ||
101 | #define STV090x_WIDTH_SDEMOD_IRQ_1_FIELD 1 | ||
102 | #define STV090x_OFFST_SBCH_ERRFLAG_FIELD 4 | ||
103 | #define STV090x_WIDTH_SBCH_ERRFLAG_FIELD 1 | ||
104 | #define STV090x_OFFST_SDISEQC2RX_IRQ_FIELD 3 | ||
105 | #define STV090x_WIDTH_SDISEQC2RX_IRQ_FIELD 1 | ||
106 | #define STV090x_OFFST_SDISEQC2TX_IRQ_FIELD 2 | ||
107 | #define STV090x_WIDTH_SDISEQC2TX_IRQ_FIELD 1 | ||
108 | #define STV090x_OFFST_SDISEQC1RX_IRQ_FIELD 1 | ||
109 | #define STV090x_WIDTH_SDISEQC1RX_IRQ_FIELD 1 | ||
110 | #define STV090x_OFFST_SDISEQC1TX_IRQ_FIELD 0 | ||
111 | #define STV090x_WIDTH_SDISEQC1TX_IRQ_FIELD 1 | ||
112 | |||
113 | #define STV090x_IRQMASK3 0xf124 | ||
114 | #define STV090x_OFFST_MPLL_LOCK_FIELD 5 | ||
115 | #define STV090x_WIDTH_MPLL_LOCK_FIELD 1 | ||
116 | #define STV090x_OFFST_MSTREAM_LCK_3_FIELD 2 | ||
117 | #define STV090x_WIDTH_MSTREAM_LCK_3_FIELD 3 | ||
118 | #define STV090x_OFFST_MSTREAM_LCK_2_FIELD 2 | ||
119 | #define STV090x_WIDTH_MSTREAM_LCK_2_FIELD 3 | ||
120 | #define STV090x_OFFST_MSTREAM_LCK_1_FIELD 2 | ||
121 | #define STV090x_WIDTH_MSTREAM_LCK_1_FIELD 3 | ||
122 | #define STV090x_OFFST_MDVBS1_PRF_2_FIELD 1 | ||
123 | #define STV090x_WIDTH_MDVBS1_PRF_2_FIELD 1 | ||
124 | #define STV090x_OFFST_MDVBS1_PRF_1_FIELD 0 | ||
125 | #define STV090x_WIDTH_MDVBS1_PRF_1_FIELD 1 | ||
126 | |||
127 | #define STV090x_IRQMASK2 0xf125 | ||
128 | #define STV090x_OFFST_MSPY_ENDSIM_3_FIELD 5 | ||
129 | #define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD 3 | ||
130 | #define STV090x_OFFST_MSPY_ENDSIM_2_FIELD 5 | ||
131 | #define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD 3 | ||
132 | #define STV090x_OFFST_MSPY_ENDSIM_1_FIELD 5 | ||
133 | #define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD 3 | ||
134 | #define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD 4 | ||
135 | #define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD 1 | ||
136 | #define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD 3 | ||
137 | #define STV090x_WIDTH_MPKTDEL_LOCKB_2_FIELD 1 | ||
138 | #define STV090x_OFFST_MPKTDEL_LOCK_2_FIELD 2 | ||
139 | #define STV090x_WIDTH_MPKTDEL_LOCK_2_FIELD 1 | ||
140 | #define STV090x_OFFST_MPKTDEL_ERROR_1_FIELD 1 | ||
141 | #define STV090x_WIDTH_MPKTDEL_ERROR_1_FIELD 1 | ||
142 | #define STV090x_OFFST_MPKTDEL_LOCKB_1_FIELD 0 | ||
143 | #define STV090x_WIDTH_MPKTDEL_LOCKB_1_FIELD 1 | ||
144 | |||
145 | #define STV090x_IRQMASK1 0xf126 | ||
146 | #define STV090x_OFFST_MPKTDEL_LOCK_1_FIELD 7 | ||
147 | #define STV090x_WIDTH_MPKTDEL_LOCK_1_FIELD 1 | ||
148 | #define STV090x_OFFST_MEXTPINB2_FIELD 6 | ||
149 | #define STV090x_WIDTH_MEXTPINB2_FIELD 1 | ||
150 | #define STV090x_OFFST_MEXTPIN2_FIELD 5 | ||
151 | #define STV090x_WIDTH_MEXTPIN2_FIELD 1 | ||
152 | #define STV090x_OFFST_MEXTPINB1_FIELD 4 | ||
153 | #define STV090x_WIDTH_MEXTPINB1_FIELD 1 | ||
154 | #define STV090x_OFFST_MEXTPIN1_FIELD 3 | ||
155 | #define STV090x_WIDTH_MEXTPIN1_FIELD 1 | ||
156 | #define STV090x_OFFST_MDEMOD_LOCKB_2_FIELD 2 | ||
157 | #define STV090x_WIDTH_MDEMOD_LOCKB_2_FIELD 1 | ||
158 | #define STV090x_OFFST_MDEMOD_LOCK_2_FIELD 1 | ||
159 | #define STV090x_WIDTH_MDEMOD_LOCK_2_FIELD 1 | ||
160 | #define STV090x_OFFST_MDEMOD_IRQ_2_FIELD 0 | ||
161 | #define STV090x_WIDTH_MDEMOD_IRQ_2_FIELD 1 | ||
162 | |||
163 | #define STV090x_IRQMASK0 0xf127 | ||
164 | #define STV090x_OFFST_MDEMOD_LOCKB_1_FIELD 7 | ||
165 | #define STV090x_WIDTH_MDEMOD_LOCKB_1_FIELD 1 | ||
166 | #define STV090x_OFFST_MDEMOD_LOCK_1_FIELD 6 | ||
167 | #define STV090x_WIDTH_MDEMOD_LOCK_1_FIELD 1 | ||
168 | #define STV090x_OFFST_MDEMOD_IRQ_1_FIELD 5 | ||
169 | #define STV090x_WIDTH_MDEMOD_IRQ_1_FIELD 1 | ||
170 | #define STV090x_OFFST_MBCH_ERRFLAG_FIELD 4 | ||
171 | #define STV090x_WIDTH_MBCH_ERRFLAG_FIELD 1 | ||
172 | #define STV090x_OFFST_MDISEQC2RX_IRQ_FIELD 3 | ||
173 | #define STV090x_WIDTH_MDISEQC2RX_IRQ_FIELD 1 | ||
174 | #define STV090x_OFFST_MDISEQC2TX_IRQ_FIELD 2 | ||
175 | #define STV090x_WIDTH_MDISEQC2TX_IRQ_FIELD 1 | ||
176 | #define STV090x_OFFST_MDISEQC1RX_IRQ_FIELD 1 | ||
177 | #define STV090x_WIDTH_MDISEQC1RX_IRQ_FIELD 1 | ||
178 | #define STV090x_OFFST_MDISEQC1TX_IRQ_FIELD 0 | ||
179 | #define STV090x_WIDTH_MDISEQC1TX_IRQ_FIELD 1 | ||
180 | |||
181 | #define STV090x_I2CCFG 0xf129 | ||
182 | #define STV090x_OFFST_12C_FASTMODE_FIELD 3 | ||
183 | #define STV090x_WIDTH_12C_FASTMODE_FIELD 1 | ||
184 | #define STV090x_OFFST_12CADDR_INC_FIELD 0 | ||
185 | #define STV090x_WIDTH_12CADDR_INC_FIELD 2 | ||
186 | |||
187 | #define STV090x_Px_I2CRPT(__x) (0xf12a + (__x - 1) * 0x1) | ||
188 | #define STV090x_P1_I2CRPT STV090x_Px_I2CRPT(1) | ||
189 | #define STV090x_P2_I2CRPT STV090x_Px_I2CRPT(2) | ||
190 | #define STV090x_OFFST_Px_I2CT_ON_FIELD 7 | ||
191 | #define STV090x_WIDTH_Px_I2CT_ON_FIELD 1 | ||
192 | #define STV090x_OFFST_Px_ENARPT_LEVEL_FIELD 4 | ||
193 | #define STV090x_WIDTH_Px_ENARPT_LEVEL_FIELD 3 | ||
194 | #define STV090x_OFFST_Px_SCLT_DELAY_FIELD 3 | ||
195 | #define STV090x_WIDTH_Px_SCLT_DELAY_FIELD 1 | ||
196 | #define STV090x_OFFST_Px_STOP_ENABLE_FIELD 2 | ||
197 | #define STV090x_WIDTH_Px_STOP_ENABLE_FIELD 1 | ||
198 | #define STV090x_OFFST_Px_STOP_SDAT2SDA_FIELD 1 | ||
199 | #define STV090x_WIDTH_Px_STOP_SDAT2SDA_FIELD 1 | ||
200 | |||
201 | #define STV090x_CLKI2CFG 0xf140 | ||
202 | #define STV090x_OFFST_CLKI2_OPD_FIELD 7 | ||
203 | #define STV090x_WIDTH_CLKI2_OPD_FIELD 1 | ||
204 | #define STV090x_OFFST_CLKI2_CONFIG_FIELD 1 | ||
205 | #define STV090x_WIDTH_CLKI2_CONFIG_FIELD 6 | ||
206 | #define STV090x_OFFST_CLKI2_XOR_FIELD 0 | ||
207 | #define STV090x_WIDTH_CLKI2_XOR_FIELD 1 | ||
208 | |||
209 | #define STV090x_GPIOxCFG(__x) (0xf141 + (__x - 1)) | ||
210 | #define STV090x_GPIO1CFG STV090x_GPIOxCFG(1) | ||
211 | #define STV090x_GPIO2CFG STV090x_GPIOxCFG(2) | ||
212 | #define STV090x_GPIO3CFG STV090x_GPIOxCFG(3) | ||
213 | #define STV090x_GPIO4CFG STV090x_GPIOxCFG(4) | ||
214 | #define STV090x_GPIO5CFG STV090x_GPIOxCFG(5) | ||
215 | #define STV090x_GPIO6CFG STV090x_GPIOxCFG(6) | ||
216 | #define STV090x_GPIO7CFG STV090x_GPIOxCFG(7) | ||
217 | #define STV090x_GPIO8CFG STV090x_GPIOxCFG(8) | ||
218 | #define STV090x_GPIO9CFG STV090x_GPIOxCFG(9) | ||
219 | #define STV090x_GPIO10CFG STV090x_GPIOxCFG(10) | ||
220 | #define STV090x_GPIO11CFG STV090x_GPIOxCFG(11) | ||
221 | #define STV090x_GPIO12CFG STV090x_GPIOxCFG(12) | ||
222 | #define STV090x_GPIO13CFG STV090x_GPIOxCFG(13) | ||
223 | #define STV090x_OFFST_GPIOx_OPD_FIELD 7 | ||
224 | #define STV090x_WIDTH_GPIOx_OPD_FIELD 1 | ||
225 | #define STV090x_OFFST_GPIOx_CONFIG_FIELD 1 | ||
226 | #define STV090x_WIDTH_GPIOx_CONFIG_FIELD 6 | ||
227 | #define STV090x_OFFST_GPIOx_XOR_FIELD 0 | ||
228 | #define STV090x_WIDTH_GPIOx_XOR_FIELD 1 | ||
229 | |||
230 | #define STV090x_CSxCFG(__x) (0xf14e + __x * 0x1) | ||
231 | #define STV090x_CS0CFG STV090x_CSxCFG(0) | ||
232 | #define STV090x_CS1CFG STV090x_CSxCFG(1) | ||
233 | #define STV090x_OFFST_CSX_OPD_FIELD 7 | ||
234 | #define STV090x_WIDTH_CSX_OPD_FIELD 1 | ||
235 | #define STV090x_OFFST_CSX_CONFIG_FIELD 1 | ||
236 | #define STV090x_WIDTH_CSX_CONFIG_FIELD 6 | ||
237 | #define STV090x_OFFST_CSX_XOR_FIELD 0 | ||
238 | #define STV090x_WIDTH_CSX_XOR_FIELD 1 | ||
239 | |||
240 | |||
241 | #define STV090x_STDBYCFG 0xf150 | ||
242 | #define STV090x_OFFST_STDBY_OPD_FIELD 7 | ||
243 | #define STV090x_WIDTH_STDBY_OPD_FIELD 1 | ||
244 | #define STV090x_OFFST_STDBY_CONFIG_FIELD 1 | ||
245 | #define STV090x_WIDTH_STDBY_CONFIG_FIELD 6 | ||
246 | #define STV090x_OFFST_STDBY_XOR_FIELD 0 | ||
247 | #define STV090x_WIDTH_STDBY_XOR_FIELD 1 | ||
248 | |||
249 | #define STV090x_DIRCLKCFG 0xf151 | ||
250 | #define STV090x_OFFST_DIRCLK_OPD_FIELD 7 | ||
251 | #define STV090x_WIDTH_DIRCLK_OPD_FIELD 1 | ||
252 | #define STV090x_OFFST_DIRCLK_CONFIG_FIELD 1 | ||
253 | #define STV090x_WIDTH_DIRCLK_CONFIG_FIELD 6 | ||
254 | #define STV090x_OFFST_DIRCLK_XOR_FIELD 0 | ||
255 | #define STV090x_WIDTH_DIRCLK_XOR_FIELD 1 | ||
256 | |||
257 | |||
258 | #define STV090x_AGCRFxCFG(__x) (0xf152 + (__x - 1) * 0x4) | ||
259 | #define STV090x_AGCRF1CFG STV090x_AGCRFxCFG(1) | ||
260 | #define STV090x_AGCRF2CFG STV090x_AGCRFxCFG(2) | ||
261 | #define STV090x_OFFST_AGCRFx_OPD_FIELD 7 | ||
262 | #define STV090x_WIDTH_AGCRFx_OPD_FIELD 1 | ||
263 | #define STV090x_OFFST_AGCRFx_CONFIG_FIELD 1 | ||
264 | #define STV090x_WIDTH_AGCRFx_CONFIG_FIELD 6 | ||
265 | #define STV090x_OFFST_AGCRFx_XOR_FIELD 0 | ||
266 | #define STV090x_WIDTH_AGCRFx_XOR_FIELD 1 | ||
267 | |||
268 | #define STV090x_SDATxCFG(__x) (0xf153 + (__x - 1) * 0x4) | ||
269 | #define STV090x_SDAT1CFG STV090x_SDATxCFG(1) | ||
270 | #define STV090x_SDAT2CFG STV090x_SDATxCFG(2) | ||
271 | #define STV090x_OFFST_SDATx_OPD_FIELD 7 | ||
272 | #define STV090x_WIDTH_SDATx_OPD_FIELD 1 | ||
273 | #define STV090x_OFFST_SDATx_CONFIG_FIELD 1 | ||
274 | #define STV090x_WIDTH_SDATx_CONFIG_FIELD 6 | ||
275 | #define STV090x_OFFST_SDATx_XOR_FIELD 0 | ||
276 | #define STV090x_WIDTH_SDATx_XOR_FIELD 1 | ||
277 | |||
278 | #define STV090x_SCLTxCFG(__x) (0xf154 + (__x - 1) * 0x4) | ||
279 | #define STV090x_SCLT1CFG STV090x_SCLTxCFG(1) | ||
280 | #define STV090x_SCLT2CFG STV090x_SCLTxCFG(2) | ||
281 | #define STV090x_OFFST_SCLTx_OPD_FIELD 7 | ||
282 | #define STV090x_WIDTH_SCLTx_OPD_FIELD 1 | ||
283 | #define STV090x_OFFST_SCLTx_CONFIG_FIELD 1 | ||
284 | #define STV090x_WIDTH_SCLTx_CONFIG_FIELD 6 | ||
285 | #define STV090x_OFFST_SCLTx_XOR_FIELD 0 | ||
286 | #define STV090x_WIDTH_SCLTx_XOR_FIELD 1 | ||
287 | |||
288 | #define STV090x_DISEQCOxCFG(__x) (0xf155 + (__x - 1) * 0x4) | ||
289 | #define STV090x_DISEQCO1CFG STV090x_DISEQCOxCFG(1) | ||
290 | #define STV090x_DISEQCO2CFG STV090x_DISEQCOxCFG(2) | ||
291 | #define STV090x_OFFST_DISEQCOx_OPD_FIELD 7 | ||
292 | #define STV090x_WIDTH_DISEQCOx_OPD_FIELD 1 | ||
293 | #define STV090x_OFFST_DISEQCOx_CONFIG_FIELD 1 | ||
294 | #define STV090x_WIDTH_DISEQCOx_CONFIG_FIELD 6 | ||
295 | #define STV090x_OFFST_DISEQCOx_XOR_FIELD 0 | ||
296 | #define STV090x_WIDTH_DISEQCOx_XOR_FIELD 1 | ||
297 | |||
298 | #define STV090x_CLKOUT27CFG 0xf15a | ||
299 | #define STV090x_OFFST_CLKOUT27_OPD_FIELD 7 | ||
300 | #define STV090x_WIDTH_CLKOUT27_OPD_FIELD 1 | ||
301 | #define STV090x_OFFST_CLKOUT27_CONFIG_FIELD 1 | ||
302 | #define STV090x_WIDTH_CLKOUT27_CONFIG_FIELD 6 | ||
303 | #define STV090x_OFFST_CLKOUT27_XOR_FIELD 0 | ||
304 | #define STV090x_WIDTH_CLKOUT27_XOR_FIELD 1 | ||
305 | |||
306 | #define STV090x_ERRORxCFG(__x) (0xf15b + (__x - 1) * 0x5) | ||
307 | #define STV090x_ERROR1CFG STV090x_ERRORxCFG(1) | ||
308 | #define STV090x_ERROR2CFG STV090x_ERRORxCFG(2) | ||
309 | #define STV090x_ERROR3CFG STV090x_ERRORxCFG(3) | ||
310 | #define STV090x_OFFST_ERRORx_OPD_FIELD 7 | ||
311 | #define STV090x_WIDTH_ERRORx_OPD_FIELD 1 | ||
312 | #define STV090x_OFFST_ERRORx_CONFIG_FIELD 1 | ||
313 | #define STV090x_WIDTH_ERRORx_CONFIG_FIELD 6 | ||
314 | #define STV090x_OFFST_ERRORx_XOR_FIELD 0 | ||
315 | #define STV090x_WIDTH_ERRORx_XOR_FIELD 1 | ||
316 | |||
317 | #define STV090x_DPNxCFG(__x) (0xf15c + (__x - 1) * 0x5) | ||
318 | #define STV090x_DPN1CFG STV090x_DPNxCFG(1) | ||
319 | #define STV090x_DPN2CFG STV090x_DPNxCFG(2) | ||
320 | #define STV090x_DPN3CFG STV090x_DPNxCFG(3) | ||
321 | #define STV090x_OFFST_DPNx_OPD_FIELD 7 | ||
322 | #define STV090x_WIDTH_DPNx_OPD_FIELD 1 | ||
323 | #define STV090x_OFFST_DPNx_CONFIG_FIELD 1 | ||
324 | #define STV090x_WIDTH_DPNx_CONFIG_FIELD 6 | ||
325 | #define STV090x_OFFST_DPNx_XOR_FIELD 0 | ||
326 | #define STV090x_WIDTH_DPNx_XOR_FIELD 1 | ||
327 | |||
328 | #define STV090x_STROUTxCFG(__x) (0xf15d + (__x - 1) * 0x5) | ||
329 | #define STV090x_STROUT1CFG STV090x_STROUTxCFG(1) | ||
330 | #define STV090x_STROUT2CFG STV090x_STROUTxCFG(2) | ||
331 | #define STV090x_STROUT3CFG STV090x_STROUTxCFG(3) | ||
332 | #define STV090x_OFFST_STROUTx_OPD_FIELD 7 | ||
333 | #define STV090x_WIDTH_STROUTx_OPD_FIELD 1 | ||
334 | #define STV090x_OFFST_STROUTx_CONFIG_FIELD 1 | ||
335 | #define STV090x_WIDTH_STROUTx_CONFIG_FIELD 6 | ||
336 | #define STV090x_OFFST_STROUTx_XOR_FIELD 0 | ||
337 | #define STV090x_WIDTH_STROUTx_XOR_FIELD 1 | ||
338 | |||
339 | #define STV090x_CLKOUTxCFG(__x) (0xf15e + (__x - 1) * 0x5) | ||
340 | #define STV090x_CLKOUT1CFG STV090x_CLKOUTxCFG(1) | ||
341 | #define STV090x_CLKOUT2CFG STV090x_CLKOUTxCFG(2) | ||
342 | #define STV090x_CLKOUT3CFG STV090x_CLKOUTxCFG(3) | ||
343 | #define STV090x_OFFST_CLKOUTx_OPD_FIELD 7 | ||
344 | #define STV090x_WIDTH_CLKOUTx_OPD_FIELD 1 | ||
345 | #define STV090x_OFFST_CLKOUTx_CONFIG_FIELD 1 | ||
346 | #define STV090x_WIDTH_CLKOUTx_CONFIG_FIELD 6 | ||
347 | #define STV090x_OFFST_CLKOUTx_XOR_FIELD 0 | ||
348 | #define STV090x_WIDTH_CLKOUTx_XOR_FIELD 1 | ||
349 | |||
350 | #define STV090x_DATAxCFG(__x) (0xf15f + (__x - 71) * 0x5) | ||
351 | #define STV090x_DATA71CFG STV090x_DATAxCFG(71) | ||
352 | #define STV090x_DATA72CFG STV090x_DATAxCFG(72) | ||
353 | #define STV090x_DATA73CFG STV090x_DATAxCFG(73) | ||
354 | #define STV090x_OFFST_DATAx_OPD_FIELD 7 | ||
355 | #define STV090x_WIDTH_DATAx_OPD_FIELD 1 | ||
356 | #define STV090x_OFFST_DATAx_CONFIG_FIELD 1 | ||
357 | #define STV090x_WIDTH_DATAx_CONFIG_FIELD 6 | ||
358 | #define STV090x_OFFST_DATAx_XOR_FIELD 0 | ||
359 | #define STV090x_WIDTH_DATAx_XOR_FIELD 1 | ||
360 | |||
361 | #define STV090x_NCOARSE 0xf1b3 | ||
362 | #define STV090x_OFFST_M_DIV_FIELD 0 | ||
363 | #define STV090x_WIDTH_M_DIV_FIELD 8 | ||
364 | |||
365 | #define STV090x_SYNTCTRL 0xf1b6 | ||
366 | #define STV090x_OFFST_STANDBY_FIELD 7 | ||
367 | #define STV090x_WIDTH_STANDBY_FIELD 1 | ||
368 | #define STV090x_OFFST_BYPASSPLLCORE_FIELD 6 | ||
369 | #define STV090x_WIDTH_BYPASSPLLCORE_FIELD 1 | ||
370 | #define STV090x_OFFST_SELX1RATIO_FIELD 5 | ||
371 | #define STV090x_WIDTH_SELX1RATIO_FIELD 1 | ||
372 | #define STV090x_OFFST_STOP_PLL_FIELD 3 | ||
373 | #define STV090x_WIDTH_SELX1RATIO_FIELD 1 | ||
374 | #define STV090x_OFFST_BYPASSPLLFSK_FIELD 2 | ||
375 | #define STV090x_WIDTH_BYPASSPLLFSK_FIELD 1 | ||
376 | #define STV090x_OFFST_SELOSCI_FIELD 1 | ||
377 | #define STV090x_WIDTH_SELOSCI_FIELD 1 | ||
378 | #define STV090x_OFFST_BYPASSPLLADC_FIELD 0 | ||
379 | #define STV090x_WIDTH_BYPASSPLLADC_FIELD 1 | ||
380 | |||
381 | #define STV090x_FILTCTRL 0xf1b7 | ||
382 | #define STV090x_OFFST_INV_CLK135_FIELD 7 | ||
383 | #define STV090x_WIDTH_INV_CLK135_FIELD 1 | ||
384 | #define STV090x_OFFST_SEL_FSKCKDIV_FIELD 2 | ||
385 | #define STV090x_WIDTH_SEL_FSKCKDIV_FIELD 1 | ||
386 | #define STV090x_OFFST_INV_CLKFSK_FIELD 1 | ||
387 | #define STV090x_WIDTH_INV_CLKFSK_FIELD 1 | ||
388 | #define STV090x_OFFST_BYPASS_APPLI_FIELD 0 | ||
389 | #define STV090x_WIDTH_BYPASS_APPLI_FIELD 1 | ||
390 | |||
391 | #define STV090x_PLLSTAT 0xf1b8 | ||
392 | #define STV090x_OFFST_PLLLOCK_FIELD 0 | ||
393 | #define STV090x_WIDTH_PLLLOCK_FIELD 1 | ||
394 | |||
395 | #define STV090x_STOPCLK1 0xf1c2 | ||
396 | #define STV090x_OFFST_STOP_CLKPKDT2_FIELD 6 | ||
397 | #define STV090x_WIDTH_STOP_CLKPKDT2_FIELD 1 | ||
398 | #define STV090x_OFFST_STOP_CLKPKDT1_FIELD 5 | ||
399 | #define STV090x_WIDTH_STOP_CLKPKDT1_FIELD 1 | ||
400 | #define STV090x_OFFST_STOP_CLKFEC_FIELD 4 | ||
401 | #define STV090x_WIDTH_STOP_CLKFEC_FIELD 1 | ||
402 | #define STV090x_OFFST_STOP_CLKADCI2_FIELD 3 | ||
403 | #define STV090x_WIDTH_STOP_CLKADCI2_FIELD 1 | ||
404 | #define STV090x_OFFST_INV_CLKADCI2_FIELD 2 | ||
405 | #define STV090x_WIDTH_INV_CLKADCI2_FIELD 1 | ||
406 | #define STV090x_OFFST_STOP_CLKADCI1_FIELD 1 | ||
407 | #define STV090x_WIDTH_STOP_CLKADCI1_FIELD 1 | ||
408 | #define STV090x_OFFST_INV_CLKADCI1_FIELD 0 | ||
409 | #define STV090x_WIDTH_INV_CLKADCI1_FIELD 1 | ||
410 | |||
411 | #define STV090x_STOPCLK2 0xf1c3 | ||
412 | #define STV090x_OFFST_STOP_CLKSAMP2_FIELD 4 | ||
413 | #define STV090x_WIDTH_STOP_CLKSAMP2_FIELD 1 | ||
414 | #define STV090x_OFFST_STOP_CLKSAMP1_FIELD 3 | ||
415 | #define STV090x_WIDTH_STOP_CLKSAMP1_FIELD 1 | ||
416 | #define STV090x_OFFST_STOP_CLKVIT2_FIELD 2 | ||
417 | #define STV090x_WIDTH_STOP_CLKVIT2_FIELD 1 | ||
418 | #define STV090x_OFFST_STOP_CLKVIT1_FIELD 1 | ||
419 | #define STV090x_WIDTH_STOP_CLKVIT1_FIELD 1 | ||
420 | #define STV090x_OFFST_STOP_CLKTS_FIELD 0 | ||
421 | #define STV090x_WIDTH_STOP_CLKTS_FIELD 1 | ||
422 | |||
423 | #define STV090x_TSTTNR0 0xf1df | ||
424 | #define STV090x_OFFST_SEL_FSK_FIELD 7 | ||
425 | #define STV090x_WIDTH_SEL_FSK_FIELD 1 | ||
426 | #define STV090x_OFFST_FSK_PON_FIELD 2 | ||
427 | #define STV090x_WIDTH_FSK_PON_FIELD 1 | ||
428 | |||
429 | #define STV090x_TSTTNR1 0xf1e0 | ||
430 | #define STV090x_OFFST_ADC1_PON_FIELD 1 | ||
431 | #define STV090x_WIDTH_ADC1_PON_FIELD 1 | ||
432 | #define STV090x_OFFST_ADC1_INMODE_FIELD 0 | ||
433 | #define STV090x_WIDTH_ADC1_INMODE_FIELD 1 | ||
434 | |||
435 | #define STV090x_TSTTNR2 0xf1e1 | ||
436 | #define STV090x_OFFST_DISEQC1_PON_FIELD 5 | ||
437 | #define STV090x_WIDTH_DISEQC1_PON_FIELD 1 | ||
438 | |||
439 | #define STV090x_TSTTNR3 0xf1e2 | ||
440 | #define STV090x_OFFST_ADC2_PON_FIELD 1 | ||
441 | #define STV090x_WIDTH_ADC2_PON_FIELD 1 | ||
442 | #define STV090x_OFFST_ADC2_INMODE_FIELD 0 | ||
443 | #define STV090x_WIDTH_ADC2_INMODE_FIELD 1 | ||
444 | |||
445 | #define STV090x_TSTTNR4 0xf1e3 | ||
446 | #define STV090x_OFFST_DISEQC2_PON_FIELD 5 | ||
447 | #define STV090x_WIDTH_DISEQC2_PON_FIELD 1 | ||
448 | |||
449 | #define STV090x_FSKTFC2 0xf170 | ||
450 | #define STV090x_OFFST_FSKT_KMOD_FIELD 2 | ||
451 | #define STV090x_WIDTH_FSKT_KMOD_FIELD 6 | ||
452 | #define STV090x_OFFST_FSKT_CAR_FIELD 0 | ||
453 | #define STV090x_WIDTH_FSKT_CAR_FIELD 2 | ||
454 | |||
455 | #define STV090x_FSKTFC1 0xf171 | ||
456 | #define STV090x_OFFST_FSKTC1_CAR_FIELD 0 | ||
457 | #define STV090x_WIDTH_FSKTC1_CAR_FIELD 8 | ||
458 | |||
459 | #define STV090x_FSKTFC0 0xf172 | ||
460 | #define STV090x_OFFST_FSKTC0_CAR_FIELD 0 | ||
461 | #define STV090x_WIDTH_FSKTC0_CAR_FIELD 8 | ||
462 | |||
463 | #define STV090x_FSKTDELTAF1 0xf173 | ||
464 | #define STV090x_OFFST_FSKTF1_DELTAF_FIELD 0 | ||
465 | #define STV090x_WIDTH_FSKTF1_DELTAF_FIELD 4 | ||
466 | |||
467 | #define STV090x_FSKTDELTAF0 0xf174 | ||
468 | #define STV090x_OFFST_FSKTF0_DELTAF_FIELD 0 | ||
469 | #define STV090x_WIDTH_FSKTF0_DELTAF_FIELD 8 | ||
470 | |||
471 | #define STV090x_FSKTCTRL 0xf175 | ||
472 | #define STV090x_OFFST_FSKT_EN_SGN_FIELD 6 | ||
473 | #define STV090x_WIDTH_FSKT_EN_SGN_FIELD 1 | ||
474 | #define STV090x_OFFST_FSKT_MOD_SGN_FIELD 5 | ||
475 | #define STV090x_WIDTH_FSKT_MOD_SGN_FIELD 1 | ||
476 | #define STV090x_OFFST_FSKT_MOD_EN_FIELD 2 | ||
477 | #define STV090x_WIDTH_FSKT_MOD_EN_FIELD 3 | ||
478 | #define STV090x_OFFST_FSKT_DACMODE_FIELD 0 | ||
479 | #define STV090x_WIDTH_FSKT_DACMODE_FIELD 2 | ||
480 | |||
481 | #define STV090x_FSKRFC2 0xf176 | ||
482 | #define STV090x_OFFST_FSKRC2_DETSGN_FIELD 6 | ||
483 | #define STV090x_WIDTH_FSKRC2_DETSGN_FIELD 1 | ||
484 | #define STV090x_OFFST_FSKRC2_OUTSGN_FIELD 5 | ||
485 | #define STV090x_WIDTH_FSKRC2_OUTSGN_FIELD 1 | ||
486 | #define STV090x_OFFST_FSKRC2_KAGC_FIELD 2 | ||
487 | #define STV090x_WIDTH_FSKRC2_KAGC_FIELD 3 | ||
488 | #define STV090x_OFFST_FSKRC2_CAR_FIELD 0 | ||
489 | #define STV090x_WIDTH_FSKRC2_CAR_FIELD 2 | ||
490 | |||
491 | #define STV090x_FSKRFC1 0xf177 | ||
492 | #define STV090x_OFFST_FSKRC1_CAR_FIELD 0 | ||
493 | #define STV090x_WIDTH_FSKRC1_CAR_FIELD 8 | ||
494 | |||
495 | #define STV090x_FSKRFC0 0xf178 | ||
496 | #define STV090x_OFFST_FSKRC0_CAR_FIELD 0 | ||
497 | #define STV090x_WIDTH_FSKRC0_CAR_FIELD 8 | ||
498 | |||
499 | #define STV090x_FSKRK1 0xf179 | ||
500 | #define STV090x_OFFST_FSKR_K1_EXP_FIELD 5 | ||
501 | #define STV090x_WIDTH_FSKR_K1_EXP_FIELD 3 | ||
502 | #define STV090x_OFFST_FSKR_K1_MANT_FIELD 0 | ||
503 | #define STV090x_WIDTH_FSKR_K1_MANT_FIELD 5 | ||
504 | |||
505 | #define STV090x_FSKRK2 0xf17a | ||
506 | #define STV090x_OFFST_FSKR_K2_EXP_FIELD 5 | ||
507 | #define STV090x_WIDTH_FSKR_K2_EXP_FIELD 3 | ||
508 | #define STV090x_OFFST_FSKR_K2_MANT_FIELD 0 | ||
509 | #define STV090x_WIDTH_FSKR_K2_MANT_FIELD 5 | ||
510 | |||
511 | #define STV090x_FSKRAGCR 0xf17b | ||
512 | #define STV090x_OFFST_FSKR_OUTCTL_FIELD 6 | ||
513 | #define STV090x_WIDTH_FSKR_OUTCTL_FIELD 2 | ||
514 | #define STV090x_OFFST_FSKR_AGC_REF_FIELD 0 | ||
515 | #define STV090x_WIDTH_FSKR_AGC_REF_FIELD 6 | ||
516 | |||
517 | #define STV090x_FSKRAGC 0xf17c | ||
518 | #define STV090x_OFFST_FSKR_AGC_ACCU_FIELD 0 | ||
519 | #define STV090x_WIDTH_FSKR_AGC_ACCU_FIELD 8 | ||
520 | |||
521 | #define STV090x_FSKRALPHA 0xf17d | ||
522 | #define STV090x_OFFST_FSKR_ALPHA_EXP_FIELD 2 | ||
523 | #define STV090x_WIDTH_FSKR_ALPHA_EXP_FIELD 3 | ||
524 | #define STV090x_OFFST_FSKR_ALPHA_M_FIELD 0 | ||
525 | #define STV090x_WIDTH_FSKR_ALPHA_M_FIELD 2 | ||
526 | |||
527 | #define STV090x_FSKRPLTH1 0xf17e | ||
528 | #define STV090x_OFFST_FSKR_BETA_FIELD 4 | ||
529 | #define STV090x_WIDTH_FSKR_BETA_FIELD 4 | ||
530 | #define STV090x_OFFST_FSKR_PLL_TRESH1_FIELD 0 | ||
531 | #define STV090x_WIDTH_FSKR_PLL_TRESH1_FIELD 4 | ||
532 | |||
533 | #define STV090x_FSKRPLTH0 0xf17f | ||
534 | #define STV090x_OFFST_FSKR_PLL_TRESH0_FIELD 0 | ||
535 | #define STV090x_WIDTH_FSKR_PLL_TRESH0_FIELD 8 | ||
536 | |||
537 | #define STV090x_FSKRDF1 0xf180 | ||
538 | #define STV090x_OFFST_FSKR_DELTAF1_FIELD 0 | ||
539 | #define STV090x_WIDTH_FSKR_DELTAF1_FIELD 5 | ||
540 | |||
541 | #define STV090x_FSKRDF0 0xf181 | ||
542 | #define STV090x_OFFST_FSKR_DELTAF0_FIELD 0 | ||
543 | #define STV090x_WIDTH_FSKR_DELTAF0_FIELD 8 | ||
544 | |||
545 | #define STV090x_FSKRSTEPP 0xf182 | ||
546 | #define STV090x_OFFST_FSKR_STEP_PLUS_FIELD 0 | ||
547 | #define STV090x_WIDTH_FSKR_STEP_PLUS_FIELD 8 | ||
548 | |||
549 | #define STV090x_FSKRSTEPM 0xf183 | ||
550 | #define STV090x_OFFST_FSKR_STEP_MINUS_FIELD 0 | ||
551 | #define STV090x_WIDTH_FSKR_STEP_MINUS_FIELD 8 | ||
552 | |||
553 | #define STV090x_FSKRDET1 0xf184 | ||
554 | #define STV090x_OFFST_FSKR_CARDET1_ACCU_FIELD 0 | ||
555 | #define STV090x_WIDTH_FSKR_CARDET1_ACCU_FIELD 4 | ||
556 | |||
557 | #define STV090x_FSKRDET0 0xf185 | ||
558 | #define STV090x_OFFST_FSKR_CARDET0_ACCU_FIELD 0 | ||
559 | #define STV090x_WIDTH_FSKR_CARDET0_ACCU_FIELD 8 | ||
560 | |||
561 | #define STV090x_FSKRDTH1 0xf186 | ||
562 | #define STV090x_OFFST_FSKR_CARLOSS_THRESH1_FIELD 4 | ||
563 | #define STV090x_WIDTH_FSKR_CARLOSS_THRESH1_FIELD 4 | ||
564 | #define STV090x_OFFST_FSKR_CARDET_THRESH1_FIELD 0 | ||
565 | #define STV090x_WIDTH_FSKR_CARDET_THRESH1_FIELD 4 | ||
566 | |||
567 | #define STV090x_FSKRDTH0 0xf187 | ||
568 | #define STV090x_OFFST_FSKR_CARDET_THRESH0_FIELD 0 | ||
569 | #define STV090x_WIDTH_FSKR_CARDET_THRESH0_FIELD 8 | ||
570 | |||
571 | #define STV090x_FSKRLOSS 0xf188 | ||
572 | #define STV090x_OFFST_FSKR_CARLOSS_THRESH_FIELD 0 | ||
573 | #define STV090x_WIDTH_FSKR_CARLOSS_THRESH_FIELD 8 | ||
574 | |||
575 | #define STV090x_Px_DISTXCTL(__x) (0xF1A0 - (__x - 1) * 0x10) | ||
576 | #define STV090x_P1_DISTXCTL STV090x_Px_DISTXCTL(1) | ||
577 | #define STV090x_P2_DISTXCTL STV090x_Px_DISTXCTL(2) | ||
578 | #define STV090x_OFFST_Px_TIM_OFF_FIELD 7 | ||
579 | #define STV090x_WIDTH_Px_TIM_OFF_FIELD 1 | ||
580 | #define STV090x_OFFST_Px_DISEQC_RESET_FIELD 6 | ||
581 | #define STV090x_WIDTH_Px_DISEQC_RESET_FIELD 1 | ||
582 | #define STV090x_OFFST_Px_TIM_CMD_FIELD 4 | ||
583 | #define STV090x_WIDTH_Px_TIM_CMD_FIELD 2 | ||
584 | #define STV090x_OFFST_Px_DIS_PRECHARGE_FIELD 3 | ||
585 | #define STV090x_WIDTH_Px_DIS_PRECHARGE_FIELD 1 | ||
586 | #define STV090x_OFFST_Px_DISTX_MODE_FIELD 0 | ||
587 | #define STV090x_WIDTH_Px_DISTX_MODE_FIELD 3 | ||
588 | |||
589 | #define STV090x_Px_DISRXCTL(__x) (0xf1a1 - (__x - 1) * 0x10) | ||
590 | #define STV090x_P1_DISRXCTL STV090x_Px_DISRXCTL(1) | ||
591 | #define STV090x_P2_DISRXCTL STV090x_Px_DISRXCTL(2) | ||
592 | #define STV090x_OFFST_Px_RECEIVER_ON_FIELD 7 | ||
593 | #define STV090x_WIDTH_Px_RECEIVER_ON_FIELD 1 | ||
594 | #define STV090x_OFFST_Px_IGNO_SHORT22K_FIELD 6 | ||
595 | #define STV090x_WIDTH_Px_IGNO_SHORT22K_FIELD 1 | ||
596 | #define STV090x_OFFST_Px_ONECHIP_TRX_FIELD 5 | ||
597 | #define STV090x_WIDTH_Px_ONECHIP_TRX_FIELD 1 | ||
598 | #define STV090x_OFFST_Px_EXT_ENVELOP_FIELD 4 | ||
599 | #define STV090x_WIDTH_Px_EXT_ENVELOP_FIELD 1 | ||
600 | #define STV090x_OFFST_Px_PIN_SELECT_FIELD 2 | ||
601 | #define STV090x_WIDTH_Px_PIN_SELECT_FIELD 2 | ||
602 | #define STV090x_OFFST_Px_IRQ_RXEND_FIELD 1 | ||
603 | #define STV090x_WIDTH_Px_IRQ_RXEND_FIELD 1 | ||
604 | #define STV090x_OFFST_Px_IRQ_4NBYTES_FIELD 0 | ||
605 | #define STV090x_WIDTH_Px_IRQ_4NBYTES_FIELD 1 | ||
606 | |||
607 | #define STV090x_Px_DISRX_ST0(__x) (0xf1a4 - (__x - 1) * 0x10) | ||
608 | #define STV090x_P1_DISRX_ST0 STV090x_Px_DISRX_ST0(1) | ||
609 | #define STV090x_P2_DISRX_ST0 STV090x_Px_DISRX_ST0(2) | ||
610 | #define STV090x_OFFST_Px_RX_END_FIELD 7 | ||
611 | #define STV090x_WIDTH_Px_RX_END_FIELD 1 | ||
612 | #define STV090x_OFFST_Px_RX_ACTIVE_FIELD 6 | ||
613 | #define STV090x_WIDTH_Px_RX_ACTIVE_FIELD 1 | ||
614 | #define STV090x_OFFST_Px_SHORT_22KHZ_FIELD 5 | ||
615 | #define STV090x_WIDTH_Px_SHORT_22KHZ_FIELD 1 | ||
616 | #define STV090x_OFFST_Px_CONT_TONE_FIELD 4 | ||
617 | #define STV090x_WIDTH_Px_CONT_TONE_FIELD 1 | ||
618 | #define STV090x_OFFST_Px_FIFO_4BREADY_FIELD 3 | ||
619 | #define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD 2 | ||
620 | #define STV090x_OFFST_Px_FIFO_EMPTY_FIELD 2 | ||
621 | #define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD 1 | ||
622 | #define STV090x_OFFST_Px_ABORT_DISRX_FIELD 0 | ||
623 | #define STV090x_WIDTH_Px_ABORT_DISRX_FIELD 1 | ||
624 | |||
625 | #define STV090x_Px_DISRX_ST1(__x) (0xf1a5 - (__x - 1) * 0x10) | ||
626 | #define STV090x_P1_DISRX_ST1 STV090x_Px_DISRX_ST1(1) | ||
627 | #define STV090x_P2_DISRX_ST1 STV090x_Px_DISRX_ST1(2) | ||
628 | #define STV090x_OFFST_Px_RX_FAIL_FIELD 7 | ||
629 | #define STV090x_WIDTH_Px_RX_FAIL_FIELD 1 | ||
630 | #define STV090x_OFFST_Px_FIFO_PARITYFAIL_FIELD 6 | ||
631 | #define STV090x_WIDTH_Px_FIFO_PARITYFAIL_FIELD 1 | ||
632 | #define STV090x_OFFST_Px_RX_NONBYTE_FIELD 5 | ||
633 | #define STV090x_WIDTH_Px_RX_NONBYTE_FIELD 1 | ||
634 | #define STV090x_OFFST_Px_FIFO_OVERFLOW_FIELD 4 | ||
635 | #define STV090x_WIDTH_Px_FIFO_OVERFLOW_FIELD 1 | ||
636 | #define STV090x_OFFST_Px_FIFO_BYTENBR_FIELD 0 | ||
637 | #define STV090x_WIDTH_Px_FIFO_BYTENBR_FIELD 4 | ||
638 | |||
639 | #define STV090x_Px_DISRXDATA(__x) (0xf1a6 - (__x - 1) * 0x10) | ||
640 | #define STV090x_P1_DISRXDATA STV090x_Px_DISRXDATA(1) | ||
641 | #define STV090x_P2_DISRXDATA STV090x_Px_DISRXDATA(2) | ||
642 | #define STV090x_OFFST_Px_DISRX_DATA_FIELD 0 | ||
643 | #define STV090x_WIDTH_Px_DISRX_DATA_FIELD 8 | ||
644 | |||
645 | #define STV090x_Px_DISTXDATA(__x) (0xf1a7 - (__x - 1) * 0x10) | ||
646 | #define STV090x_P1_DISTXDATA STV090x_Px_DISTXDATA(1) | ||
647 | #define STV090x_P2_DISTXDATA STV090x_Px_DISTXDATA(2) | ||
648 | #define STV090x_OFFST_Px_DISEQC_FIFO_FIELD 0 | ||
649 | #define STV090x_WIDTH_Px_DISEQC_FIFO_FIELD 8 | ||
650 | |||
651 | #define STV090x_Px_DISTXSTATUS(__x) (0xf1a8 - (__x - 1) * 0x10) | ||
652 | #define STV090x_P1_DISTXSTATUS STV090x_Px_DISTXSTATUS(1) | ||
653 | #define STV090x_P2_DISTXSTATUS STV090x_Px_DISTXSTATUS(2) | ||
654 | #define STV090x_OFFST_Px_TX_FAIL_FIELD 7 | ||
655 | #define STV090x_WIDTH_Px_TX_FAIL_FIELD 1 | ||
656 | #define STV090x_OFFST_Px_FIFO_FULL_FIELD 6 | ||
657 | #define STV090x_WIDTH_Px_FIFO_FULL_FIELD 1 | ||
658 | #define STV090x_OFFST_Px_TX_IDLE_FIELD 5 | ||
659 | #define STV090x_WIDTH_Px_TX_IDLE_FIELD 1 | ||
660 | #define STV090x_OFFST_Px_GAP_BURST_FIELD 4 | ||
661 | #define STV090x_WIDTH_Px_GAP_BURST_FIELD 1 | ||
662 | #define STV090x_OFFST_Px_TXFIFO_BYTES_FIELD 0 | ||
663 | #define STV090x_WIDTH_Px_TXFIFO_BYTES_FIELD 4 | ||
664 | |||
665 | #define STV090x_Px_F22TX(__x) (0xf1a9 - (__x - 1) * 0x10) | ||
666 | #define STV090x_P1_F22TX STV090x_Px_F22TX(1) | ||
667 | #define STV090x_P2_F22TX STV090x_Px_F22TX(2) | ||
668 | #define STV090x_OFFST_Px_F22_REG_FIELD 0 | ||
669 | #define STV090x_WIDTH_Px_F22_REG_FIELD 8 | ||
670 | |||
671 | #define STV090x_Px_F22RX(__x) (0xf1aa - (__x - 1) * 0x10) | ||
672 | #define STV090x_P1_F22RX STV090x_Px_F22RX(1) | ||
673 | #define STV090x_P2_F22RX STV090x_Px_F22RX(2) | ||
674 | #define STV090x_OFFST_Px_F22RX_REG_FIELD 0 | ||
675 | #define STV090x_WIDTH_Px_F22RX_REG_FIELD 8 | ||
676 | |||
677 | #define STV090x_Px_ACRPRESC(__x) (0xf1ac - (__x - 1) * 0x10) | ||
678 | #define STV090x_P1_ACRPRESC STV090x_Px_ACRPRESC(1) | ||
679 | #define STV090x_P2_ACRPRESC STV090x_Px_ACRPRESC(2) | ||
680 | #define STV090x_OFFST_Px_ACR_PRESC_FIELD 0 | ||
681 | #define STV090x_WIDTH_Px_ACR_PRESC_FIELD 3 | ||
682 | |||
683 | #define STV090x_Px_ACRDIV(__x) (0xf1ad - (__x - 1) * 0x10) | ||
684 | #define STV090x_P1_ACRDIV STV090x_Px_ACRDIV(1) | ||
685 | #define STV090x_P2_ACRDIV STV090x_Px_ACRDIV(2) | ||
686 | #define STV090x_OFFST_Px_ACR_DIV_FIELD 0 | ||
687 | #define STV090x_WIDTH_Px_ACR_DIV_FIELD 8 | ||
688 | |||
689 | #define STV090x_Px_IQCONST(__x) (0xF400 - (__x - 1) * 0x200) | ||
690 | #define STV090x_P1_IQCONST STV090x_Px_IQCONST(1) | ||
691 | #define STV090x_P2_IQCONST STV090x_Px_IQCONST(2) | ||
692 | #define STV090x_OFFST_Px_CONSTEL_SELECT_FIELD 5 | ||
693 | #define STV090x_WIDTH_Px_CONSTEL_SELECT_FIELD 2 | ||
694 | |||
695 | #define STV090x_Px_NOSCFG(__x) (0xF401 - (__x - 1) * 0x200) | ||
696 | #define STV090x_P1_NOSCFG STV090x_Px_NOSCFG(1) | ||
697 | #define STV090x_P2_NOSCFG STV090x_Px_NOSCFG(2) | ||
698 | #define STV090x_OFFST_Px_NOSPLH_BETA_FIELD 3 | ||
699 | #define STV090x_WIDTH_Px_NOSPLH_BETA_FIELD 2 | ||
700 | #define STV090x_OFFST_Px_NOSDATA_BETA_FIELD 0 | ||
701 | #define STV090x_WIDTH_Px_NOSDATA_BETA_FIELD 3 | ||
702 | |||
703 | #define STV090x_Px_ISYMB(__x) (0xF402 - (__x - 1) * 0x200) | ||
704 | #define STV090x_P1_ISYMB STV090x_Px_ISYMB(1) | ||
705 | #define STV090x_P2_ISYMB STV090x_Px_ISYMB(2) | ||
706 | #define STV090x_OFFST_Px_I_SYMBOL_FIELD 0 | ||
707 | #define STV090x_WIDTH_Px_I_SYMBOL_FIELD 8 | ||
708 | |||
709 | #define STV090x_Px_QSYMB(__x) (0xF403 - (__x - 1) * 0x200) | ||
710 | #define STV090x_P1_QSYMB STV090x_Px_QSYMB(1) | ||
711 | #define STV090x_P2_QSYMB STV090x_Px_QSYMB(2) | ||
712 | #define STV090x_OFFST_Px_Q_SYMBOL_FIELD 0 | ||
713 | #define STV090x_WIDTH_Px_Q_SYMBOL_FIELD 8 | ||
714 | |||
715 | #define STV090x_Px_AGC1CFG(__x) (0xF404 - (__x - 1) * 0x200) | ||
716 | #define STV090x_P1_AGC1CFG STV090x_Px_AGC1CFG(1) | ||
717 | #define STV090x_P2_AGC1CFG STV090x_Px_AGC1CFG(2) | ||
718 | #define STV090x_OFFST_Px_DC_FROZEN_FIELD 7 | ||
719 | #define STV090x_WIDTH_Px_DC_FROZEN_FIELD 1 | ||
720 | #define STV090x_OFFST_Px_DC_CORRECT_FIELD 6 | ||
721 | #define STV090x_WIDTH_Px_DC_CORRECT_FIELD 1 | ||
722 | #define STV090x_OFFST_Px_AMM_FROZEN_FIELD 5 | ||
723 | #define STV090x_WIDTH_Px_AMM_FROZEN_FIELD 1 | ||
724 | #define STV090x_OFFST_Px_AMM_CORRECT_FIELD 4 | ||
725 | #define STV090x_WIDTH_Px_AMM_CORRECT_FIELD 1 | ||
726 | #define STV090x_OFFST_Px_QUAD_FROZEN_FIELD 3 | ||
727 | #define STV090x_WIDTH_Px_QUAD_FROZEN_FIELD 1 | ||
728 | #define STV090x_OFFST_Px_QUAD_CORRECT_FIELD 2 | ||
729 | #define STV090x_WIDTH_Px_QUAD_CORRECT_FIELD 1 | ||
730 | |||
731 | #define STV090x_Px_AGC1CN(__x) (0xF406 - (__x - 1) * 0x200) | ||
732 | #define STV090x_P1_AGC1CN STV090x_Px_AGC1CN(1) | ||
733 | #define STV090x_P2_AGC1CN STV090x_Px_AGC1CN(2) | ||
734 | #define STV090x_WIDTH_Px_AGC1_LOCKED_FIELD 7 | ||
735 | #define STV090x_OFFST_Px_AGC1_LOCKED_FIELD 1 | ||
736 | #define STV090x_OFFST_Px_AGC1_MINPOWER_FIELD 4 | ||
737 | #define STV090x_WIDTH_Px_AGC1_MINPOWER_FIELD 1 | ||
738 | #define STV090x_OFFST_Px_AGCOUT_FAST_FIELD 3 | ||
739 | #define STV090x_WIDTH_Px_AGCOUT_FAST_FIELD 1 | ||
740 | #define STV090x_OFFST_Px_AGCIQ_BETA_FIELD 0 | ||
741 | #define STV090x_WIDTH_Px_AGCIQ_BETA_FIELD 3 | ||
742 | |||
743 | #define STV090x_Px_AGC1REF(__x) (0xF407 - (__x - 1) * 0x200) | ||
744 | #define STV090x_P1_AGC1REF STV090x_Px_AGC1REF(1) | ||
745 | #define STV090x_P2_AGC1REF STV090x_Px_AGC1REF(2) | ||
746 | #define STV090x_OFFST_Px_AGCIQ_REF_FIELD 0 | ||
747 | #define STV090x_WIDTH_Px_AGCIQ_REF_FIELD 8 | ||
748 | |||
749 | #define STV090x_Px_IDCCOMP(__x) (0xF408 - (__x - 1) * 0x200) | ||
750 | #define STV090x_P1_IDCCOMP STV090x_Px_IDCCOMP(1) | ||
751 | #define STV090x_P2_IDCCOMP STV090x_Px_IDCCOMP(2) | ||
752 | #define STV090x_OFFST_Px_IAVERAGE_ADJ_FIELD 0 | ||
753 | #define STV090x_WIDTH_Px_IAVERAGE_ADJ_FIELD 8 | ||
754 | |||
755 | #define STV090x_Px_QDCCOMP(__x) (0xF409 - (__x - 1) * 0x200) | ||
756 | #define STV090x_P1_QDCCOMP STV090x_Px_QDCCOMP(1) | ||
757 | #define STV090x_P2_QDCCOMP STV090x_Px_QDCCOMP(2) | ||
758 | #define STV090x_OFFST_Px_QAVERAGE_ADJ_FIELD 0 | ||
759 | #define STV090x_WIDTH_Px_QAVERAGE_ADJ_FIELD 8 | ||
760 | |||
761 | #define STV090x_Px_POWERI(__x) (0xF40A - (__x - 1) * 0x200) | ||
762 | #define STV090x_P1_POWERI STV090x_Px_POWERI(1) | ||
763 | #define STV090x_P2_POWERI STV090x_Px_POWERI(2) | ||
764 | #define STV090x_OFFST_Px_POWER_I_FIELD 0 | ||
765 | #define STV090x_WIDTH_Px_POWER_I_FIELD 8 | ||
766 | |||
767 | #define STV090x_Px_POWERQ(__x) (0xF40B - (__x - 1) * 0x200) | ||
768 | #define STV090x_P1_POWERQ STV090x_Px_POWERQ(1) | ||
769 | #define STV090x_P2_POWERQ STV090x_Px_POWERQ(2) | ||
770 | #define STV090x_OFFST_Px_POWER_Q_FIELD 0 | ||
771 | #define STV090x_WIDTH_Px_POWER_Q_FIELD 8 | ||
772 | |||
773 | #define STV090x_Px_AGC1AMM(__x) (0xF40C - (__x - 1) * 0x200) | ||
774 | #define STV090x_P1_AGC1AMM STV090x_Px_AGC1AMM(1) | ||
775 | #define STV090x_P2_AGC1AMM STV090x_Px_AGC1AMM(2) | ||
776 | #define STV090x_OFFST_Px_AMM_VALUE_FIELD 0 | ||
777 | #define STV090x_WIDTH_Px_AMM_VALUE_FIELD 8 | ||
778 | |||
779 | #define STV090x_Px_AGC1QUAD(__x) (0xF40D - (__x - 1) * 0x200) | ||
780 | #define STV090x_P1_AGC1QUAD STV090x_Px_AGC1QUAD(1) | ||
781 | #define STV090x_P2_AGC1QUAD STV090x_Px_AGC1QUAD(2) | ||
782 | #define STV090x_OFFST_Px_QUAD_VALUE_FIELD 0 | ||
783 | #define STV090x_WIDTH_Px_QUAD_VALUE_FIELD 8 | ||
784 | |||
785 | #define STV090x_Px_AGCIQINy(__x, __y) (0xF40F - (__x-1) * 0x200 - __y * 0x1) | ||
786 | #define STV090x_P1_AGCIQIN0 STV090x_Px_AGCIQINy(1, 0) | ||
787 | #define STV090x_P1_AGCIQIN1 STV090x_Px_AGCIQINy(1, 1) | ||
788 | #define STV090x_P2_AGCIQIN0 STV090x_Px_AGCIQINy(2, 0) | ||
789 | #define STV090x_P2_AGCIQIN1 STV090x_Px_AGCIQINy(2, 1) | ||
790 | #define STV090x_OFFST_Px_AGCIQ_VALUE_FIELD 0 | ||
791 | #define STV090x_WIDTH_Px_AGCIQ_VALUE_FIELD 8 | ||
792 | |||
793 | #define STV090x_Px_DEMOD(__x) (0xF410 - (__x - 1) * 0x200) | ||
794 | #define STV090x_P1_DEMOD STV090x_Px_DEMOD(1) | ||
795 | #define STV090x_P2_DEMOD STV090x_Px_DEMOD(2) | ||
796 | #define STV090x_OFFST_Px_MANUAL_S2ROLLOFF_FIELD 7 | ||
797 | #define STV090x_WIDTH_Px_MANUAL_S2ROLLOFF_FIELD 1 | ||
798 | #define STV090x_OFFST_Px_DEMOD_STOP_FIELD 6 | ||
799 | #define STV090x_WIDTH_Px_DEMOD_STOP_FIELD 1 | ||
800 | #define STV090x_OFFST_Px_SPECINV_CONTROL_FIELD 4 | ||
801 | #define STV090x_WIDTH_Px_SPECINV_CONTROL_FIELD 2 | ||
802 | #define STV090x_OFFST_Px_FORCE_ENASAMP_FIELD 3 | ||
803 | #define STV090x_WIDTH_Px_FORCE_ENASAMP_FIELD 1 | ||
804 | #define STV090x_OFFST_Px_MANUAL_SXROLLOFF_FIELD 2 | ||
805 | #define STV090x_WIDTH_Px_MANUAL_SXROLLOFF_FIELD 1 | ||
806 | #define STV090x_OFFST_Px_ROLLOFF_CONTROL_FIELD 0 | ||
807 | #define STV090x_WIDTH_Px_ROLLOFF_CONTROL_FIELD 2 | ||
808 | |||
809 | #define STV090x_Px_DMDMODCOD(__x) (0xF411 - (__x - 1) * 0x200) | ||
810 | #define STV090x_P1_DMDMODCOD STV090x_Px_DMDMODCOD(1) | ||
811 | #define STV090x_P2_DMDMODCOD STV090x_Px_DMDMODCOD(2) | ||
812 | #define STV090x_OFFST_Px_MANUAL_MODCOD_FIELD 7 | ||
813 | #define STV090x_WIDTH_Px_MANUAL_MODCOD_FIELD 1 | ||
814 | #define STV090x_OFFST_Px_DEMOD_MODCOD_FIELD 2 | ||
815 | #define STV090x_WIDTH_Px_DEMOD_MODCOD_FIELD 5 | ||
816 | #define STV090x_OFFST_Px_DEMOD_TYPE_FIELD 0 | ||
817 | #define STV090x_WIDTH_Px_DEMOD_TYPE_FIELD 2 | ||
818 | |||
819 | #define STV090x_Px_DSTATUS(__x) (0xF412 - (__x - 1) * 0x200) | ||
820 | #define STV090x_P1_DSTATUS STV090x_Px_DSTATUS(1) | ||
821 | #define STV090x_P2_DSTATUS STV090x_Px_DSTATUS(2) | ||
822 | #define STV090x_OFFST_Px_CAR_LOCK_FIELD 7 | ||
823 | #define STV090x_WIDTH_Px_CAR_LOCK_FIELD 1 | ||
824 | #define STV090x_OFFST_Px_TMGLOCK_QUALITY_FIELD 5 | ||
825 | #define STV090x_WIDTH_Px_TMGLOCK_QUALITY_FIELD 2 | ||
826 | #define STV090x_OFFST_Px_LOCK_DEFINITIF_FIELD 3 | ||
827 | #define STV090x_WIDTH_Px_LOCK_DEFINITIF_FIELD 1 | ||
828 | |||
829 | #define STV090x_Px_DSTATUS2(__x) (0xF413 - (__x - 1) * 0x200) | ||
830 | #define STV090x_P1_DSTATUS2 STV090x_Px_DSTATUS2(1) | ||
831 | #define STV090x_P2_DSTATUS2 STV090x_Px_DSTATUS2(2) | ||
832 | #define STV090x_OFFST_Px_DEMOD_DELOCK_FIELD 7 | ||
833 | #define STV090x_WIDTH_Px_DEMOD_DELOCK_FIELD 1 | ||
834 | #define STV090x_OFFST_Px_AGC1_NOSIGNALACK_FIELD 3 | ||
835 | #define STV090x_WIDTH_Px_AGC1_NOSIGNALACK_FIELD 1 | ||
836 | #define STV090x_OFFST_Px_AGC2_OVERFLOW_FIELD 2 | ||
837 | #define STV090x_WIDTH_Px_AGC2_OVERFLOW_FIELD 1 | ||
838 | #define STV090x_OFFST_Px_CFR_OVERFLOW_FIELD 1 | ||
839 | #define STV090x_WIDTH_Px_CFR_OVERFLOW_FIELD 1 | ||
840 | #define STV090x_OFFST_Px_GAMMA_OVERUNDER_FIELD 0 | ||
841 | #define STV090x_WIDTH_Px_GAMMA_OVERUNDER_FIELD 1 | ||
842 | |||
843 | #define STV090x_Px_DMDCFGMD(__x) (0xF414 - (__x - 1) * 0x200) | ||
844 | #define STV090x_P1_DMDCFGMD STV090x_Px_DMDCFGMD(1) | ||
845 | #define STV090x_P2_DMDCFGMD STV090x_Px_DMDCFGMD(2) | ||
846 | #define STV090x_OFFST_Px_DVBS2_ENABLE_FIELD 7 | ||
847 | #define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD 1 | ||
848 | #define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD 6 | ||
849 | #define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD 1 | ||
850 | #define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD 5 /* check */ | ||
851 | #define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD 1 | ||
852 | #define STV090x_OFFST_Px_SCAN_ENABLE_FIELD 4 /* check */ | ||
853 | #define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD 1 | ||
854 | #define STV090x_OFFST_Px_TUN_AUTOSCAN_FIELD 3 | ||
855 | #define STV090x_WIDTH_Px_TUN_AUTOSCAN_FIELD 1 | ||
856 | #define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD 2 | ||
857 | #define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD 1 | ||
858 | #define STV090x_OFFST_Px_TUN_RNG_FIELD 0 | ||
859 | #define STV090x_WIDTH_Px_TUN_RNG_FIELD 2 | ||
860 | |||
861 | #define STV090x_Px_DMDCFG2(__x) (0xF415 - (__x - 1) * 0x200) | ||
862 | #define STV090x_P1_DMDCFG2 STV090x_Px_DMDCFG2(1) | ||
863 | #define STV090x_P2_DMDCFG2 STV090x_Px_DMDCFG2(2) | ||
864 | #define STV090x_OFFST_Px_S1S2_SEQUENTIAL_FIELD 6 | ||
865 | #define STV090x_WIDTH_Px_S1S2_SEQUENTIAL_FIELD 1 | ||
866 | |||
867 | #define STV090x_Px_DMDISTATE(__x) (0xF416 - (__x - 1) * 0x200) | ||
868 | #define STV090x_P1_DMDISTATE STV090x_Px_DMDISTATE(1) | ||
869 | #define STV090x_P2_DMDISTATE STV090x_Px_DMDISTATE(2) | ||
870 | #define STV090x_OFFST_Px_I2C_DEMOD_MODE_FIELD 0 | ||
871 | #define STV090x_WIDTH_Px_I2C_DEMOD_MODE_FIELD 5 | ||
872 | |||
873 | #define STV090x_Px_DMDTOM(__x) (0xF417 - (__x - 1) * 0x200) /* check */ | ||
874 | #define STV090x_P1_DMDTOM STV090x_Px_DMDTOM(1) | ||
875 | #define STV090x_P2_DMDTOM STV090x_Px_DMDTOM(2) | ||
876 | |||
877 | #define STV090x_Px_DMDSTATE(__x) (0xF41B - (__x - 1) * 0x200) | ||
878 | #define STV090x_P1_DMDSTATE STV090x_Px_DMDSTATE(1) | ||
879 | #define STV090x_P2_DMDSTATE STV090x_Px_DMDSTATE(2) | ||
880 | #define STV090x_OFFST_Px_HEADER_MODE_FIELD 5 | ||
881 | #define STV090x_WIDTH_Px_HEADER_MODE_FIELD 2 | ||
882 | |||
883 | #define STV090x_Px_DMDFLYW(__x) (0xF41C - (__x - 1) * 0x200) | ||
884 | #define STV090x_P1_DMDFLYW STV090x_Px_DMDFLYW(1) | ||
885 | #define STV090x_P2_DMDFLYW STV090x_Px_DMDFLYW(2) | ||
886 | #define STV090x_OFFST_Px_I2C_IRQVAL_FIELD 4 | ||
887 | #define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD 4 | ||
888 | #define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD 0 /* check */ | ||
889 | #define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD 4 | ||
890 | |||
891 | #define STV090x_Px_DSTATUS3(__x) (0xF41D - (__x - 1) * 0x200) | ||
892 | #define STV090x_P1_DSTATUS3 STV090x_Px_DSTATUS3(1) | ||
893 | #define STV090x_P2_DSTATUS3 STV090x_Px_DSTATUS3(2) | ||
894 | #define STV090x_OFFST_Px_DEMOD_CFGMODE_FIELD 5 | ||
895 | #define STV090x_WIDTH_Px_DEMOD_CFGMODE_FIELD 2 | ||
896 | |||
897 | #define STV090x_Px_DMDCFG3(__x) (0xF41E - (__x - 1) * 0x200) | ||
898 | #define STV090x_P1_DMDCFG3 STV090x_Px_DMDCFG3(1) | ||
899 | #define STV090x_P2_DMDCFG3 STV090x_Px_DMDCFG3(2) | ||
900 | #define STV090x_OFFST_Px_NOSTOP_FIFOFULL_FIELD 3 | ||
901 | #define STV090x_WIDTH_Px_NOSTOP_FIFOFULL_FIELD 1 | ||
902 | |||
903 | #define STV090x_Px_DMDCFG4(__x) (0xf41f - (__x - 1) * 0x200) | ||
904 | #define STV090x_P1_DMDCFG4 STV090x_Px_DMDCFG4(1) | ||
905 | #define STV090x_P2_DMDCFG4 STV090x_Px_DMDCFG4(2) | ||
906 | |||
907 | #define STV090x_Px_CORRELMANT(__x) (0xF420 - (__x - 1) * 0x200) | ||
908 | #define STV090x_P1_CORRELMANT STV090x_Px_CORRELMANT(1) | ||
909 | #define STV090x_P2_CORRELMANT STV090x_Px_CORRELMANT(2) | ||
910 | #define STV090x_OFFST_Px_CORREL_MANT_FIELD 0 | ||
911 | #define STV090x_WIDTH_Px_CORREL_MANT_FIELD 8 | ||
912 | |||
913 | #define STV090x_Px_CORRELABS(__x) (0xF421 - (__x - 1) * 0x200) | ||
914 | #define STV090x_P1_CORRELABS STV090x_Px_CORRELABS(1) | ||
915 | #define STV090x_P2_CORRELABS STV090x_Px_CORRELABS(2) | ||
916 | #define STV090x_OFFST_Px_CORREL_ABS_FIELD 0 | ||
917 | #define STV090x_WIDTH_Px_CORREL_ABS_FIELD 8 | ||
918 | |||
919 | #define STV090x_Px_CORRELEXP(__x) (0xF422 - (__x - 1) * 0x200) | ||
920 | #define STV090x_P1_CORRELEXP STV090x_Px_CORRELEXP(1) | ||
921 | #define STV090x_P2_CORRELEXP STV090x_Px_CORRELEXP(2) | ||
922 | #define STV090x_OFFST_Px_CORREL_ABSEXP_FIELD 4 | ||
923 | #define STV090x_WIDTH_Px_CORREL_ABSEXP_FIELD 4 | ||
924 | #define STV090x_OFFST_Px_CORREL_EXP_FIELD 0 | ||
925 | #define STV090x_WIDTH_Px_CORREL_EXP_FIELD 4 | ||
926 | |||
927 | #define STV090x_Px_PLHMODCOD(__x) (0xF424 - (__x - 1) * 0x200) | ||
928 | #define STV090x_P1_PLHMODCOD STV090x_Px_PLHMODCOD(1) | ||
929 | #define STV090x_P2_PLHMODCOD STV090x_Px_PLHMODCOD(2) | ||
930 | #define STV090x_OFFST_Px_SPECINV_DEMOD_FIELD 7 | ||
931 | #define STV090x_WIDTH_Px_SPECINV_DEMOD_FIELD 1 | ||
932 | #define STV090x_OFFST_Px_PLH_MODCOD_FIELD 2 | ||
933 | #define STV090x_WIDTH_Px_PLH_MODCOD_FIELD 5 | ||
934 | #define STV090x_OFFST_Px_PLH_TYPE_FIELD 0 | ||
935 | #define STV090x_WIDTH_Px_PLH_TYPE_FIELD 2 | ||
936 | |||
937 | #define STV090x_Px_AGCK32(__x) (0xf42b - (__x - 1) * 0x200) | ||
938 | #define STV090x_P1_AGCK32 STV090x_Px_AGCK32(1) | ||
939 | #define STV090x_P2_AGCK32 STV090x_Px_AGCK32(2) | ||
940 | |||
941 | #define STV090x_Px_AGC2O(__x) (0xF42C - (__x - 1) * 0x200) | ||
942 | #define STV090x_P1_AGC2O STV090x_Px_AGC2O(1) | ||
943 | #define STV090x_P2_AGC2O STV090x_Px_AGC2O(2) | ||
944 | |||
945 | #define STV090x_Px_AGC2REF(__x) (0xF42D - (__x - 1) * 0x200) | ||
946 | #define STV090x_P1_AGC2REF STV090x_Px_AGC2REF(1) | ||
947 | #define STV090x_P2_AGC2REF STV090x_Px_AGC2REF(2) | ||
948 | #define STV090x_OFFST_Px_AGC2_REF_FIELD 0 | ||
949 | #define STV090x_WIDTH_Px_AGC2_REF_FIELD 8 | ||
950 | |||
951 | #define STV090x_Px_AGC1ADJ(__x) (0xF42E - (__x - 1) * 0x200) | ||
952 | #define STV090x_P1_AGC1ADJ STV090x_Px_AGC1ADJ(1) | ||
953 | #define STV090x_P2_AGC1ADJ STV090x_Px_AGC1ADJ(2) | ||
954 | #define STV090x_OFFST_Px_AGC1_ADJUSTED_FIELD 0 | ||
955 | #define STV090x_WIDTH_Px_AGC1_ADJUSTED_FIELD 7 | ||
956 | |||
957 | #define STV090x_Px_AGC2Iy(__x, __y) (0xF437 - (__x - 1) * 0x200 - __y * 0x1) | ||
958 | #define STV090x_P1_AGC2I0 STV090x_Px_AGC2Iy(1, 0) | ||
959 | #define STV090x_P1_AGC2I1 STV090x_Px_AGC2Iy(1, 1) | ||
960 | #define STV090x_P2_AGC2I0 STV090x_Px_AGC2Iy(2, 0) | ||
961 | #define STV090x_P2_AGC2I1 STV090x_Px_AGC2Iy(2, 1) | ||
962 | #define STV090x_OFFST_Px_AGC2_INTEGRATOR_FIELD 0 | ||
963 | #define STV090x_WIDTH_Px_AGC2_INTEGRATOR_FIELD 8 | ||
964 | |||
965 | #define STV090x_Px_CARCFG(__x) (0xF438 - (__x - 1) * 0x200) | ||
966 | #define STV090x_P1_CARCFG STV090x_Px_CARCFG(1) | ||
967 | #define STV090x_P2_CARCFG STV090x_Px_CARCFG(2) | ||
968 | #define STV090x_OFFST_Px_EN_CAR2CENTER_FIELD 5 | ||
969 | #define STV090x_WIDTH_Px_EN_CAR2CENTER_FIELD 1 | ||
970 | #define STV090x_OFFST_Px_ROTATON_FIELD 2 | ||
971 | #define STV090x_WIDTH_Px_ROTATON_FIELD 1 | ||
972 | #define STV090x_OFFST_Px_PH_DET_ALGO_FIELD 0 | ||
973 | #define STV090x_WIDTH_Px_PH_DET_ALGO_FIELD 2 | ||
974 | |||
975 | #define STV090x_Px_ACLC(__x) (0xF439 - (__x - 1) * 0x200) | ||
976 | #define STV090x_P1_ACLC STV090x_Px_ACLC(1) | ||
977 | #define STV090x_P2_ACLC STV090x_Px_ACLC(2) | ||
978 | #define STV090x_OFFST_Px_CAR_ALPHA_MANT_FIELD 4 | ||
979 | #define STV090x_WIDTH_Px_CAR_ALPHA_MANT_FIELD 2 | ||
980 | #define STV090x_OFFST_Px_CAR_ALPHA_EXP_FIELD 0 | ||
981 | #define STV090x_WIDTH_Px_CAR_ALPHA_EXP_FIELD 4 | ||
982 | |||
983 | #define STV090x_Px_BCLC(__x) (0xF43A - (__x - 1) * 0x200) | ||
984 | #define STV090x_P1_BCLC STV090x_Px_BCLC(1) | ||
985 | #define STV090x_P2_BCLC STV090x_Px_BCLC(2) | ||
986 | #define STV090x_OFFST_Px_CAR_BETA_MANT_FIELD 4 | ||
987 | #define STV090x_WIDTH_Px_CAR_BETA_MANT_FIELD 2 | ||
988 | #define STV090x_OFFST_Px_CAR_BETA_EXP_FIELD 0 | ||
989 | #define STV090x_WIDTH_Px_CAR_BETA_EXP_FIELD 4 | ||
990 | |||
991 | #define STV090x_Px_CARFREQ(__x) (0xF43D - (__x - 1) * 0x200) | ||
992 | #define STV090x_P1_CARFREQ STV090x_Px_CARFREQ(1) | ||
993 | #define STV090x_P2_CARFREQ STV090x_Px_CARFREQ(2) | ||
994 | #define STV090x_OFFST_Px_KC_COARSE_EXP_FIELD 4 | ||
995 | #define STV090x_WIDTH_Px_KC_COARSE_EXP_FIELD 4 | ||
996 | #define STV090x_OFFST_Px_BETA_FREQ_FIELD 0 | ||
997 | #define STV090x_WIDTH_Px_BETA_FREQ_FIELD 4 | ||
998 | |||
999 | #define STV090x_Px_CARHDR(__x) (0xF43E - (__x - 1) * 0x200) | ||
1000 | #define STV090x_P1_CARHDR STV090x_Px_CARHDR(1) | ||
1001 | #define STV090x_P2_CARHDR STV090x_Px_CARHDR(2) | ||
1002 | #define STV090x_OFFST_Px_FREQ_HDR_FIELD 0 | ||
1003 | #define STV090x_WIDTH_Px_FREQ_HDR_FIELD 8 | ||
1004 | |||
1005 | #define STV090x_Px_LDT(__x) (0xF43F - (__x - 1) * 0x200) | ||
1006 | #define STV090x_P1_LDT STV090x_Px_LDT(1) | ||
1007 | #define STV090x_P2_LDT STV090x_Px_LDT(2) | ||
1008 | #define STV090x_OFFST_Px_CARLOCK_THRES_FIELD 0 | ||
1009 | #define STV090x_WIDTH_Px_CARLOCK_THRES_FIELD 8 | ||
1010 | |||
1011 | #define STV090x_Px_LDT2(__x) (0xF440 - (__x - 1) * 0x200) | ||
1012 | #define STV090x_P1_LDT2 STV090x_Px_LDT2(1) | ||
1013 | #define STV090x_P2_LDT2 STV090x_Px_LDT2(2) | ||
1014 | #define STV090x_OFFST_Px_CARLOCK_THRES2_FIELD 0 | ||
1015 | #define STV090x_WIDTH_Px_CARLOCK_THRES2_FIELD 8 | ||
1016 | |||
1017 | #define STV090x_Px_CFRICFG(__x) (0xF441 - (__x - 1) * 0x200) | ||
1018 | #define STV090x_P1_CFRICFG STV090x_Px_CFRICFG(1) | ||
1019 | #define STV090x_P2_CFRICFG STV090x_Px_CFRICFG(2) | ||
1020 | #define STV090x_OFFST_Px_NEG_CFRSTEP_FIELD 0 | ||
1021 | #define STV090x_WIDTH_Px_NEG_CFRSTEP_FIELD 1 | ||
1022 | |||
1023 | #define STV090x_Pn_CFRUPy(__x, __y) (0xF443 - (__x - 1) * 0x200 - __y * 0x1) | ||
1024 | #define STV090x_P1_CFRUP0 STV090x_Pn_CFRUPy(1, 0) | ||
1025 | #define STV090x_P1_CFRUP1 STV090x_Pn_CFRUPy(1, 1) | ||
1026 | #define STV090x_P2_CFRUP0 STV090x_Pn_CFRUPy(2, 0) | ||
1027 | #define STV090x_P2_CFRUP1 STV090x_Pn_CFRUPy(2, 1) | ||
1028 | #define STV090x_OFFST_Px_CFR_UP_FIELD 0 | ||
1029 | #define STV090x_WIDTH_Px_CFR_UP_FIELD 8 | ||
1030 | |||
1031 | #define STV090x_Pn_CFRLOWy(__x, __y) (0xF447 - (__x - 1) * 0x200 - __y * 0x1) | ||
1032 | #define STV090x_P1_CFRLOW0 STV090x_Pn_CFRLOWy(1, 0) | ||
1033 | #define STV090x_P1_CFRLOW1 STV090x_Pn_CFRLOWy(1, 1) | ||
1034 | #define STV090x_P2_CFRLOW0 STV090x_Pn_CFRLOWy(2, 0) | ||
1035 | #define STV090x_P2_CFRLOW1 STV090x_Pn_CFRLOWy(2, 1) | ||
1036 | #define STV090x_OFFST_Px_CFR_LOW_FIELD 0 | ||
1037 | #define STV090x_WIDTH_Px_CFR_LOW_FIELD 8 | ||
1038 | |||
1039 | #define STV090x_Pn_CFRINITy(__x, __y) (0xF449 - (__x - 1) * 0x200 - __y * 0x1) | ||
1040 | #define STV090x_P1_CFRINIT0 STV090x_Pn_CFRINITy(1, 0) | ||
1041 | #define STV090x_P1_CFRINIT1 STV090x_Pn_CFRINITy(1, 1) | ||
1042 | #define STV090x_P2_CFRINIT0 STV090x_Pn_CFRINITy(2, 0) | ||
1043 | #define STV090x_P2_CFRINIT1 STV090x_Pn_CFRINITy(2, 1) | ||
1044 | #define STV090x_OFFST_Px_CFR_INIT_FIELD 0 | ||
1045 | #define STV090x_WIDTH_Px_CFR_INIT_FIELD 8 | ||
1046 | |||
1047 | #define STV090x_Px_CFRINC1(__x) (0xF44A - (__x - 1) * 0x200) | ||
1048 | #define STV090x_P1_CFRINC1 STV090x_Px_CFRINC1(1) | ||
1049 | #define STV090x_P2_CFRINC1 STV090x_Px_CFRINC1(2) | ||
1050 | #define STV090x_OFFST_Px_CFR_INC1_FIELD 0 | ||
1051 | #define STV090x_WIDTH_Px_CFR_INC1_FIELD 7 | ||
1052 | |||
1053 | #define STV090x_Px_CFRINC0(__x) (0xF44B - (__x - 1) * 0x200) | ||
1054 | #define STV090x_P1_CFRINC0 STV090x_Px_CFRINC0(1) | ||
1055 | #define STV090x_P2_CFRINC0 STV090x_Px_CFRINC0(2) | ||
1056 | #define STV090x_OFFST_Px_CFR_INC0_FIELD 4 | ||
1057 | #define STV090x_WIDTH_Px_CFR_INC0_FIELD 4 | ||
1058 | |||
1059 | #define STV090x_Pn_CFRy(__x, __y) (0xF44E - (__x - 1) * 0x200 - __y * 0x1) | ||
1060 | #define STV090x_P1_CFR0 STV090x_Pn_CFRy(1, 0) | ||
1061 | #define STV090x_P1_CFR1 STV090x_Pn_CFRy(1, 1) | ||
1062 | #define STV090x_P1_CFR2 STV090x_Pn_CFRy(1, 2) | ||
1063 | #define STV090x_P2_CFR0 STV090x_Pn_CFRy(2, 0) | ||
1064 | #define STV090x_P2_CFR1 STV090x_Pn_CFRy(2, 1) | ||
1065 | #define STV090x_P2_CFR2 STV090x_Pn_CFRy(2, 2) | ||
1066 | #define STV090x_OFFST_Px_CAR_FREQ_FIELD 0 | ||
1067 | #define STV090x_WIDTH_Px_CAR_FREQ_FIELD 8 | ||
1068 | |||
1069 | #define STV090x_Px_LDI(__x) (0xF44F - (__x - 1) * 0x200) | ||
1070 | #define STV090x_P1_LDI STV090x_Px_LDI(1) | ||
1071 | #define STV090x_P2_LDI STV090x_Px_LDI(2) | ||
1072 | #define STV090x_OFFST_Px_LOCK_DET_INTEGR_FIELD 0 | ||
1073 | #define STV090x_WIDTH_Px_LOCK_DET_INTEGR_FIELD 8 | ||
1074 | |||
1075 | #define STV090x_Px_TMGCFG(__x) (0xF450 - (__x - 1) * 0x200) | ||
1076 | #define STV090x_P1_TMGCFG STV090x_Px_TMGCFG(1) | ||
1077 | #define STV090x_P2_TMGCFG STV090x_Px_TMGCFG(2) | ||
1078 | #define STV090x_OFFST_Px_TMGLOCK_BETA_FIELD 6 | ||
1079 | #define STV090x_WIDTH_Px_TMGLOCK_BETA_FIELD 2 | ||
1080 | #define STV090x_OFFST_Px_DO_TIMING_FIELD 4 | ||
1081 | #define STV090x_WIDTH_Px_DO_TIMING_FIELD 1 | ||
1082 | #define STV090x_OFFST_Px_TMG_MINFREQ_FIELD 0 | ||
1083 | #define STV090x_WIDTH_Px_TMG_MINFREQ_FIELD 2 | ||
1084 | |||
1085 | #define STV090x_Px_RTC(__x) (0xF451 - (__x - 1) * 0x200) | ||
1086 | #define STV090x_P1_RTC STV090x_Px_RTC(1) | ||
1087 | #define STV090x_P2_RTC STV090x_Px_RTC(2) | ||
1088 | #define STV090x_OFFST_Px_TMGALPHA_EXP_FIELD 4 | ||
1089 | #define STV090x_WIDTH_Px_TMGALPHA_EXP_FIELD 4 | ||
1090 | #define STV090x_OFFST_Px_TMGBETA_EXP_FIELD 0 | ||
1091 | #define STV090x_WIDTH_Px_TMGBETA_EXP_FIELD 4 | ||
1092 | |||
1093 | #define STV090x_Px_RTCS2(__x) (0xF452 - (__x - 1) * 0x200) | ||
1094 | #define STV090x_P1_RTCS2 STV090x_Px_RTCS2(1) | ||
1095 | #define STV090x_P2_RTCS2 STV090x_Px_RTCS2(2) | ||
1096 | #define STV090x_OFFST_Px_TMGALPHAS2_EXP_FIELD 4 | ||
1097 | #define STV090x_WIDTH_Px_TMGALPHAS2_EXP_FIELD 4 | ||
1098 | #define STV090x_OFFST_Px_TMGBETAS2_EXP_FIELD 0 | ||
1099 | #define STV090x_WIDTH_Px_TMGBETAS2_EXP_FIELD 4 | ||
1100 | |||
1101 | #define STV090x_Px_TMGTHRISE(__x) (0xF453 - (__x - 1) * 0x200) | ||
1102 | #define STV090x_P1_TMGTHRISE STV090x_Px_TMGTHRISE(1) | ||
1103 | #define STV090x_P2_TMGTHRISE STV090x_Px_TMGTHRISE(2) | ||
1104 | #define STV090x_OFFST_Px_TMGLOCK_THRISE_FIELD 0 | ||
1105 | #define STV090x_WIDTH_Px_TMGLOCK_THRISE_FIELD 8 | ||
1106 | |||
1107 | #define STV090x_Px_TMGTHFALL(__x) (0xF454 - (__x - 1) * 0x200) | ||
1108 | #define STV090x_P1_TMGTHFALL STV090x_Px_TMGTHFALL(1) | ||
1109 | #define STV090x_P2_TMGTHFALL STV090x_Px_TMGTHFALL(2) | ||
1110 | #define STV090x_OFFST_Px_TMGLOCK_THFALL_FIELD 0 | ||
1111 | #define STV090x_WIDTH_Px_TMGLOCK_THFALL_FIELD 8 | ||
1112 | |||
1113 | #define STV090x_Px_SFRUPRATIO(__x) (0xF455 - (__x - 1) * 0x200) | ||
1114 | #define STV090x_P1_SFRUPRATIO STV090x_Px_SFRUPRATIO(1) | ||
1115 | #define STV090x_P2_SFRUPRATIO STV090x_Px_SFRUPRATIO(2) | ||
1116 | #define STV090x_OFFST_Px_SFR_UPRATIO_FIELD 0 | ||
1117 | #define STV090x_WIDTH_Px_SFR_UPRATIO_FIELD 8 | ||
1118 | |||
1119 | #define STV090x_Px_SFRLOWRATIO(__x) (0xF456 - (__x - 1) * 0x200) | ||
1120 | #define STV090x_P1_SFRLOWRATIO STV090x_Px_SFRLOWRATIO(1) | ||
1121 | #define STV090x_P2_SFRLOWRATIO STV090x_Px_SFRLOWRATIO(2) | ||
1122 | #define STV090x_OFFST_Px_SFR_LOWRATIO_FIELD 0 | ||
1123 | #define STV090x_WIDTH_Px_SFR_LOWRATIO_FIELD 8 | ||
1124 | |||
1125 | #define STV090x_Px_KREFTMG(__x) (0xF458 - (__x - 1) * 0x200) | ||
1126 | #define STV090x_P1_KREFTMG STV090x_Px_KREFTMG(1) | ||
1127 | #define STV090x_P2_KREFTMG STV090x_Px_KREFTMG(2) | ||
1128 | #define STV090x_OFFST_Px_KREF_TMG_FIELD 0 | ||
1129 | #define STV090x_WIDTH_Px_KREF_TMG_FIELD 8 | ||
1130 | |||
1131 | #define STV090x_Px_SFRSTEP(__x) (0xF459 - (__x - 1) * 0x200) | ||
1132 | #define STV090x_P1_SFRSTEP STV090x_Px_SFRSTEP(1) | ||
1133 | #define STV090x_P2_SFRSTEP STV090x_Px_SFRSTEP(2) | ||
1134 | #define STV090x_OFFST_Px_SFR_SCANSTEP_FIELD 4 | ||
1135 | #define STV090x_WIDTH_Px_SFR_SCANSTEP_FIELD 4 | ||
1136 | #define STV090x_OFFST_Px_SFR_CENTERSTEP_FIELD 0 | ||
1137 | #define STV090x_WIDTH_Px_SFR_CENTERSTEP_FIELD 4 | ||
1138 | |||
1139 | #define STV090x_Px_TMGCFG2(__x) (0xF45A - (__x - 1) * 0x200) | ||
1140 | #define STV090x_P1_TMGCFG2 STV090x_Px_TMGCFG2(1) | ||
1141 | #define STV090x_P2_TMGCFG2 STV090x_Px_TMGCFG2(2) | ||
1142 | #define STV090x_OFFST_Px_SFRRATIO_FINE_FIELD 0 | ||
1143 | #define STV090x_WIDTH_Px_SFRRATIO_FINE_FIELD 1 | ||
1144 | |||
1145 | #define STV090x_Px_SFRINIT1(__x) (0xF45E - (__x - 1) * 0x200) | ||
1146 | #define STV090x_P1_SFRINIT1 STV090x_Px_SFRINIT1(1) | ||
1147 | #define STV090x_P2_SFRINIT1 STV090x_Px_SFRINIT1(2) | ||
1148 | #define STV090x_OFFST_Px_SFR_INIT_FIELD 0 | ||
1149 | #define STV090x_WIDTH_Px_SFR_INIT_FIELD 8 | ||
1150 | |||
1151 | #define STV090x_Px_SFRINIT0(__x) (0xF45F - (__x - 1) * 0x200) | ||
1152 | #define STV090x_P1_SFRINIT0 STV090x_Px_SFRINIT0(1) | ||
1153 | #define STV090x_P2_SFRINIT0 STV090x_Px_SFRINIT0(2) | ||
1154 | #define STV090x_OFFST_Px_SFR_INIT_FIELD 0 | ||
1155 | #define STV090x_WIDTH_Px_SFR_INIT_FIELD 8 | ||
1156 | |||
1157 | #define STV090x_Px_SFRUP1(__x) (0xF460 - (__x - 1) * 0x200) | ||
1158 | #define STV090x_P1_SFRUP1 STV090x_Px_SFRUP1(1) | ||
1159 | #define STV090x_P2_SFRUP1 STV090x_Px_SFRUP1(2) | ||
1160 | #define STV090x_OFFST_Px_SYMB_FREQ_UP1_FIELD 0 | ||
1161 | #define STV090x_WIDTH_Px_SYMB_FREQ_UP1_FIELD 7 | ||
1162 | |||
1163 | #define STV090x_Px_SFRUP0(__x) (0xF461 - (__x - 1) * 0x200) | ||
1164 | #define STV090x_P1_SFRUP0 STV090x_Px_SFRUP0(1) | ||
1165 | #define STV090x_P2_SFRUP0 STV090x_Px_SFRUP0(2) | ||
1166 | #define STV090x_OFFST_Px_SYMB_FREQ_UP0_FIELD 0 | ||
1167 | #define STV090x_WIDTH_Px_SYMB_FREQ_UP0_FIELD 8 | ||
1168 | |||
1169 | #define STV090x_Px_SFRLOW1(__x) (0xF462 - (__x - 1) * 0x200) | ||
1170 | #define STV090x_P1_SFRLOW1 STV090x_Px_SFRLOW1(1) | ||
1171 | #define STV090x_P2_SFRLOW1 STV090x_Px_SFRLOW1(2) | ||
1172 | #define STV090x_OFFST_Px_SYMB_FREQ_LOW1_FIELD 0 | ||
1173 | #define STV090x_WIDTH_Px_SYMB_FREQ_LOW1_FIELD 7 | ||
1174 | |||
1175 | #define STV090x_Px_SFRLOW0(__x) (0xF463 - (__x - 1) * 0x200) | ||
1176 | #define STV090x_P1_SFRLOW0 STV090x_Px_SFRLOW0(1) | ||
1177 | #define STV090x_P2_SFRLOW0 STV090x_Px_SFRLOW0(2) | ||
1178 | #define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD 0 | ||
1179 | #define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD 8 | ||
1180 | |||
1181 | #define STV090x_Px_SFRy(__x, __y) (0xF464 - (__x-1) * 0x200 + (3 - __y)) | ||
1182 | #define STV090x_P1_SFR0 STV090x_Px_SFRy(1, 0) | ||
1183 | #define STV090x_P1_SFR1 STV090x_Px_SFRy(1, 1) | ||
1184 | #define STV090x_P1_SFR2 STV090x_Px_SFRy(1, 2) | ||
1185 | #define STV090x_P1_SFR3 STV090x_Px_SFRy(1, 3) | ||
1186 | #define STV090x_P2_SFR0 STV090x_Px_SFRy(2, 0) | ||
1187 | #define STV090x_P2_SFR1 STV090x_Px_SFRy(2, 1) | ||
1188 | #define STV090x_P2_SFR2 STV090x_Px_SFRy(2, 2) | ||
1189 | #define STV090x_P2_SFR3 STV090x_Px_SFRy(2, 3) | ||
1190 | #define STV090x_OFFST_Px_SYMB_FREQ_FIELD 0 | ||
1191 | #define STV090x_WIDTH_Px_SYMB_FREQ_FIELD 32 | ||
1192 | |||
1193 | #define STV090x_Px_TMGREG2(__x) (0xF468 - (__x - 1) * 0x200) | ||
1194 | #define STV090x_P1_TMGREG2 STV090x_Px_TMGREG2(1) | ||
1195 | #define STV090x_P2_TMGREG2 STV090x_Px_TMGREG2(2) | ||
1196 | #define STV090x_OFFST_Px_TMGREG_FIELD 0 | ||
1197 | #define STV090x_WIDTH_Px_TMGREG_FIELD 8 | ||
1198 | |||
1199 | #define STV090x_Px_TMGREG1(__x) (0xF469 - (__x - 1) * 0x200) | ||
1200 | #define STV090x_P1_TMGREG1 STV090x_Px_TMGREG1(1) | ||
1201 | #define STV090x_P2_TMGREG1 STV090x_Px_TMGREG1(2) | ||
1202 | #define STV090x_OFFST_Px_TMGREG_FIELD 0 | ||
1203 | #define STV090x_WIDTH_Px_TMGREG_FIELD 8 | ||
1204 | |||
1205 | #define STV090x_Px_TMGREG0(__x) (0xF46A - (__x - 1) * 0x200) | ||
1206 | #define STV090x_P1_TMGREG0 STV090x_Px_TMGREG0(1) | ||
1207 | #define STV090x_P2_TMGREG0 STV090x_Px_TMGREG0(2) | ||
1208 | #define STV090x_OFFST_Px_TMGREG_FIELD 0 | ||
1209 | #define STV090x_WIDTH_Px_TMGREG_FIELD 8 | ||
1210 | |||
1211 | #define STV090x_Px_TMGLOCKy(__x, __y) (0xF46C - (__x - 1) * 0x200 - __y * 0x1) | ||
1212 | #define STV090x_P1_TMGLOCK0 STV090x_Px_TMGLOCKy(1, 0) | ||
1213 | #define STV090x_P1_TMGLOCK1 STV090x_Px_TMGLOCKy(1, 1) | ||
1214 | #define STV090x_P2_TMGLOCK0 STV090x_Px_TMGLOCKy(2, 0) | ||
1215 | #define STV090x_P2_TMGLOCK1 STV090x_Px_TMGLOCKy(2, 1) | ||
1216 | #define STV090x_OFFST_Px_TMGLOCK_LEVEL_FIELD 0 | ||
1217 | #define STV090x_WIDTH_Px_TMGLOCK_LEVEL_FIELD 8 | ||
1218 | |||
1219 | #define STV090x_Px_TMGOBS(__x) (0xF46D - (__x - 1) * 0x200) | ||
1220 | #define STV090x_P1_TMGOBS STV090x_Px_TMGOBS(1) | ||
1221 | #define STV090x_P2_TMGOBS STV090x_Px_TMGOBS(2) | ||
1222 | #define STV090x_OFFST_Px_ROLLOFF_STATUS_FIELD 6 | ||
1223 | #define STV090x_WIDTH_Px_ROLLOFF_STATUS_FIELD 2 | ||
1224 | |||
1225 | #define STV090x_Px_EQUALCFG(__x) (0xF46F - (__x - 1) * 0x200) | ||
1226 | #define STV090x_P1_EQUALCFG STV090x_Px_EQUALCFG(1) | ||
1227 | #define STV090x_P2_EQUALCFG STV090x_Px_EQUALCFG(2) | ||
1228 | #define STV090x_OFFST_Px_EQUAL_ON_FIELD 6 | ||
1229 | #define STV090x_WIDTH_Px_EQUAL_ON_FIELD 1 | ||
1230 | #define STV090x_OFFST_Px_MU_EQUALDFE_FIELD 0 | ||
1231 | #define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD 3 | ||
1232 | |||
1233 | #define STV090x_Px_EQUAIy(__x, __y) (0xf470 - (__x - 1) * 0x200 + (__y - 1)) | ||
1234 | #define STV090x_P1_EQUAI1 STV090x_Px_EQUAIy(1, 1) | ||
1235 | #define STV090x_P1_EQUAI2 STV090x_Px_EQUAIy(1, 2) | ||
1236 | #define STV090x_P1_EQUAI3 STV090x_Px_EQUAIy(1, 3) | ||
1237 | #define STV090x_P1_EQUAI4 STV090x_Px_EQUAIy(1, 4) | ||
1238 | #define STV090x_P1_EQUAI5 STV090x_Px_EQUAIy(1, 5) | ||
1239 | #define STV090x_P1_EQUAI6 STV090x_Px_EQUAIy(1, 6) | ||
1240 | #define STV090x_P1_EQUAI7 STV090x_Px_EQUAIy(1, 7) | ||
1241 | #define STV090x_P1_EQUAI8 STV090x_Px_EQUAIy(1, 8) | ||
1242 | |||
1243 | #define STV090x_P2_EQUAI1 STV090x_Px_EQUAIy(2, 1) | ||
1244 | #define STV090x_P2_EQUAI2 STV090x_Px_EQUAIy(2, 2) | ||
1245 | #define STV090x_P2_EQUAI3 STV090x_Px_EQUAIy(2, 3) | ||
1246 | #define STV090x_P2_EQUAI4 STV090x_Px_EQUAIy(2, 4) | ||
1247 | #define STV090x_P2_EQUAI5 STV090x_Px_EQUAIy(2, 5) | ||
1248 | #define STV090x_P2_EQUAI6 STV090x_Px_EQUAIy(2, 6) | ||
1249 | #define STV090x_P2_EQUAI7 STV090x_Px_EQUAIy(2, 7) | ||
1250 | #define STV090x_P2_EQUAI8 STV090x_Px_EQUAIy(2, 8) | ||
1251 | #define STV090x_OFFST_Px_EQUA_ACCIy_FIELD 0 | ||
1252 | #define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD 8 | ||
1253 | |||
1254 | #define STV090x_Px_EQUAQy(__x, __y) (0xf471 - (__x - 1) * 0x200 + (__y - 1)) | ||
1255 | #define STV090x_P1_EQUAQ1 STV090x_Px_EQUAQy(1, 1) | ||
1256 | #define STV090x_P1_EQUAQ2 STV090x_Px_EQUAQy(1, 2) | ||
1257 | #define STV090x_P1_EQUAQ3 STV090x_Px_EQUAQy(1, 3) | ||
1258 | #define STV090x_P1_EQUAQ4 STV090x_Px_EQUAQy(1, 4) | ||
1259 | #define STV090x_P1_EQUAQ5 STV090x_Px_EQUAQy(1, 5) | ||
1260 | #define STV090x_P1_EQUAQ6 STV090x_Px_EQUAQy(1, 6) | ||
1261 | #define STV090x_P1_EQUAQ7 STV090x_Px_EQUAQy(1, 7) | ||
1262 | #define STV090x_P1_EQUAQ8 STV090x_Px_EQUAQy(1, 8) | ||
1263 | |||
1264 | #define STV090x_P2_EQUAQ1 STV090x_Px_EQUAQy(2, 1) | ||
1265 | #define STV090x_P2_EQUAQ2 STV090x_Px_EQUAQy(2, 2) | ||
1266 | #define STV090x_P2_EQUAQ3 STV090x_Px_EQUAQy(2, 3) | ||
1267 | #define STV090x_P2_EQUAQ4 STV090x_Px_EQUAQy(2, 4) | ||
1268 | #define STV090x_P2_EQUAQ5 STV090x_Px_EQUAQy(2, 5) | ||
1269 | #define STV090x_P2_EQUAQ6 STV090x_Px_EQUAQy(2, 6) | ||
1270 | #define STV090x_P2_EQUAQ7 STV090x_Px_EQUAQy(2, 7) | ||
1271 | #define STV090x_P2_EQUAQ8 STV090x_Px_EQUAQy(2, 8) | ||
1272 | #define STV090x_OFFST_Px_EQUA_ACCQy_FIELD 0 | ||
1273 | #define STV090x_WIDTH_Px_EQUA_ACCQy_FIELD 8 | ||
1274 | |||
1275 | #define STV090x_Px_NNOSDATATy(__x, __y) (0xf481 - (__x - 1) * 0x200 - __y * 0x1) | ||
1276 | #define STV090x_P1_NNOSDATAT0 STV090x_Px_NNOSDATATy(1, 0) | ||
1277 | #define STV090x_P1_NNOSDATAT1 STV090x_Px_NNOSDATATy(1, 1) | ||
1278 | #define STV090x_P2_NNOSDATAT0 STV090x_Px_NNOSDATATy(2, 0) | ||
1279 | #define STV090x_P2_NNOSDATAT1 STV090x_Px_NNOSDATATy(2, 1) | ||
1280 | #define STV090x_OFFST_Px_NOSDATAT_NORMED_FIELD 0 | ||
1281 | #define STV090x_WIDTH_Px_NOSDATAT_NORMED_FIELD 8 | ||
1282 | |||
1283 | #define STV090x_Px_NNOSDATAy(__x, __y) (0xf483 - (__x - 1) * 0x200 - __y * 0x1) | ||
1284 | #define STV090x_P1_NNOSDATA0 STV090x_Px_NNOSDATAy(1, 0) | ||
1285 | #define STV090x_P1_NNOSDATA1 STV090x_Px_NNOSDATAy(1, 1) | ||
1286 | #define STV090x_P2_NNOSDATA0 STV090x_Px_NNOSDATAy(2, 0) | ||
1287 | #define STV090x_P2_NNOSDATA1 STV090x_Px_NNOSDATAy(2, 1) | ||
1288 | #define STV090x_OFFST_Px_NOSDATA_NORMED_FIELD 0 | ||
1289 | #define STV090x_WIDTH_Px_NOSDATA_NORMED_FIELD 8 | ||
1290 | |||
1291 | #define STV090x_Px_NNOSPLHTy(__x, __y) (0xf485 - (__x - 1) * 0x200 - __y * 0x1) | ||
1292 | #define STV090x_P1_NNOSPLHT0 STV090x_Px_NNOSPLHTy(1, 0) | ||
1293 | #define STV090x_P1_NNOSPLHT1 STV090x_Px_NNOSPLHTy(1, 1) | ||
1294 | #define STV090x_P2_NNOSPLHT0 STV090x_Px_NNOSPLHTy(2, 0) | ||
1295 | #define STV090x_P2_NNOSPLHT1 STV090x_Px_NNOSPLHTy(2, 1) | ||
1296 | #define STV090x_OFFST_Px_NOSPLHT_NORMED_FIELD 0 | ||
1297 | #define STV090x_WIDTH_Px_NOSPLHT_NORMED_FIELD 8 | ||
1298 | |||
1299 | #define STV090x_Px_NNOSPLHy(__x, __y) (0xf487 - (__x - 1) * 0x200 - __y * 0x1) | ||
1300 | #define STV090x_P1_NNOSPLH0 STV090x_Px_NNOSPLHy(1, 0) | ||
1301 | #define STV090x_P1_NNOSPLH1 STV090x_Px_NNOSPLHy(1, 1) | ||
1302 | #define STV090x_P2_NNOSPLH0 STV090x_Px_NNOSPLHy(2, 0) | ||
1303 | #define STV090x_P2_NNOSPLH1 STV090x_Px_NNOSPLHy(2, 1) | ||
1304 | #define STV090x_OFFST_Px_NOSPLH_NORMED_FIELD 0 | ||
1305 | #define STV090x_WIDTH_Px_NOSPLH_NORMED_FIELD 8 | ||
1306 | |||
1307 | #define STV090x_Px_NOSDATATy(__x, __y) (0xf489 - (__x - 1) * 0x200 - __y * 0x1) | ||
1308 | #define STV090x_P1_NOSDATAT0 STV090x_Px_NOSDATATy(1, 0) | ||
1309 | #define STV090x_P1_NOSDATAT1 STV090x_Px_NOSDATATy(1, 1) | ||
1310 | #define STV090x_P2_NOSDATAT0 STV090x_Px_NOSDATATy(2, 0) | ||
1311 | #define STV090x_P2_NOSDATAT1 STV090x_Px_NOSDATATy(2, 1) | ||
1312 | #define STV090x_OFFST_Px_NOSDATAT_UNNORMED_FIELD 0 | ||
1313 | #define STV090x_WIDTH_Px_NOSDATAT_UNNORMED_FIELD 8 | ||
1314 | |||
1315 | #define STV090x_Px_NOSDATAy(__x, __y) (0xf48b - (__x - 1) * 0x200 - __y * 0x1) | ||
1316 | #define STV090x_P1_NOSDATA0 STV090x_Px_NOSDATAy(1, 0) | ||
1317 | #define STV090x_P1_NOSDATA1 STV090x_Px_NOSDATAy(1, 1) | ||
1318 | #define STV090x_P2_NOSDATA0 STV090x_Px_NOSDATAy(2, 0) | ||
1319 | #define STV090x_P2_NOSDATA1 STV090x_Px_NOSDATAy(2, 1) | ||
1320 | #define STV090x_OFFST_Px_NOSDATA_UNNORMED_FIELD 0 | ||
1321 | #define STV090x_WIDTH_Px_NOSDATA_UNNORMED_FIELD 8 | ||
1322 | |||
1323 | #define STV090x_Px_NOSPLHTy(__x, __y) (0xf48d - (__x - 1) * 0x200 - __y * 0x1) | ||
1324 | #define STV090x_P1_NOSPLHT0 STV090x_Px_NOSPLHTy(1, 0) | ||
1325 | #define STV090x_P1_NOSPLHT1 STV090x_Px_NOSPLHTy(1, 1) | ||
1326 | #define STV090x_P2_NOSPLHT0 STV090x_Px_NOSPLHTy(2, 0) | ||
1327 | #define STV090x_P2_NOSPLHT1 STV090x_Px_NOSPLHTy(2, 1) | ||
1328 | #define STV090x_OFFST_Px_NOSPLHT_UNNORMED_FIELD 0 | ||
1329 | #define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD 8 | ||
1330 | |||
1331 | #define STV090x_Px_NOSPLHy(__x, __y) (0xf48f - (__x - 1) * 0x200 - __y * 0x1) | ||
1332 | #define STv090x_P1_NOSPLH0 STV090x_Px_NOSPLHy(1, 0) | ||
1333 | #define STv090x_P1_NOSPLH1 STV090x_Px_NOSPLHy(1, 1) | ||
1334 | #define STv090x_P2_NOSPLH0 STV090x_Px_NOSPLHy(2, 0) | ||
1335 | #define STv090x_P2_NOSPLH1 STV090x_Px_NOSPLHy(2, 1) | ||
1336 | #define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0 | ||
1337 | #define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8 | ||
1338 | |||
1339 | #define STV090x_Px_CAR2CFG(__x) (0xf490 - (__x - 1) * 0x200) | ||
1340 | #define STV090x_P1_CAR2CFG STV090x_Px_CAR2CFG(1) | ||
1341 | #define STV090x_P2_CAR2CFG STV090x_Px_CAR2CFG(2) | ||
1342 | #define STV090x_OFFST_Px_PN4_SELECT_FIELD 6 | ||
1343 | #define STV090x_WIDTH_Px_PN4_SELECT_FIELD 1 | ||
1344 | #define STV090x_OFFST_Px_CFR2_STOPDVBS1_FIELD 5 | ||
1345 | #define STV090x_WIDTH_Px_CFR2_STOPDVBS1_FIELD 1 | ||
1346 | #define STV090x_OFFST_Px_ROTA2ON_FIELD 2 | ||
1347 | #define STV090x_WIDTH_Px_ROTA2ON_FIELD 1 | ||
1348 | #define STV090x_OFFST_Px_PH_DET_ALGO2_FIELD 0 | ||
1349 | #define STV090x_WIDTH_Px_PH_DET_ALGO2_FIELD 2 | ||
1350 | |||
1351 | #define STV090x_Px_ACLC2(__x) (0xf491 - (__x - 1) * 0x200) | ||
1352 | #define STV090x_P1_ACLC2 STV090x_Px_ACLC2(1) | ||
1353 | #define STV090x_P2_ACLC2 STV090x_Px_ACLC2(2) | ||
1354 | #define STV090x_OFFST_Px_CAR2_ALPHA_MANT_FIELD 4 | ||
1355 | #define STV090x_WIDTH_Px_CAR2_ALPHA_MANT_FIELD 2 | ||
1356 | #define STV090x_OFFST_Px_CAR2_ALPHA_EXP_FIELD 0 | ||
1357 | #define STV090x_WIDTH_Px_CAR2_ALPHA_EXP_FIELD 4 | ||
1358 | |||
1359 | #define STV090x_Px_BCLC2(__x) (0xf492 - (__x - 1) * 0x200) | ||
1360 | #define STV090x_P1_BCLC2 STV090x_Px_BCLC2(1) | ||
1361 | #define STV090x_P2_BCLC2 STV090x_Px_BCLC2(2) | ||
1362 | #define STV090x_OFFST_Px_CAR2_BETA_MANT_FIELD 4 | ||
1363 | #define STV090x_WIDTH_Px_CAR2_BETA_MANT_FIELD 2 | ||
1364 | #define STV090x_OFFST_Px_CAR2_BETA_EXP_FIELD 0 | ||
1365 | #define STV090x_WIDTH_Px_CAR2_BETA_EXP_FIELD 4 | ||
1366 | |||
1367 | #define STV090x_Px_ACLC2S2Q(__x) (0xf497 - (__x - 1) * 0x200) | ||
1368 | #define STV090x_P1_ACLC2S2Q STV090x_Px_ACLC2S2Q(1) | ||
1369 | #define STV090x_P2_ACLC2S2Q STV090x_Px_ACLC2S2Q(2) | ||
1370 | #define STV090x_OFFST_Px_ENAB_SPSKSYMB_FIELD 7 | ||
1371 | #define STV090x_WIDTH_Px_ENAB_SPSKSYMB_FIELD 1 | ||
1372 | #define STV090x_OFFST_Px_CAR2S2_Q_ALPH_M_FIELD 4 | ||
1373 | #define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_M_FIELD 2 | ||
1374 | #define STV090x_OFFST_Px_CAR2S2_Q_ALPH_E_FIELD 0 | ||
1375 | #define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_E_FIELD 4 | ||
1376 | |||
1377 | #define STV090x_Px_ACLC2S28(__x) (0xf498 - (__x - 1) * 0x200) | ||
1378 | #define STV090x_P1_ACLC2S28 STV090x_Px_ACLC2S28(1) | ||
1379 | #define STV090x_P2_ACLC2S28 STV090x_Px_ACLC2S28(2) | ||
1380 | #define STV090x_OFFST_Px_CAR2S2_8_ALPH_M_FIELD 4 | ||
1381 | #define STV090x_WIDTH_Px_CAR2S2_8_ALPH_M_FIELD 2 | ||
1382 | #define STV090x_OFFST_Px_CAR2S2_8_ALPH_E_FIELD 0 | ||
1383 | #define STV090x_WIDTH_Px_CAR2S2_8_ALPH_E_FIELD 4 | ||
1384 | |||
1385 | #define STV090x_Px_ACLC2S216A(__x) (0xf499 - (__x - 1) * 0x200) | ||
1386 | #define STV090x_P1_ACLC2S216A STV090x_Px_ACLC2S216A(1) | ||
1387 | #define STV090x_P2_ACLC2S216A STV090x_Px_ACLC2S216A(2) | ||
1388 | #define STV090x_OFFST_Px_CAR2S2_16A_ALPH_M_FIELD 4 | ||
1389 | #define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_M_FIELD 2 | ||
1390 | #define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD 0 | ||
1391 | #define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD 4 | ||
1392 | |||
1393 | #define STV090x_Px_ACLC2S232A(__x) (0xf499 - (__x - 1) * 0x200) | ||
1394 | #define STV090x_P1_ACLC2S232A STV090x_Px_ACLC2S232A(1) | ||
1395 | #define STV090x_P2_ACLC2S232A STV090x_Px_ACLC2S232A(2) | ||
1396 | #define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD 4 | ||
1397 | #define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_M_FIELD 2 | ||
1398 | #define STV090x_OFFST_Px_CAR2S2_32A_ALPH_E_FIELD 0 | ||
1399 | #define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_E_FIELD 4 | ||
1400 | |||
1401 | #define STV090x_Px_BCLC2S2Q(__x) (0xf49c - (__x - 1) * 0x200) | ||
1402 | #define STV090x_P1_BCLC2S2Q STV090x_Px_BCLC2S2Q(1) | ||
1403 | #define STV090x_P2_BCLC2S2Q STV090x_Px_BCLC2S2Q(2) | ||
1404 | #define STV090x_OFFST_Px_CAR2S2_Q_BETA_M_FIELD 4 | ||
1405 | #define STV090x_WIDTH_Px_CAR2S2_Q_BETA_M_FIELD 2 | ||
1406 | #define STV090x_OFFST_Px_CAR2S2_Q_BETA_E_FIELD 0 | ||
1407 | #define STV090x_WIDTH_Px_CAR2S2_Q_BETA_E_FIELD 4 | ||
1408 | |||
1409 | #define STV090x_Px_BCLC2S28(__x) (0xf49d - (__x - 1) * 0x200) | ||
1410 | #define STV090x_P1_BCLC2S28 STV090x_Px_BCLC2S28(1) | ||
1411 | #define STV090x_P2_BCLC2S28 STV090x_Px_BCLC2S28(1) | ||
1412 | #define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4 | ||
1413 | #define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2 | ||
1414 | #define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0 | ||
1415 | #define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD 4 | ||
1416 | |||
1417 | #define STV090x_Px_BCLC2S216A(__x) (0xf49d - (__x - 1) * 0x200) | ||
1418 | #define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1) | ||
1419 | #define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(1) | ||
1420 | #define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4 | ||
1421 | #define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD 2 | ||
1422 | #define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0 | ||
1423 | #define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD 4 | ||
1424 | |||
1425 | #define STV090x_Px_BCLC2S232A(__x) (0xf49d - (__x - 1) * 0x200) | ||
1426 | #define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1) | ||
1427 | #define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(1) | ||
1428 | #define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4 | ||
1429 | #define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD 2 | ||
1430 | #define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD 0 | ||
1431 | #define STV090x_WIDTH_Px_CAR2S2_32A_BETA_E_FIELD 4 | ||
1432 | |||
1433 | #define STV090x_Px_PLROOT2(__x) (0xf4ac - (__x - 1) * 0x200) | ||
1434 | #define STV090x_P1_PLROOT2 STV090x_Px_PLROOT2(1) | ||
1435 | #define STV090x_P2_PLROOT2 STV090x_Px_PLROOT2(2) | ||
1436 | #define STV090x_OFFST_Px_PLSCRAMB_MODE_FIELD 2 | ||
1437 | #define STV090x_WIDTH_Px_PLSCRAMB_MODE_FIELD 2 | ||
1438 | #define STV090x_OFFST_Px_PLSCRAMB_ROOT_FIELD 0 | ||
1439 | #define STV090x_WIDTH_Px_PLSCRAMB_ROOT_FIELD 2 | ||
1440 | |||
1441 | #define STV090x_Px_PLROOT1(__x) (0xf4ad - (__x - 1) * 0x200) | ||
1442 | #define STV090x_P1_PLROOT1 STV090x_Px_PLROOT1(1) | ||
1443 | #define STV090x_P2_PLROOT1 STV090x_Px_PLROOT1(2) | ||
1444 | #define STV090x_OFFST_Px_PLSCRAMB_ROOT1_FIELD 0 | ||
1445 | #define STV090x_WIDTH_Px_PLSCRAMB_ROOT1_FIELD 8 | ||
1446 | |||
1447 | #define STV090x_Px_PLROOT0(__x) (0xf4ae - (__x - 1) * 0x200) | ||
1448 | #define STV090x_P1_PLROOT0 STV090x_Px_PLROOT0(1) | ||
1449 | #define STV090x_P2_PLROOT0 STV090x_Px_PLROOT0(2) | ||
1450 | #define STV090x_OFFST_Px_PLSCRAMB_ROOT0_FIELD 0 | ||
1451 | #define STV090x_WIDTH_Px_PLSCRAMB_ROOT0_FIELD 8 | ||
1452 | |||
1453 | #define STV090x_Px_MODCODLST0(__x) (0xf4b0 - (__x - 1) * 0x200) /* check */ | ||
1454 | #define STV090x_P1_MODCODLST0 STV090x_Px_MODCODLST0(1) | ||
1455 | #define STV090x_P2_MODCODLST0 STV090x_Px_MODCODLST0(2) | ||
1456 | |||
1457 | #define STV090x_Px_MODCODLST1(__x) (0xf4b1 - (__x - 1) * 0x200) | ||
1458 | #define STV090x_P1_MODCODLST1 STV090x_Px_MODCODLST1(1) | ||
1459 | #define STV090x_P2_MODCODLST1 STV090x_Px_MODCODLST1(2) | ||
1460 | #define STV090x_OFFST_Px_DIS_MODCOD29_FIELD 4 | ||
1461 | #define STV090x_WIDTH_Px_DIS_MODCOD29T_FIELD 4 | ||
1462 | #define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD 0 | ||
1463 | #define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD 4 | ||
1464 | |||
1465 | #define STV090x_Px_MODCODLST2(__x) (0xf4b2 - (__x - 1) * 0x200) | ||
1466 | #define STV090x_P1_MODCODLST2 STV090x_Px_MODCODLST2(1) | ||
1467 | #define STV090x_P2_MODCODLST2 STV090x_Px_MODCODLST2(2) | ||
1468 | #define STV090x_OFFST_Px_DIS_32PSK_8_9_FIELD 4 | ||
1469 | #define STV090x_WIDTH_Px_DIS_32PSK_8_9_FIELD 4 | ||
1470 | #define STV090x_OFFST_Px_DIS_32PSK_5_6_FIELD 0 | ||
1471 | #define STV090x_WIDTH_Px_DIS_32PSK_5_6_FIELD 4 | ||
1472 | |||
1473 | #define STV090x_Px_MODCODLST3(__x) (0xf4b3 - (__x - 1) * 0x200) | ||
1474 | #define STV090x_P1_MODCODLST3 STV090x_Px_MODCODLST3(1) | ||
1475 | #define STV090x_P2_MODCODLST3 STV090x_Px_MODCODLST3(2) | ||
1476 | #define STV090x_OFFST_Px_DIS_32PSK_4_5_FIELD 4 | ||
1477 | #define STV090x_WIDTH_Px_DIS_32PSK_4_5_FIELD 4 | ||
1478 | #define STV090x_OFFST_Px_DIS_32PSK_3_4_FIELD 0 | ||
1479 | #define STV090x_WIDTH_Px_DIS_32PSK_3_4_FIELD 4 | ||
1480 | |||
1481 | #define STV090x_Px_MODCODLST4(__x) (0xf4b4 - (__x - 1) * 0x200) | ||
1482 | #define STV090x_P1_MODCODLST4 STV090x_Px_MODCODLST4(1) | ||
1483 | #define STV090x_P2_MODCODLST4 STV090x_Px_MODCODLST4(2) | ||
1484 | #define STV090x_OFFST_Px_DIS_16PSK_9_10_FIELD 4 | ||
1485 | #define STV090x_WIDTH_Px_DIS_16PSK_9_10_FIELD 4 | ||
1486 | #define STV090x_OFFST_Px_DIS_16PSK_8_9_FIELD 0 | ||
1487 | #define STV090x_WIDTH_Px_DIS_16PSK_8_9_FIELD 4 | ||
1488 | |||
1489 | #define STV090x_Px_MODCODLST5(__x) (0xf4b5 - (__x - 1) * 0x200) | ||
1490 | #define STV090x_P1_MODCODLST5 STV090x_Px_MODCODLST5(1) | ||
1491 | #define STV090x_P2_MODCODLST5 STV090x_Px_MODCODLST5(2) | ||
1492 | #define STV090x_OFFST_Px_DIS_16PSK_5_6_FIELD 4 | ||
1493 | #define STV090x_WIDTH_Px_DIS_16PSK_5_6_FIELD 4 | ||
1494 | #define STV090x_OFFST_Px_DIS_16PSK_4_5_FIELD 0 | ||
1495 | #define STV090x_WIDTH_Px_DIS_16PSK_4_5_FIELD 4 | ||
1496 | |||
1497 | #define STV090x_Px_MODCODLST6(__x) (0xf4b6 - (__x - 1) * 0x200) | ||
1498 | #define STV090x_P1_MODCODLST6 STV090x_Px_MODCODLST6(1) | ||
1499 | #define STV090x_P2_MODCODLST6 STV090x_Px_MODCODLST6(2) | ||
1500 | #define STV090x_OFFST_Px_DIS_16PSK_3_4_FIELD 4 | ||
1501 | #define STV090x_WIDTH_Px_DIS_16PSK_3_4_FIELD 4 | ||
1502 | #define STV090x_OFFST_Px_DIS_16PSK_2_3_FIELD 0 | ||
1503 | #define STV090x_WIDTH_Px_DIS_16PSK_2_3_FIELD 4 | ||
1504 | |||
1505 | #define STV090x_Px_MODCODLST7(__x) (0xf4b7 - (__x - 1) * 0x200) | ||
1506 | #define STV090x_P1_MODCODLST7 STV090x_Px_MODCODLST7(1) | ||
1507 | #define STV090x_P2_MODCODLST7 STV090x_Px_MODCODLST7(2) | ||
1508 | #define STV090x_OFFST_Px_DIS_8P_9_10_FIELD 4 | ||
1509 | #define STV090x_WIDTH_Px_DIS_8P_9_10_FIELD 4 | ||
1510 | #define STV090x_OFFST_Px_DIS_8P_8_9_FIELD 0 | ||
1511 | #define STV090x_WIDTH_Px_DIS_8P_8_9_FIELD 4 | ||
1512 | |||
1513 | #define STV090x_Px_MODCODLST8(__x) (0xf4b8 - (__x - 1) * 0x200) | ||
1514 | #define STV090x_P1_MODCODLST8 STV090x_Px_MODCODLST8(1) | ||
1515 | #define STV090x_P2_MODCODLST8 STV090x_Px_MODCODLST8(2) | ||
1516 | #define STV090x_OFFST_Px_DIS_8P_5_6_FIELD 4 | ||
1517 | #define STV090x_WIDTH_Px_DIS_8P_5_6_FIELD 4 | ||
1518 | #define STV090x_OFFST_Px_DIS_8P_3_4_FIELD 0 | ||
1519 | #define STV090x_WIDTH_Px_DIS_8P_3_4_FIELD 4 | ||
1520 | |||
1521 | #define STV090x_Px_MODCODLST9(__x) (0xf4b9 - (__x - 1) * 0x200) | ||
1522 | #define STV090x_P1_MODCODLST9 STV090x_Px_MODCODLST9(1) | ||
1523 | #define STV090x_P2_MODCODLST9 STV090x_Px_MODCODLST9(2) | ||
1524 | #define STV090x_OFFST_Px_DIS_8P_2_3_FIELD 4 | ||
1525 | #define STV090x_WIDTH_Px_DIS_8P_2_3_FIELD 4 | ||
1526 | #define STV090x_OFFST_Px_DIS_8P_3_5_FIELD 0 | ||
1527 | #define STV090x_WIDTH_Px_DIS_8P_3_5_FIELD 4 | ||
1528 | |||
1529 | #define STV090x_Px_MODCODLSTA(__x) (0xf4ba - (__x - 1) * 0x200) | ||
1530 | #define STV090x_P1_MODCODLSTA STV090x_Px_MODCODLSTA(1) | ||
1531 | #define STV090x_P2_MODCODLSTA STV090x_Px_MODCODLSTA(2) | ||
1532 | #define STV090x_OFFST_Px_DIS_QP_9_10_FIELD 4 | ||
1533 | #define STV090x_WIDTH_Px_DIS_QP_9_10_FIELD 4 | ||
1534 | #define STV090x_OFFST_Px_DIS_QP_8_9_FIELD 0 | ||
1535 | #define STV090x_WIDTH_Px_DIS_QP_8_9_FIELD 4 | ||
1536 | |||
1537 | #define STV090x_Px_MODCODLSTB(__x) (0xf4bb - (__x - 1) * 0x200) | ||
1538 | #define STV090x_P1_MODCODLSTB STV090x_Px_MODCODLSTB(1) | ||
1539 | #define STV090x_P2_MODCODLSTB STV090x_Px_MODCODLSTB(2) | ||
1540 | #define STV090x_OFFST_Px_DIS_QP_5_6_FIELD 4 | ||
1541 | #define STV090x_WIDTH_Px_DIS_QP_5_6_FIELD 4 | ||
1542 | #define STV090x_OFFST_Px_DIS_QP_4_5_FIELD 0 | ||
1543 | #define STV090x_WIDTH_Px_DIS_QP_4_5_FIELD 4 | ||
1544 | |||
1545 | #define STV090x_Px_MODCODLSTC(__x) (0xf4bc - (__x - 1) * 0x200) | ||
1546 | #define STV090x_P1_MODCODLSTC STV090x_Px_MODCODLSTC(1) | ||
1547 | #define STV090x_P2_MODCODLSTC STV090x_Px_MODCODLSTC(2) | ||
1548 | #define STV090x_OFFST_Px_DIS_QP_3_4_FIELD 4 | ||
1549 | #define STV090x_WIDTH_Px_DIS_QP_3_4_FIELD 4 | ||
1550 | #define STV090x_OFFST_Px_DIS_QP_2_3_FIELD 0 | ||
1551 | #define STV090x_WIDTH_Px_DIS_QP_2_3_FIELD 4 | ||
1552 | |||
1553 | #define STV090x_Px_MODCODLSTD(__x) (0xf4bd - (__x - 1) * 0x200) | ||
1554 | #define STV090x_P1_MODCODLSTD STV090x_Px_MODCODLSTD(1) | ||
1555 | #define STV090x_P2_MODCODLSTD STV090x_Px_MODCODLSTD(2) | ||
1556 | #define STV090x_OFFST_Px_DIS_QP_3_5_FIELD 4 | ||
1557 | #define STV090x_WIDTH_Px_DIS_QP_3_5_FIELD 4 | ||
1558 | #define STV090x_OFFST_Px_DIS_QP_1_2_FIELD 0 | ||
1559 | #define STV090x_WIDTH_Px_DIS_QP_1_2_FIELD 4 | ||
1560 | |||
1561 | #define STV090x_Px_MODCODLSTE(__x) (0xf4be - (__x - 1) * 0x200) | ||
1562 | #define STV090x_P1_MODCODLSTE STV090x_Px_MODCODLSTE(1) | ||
1563 | #define STV090x_P2_MODCODLSTE STV090x_Px_MODCODLSTE(2) | ||
1564 | #define STV090x_OFFST_Px_DIS_QP_2_5_FIELD 4 | ||
1565 | #define STV090x_WIDTH_Px_DIS_QP_2_5_FIELD 4 | ||
1566 | #define STV090x_OFFST_Px_DIS_QP_1_3_FIELD 0 | ||
1567 | #define STV090x_WIDTH_Px_DIS_QP_1_3_FIELD 4 | ||
1568 | |||
1569 | #define STV090x_Px_MODCODLSTF(__x) (0xf4bf - (__x - 1) * 0x200) | ||
1570 | #define STV090x_P1_MODCODLSTF STV090x_Px_MODCODLSTF(1) | ||
1571 | #define STV090x_P2_MODCODLSTF STV090x_Px_MODCODLSTF(2) | ||
1572 | #define STV090x_OFFST_Px_DIS_QP_1_4_FIELD 4 | ||
1573 | #define STV090x_WIDTH_Px_DIS_QP_1_4_FIELD 4 | ||
1574 | |||
1575 | #define STV090x_Px_GAUSSR0(__x) (0xf4c0 - (__x - 1) * 0x200) | ||
1576 | #define STV090x_P1_GAUSSR0 STV090x_Px_GAUSSR0(1) | ||
1577 | #define STV090x_P2_GAUSSR0 STV090x_Px_GAUSSR0(2) | ||
1578 | #define STV090x_OFFST_Px_EN_CCIMODE_FIELD 7 | ||
1579 | #define STV090x_WIDTH_Px_EN_CCIMODE_FIELD 1 | ||
1580 | #define STV090x_OFFST_Px_R0_GAUSSIEN_FIELD 0 | ||
1581 | #define STV090x_WIDTH_Px_R0_GAUSSIEN_FIELD 7 | ||
1582 | |||
1583 | #define STV090x_Px_CCIR0(__x) (0xf4c1 - (__x - 1) * 0x200) | ||
1584 | #define STV090x_P1_CCIR0 STV090x_Px_CCIR0(1) | ||
1585 | #define STV090x_P2_CCIR0 STV090x_Px_CCIR0(2) | ||
1586 | #define STV090x_OFFST_Px_CCIDETECT_PLH_FIELD 7 | ||
1587 | #define STV090x_WIDTH_Px_CCIDETECT_PLH_FIELD 1 | ||
1588 | #define STV090x_OFFST_Px_R0_CCI_FIELD 0 | ||
1589 | #define STV090x_WIDTH_Px_R0_CCI_FIELD 7 | ||
1590 | |||
1591 | #define STV090x_Px_CCIQUANT(__x) (0xf4c2 - (__x - 1) * 0x200) | ||
1592 | #define STV090x_P1_CCIQUANT STV090x_Px_CCIQUANT(1) | ||
1593 | #define STV090x_P2_CCIQUANT STV090x_Px_CCIQUANT(2) | ||
1594 | #define STV090x_OFFST_Px_CCI_BETA_FIELD 5 | ||
1595 | #define STV090x_WIDTH_Px_CCI_BETA_FIELD 3 | ||
1596 | #define STV090x_OFFST_Px_CCI_QUANT_FIELD 0 | ||
1597 | #define STV090x_WIDTH_Px_CCI_QUANT_FIELD 5 | ||
1598 | |||
1599 | #define STV090x_Px_CCITHRESH(__x) (0xf4c3 - (__x - 1) * 0x200) | ||
1600 | #define STV090x_P1_CCITHRESH STV090x_Px_CCITHRESH(1) | ||
1601 | #define STV090x_P2_CCITHRESH STV090x_Px_CCITHRESH(2) | ||
1602 | #define STV090x_OFFST_Px_CCI_THRESHOLD_FIELD 0 | ||
1603 | #define STV090x_WIDTH_Px_CCI_THRESHOLD_FIELD 8 | ||
1604 | |||
1605 | #define STV090x_Px_CCIACC(__x) (0xf4c4 - (__x - 1) * 0x200) | ||
1606 | #define STV090x_P1_CCIACC STV090x_Px_CCIACC(1) | ||
1607 | #define STV090x_P2_CCIACC STV090x_Px_CCIACC(1) | ||
1608 | #define STV090x_OFFST_Px_CCI_VALUE_FIELD 0 | ||
1609 | #define STV090x_WIDTH_Px_CCI_VALUE_FIELD 8 | ||
1610 | |||
1611 | #define STV090x_Px_DMDRESCFG(__x) (0xF4C6 - (__x - 1) * 0x200) | ||
1612 | #define STV090x_P1_DMDRESCFG STV090x_Px_DMDRESCFG(1) | ||
1613 | #define STV090x_P2_DMDRESCFG STV090x_Px_DMDRESCFG(2) | ||
1614 | #define STV090x_OFFST_Px_DMDRES_RESET_FIELD 7 | ||
1615 | #define STV090x_WIDTH_Px_DMDRES_RESET_FIELD 1 | ||
1616 | |||
1617 | #define STV090x_Px_DMDRESADR(__x) (0xF4C7 - (__x - 1) * 0x200) | ||
1618 | #define STV090x_P1_DMDRESADR STV090x_Px_DMDRESADR(1) | ||
1619 | #define STV090x_P2_DMDRESADR STV090x_Px_DMDRESADR(2) | ||
1620 | #define STV090x_OFFST_Px_DMDRES_RESNBR_FIELD 0 | ||
1621 | #define STV090x_WIDTH_Px_DMDRES_RESNBR_FIELD 4 | ||
1622 | |||
1623 | #define STV090x_Px_DMDRESDATAy(__x, __y) (0xF4C8 - (__x - 1) * 0x200 + (7 - __y)) | ||
1624 | #define STV090x_P1_DMDRESDATA0 STV090x_Px_DMDRESDATAy(1, 0) | ||
1625 | #define STV090x_P1_DMDRESDATA1 STV090x_Px_DMDRESDATAy(1, 1) | ||
1626 | #define STV090x_P1_DMDRESDATA2 STV090x_Px_DMDRESDATAy(1, 2) | ||
1627 | #define STV090x_P1_DMDRESDATA3 STV090x_Px_DMDRESDATAy(1, 3) | ||
1628 | #define STV090x_P1_DMDRESDATA4 STV090x_Px_DMDRESDATAy(1, 4) | ||
1629 | #define STV090x_P1_DMDRESDATA5 STV090x_Px_DMDRESDATAy(1, 5) | ||
1630 | #define STV090x_P1_DMDRESDATA6 STV090x_Px_DMDRESDATAy(1, 6) | ||
1631 | #define STV090x_P1_DMDRESDATA7 STV090x_Px_DMDRESDATAy(1, 7) | ||
1632 | #define STV090x_P2_DMDRESDATA0 STV090x_Px_DMDRESDATAy(2, 0) | ||
1633 | #define STV090x_P2_DMDRESDATA1 STV090x_Px_DMDRESDATAy(2, 1) | ||
1634 | #define STV090x_P2_DMDRESDATA2 STV090x_Px_DMDRESDATAy(2, 2) | ||
1635 | #define STV090x_P2_DMDRESDATA3 STV090x_Px_DMDRESDATAy(2, 3) | ||
1636 | #define STV090x_P2_DMDRESDATA4 STV090x_Px_DMDRESDATAy(2, 4) | ||
1637 | #define STV090x_P2_DMDRESDATA5 STV090x_Px_DMDRESDATAy(2, 5) | ||
1638 | #define STV090x_P2_DMDRESDATA6 STV090x_Px_DMDRESDATAy(2, 6) | ||
1639 | #define STV090x_P2_DMDRESDATA7 STV090x_Px_DMDRESDATAy(2, 7) | ||
1640 | #define STV090x_OFFST_Px_DMDRES_DATA_FIELD 0 | ||
1641 | #define STV090x_WIDTH_Px_DMDRES_DATA_FIELD 8 | ||
1642 | |||
1643 | #define STV090x_Px_FFEIy(__x, __y) (0xf4d0 - (__x - 1) * 0x200 + 0x2 * (__y - 1)) | ||
1644 | #define STV090x_P1_FFEI1 STV090x_Px_FFEIy(1, 1) | ||
1645 | #define STV090x_P1_FFEI2 STV090x_Px_FFEIy(1, 2) | ||
1646 | #define STV090x_P1_FFEI3 STV090x_Px_FFEIy(1, 3) | ||
1647 | #define STV090x_P1_FFEI4 STV090x_Px_FFEIy(1, 4) | ||
1648 | #define STV090x_P2_FFEI1 STV090x_Px_FFEIy(2, 1) | ||
1649 | #define STV090x_P2_FFEI2 STV090x_Px_FFEIy(2, 2) | ||
1650 | #define STV090x_P2_FFEI3 STV090x_Px_FFEIy(2, 3) | ||
1651 | #define STV090x_P2_FFEI4 STV090x_Px_FFEIy(2, 4) | ||
1652 | #define STV090x_OFFST_Px_FFE_ACCIy_FIELD 0 | ||
1653 | #define STV090x_WIDTH_Px_FFE_ACCIy_FIELD 8 | ||
1654 | |||
1655 | #define STV090x_Px_FFEQy(__x, __y) (0xf4d1 - (__x - 1) * 0x200 + 0x2 * (__y - 1)) | ||
1656 | #define STV090x_P1_FFEQ1 STV090x_Px_FFEQy(1, 1) | ||
1657 | #define STV090x_P1_FFEQ2 STV090x_Px_FFEQy(1, 2) | ||
1658 | #define STV090x_P1_FFEQ3 STV090x_Px_FFEQy(1, 3) | ||
1659 | #define STV090x_P1_FFEQ4 STV090x_Px_FFEQy(1, 4) | ||
1660 | #define STV090x_P2_FFEQ1 STV090x_Px_FFEQy(2, 1) | ||
1661 | #define STV090x_P2_FFEQ2 STV090x_Px_FFEQy(2, 2) | ||
1662 | #define STV090x_P2_FFEQ3 STV090x_Px_FFEQy(2, 3) | ||
1663 | #define STV090x_P2_FFEQ4 STV090x_Px_FFEQy(2, 4) | ||
1664 | #define STV090x_OFFST_Px_FFE_ACCQy_FIELD 0 | ||
1665 | #define STV090x_WIDTH_Px_FFE_ACCQy_FIELD 8 | ||
1666 | |||
1667 | #define STV090x_Px_FFECFG(__x) (0xf4d8 - (__x - 1) * 0x200) | ||
1668 | #define STV090x_P1_FFECFG STV090x_Px_FFECFG(1) | ||
1669 | #define STV090x_P2_FFECFG STV090x_Px_FFECFG(2) | ||
1670 | #define STV090x_OFFST_Px_EQUALFFE_ON_FIELD 6 | ||
1671 | #define STV090x_WIDTH_Px_EQUALFFE_ON_FIELD 1 | ||
1672 | |||
1673 | #define STV090x_Px_SMAPCOEF7(__x) (0xf500 - (__x - 1) * 0x200) | ||
1674 | #define STV090x_P1_SMAPCOEF7 STV090x_Px_SMAPCOEF7(1) | ||
1675 | #define STV090x_P2_SMAPCOEF7 STV090x_Px_SMAPCOEF7(2) | ||
1676 | #define STV090x_OFFST_Px_DIS_QSCALE_FIELD 7 | ||
1677 | #define STV090x_WIDTH_Px_DIS_QSCALE_FIELD 1 | ||
1678 | #define STV090x_OFFST_Px_SMAPCOEF_Q_LLR12_FIELD 0 | ||
1679 | #define STV090x_WIDTH_Px_SMAPCOEF_Q_LLR12_FIELD 7 | ||
1680 | |||
1681 | #define STV090x_Px_SMAPCOEF6(__x) (0xf501 - (__x - 1) * 0x200) | ||
1682 | #define STV090x_P1_SMAPCOEF6 STV090x_Px_SMAPCOEF6(1) | ||
1683 | #define STV090x_P2_SMAPCOEF6 STV090x_Px_SMAPCOEF6(2) | ||
1684 | #define STV090x_OFFST_Px_ADJ_8PSKLLR1_FIELD 2 | ||
1685 | #define STV090x_WIDTH_Px_ADJ_8PSKLLR1_FIELD 1 | ||
1686 | #define STV090x_OFFST_Px_OLD_8PSKLLR1_FIELD 1 | ||
1687 | #define STV090x_WIDTH_Px_OLD_8PSKLLR1_FIELD 1 | ||
1688 | #define STV090x_OFFST_Px_DIS_AB8PSK_FIELD 0 | ||
1689 | #define STV090x_WIDTH_Px_DIS_AB8PSK_FIELD 1 | ||
1690 | |||
1691 | #define STV090x_Px_SMAPCOEF5(__x) (0xf502 - (__x - 1) * 0x200) | ||
1692 | #define STV090x_P1_SMAPCOEF5 STV090x_Px_SMAPCOEF5(1) | ||
1693 | #define STV090x_P2_SMAPCOEF5 STV090x_Px_SMAPCOEF5(2) | ||
1694 | #define STV090x_OFFST_Px_DIS_8SCALE_FIELD 7 | ||
1695 | #define STV090x_WIDTH_Px_DIS_8SCALE_FIELD 1 | ||
1696 | #define STV090x_OFFST_Px_SMAPCOEF_8P_LLR23_FIELD 0 | ||
1697 | #define STV090x_WIDTH_Px_SMAPCOEF_8P_LLR23_FIELD 7 | ||
1698 | |||
1699 | #define STV090x_Px_DMDPLHSTAT(__x) (0xF520 - (__x - 1) * 0x200) | ||
1700 | #define STV090x_P1_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(1) | ||
1701 | #define STV090x_P2_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(2) | ||
1702 | #define STV090x_OFFST_Px_PLH_STATISTIC_FIELD 0 | ||
1703 | #define STV090x_WIDTH_Px_PLH_STATISTIC_FIELD 8 | ||
1704 | |||
1705 | #define STV090x_Px_LOCKTIMEy(__x, __y) (0xF525 - (__x - 1) * 0x200 - __y * 0x1) | ||
1706 | #define STV090x_P1_LOCKTIME0 STV090x_Px_LOCKTIMEy(1, 0) | ||
1707 | #define STV090x_P1_LOCKTIME1 STV090x_Px_LOCKTIMEy(1, 1) | ||
1708 | #define STV090x_P1_LOCKTIME2 STV090x_Px_LOCKTIMEy(1, 2) | ||
1709 | #define STV090x_P1_LOCKTIME3 STV090x_Px_LOCKTIMEy(1, 3) | ||
1710 | #define STV090x_P2_LOCKTIME0 STV090x_Px_LOCKTIMEy(2, 0) | ||
1711 | #define STV090x_P2_LOCKTIME1 STV090x_Px_LOCKTIMEy(2, 1) | ||
1712 | #define STV090x_P2_LOCKTIME2 STV090x_Px_LOCKTIMEy(2, 2) | ||
1713 | #define STV090x_P2_LOCKTIME3 STV090x_Px_LOCKTIMEy(2, 3) | ||
1714 | #define STV090x_OFFST_Px_DEMOD_LOCKTIME_FIELD 0 | ||
1715 | #define STV090x_WIDTH_Px_DEMOD_LOCKTIME_FIELD 8 | ||
1716 | |||
1717 | #define STV090x_Px_TNRCFG(__x) (0xf4e0 - (__x - 1) * 0x200) /* check */ | ||
1718 | #define STV090x_P1_TNRCFG STV090x_Px_TNRCFG(1) | ||
1719 | #define STV090x_P2_TNRCFG STV090x_Px_TNRCFG(2) | ||
1720 | |||
1721 | #define STV090x_Px_TNRCFG2(__x) (0xf4e1 - (__x - 1) * 0x200) | ||
1722 | #define STV090x_P1_TNRCFG2 STV090x_Px_TNRCFG2(1) | ||
1723 | #define STV090x_P2_TNRCFG2 STV090x_Px_TNRCFG2(2) | ||
1724 | #define STV090x_OFFST_Px_TUN_IQSWAP_FIELD 7 | ||
1725 | #define STV090x_WIDTH_Px_TUN_IQSWAP_FIELD 1 | ||
1726 | |||
1727 | #define STV090x_Px_VITSCALE(__x) (0xf532 - (__x - 1) * 0x200) | ||
1728 | #define STV090x_P1_VITSCALE STV090x_Px_VITSCALE(1) | ||
1729 | #define STV090x_P2_VITSCALE STV090x_Px_VITSCALE(2) | ||
1730 | #define STV090x_OFFST_Px_NVTH_NOSRANGE_FIELD 7 | ||
1731 | #define STV090x_WIDTH_Px_NVTH_NOSRANGE_FIELD 1 | ||
1732 | #define STV090x_OFFST_Px_VERROR_MAXMODE_FIELD 6 | ||
1733 | #define STV090x_WIDTH_Px_VERROR_MAXMODE_FIELD 1 | ||
1734 | #define STV090x_OFFST_Px_NSLOWSN_LOCKED_FIELD 3 | ||
1735 | #define STV090x_WIDTH_Px_NSLOWSN_LOCKED_FIELD 1 | ||
1736 | #define STV090x_OFFST_Px_DIS_RSFLOCK_FIELD 1 | ||
1737 | #define STV090x_WIDTH_Px_DIS_RSFLOCK_FIELD 1 | ||
1738 | |||
1739 | #define STV090x_Px_FECM(__x) (0xf533 - (__x - 1) * 0x200) | ||
1740 | #define STV090x_P1_FECM STV090x_Px_FECM(1) | ||
1741 | #define STV090x_P2_FECM STV090x_Px_FECM(2) | ||
1742 | #define STV090x_OFFST_Px_DSS_DVB_FIELD 7 | ||
1743 | #define STV090x_WIDTH_Px_DSS_DVB_FIELD 1 | ||
1744 | #define STV090x_OFFST_Px_DSS_SRCH_FIELD 4 | ||
1745 | #define STV090x_WIDTH_Px_DSS_SRCH_FIELD 1 | ||
1746 | #define STV090x_OFFST_Px_SYNCVIT_FIELD 1 | ||
1747 | #define STV090x_WIDTH_Px_SYNCVIT_FIELD 1 | ||
1748 | #define STV090x_OFFST_Px_IQINV_FIELD 0 | ||
1749 | #define STV090x_WIDTH_Px_IQINV_FIELD 1 | ||
1750 | |||
1751 | #define STV090x_Px_VTH12(__x) (0xf534 - (__x - 1) * 0x200) | ||
1752 | #define STV090x_P1_VTH12 STV090x_Px_VTH12(1) | ||
1753 | #define STV090x_P2_VTH12 STV090x_Px_VTH12(2) | ||
1754 | #define STV090x_OFFST_Px_VTH12_FIELD 0 | ||
1755 | #define STV090x_WIDTH_Px_VTH12_FIELD 8 | ||
1756 | |||
1757 | #define STV090x_Px_VTH23(__x) (0xf535 - (__x - 1) * 0x200) | ||
1758 | #define STV090x_P1_VTH23 STV090x_Px_VTH23(1) | ||
1759 | #define STV090x_P2_VTH23 STV090x_Px_VTH23(2) | ||
1760 | #define STV090x_OFFST_Px_VTH23_FIELD 0 | ||
1761 | #define STV090x_WIDTH_Px_VTH23_FIELD 8 | ||
1762 | |||
1763 | #define STV090x_Px_VTH34(__x) (0xf536 - (__x - 1) * 0x200) | ||
1764 | #define STV090x_P1_VTH34 STV090x_Px_VTH34(1) | ||
1765 | #define STV090x_P2_VTH34 STV090x_Px_VTH34(2) | ||
1766 | #define STV090x_OFFST_Px_VTH34_FIELD 0 | ||
1767 | #define STV090x_WIDTH_Px_VTH34_FIELD 8 | ||
1768 | |||
1769 | #define STV090x_Px_VTH56(__x) (0xf537 - (__x - 1) * 0x200) | ||
1770 | #define STV090x_P1_VTH56 STV090x_Px_VTH56(1) | ||
1771 | #define STV090x_P2_VTH56 STV090x_Px_VTH56(2) | ||
1772 | #define STV090x_OFFST_Px_VTH56_FIELD 0 | ||
1773 | #define STV090x_WIDTH_Px_VTH56_FIELD 8 | ||
1774 | |||
1775 | #define STV090x_Px_VTH67(__x) (0xf538 - (__x - 1) * 0x200) | ||
1776 | #define STV090x_P1_VTH67 STV090x_Px_VTH67(1) | ||
1777 | #define STV090x_P2_VTH67 STV090x_Px_VTH67(2) | ||
1778 | #define STV090x_OFFST_Px_VTH67_FIELD 0 | ||
1779 | #define STV090x_WIDTH_Px_VTH67_FIELD 8 | ||
1780 | |||
1781 | #define STV090x_Px_VTH78(__x) (0xf539 - (__x - 1) * 0x200) | ||
1782 | #define STV090x_P1_VTH78 STV090x_Px_VTH78(1) | ||
1783 | #define STV090x_P2_VTH78 STV090x_Px_VTH78(2) | ||
1784 | #define STV090x_OFFST_Px_VTH78_FIELD 0 | ||
1785 | #define STV090x_WIDTH_Px_VTH78_FIELD 8 | ||
1786 | |||
1787 | #define STV090x_Px_VITCURPUN(__x) (0xf53a - (__x - 1) * 0x200) | ||
1788 | #define STV090x_P1_VITCURPUN STV090x_Px_VITCURPUN(1) | ||
1789 | #define STV090x_P2_VITCURPUN STV090x_Px_VITCURPUN(2) | ||
1790 | #define STV090x_OFFST_Px_VIT_CURPUN_FIELD 0 | ||
1791 | #define STV090x_WIDTH_Px_VIT_CURPUN_FIELD 5 | ||
1792 | |||
1793 | #define STV090x_Px_VERROR(__x) (0xf53b - (__x - 1) * 0x200) | ||
1794 | #define STV090x_P1_VERROR STV090x_Px_VERROR(1) | ||
1795 | #define STV090x_P2_VERROR STV090x_Px_VERROR(2) | ||
1796 | #define STV090x_OFFST_Px_REGERR_VIT_FIELD 0 | ||
1797 | #define STV090x_WIDTH_Px_REGERR_VIT_FIELD 8 | ||
1798 | |||
1799 | #define STV090x_Px_PRVIT(__x) (0xf53c - (__x - 1) * 0x200) | ||
1800 | #define STV090x_P1_PRVIT STV090x_Px_PRVIT(1) | ||
1801 | #define STV090x_P2_PRVIT STV090x_Px_PRVIT(2) | ||
1802 | #define STV090x_OFFST_Px_DIS_VTHLOCK_FIELD 6 | ||
1803 | #define STV090x_WIDTH_Px_DIS_VTHLOCK_FIELD 1 | ||
1804 | #define STV090x_OFFST_Px_E7_8VIT_FIELD 5 | ||
1805 | #define STV090x_WIDTH_Px_E7_8VIT_FIELD 1 | ||
1806 | #define STV090x_OFFST_Px_E6_7VIT_FIELD 4 | ||
1807 | #define STV090x_WIDTH_Px_E6_7VIT_FIELD 1 | ||
1808 | #define STV090x_OFFST_Px_E5_6VIT_FIELD 3 | ||
1809 | #define STV090x_WIDTH_Px_E5_6VIT_FIELD 1 | ||
1810 | #define STV090x_OFFST_Px_E3_4VIT_FIELD 2 | ||
1811 | #define STV090x_WIDTH_Px_E3_4VIT_FIELD 1 | ||
1812 | #define STV090x_OFFST_Px_E2_3VIT_FIELD 1 | ||
1813 | #define STV090x_WIDTH_Px_E2_3VIT_FIELD 1 | ||
1814 | #define STV090x_OFFST_Px_E1_2VIT_FIELD 0 | ||
1815 | #define STV090x_WIDTH_Px_E1_2VIT_FIELD 1 | ||
1816 | |||
1817 | #define STV090x_Px_VAVSRVIT(__x) (0xf53d - (__x - 1) * 0x200) | ||
1818 | #define STV090x_P1_VAVSRVIT STV090x_Px_VAVSRVIT(1) | ||
1819 | #define STV090x_P2_VAVSRVIT STV090x_Px_VAVSRVIT(2) | ||
1820 | #define STV090x_OFFST_Px_SNVIT_FIELD 4 | ||
1821 | #define STV090x_WIDTH_Px_SNVIT_FIELD 2 | ||
1822 | #define STV090x_OFFST_Px_TOVVIT_FIELD 2 | ||
1823 | #define STV090x_WIDTH_Px_TOVVIT_FIELD 2 | ||
1824 | #define STV090x_OFFST_Px_HYPVIT_FIELD 0 | ||
1825 | #define STV090x_WIDTH_Px_HYPVIT_FIELD 2 | ||
1826 | |||
1827 | #define STV090x_Px_VSTATUSVIT(__x) (0xf53e - (__x - 1) * 0x200) | ||
1828 | #define STV090x_P1_VSTATUSVIT STV090x_Px_VSTATUSVIT(1) | ||
1829 | #define STV090x_P2_VSTATUSVIT STV090x_Px_VSTATUSVIT(2) | ||
1830 | #define STV090x_OFFST_Px_PRFVIT_FIELD 4 | ||
1831 | #define STV090x_WIDTH_Px_PRFVIT_FIELD 1 | ||
1832 | #define STV090x_OFFST_Px_LOCKEDVIT_FIELD 3 | ||
1833 | #define STV090x_WIDTH_Px_LOCKEDVIT_FIELD 1 | ||
1834 | |||
1835 | #define STV090x_Px_VTHINUSE(__x) (0xf53f - (__x - 1) * 0x200) | ||
1836 | #define STV090x_P1_VTHINUSE STV090x_Px_VTHINUSE(1) | ||
1837 | #define STV090x_P2_VTHINUSE STV090x_Px_VTHINUSE(2) | ||
1838 | #define STV090x_OFFST_Px_VIT_INUSE_FIELD 0 | ||
1839 | #define STV090x_WIDTH_Px_VIT_INUSE_FIELD 8 | ||
1840 | |||
1841 | #define STV090x_Px_KDIV12(__x) (0xf540 - (__x - 1) * 0x200) | ||
1842 | #define STV090x_P1_KDIV12 STV090x_Px_KDIV12(1) | ||
1843 | #define STV090x_P2_KDIV12 STV090x_Px_KDIV12(2) | ||
1844 | #define STV090x_OFFST_Px_K_DIVIDER_12_FIELD 0 | ||
1845 | #define STV090x_WIDTH_Px_K_DIVIDER_12_FIELD 7 | ||
1846 | |||
1847 | #define STV090x_Px_KDIV23(__x) (0xf541 - (__x - 1) * 0x200) | ||
1848 | #define STV090x_P1_KDIV23 STV090x_Px_KDIV23(1) | ||
1849 | #define STV090x_P2_KDIV23 STV090x_Px_KDIV23(2) | ||
1850 | #define STV090x_OFFST_Px_K_DIVIDER_23_FIELD 0 | ||
1851 | #define STV090x_WIDTH_Px_K_DIVIDER_23_FIELD 7 | ||
1852 | |||
1853 | #define STV090x_Px_KDIV34(__x) (0xf542 - (__x - 1) * 0x200) | ||
1854 | #define STV090x_P1_KDIV34 STV090x_Px_KDIV34(1) | ||
1855 | #define STV090x_P2_KDIV34 STV090x_Px_KDIV34(2) | ||
1856 | #define STV090x_OFFST_Px_K_DIVIDER_34_FIELD 0 | ||
1857 | #define STV090x_WIDTH_Px_K_DIVIDER_34_FIELD 7 | ||
1858 | |||
1859 | #define STV090x_Px_KDIV56(__x) (0xf543 - (__x - 1) * 0x200) | ||
1860 | #define STV090x_P1_KDIV56 STV090x_Px_KDIV56(1) | ||
1861 | #define STV090x_P2_KDIV56 STV090x_Px_KDIV56(2) | ||
1862 | #define STV090x_OFFST_Px_K_DIVIDER_56_FIELD 0 | ||
1863 | #define STV090x_WIDTH_Px_K_DIVIDER_56_FIELD 7 | ||
1864 | |||
1865 | #define STV090x_Px_KDIV67(__x) (0xf544 - (__x - 1) * 0x200) | ||
1866 | #define STV090x_P1_KDIV67 STV090x_Px_KDIV67(1) | ||
1867 | #define STV090x_P2_KDIV67 STV090x_Px_KDIV67(2) | ||
1868 | #define STV090x_OFFST_Px_K_DIVIDER_67_FIELD 0 | ||
1869 | #define STV090x_WIDTH_Px_K_DIVIDER_67_FIELD 7 | ||
1870 | |||
1871 | #define STV090x_Px_KDIV78(__x) (0xf545 - (__x - 1) * 0x200) | ||
1872 | #define STV090x_P1_KDIV78 STV090x_Px_KDIV78(1) | ||
1873 | #define STV090x_P2_KDIV78 STV090x_Px_KDIV78(2) | ||
1874 | #define STV090x_OFFST_Px_K_DIVIDER_78_FIELD 0 | ||
1875 | #define STV090x_WIDTH_Px_K_DIVIDER_78_FIELD 7 | ||
1876 | |||
1877 | #define STV090x_Px_PDELCTRL1(__x) (0xf550 - (__x - 1) * 0x200) | ||
1878 | #define STV090x_P1_PDELCTRL1 STV090x_Px_PDELCTRL1(1) | ||
1879 | #define STV090x_P2_PDELCTRL1 STV090x_Px_PDELCTRL1(2) | ||
1880 | #define STV090x_OFFST_Px_INV_MISMASK_FIELD 7 | ||
1881 | #define STV090x_WIDTH_Px_INV_MISMASK_FIELD 1 | ||
1882 | #define STV090x_OFFST_Px_FILTER_EN_FIELD 5 | ||
1883 | #define STV090x_WIDTH_Px_FILTER_EN_FIELD 1 | ||
1884 | #define STV090x_OFFST_Px_EN_MIS00_FIELD 1 | ||
1885 | #define STV090x_WIDTH_Px_EN_MIS00_FIELD 1 | ||
1886 | #define STV090x_OFFST_Px_ALGOSWRST_FIELD 0 | ||
1887 | #define STV090x_WIDTH_Px_ALGOSWRST_FIELD 1 | ||
1888 | |||
1889 | #define STV090x_Px_PDELCTRL2(__x) (0xf551 - (__x - 1) * 0x200) | ||
1890 | #define STV090x_P1_PDELCTRL2 STV090x_Px_PDELCTRL2(1) | ||
1891 | #define STV090x_P2_PDELCTRL2 STV090x_Px_PDELCTRL2(2) | ||
1892 | #define STV090x_OFFST_Px_FORCE_CONTINUOUS 7 | ||
1893 | #define STV090x_WIDTH_Px_FORCE_CONTINUOUS 1 | ||
1894 | #define STV090x_OFFST_Px_RESET_UPKO_COUNT 6 | ||
1895 | #define STV090x_WIDTH_Px_RESET_UPKO_COUNT 1 | ||
1896 | #define STV090x_OFFST_Px_USER_PKTDELIN_NB 5 | ||
1897 | #define STV090x_WIDTH_Px_USER_PKTDELIN_NB 1 | ||
1898 | #define STV090x_OFFST_Px_FORCE_LOCKED 4 | ||
1899 | #define STV090x_WIDTH_Px_FORCE_LOCKED 1 | ||
1900 | #define STV090x_OFFST_Px_DATA_UNBBSCRAM 3 | ||
1901 | #define STV090x_WIDTH_Px_DATA_UNBBSCRAM 1 | ||
1902 | #define STV090x_OFFST_Px_FORCE_LONGPACKET 2 | ||
1903 | #define STV090x_WIDTH_Px_FORCE_LONGPACKET 1 | ||
1904 | #define STV090x_OFFST_Px_FRAME_MODE_FIELD 1 | ||
1905 | #define STV090x_WIDTH_Px_FRAME_MODE_FIELD 1 | ||
1906 | |||
1907 | #define STV090x_Px_HYSTTHRESH(__x) (0xf554 - (__x - 1) * 0x200) | ||
1908 | #define STV090x_P1_HYSTTHRESH STV090x_Px_HYSTTHRESH(1) | ||
1909 | #define STV090x_P2_HYSTTHRESH STV090x_Px_HYSTTHRESH(2) | ||
1910 | #define STV090x_OFFST_Px_UNLCK_THRESH_FIELD 4 | ||
1911 | #define STV090x_WIDTH_Px_UNLCK_THRESH_FIELD 4 | ||
1912 | #define STV090x_OFFST_Px_DELIN_LCK_THRESH_FIELD 0 | ||
1913 | #define STV090x_WIDTH_Px_DELIN_LCK_THRESH_FIELD 4 | ||
1914 | |||
1915 | #define STV090x_Px_ISIENTRY(__x) (0xf55e - (__x - 1) * 0x200) | ||
1916 | #define STV090x_P1_ISIENTRY STV090x_Px_ISIENTRY(1) | ||
1917 | #define STV090x_P2_ISIENTRY STV090x_Px_ISIENTRY(2) | ||
1918 | #define STV090x_OFFST_Px_ISI_ENTRY_FIELD 0 | ||
1919 | #define STV090x_WIDTH_Px_ISI_ENTRY_FIELD 8 | ||
1920 | |||
1921 | #define STV090x_Px_ISIBITENA(__x) (0xf55f - (__x - 1) * 0x200) | ||
1922 | #define STV090x_P1_ISIBITENA STV090x_Px_ISIBITENA(1) | ||
1923 | #define STV090x_P2_ISIBITENA STV090x_Px_ISIBITENA(2) | ||
1924 | #define STV090x_OFFST_Px_ISI_BIT_EN_FIELD 0 | ||
1925 | #define STV090x_WIDTH_Px_ISI_BIT_EN_FIELD 8 | ||
1926 | |||
1927 | #define STV090x_Px_MATSTRy(__x, __y) (0xf561 - (__x - 1) * 0x200 - __y * 0x1) | ||
1928 | #define STV090x_P1_MATSTR0 STV090x_Px_MATSTRy(1, 0) | ||
1929 | #define STV090x_P1_MATSTR1 STV090x_Px_MATSTRy(1, 1) | ||
1930 | #define STV090x_P2_MATSTR0 STV090x_Px_MATSTRy(2, 0) | ||
1931 | #define STV090x_P2_MATSTR1 STV090x_Px_MATSTRy(2, 1) | ||
1932 | #define STV090x_OFFST_Px_MATYPE_CURRENT_FIELD 0 | ||
1933 | #define STV090x_WIDTH_Px_MATYPE_CURRENT_FIELD 8 | ||
1934 | |||
1935 | #define STV090x_Px_UPLSTRy(__x, __y) (0xf563 - (__x - 1) * 0x200 - __y * 0x1) | ||
1936 | #define STV090x_P1_UPLSTR0 STV090x_Px_UPLSTRy(1, 0) | ||
1937 | #define STV090x_P1_UPLSTR1 STV090x_Px_UPLSTRy(1, 1) | ||
1938 | #define STV090x_P2_UPLSTR0 STV090x_Px_UPLSTRy(2, 0) | ||
1939 | #define STV090x_P2_UPLSTR1 STV090x_Px_UPLSTRy(2, 1) | ||
1940 | #define STV090x_OFFST_Px_UPL_CURRENT_FIELD 0 | ||
1941 | #define STV090x_WIDTH_Px_UPL_CURRENT_FIELD 8 | ||
1942 | |||
1943 | #define STV090x_Px_DFLSTRy(__x, __y) (0xf565 - (__x - 1) * 0x200 - __y * 0x1) | ||
1944 | #define STV090x_P1_DFLSTR0 STV090x_Px_DFLSTRy(1, 0) | ||
1945 | #define STV090x_P1_DFLSTR1 STV090x_Px_DFLSTRy(1, 1) | ||
1946 | #define STV090x_P2_DFLSTR0 STV090x_Px_DFLSTRy(2, 0) | ||
1947 | #define STV090x_P2_DFLSTR1 STV090x_Px_DFLSTRy(2, 1) | ||
1948 | #define STV090x_OFFST_Px_DFL_CURRENT_FIELD 0 | ||
1949 | #define STV090x_WIDTH_Px_DFL_CURRENT_FIELD 8 | ||
1950 | |||
1951 | #define STV090x_Px_SYNCSTR(__x) (0xf566 - (__x - 1) * 0x200) | ||
1952 | #define STV090x_P1_SYNCSTR STV090x_Px_SYNCSTR(1) | ||
1953 | #define STV090x_P2_SYNCSTR STV090x_Px_SYNCSTR(2) | ||
1954 | #define STV090x_OFFST_Px_SYNC_CURRENT_FIELD 0 | ||
1955 | #define STV090x_WIDTH_Px_SYNC_CURRENT_FIELD 8 | ||
1956 | |||
1957 | #define STV090x_Px_SYNCDSTRy(__x, __y) (0xf568 - (__x - 1) * 0x200 - __y * 0x1) | ||
1958 | #define STV090x_P1_SYNCDSTR0 STV090x_Px_SYNCDSTRy(1, 0) | ||
1959 | #define STV090x_P1_SYNCDSTR1 STV090x_Px_SYNCDSTRy(1, 1) | ||
1960 | #define STV090x_P2_SYNCDSTR0 STV090x_Px_SYNCDSTRy(2, 0) | ||
1961 | #define STV090x_P2_SYNCDSTR1 STV090x_Px_SYNCDSTRy(2, 1) | ||
1962 | #define STV090x_OFFST_Px_SYNCD_CURRENT_FIELD 0 | ||
1963 | #define STV090x_WIDTH_Px_SYNCD_CURRENT_FIELD 8 | ||
1964 | |||
1965 | #define STV090x_Px_PDELSTATUS1(__x) (0xf569 - (__x - 1) * 0x200) | ||
1966 | #define STV090x_P1_PDELSTATUS1 STV090x_Px_PDELSTATUS1(1) | ||
1967 | #define STV090x_P2_PDELSTATUS1 STV090x_Px_PDELSTATUS1(2) | ||
1968 | #define STV090x_OFFST_Px_PKTDELIN_LOCK_FIELD 1 | ||
1969 | #define STV090x_WIDTH_Px_PKTDELIN_LOCK_FIELD 1 | ||
1970 | #define STV090x_OFFST_Px_FIRST_LOCK_FIELD 0 | ||
1971 | #define STV090x_WIDTH_Px_FIRST_LOCK_FIELD 1 | ||
1972 | |||
1973 | #define STV090x_Px_PDELSTATUS2(__x) (0xf56a - (__x - 1) * 0x200) | ||
1974 | #define STV090x_P1_PDELSTATUS2 STV090x_Px_PDELSTATUS2(1) | ||
1975 | #define STV090x_P2_PDELSTATUS2 STV090x_Px_PDELSTATUS2(2) | ||
1976 | #define STV090x_OFFST_Px_FRAME_MODCOD_FIELD 2 | ||
1977 | #define STV090x_WIDTH_Px_FRAME_MODCOD_FIELD 5 | ||
1978 | #define STV090x_OFFST_Px_FRAME_TYPE_FIELD 0 | ||
1979 | #define STV090x_WIDTH_Px_FRAME_TYPE_FIELD 2 | ||
1980 | |||
1981 | #define STV090x_Px_BBFCRCKO1(__x) (0xf56b - (__x - 1) * 0x200) | ||
1982 | #define STV090x_P1_BBFCRCKO1 STV090x_Px_BBFCRCKO1(1) | ||
1983 | #define STV090x_P2_BBFCRCKO1 STV090x_Px_BBFCRCKO1(2) | ||
1984 | #define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD 0 | ||
1985 | #define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD 8 | ||
1986 | |||
1987 | #define STV090x_Px_BBFCRCKO0(__x) (0xf56c - (__x - 1) * 0x200) | ||
1988 | #define STV090x_P1_BBFCRCKO0 STV090x_Px_BBFCRCKO0(1) | ||
1989 | #define STV090x_P2_BBFCRCKO0 STV090x_Px_BBFCRCKO0(2) | ||
1990 | #define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD 0 | ||
1991 | #define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD 8 | ||
1992 | |||
1993 | #define STV090x_Px_UPCRCKO1(__x) (0xf56d - (__x - 1) * 0x200) | ||
1994 | #define STV090x_P1_UPCRCKO1 STV090x_Px_UPCRCKO1(1) | ||
1995 | #define STV090x_P2_UPCRCKO1 STV090x_Px_UPCRCKO1(2) | ||
1996 | #define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD 0 | ||
1997 | #define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD 8 | ||
1998 | |||
1999 | #define STV090x_Px_UPCRCKO0(__x) (0xf56e - (__x - 1) * 0x200) | ||
2000 | #define STV090x_P1_UPCRCKO0 STV090x_Px_UPCRCKO0(1) | ||
2001 | #define STV090x_P2_UPCRCKO0 STV090x_Px_UPCRCKO0(2) | ||
2002 | #define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD 0 | ||
2003 | #define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD 8 | ||
2004 | |||
2005 | #define STV090x_NBITER_NFx(__x) (0xFA03 + (__x - 4) * 0x1) | ||
2006 | #define STV090x_NBITER_NF4 STV090x_NBITER_NFx(4) | ||
2007 | #define STV090x_NBITER_NF5 STV090x_NBITER_NFx(5) | ||
2008 | #define STV090x_NBITER_NF6 STV090x_NBITER_NFx(6) | ||
2009 | #define STV090x_NBITER_NF7 STV090x_NBITER_NFx(7) | ||
2010 | #define STV090x_NBITER_NF8 STV090x_NBITER_NFx(8) | ||
2011 | #define STV090x_NBITER_NF9 STV090x_NBITER_NFx(9) | ||
2012 | #define STV090x_NBITER_NF10 STV090x_NBITER_NFx(10) | ||
2013 | #define STV090x_NBITER_NF11 STV090x_NBITER_NFx(11) | ||
2014 | #define STV090x_NBITER_NF12 STV090x_NBITER_NFx(12) | ||
2015 | #define STV090x_NBITER_NF13 STV090x_NBITER_NFx(13) | ||
2016 | #define STV090x_NBITER_NF14 STV090x_NBITER_NFx(14) | ||
2017 | #define STV090x_NBITER_NF15 STV090x_NBITER_NFx(15) | ||
2018 | #define STV090x_NBITER_NF16 STV090x_NBITER_NFx(16) | ||
2019 | #define STV090x_NBITER_NF17 STV090x_NBITER_NFx(17) | ||
2020 | |||
2021 | #define STV090x_NBITERNOERR 0xFA3F | ||
2022 | #define STV090x_OFFST_NBITER_STOP_CRIT_FIELD 0 | ||
2023 | #define STV090x_WIDTH_NBITER_STOP_CRIT_FIELD 4 | ||
2024 | |||
2025 | #define STV090x_GAINLLR_NFx(__x) (0xFA43 + (__x - 4) * 0x1) | ||
2026 | #define STV090x_GAINLLR_NF4 STV090x_GAINLLR_NFx(4) | ||
2027 | #define STV090x_OFFST_GAINLLR_NF_QP_1_2_FIELD 0 | ||
2028 | #define STV090x_WIDTH_GAINLLR_NF_QP_1_2_FIELD 7 | ||
2029 | |||
2030 | #define STV090x_GAINLLR_NF5 STV090x_GAINLLR_NFx(5) | ||
2031 | #define STV090x_OFFST_GAINLLR_NF_QP_3_5_FIELD 0 | ||
2032 | #define STV090x_WIDTH_GAINLLR_NF_QP_3_5_FIELD 7 | ||
2033 | |||
2034 | #define STV090x_GAINLLR_NF6 STV090x_GAINLLR_NFx(6) | ||
2035 | #define STV090x_OFFST_GAINLLR_NF_QP_2_3_FIELD 0 | ||
2036 | #define STV090x_WIDTH_GAINLLR_NF_QP_2_3_FIELD 7 | ||
2037 | |||
2038 | #define STV090x_GAINLLR_NF7 STV090x_GAINLLR_NFx(7) | ||
2039 | #define STV090x_OFFST_GAINLLR_NF_QP_3_4_FIELD 0 | ||
2040 | #define STV090x_WIDTH_GAINLLR_NF_QP_3_4_FIELD 7 | ||
2041 | |||
2042 | #define STV090x_GAINLLR_NF8 STV090x_GAINLLR_NFx(8) | ||
2043 | #define STV090x_OFFST_GAINLLR_NF_QP_4_5_FIELD 0 | ||
2044 | #define STV090x_WIDTH_GAINLLR_NF_QP_4_5_FIELD 7 | ||
2045 | |||
2046 | #define STV090x_GAINLLR_NF9 STV090x_GAINLLR_NFx(9) | ||
2047 | #define STV090x_OFFST_GAINLLR_NF_QP_5_6_FIELD 0 | ||
2048 | #define STV090x_WIDTH_GAINLLR_NF_QP_5_6_FIELD 7 | ||
2049 | |||
2050 | #define STV090x_GAINLLR_NF10 STV090x_GAINLLR_NFx(10) | ||
2051 | #define STV090x_OFFST_GAINLLR_NF_QP_8_9_FIELD 0 | ||
2052 | #define STV090x_WIDTH_GAINLLR_NF_QP_8_9_FIELD 7 | ||
2053 | |||
2054 | #define STV090x_GAINLLR_NF11 STV090x_GAINLLR_NFx(11) | ||
2055 | #define STV090x_OFFST_GAINLLR_NF_QP_9_10_FIELD 0 | ||
2056 | #define STV090x_WIDTH_GAINLLR_NF_QP_9_10_FIELD 7 | ||
2057 | |||
2058 | #define STV090x_GAINLLR_NF12 STV090x_GAINLLR_NFx(12) | ||
2059 | #define STV090x_OFFST_GAINLLR_NF_8P_3_5_FIELD 0 | ||
2060 | #define STV090x_WIDTH_GAINLLR_NF_8P_3_5_FIELD 7 | ||
2061 | |||
2062 | #define STV090x_GAINLLR_NF13 STV090x_GAINLLR_NFx(13) | ||
2063 | #define STV090x_OFFST_GAINLLR_NF_8P_2_3_FIELD 0 | ||
2064 | #define STV090x_WIDTH_GAINLLR_NF_8P_2_3_FIELD 7 | ||
2065 | |||
2066 | #define STV090x_GAINLLR_NF14 STV090x_GAINLLR_NFx(14) | ||
2067 | #define STV090x_OFFST_GAINLLR_NF_8P_3_4_FIELD 0 | ||
2068 | #define STV090x_WIDTH_GAINLLR_NF_8P_3_4_FIELD 7 | ||
2069 | |||
2070 | #define STV090x_GAINLLR_NF15 STV090x_GAINLLR_NFx(15) | ||
2071 | #define STV090x_OFFST_GAINLLR_NF_8P_5_6_FIELD 0 | ||
2072 | #define STV090x_WIDTH_GAINLLR_NF_8P_5_6_FIELD 7 | ||
2073 | |||
2074 | #define STV090x_GAINLLR_NF16 STV090x_GAINLLR_NFx(16) | ||
2075 | #define STV090x_OFFST_GAINLLR_NF_8P_8_9_FIELD 0 | ||
2076 | #define STV090x_WIDTH_GAINLLR_NF_8P_8_9_FIELD 7 | ||
2077 | |||
2078 | #define STV090x_GAINLLR_NF17 STV090x_GAINLLR_NFx(17) | ||
2079 | #define STV090x_OFFST_GAINLLR_NF_8P_9_10_FIELD 0 | ||
2080 | #define STV090x_WIDTH_GAINLLR_NF_8P_9_10_FIELD 7 | ||
2081 | |||
2082 | #define STV090x_GENCFG 0xFA86 | ||
2083 | #define STV090x_OFFST_BROADCAST_FIELD 4 | ||
2084 | #define STV090x_WIDTH_BROADCAST_FIELD 1 | ||
2085 | #define STV090x_OFFST_PRIORITY_FIELD 1 | ||
2086 | #define STV090x_WIDTH_PRIORITY_FIELD 1 | ||
2087 | #define STV090x_OFFST_DDEMOD_FIELD 0 | ||
2088 | #define STV090x_WIDTH_DDEMOD_FIELD 1 | ||
2089 | |||
2090 | #define STV090x_LDPCERRx(__x) (0xFA97 - (__x * 0x1)) | ||
2091 | #define STV090x_LDPCERR0 STV090x_LDPCERRx(0) | ||
2092 | #define STV090x_LDPCERR1 STV090x_LDPCERRx(1) | ||
2093 | #define STV090x_OFFST_Px_LDPC_ERRORS_COUNTER_FIELD 0 | ||
2094 | #define STV090x_WIDTH_Px_LDPC_ERRORS_COUNTER_FIELD 8 | ||
2095 | |||
2096 | #define STV090x_BCHERR 0xFA98 | ||
2097 | #define STV090x_OFFST_Px_ERRORFLAG_FIELD 4 | ||
2098 | #define STV090x_WIDTH_Px_ERRORFLAG_FIELD 1 | ||
2099 | #define STV090x_OFFST_Px_BCH_ERRORS_COUNTER_FIELD 0 | ||
2100 | #define STV090x_WIDTH_Px_BCH_ERRORS_COUNTER_FIELD 4 | ||
2101 | |||
2102 | #define STV090x_Px_TSSTATEM(__x) (0xF570 - (__x - 1) * 0x200) | ||
2103 | #define STV090x_P1_TSSTATEM STV090x_Px_TSSTATEM(1) | ||
2104 | #define STV090x_P2_TSSTATEM STV090x_Px_TSSTATEM(2) | ||
2105 | #define STV090x_OFFST_Px_TSDIL_ON_FIELD 7 | ||
2106 | #define STV090x_WIDTH_Px_TSDIL_ON_FIELD 1 | ||
2107 | #define STV090x_OFFST_Px_TSRS_ON_FIELD 5 | ||
2108 | #define STV090x_WIDTH_Px_TSRS_ON_FIELD 1 | ||
2109 | |||
2110 | #define STV090x_Px_TSCFGH(__x) (0xF572 - (__x - 1) * 0x200) | ||
2111 | #define STV090x_P1_TSCFGH STV090x_Px_TSCFGH(1) | ||
2112 | #define STV090x_P2_TSCFGH STV090x_Px_TSCFGH(2) | ||
2113 | #define STV090x_OFFST_Px_TSFIFO_DVBCI_FIELD 7 | ||
2114 | #define STV090x_WIDTH_Px_TSFIFO_DVBCI_FIELD 1 | ||
2115 | #define STV090x_OFFST_Px_TSFIFO_SERIAL_FIELD 6 | ||
2116 | #define STV090x_WIDTH_Px_TSFIFO_SERIAL_FIELD 1 | ||
2117 | #define STV090x_OFFST_Px_TSFIFO_TEIUPDATE_FIELD 5 | ||
2118 | #define STV090x_WIDTH_Px_TSFIFO_TEIUPDATE_FIELD 1 | ||
2119 | #define STV090x_OFFST_Px_TSFIFO_DUTY50_FIELD 4 | ||
2120 | #define STV090x_WIDTH_Px_TSFIFO_DUTY50_FIELD 1 | ||
2121 | #define STV090x_OFFST_Px_TSFIFO_HSGNLOUT_FIELD 3 | ||
2122 | #define STV090x_WIDTH_Px_TSFIFO_HSGNLOUT_FIELD 1 | ||
2123 | #define STV090x_OFFST_Px_TSFIFO_ERRORMODE_FIELD 1 | ||
2124 | #define STV090x_WIDTH_Px_TSFIFO_ERRORMODE_FIELD 2 | ||
2125 | #define STV090x_OFFST_Px_RST_HWARE_FIELD 0 | ||
2126 | #define STV090x_WIDTH_Px_RST_HWARE_FIELD 1 | ||
2127 | |||
2128 | #define STV090x_Px_TSCFGM(__x) (0xF573 - (__x - 1) * 0x200) | ||
2129 | #define STV090x_P1_TSCFGM STV090x_Px_TSCFGM(1) | ||
2130 | #define STV090x_P2_TSCFGM STV090x_Px_TSCFGM(2) | ||
2131 | #define STV090x_OFFST_Px_TSFIFO_MANSPEED_FIELD 6 | ||
2132 | #define STV090x_WIDTH_Px_TSFIFO_MANSPEED_FIELD 2 | ||
2133 | #define STV090x_OFFST_Px_TSFIFO_PERMDATA_FIELD 5 | ||
2134 | #define STV090x_WIDTH_Px_TSFIFO_PERMDATA_FIELD 1 | ||
2135 | #define STV090x_OFFST_Px_TSFIFO_INVDATA_FIELD 0 | ||
2136 | #define STV090x_WIDTH_Px_TSFIFO_INVDATA_FIELD 1 | ||
2137 | |||
2138 | #define STV090x_Px_TSCFGL(__x) (0xF574 - (__x - 1) * 0x200) | ||
2139 | #define STV090x_P1_TSCFGL STV090x_Px_TSCFGL(1) | ||
2140 | #define STV090x_P2_TSCFGL STV090x_Px_TSCFGL(2) | ||
2141 | #define STV090x_OFFST_Px_TSFIFO_BCLKDEL1CK_FIELD 6 | ||
2142 | #define STV090x_WIDTH_Px_TSFIFO_BCLKDEL1CK_FIELD 2 | ||
2143 | #define STV090x_OFFST_Px_BCHERROR_MODE_FIELD 4 | ||
2144 | #define STV090x_WIDTH_Px_BCHERROR_MODE_FIELD 2 | ||
2145 | #define STV090x_OFFST_Px_TSFIFO_NSGNL2DATA_FIELD 3 | ||
2146 | #define STV090x_WIDTH_Px_TSFIFO_NSGNL2DATA_FIELD 1 | ||
2147 | #define STV090x_OFFST_Px_TSFIFO_EMBINDVB_FIELD 2 | ||
2148 | #define STV090x_WIDTH_Px_TSFIFO_EMBINDVB_FIELD 1 | ||
2149 | #define STV090x_OFFST_Px_TSFIFO_DPUNACT_FIELD 1 | ||
2150 | #define STV090x_WIDTH_Px_TSFIFO_DPUNACT_FIELD 1 | ||
2151 | |||
2152 | #define STV090x_Px_TSINSDELH(__x) (0xF576 - (__x - 1) * 0x200) | ||
2153 | #define STV090x_P1_TSINSDELH STV090x_Px_TSINSDELH(1) | ||
2154 | #define STV090x_P2_TSINSDELH STV090x_Px_TSINSDELH(2) | ||
2155 | #define STV090x_OFFST_Px_TSDEL_SYNCBYTE_FIELD 7 | ||
2156 | #define STV090x_WIDTH_Px_TSDEL_SYNCBYTE_FIELD 1 | ||
2157 | #define STV090x_OFFST_Px_TSDEL_XXHEADER_FIELD 6 | ||
2158 | #define STV090x_WIDTH_Px_TSDEL_XXHEADER_FIELD 1 | ||
2159 | |||
2160 | #define STV090x_Px_TSSPEED(__x) (0xF580 - (__x - 1) * 0x200) | ||
2161 | #define STV090x_P1_TSSPEED STV090x_Px_TSSPEED(1) | ||
2162 | #define STV090x_P2_TSSPEED STV090x_Px_TSSPEED(2) | ||
2163 | #define STV090x_OFFST_Px_TSFIFO_OUTSPEED_FIELD 0 | ||
2164 | #define STV090x_WIDTH_Px_TSFIFO_OUTSPEED_FIELD 8 | ||
2165 | |||
2166 | #define STV090x_Px_TSSTATUS(__x) (0xF581 - (__x - 1) * 0x200) | ||
2167 | #define STV090x_P1_TSSTATUS STV090x_Px_TSSTATUS(1) | ||
2168 | #define STV090x_P2_TSSTATUS STV090x_Px_TSSTATUS(2) | ||
2169 | #define STV090x_OFFST_Px_TSFIFO_LINEOK_FIELD 7 | ||
2170 | #define STV090x_WIDTH_Px_TSFIFO_LINEOK_FIELD 1 | ||
2171 | #define STV090x_OFFST_Px_TSFIFO_ERROR_FIELD 6 | ||
2172 | #define STV090x_WIDTH_Px_TSFIFO_ERROR_FIELD 1 | ||
2173 | |||
2174 | #define STV090x_Px_TSSTATUS2(__x) (0xF582 - (__x - 1) * 0x200) | ||
2175 | #define STV090x_P1_TSSTATUS2 STV090x_Px_TSSTATUS2(1) | ||
2176 | #define STV090x_P2_TSSTATUS2 STV090x_Px_TSSTATUS2(2) | ||
2177 | #define STV090x_OFFST_Px_TSFIFO_DEMODSEL_FIELD 7 | ||
2178 | #define STV090x_WIDTH_Px_TSFIFO_DEMODSEL_FIELD 1 | ||
2179 | #define STV090x_OFFST_Px_TSFIFOSPEED_STORE_FIELD 6 | ||
2180 | #define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD 1 | ||
2181 | #define STV090x_OFFST_Px_DILXX_RESET_FIELD 5 | ||
2182 | #define STV090x_WIDTH_Px_DILXX_RESET_FIELD 1 | ||
2183 | #define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD 5 | ||
2184 | #define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD 1 | ||
2185 | #define STV090x_OFFST_Px_SCRAMBDETECT_FIELD 1 | ||
2186 | #define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD 1 | ||
2187 | |||
2188 | #define STV090x_Px_TSBITRATEy(__x, __y) (0xF584 - (__x - 1) * 0x200 - __y * 0x1) | ||
2189 | #define STV090x_P1_TSBITRATE0 STV090x_Px_TSBITRATEy(1, 0) | ||
2190 | #define STV090x_P1_TSBITRATE1 STV090x_Px_TSBITRATEy(1, 1) | ||
2191 | #define STV090x_P2_TSBITRATE0 STV090x_Px_TSBITRATEy(2, 0) | ||
2192 | #define STV090x_P2_TSBITRATE1 STV090x_Px_TSBITRATEy(2, 1) | ||
2193 | #define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD 7 | ||
2194 | #define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD 8 | ||
2195 | |||
2196 | #define STV090x_Px_ERRCTRL1(__x) (0xF598 - (__x - 1) * 0x200) | ||
2197 | #define STV090x_P1_ERRCTRL1 STV090x_Px_ERRCTRL1(1) | ||
2198 | #define STV090x_P2_ERRCTRL1 STV090x_Px_ERRCTRL1(2) | ||
2199 | #define STV090x_OFFST_Px_ERR_SOURCE_FIELD 4 | ||
2200 | #define STV090x_WIDTH_Px_ERR_SOURCE_FIELD 4 | ||
2201 | #define STV090x_OFFST_Px_NUM_EVENT_FIELD 0 | ||
2202 | #define STV090x_WIDTH_Px_NUM_EVENT_FIELD 3 | ||
2203 | |||
2204 | #define STV090x_Px_ERRCNT12(__x) (0xF599 - (__x - 1) * 0x200) | ||
2205 | #define STV090x_P1_ERRCNT12 STV090x_Px_ERRCNT12(1) | ||
2206 | #define STV090x_P2_ERRCNT12 STV090x_Px_ERRCNT12(2) | ||
2207 | #define STV090x_OFFST_Px_ERRCNT1_OLDVALUE_FIELD 7 | ||
2208 | #define STV090x_WIDTH_Px_ERRCNT1_OLDVALUE_FIELD 1 | ||
2209 | #define STV090x_OFFST_Px_ERR_CNT12_FIELD 0 | ||
2210 | #define STV090x_WIDTH_Px_ERR_CNT12_FIELD 7 | ||
2211 | |||
2212 | #define STV090x_Px_ERRCNT11(__x) (0xF59A - (__x - 1) * 0x200) | ||
2213 | #define STV090x_P1_ERRCNT11 STV090x_Px_ERRCNT11(1) | ||
2214 | #define STV090x_P2_ERRCNT11 STV090x_Px_ERRCNT11(2) | ||
2215 | #define STV090x_OFFST_Px_ERR_CNT11_FIELD 0 | ||
2216 | #define STV090x_WIDTH_Px_ERR_CNT11_FIELD 8 | ||
2217 | |||
2218 | #define STV090x_Px_ERRCNT10(__x) (0xF59B - (__x - 1) * 0x200) | ||
2219 | #define STV090x_P1_ERRCNT10 STV090x_Px_ERRCNT10(1) | ||
2220 | #define STV090x_P2_ERRCNT10 STV090x_Px_ERRCNT10(2) | ||
2221 | #define STV090x_OFFST_Px_ERR_CNT10_FIELD 0 | ||
2222 | #define STV090x_WIDTH_Px_ERR_CNT10_FIELD 8 | ||
2223 | |||
2224 | #define STV090x_Px_ERRCTRL2(__x) (0xF59C - (__x - 1) * 0x200) | ||
2225 | #define STV090x_P1_ERRCTRL2 STV090x_Px_ERRCTRL2(1) | ||
2226 | #define STV090x_P2_ERRCTRL2 STV090x_Px_ERRCTRL2(2) | ||
2227 | #define STV090x_OFFST_Px_ERR_SOURCE2_FIELD 4 | ||
2228 | #define STV090x_WIDTH_Px_ERR_SOURCE2_FIELD 4 | ||
2229 | #define STV090x_OFFST_Px_NUM_EVENT2_FIELD 0 | ||
2230 | #define STV090x_WIDTH_Px_NUM_EVENT2_FIELD 3 | ||
2231 | |||
2232 | #define STV090x_Px_ERRCNT22(__x) (0xF59D - (__x - 1) * 0x200) | ||
2233 | #define STV090x_P1_ERRCNT22 STV090x_Px_ERRCNT22(1) | ||
2234 | #define STV090x_P2_ERRCNT22 STV090x_Px_ERRCNT22(2) | ||
2235 | #define STV090x_OFFST_Px_ERRCNT2_OLDVALUE_FIELD 7 | ||
2236 | #define STV090x_WIDTH_Px_ERRCNT2_OLDVALUE_FIELD 1 | ||
2237 | #define STV090x_OFFST_Px_ERR_CNT2_FIELD 0 | ||
2238 | #define STV090x_WIDTH_Px_ERR_CNT2_FIELD 7 | ||
2239 | |||
2240 | #define STV090x_Px_ERRCNT21(__x) (0xF59E - (__x - 1) * 0x200) | ||
2241 | #define STV090x_P1_ERRCNT21 STV090x_Px_ERRCNT21(1) | ||
2242 | #define STV090x_P2_ERRCNT21 STV090x_Px_ERRCNT21(2) | ||
2243 | #define STV090x_OFFST_Px_ERR_CNT21_FIELD 0 | ||
2244 | #define STV090x_WIDTH_Px_ERR_CNT21_FIELD 8 | ||
2245 | |||
2246 | #define STV090x_Px_ERRCNT20(__x) (0xF59F - (__x - 1) * 0x200) | ||
2247 | #define STV090x_P1_ERRCNT20 STV090x_Px_ERRCNT20(1) | ||
2248 | #define STV090x_P2_ERRCNT20 STV090x_Px_ERRCNT20(2) | ||
2249 | #define STV090x_OFFST_Px_ERR_CNT20_FIELD 0 | ||
2250 | #define STV090x_WIDTH_Px_ERR_CNT20_FIELD 8 | ||
2251 | |||
2252 | #define STV090x_Px_FECSPY(__x) (0xF5A0 - (__x - 1) * 0x200) | ||
2253 | #define STV090x_P1_FECSPY STV090x_Px_FECSPY(1) | ||
2254 | #define STV090x_P2_FECSPY STV090x_Px_FECSPY(2) | ||
2255 | #define STV090x_OFFST_Px_SPY_ENABLE_FIELD 7 | ||
2256 | #define STV090x_WIDTH_Px_SPY_ENABLE_FIELD 1 | ||
2257 | #define STV090x_OFFST_Px_BERMETER_DATAMAODE_FIELD 2 | ||
2258 | #define STV090x_WIDTH_Px_BERMETER_DATAMAODE_FIELD 2 | ||
2259 | |||
2260 | #define STV090x_Px_FSPYCFG(__x) (0xF5A1 - (__x - 1) * 0x200) | ||
2261 | #define STV090x_P1_FSPYCFG STV090x_Px_FSPYCFG(1) | ||
2262 | #define STV090x_P2_FSPYCFG STV090x_Px_FSPYCFG(2) | ||
2263 | #define STV090x_OFFST_Px_RST_ON_ERROR_FIELD 5 | ||
2264 | #define STV090x_WIDTH_Px_RST_ON_ERROR_FIELD 1 | ||
2265 | #define STV090x_OFFST_Px_ONE_SHOT_FIELD 4 | ||
2266 | #define STV090x_WIDTH_Px_ONE_SHOT_FIELD 1 | ||
2267 | #define STV090x_OFFST_Px_I2C_MODE_FIELD 2 | ||
2268 | #define STV090x_WIDTH_Px_I2C_MODE_FIELD 2 | ||
2269 | |||
2270 | #define STV090x_Px_FSPYDATA(__x) (0xF5A2 - (__x - 1) * 0x200) | ||
2271 | #define STV090x_P1_FSPYDATA STV090x_Px_FSPYDATA(1) | ||
2272 | #define STV090x_P2_FSPYDATA STV090x_Px_FSPYDATA(2) | ||
2273 | #define STV090x_OFFST_Px_SPY_STUFFING_FIELD 7 | ||
2274 | #define STV090x_WIDTH_Px_SPY_STUFFING_FIELD 1 | ||
2275 | #define STV090x_OFFST_Px_SPY_CNULLPKT_FIELD 5 | ||
2276 | #define STV090x_WIDTH_Px_SPY_CNULLPKT_FIELD 1 | ||
2277 | #define STV090x_OFFST_Px_SPY_OUTDATA_MODE_FIELD 0 | ||
2278 | #define STV090x_WIDTH_Px_SPY_OUTDATA_MODE_FIELD 5 | ||
2279 | |||
2280 | #define STV090x_Px_FSPYOUT(__x) (0xF5A3 - (__x - 1) * 0x200) | ||
2281 | #define STV090x_P1_FSPYOUT STV090x_Px_FSPYOUT(1) | ||
2282 | #define STV090x_P2_FSPYOUT STV090x_Px_FSPYOUT(2) | ||
2283 | #define STV090x_OFFST_Px_FSPY_DIRECT_FIELD 7 | ||
2284 | #define STV090x_WIDTH_Px_FSPY_DIRECT_FIELD 1 | ||
2285 | #define STV090x_OFFST_Px_STUFF_MODE_FIELD 0 | ||
2286 | #define STV090x_WIDTH_Px_STUFF_MODE_FIELD 3 | ||
2287 | |||
2288 | #define STV090x_Px_FSTATUS(__x) (0xF5A4 - (__x - 1) * 0x200) | ||
2289 | #define STV090x_P1_FSTATUS STV090x_Px_FSTATUS(1) | ||
2290 | #define STV090x_P2_FSTATUS STV090x_Px_FSTATUS(2) | ||
2291 | #define STV090x_OFFST_Px_SPY_ENDSIM_FIELD 7 | ||
2292 | #define STV090x_WIDTH_Px_SPY_ENDSIM_FIELD 1 | ||
2293 | #define STV090x_OFFST_Px_VALID_SIM_FIELD 6 | ||
2294 | #define STV090x_WIDTH_Px_VALID_SIM_FIELD 1 | ||
2295 | #define STV090x_OFFST_Px_FOUND_SIGNAL_FIELD 5 | ||
2296 | #define STV090x_WIDTH_Px_FOUND_SIGNAL_FIELD 1 | ||
2297 | #define STV090x_OFFST_Px_DSS_SYNCBYTE_FIELD 4 | ||
2298 | #define STV090x_WIDTH_Px_DSS_SYNCBYTE_FIELD 1 | ||
2299 | #define STV090x_OFFST_Px_RESULT_STATE_FIELD 0 | ||
2300 | #define STV090x_WIDTH_Px_RESULT_STATE_FIELD 4 | ||
2301 | |||
2302 | #define STV090x_Px_FBERCPT4(__x) (0xF5A8 - (__x - 1) * 0x200) | ||
2303 | #define STV090x_P1_FBERCPT4 STV090x_Px_FBERCPT4(1) | ||
2304 | #define STV090x_P2_FBERCPT4 STV090x_Px_FBERCPT4(2) | ||
2305 | #define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 | ||
2306 | #define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8 | ||
2307 | |||
2308 | #define STV090x_Px_FBERCPT3(__x) (0xF5A9 - (__x - 1) * 0x200) | ||
2309 | #define STV090x_P1_FBERCPT3 STV090x_Px_FBERCPT3(1) | ||
2310 | #define STV090x_P2_FBERCPT3 STV090x_Px_FBERCPT3(2) | ||
2311 | #define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 | ||
2312 | #define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8 | ||
2313 | |||
2314 | #define STV090x_Px_FBERCPT2(__x) (0xF5AA - (__x - 1) * 0x200) | ||
2315 | #define STV090x_P1_FBERCPT2 STV090x_Px_FBERCPT2(1) | ||
2316 | #define STV090x_P2_FBERCPT2 STV090x_Px_FBERCPT2(2) | ||
2317 | #define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 | ||
2318 | #define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8 | ||
2319 | |||
2320 | #define STV090x_Px_FBERCPT1(__x) (0xF5AB - (__x - 1) * 0x200) | ||
2321 | #define STV090x_P1_FBERCPT1 STV090x_Px_FBERCPT1(1) | ||
2322 | #define STV090x_P2_FBERCPT1 STV090x_Px_FBERCPT1(2) | ||
2323 | #define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 | ||
2324 | #define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8 | ||
2325 | |||
2326 | #define STV090x_Px_FBERCPT0(__x) (0xF5AC - (__x - 1) * 0x200) | ||
2327 | #define STV090x_P1_FBERCPT0 STV090x_Px_FBERCPT0(1) | ||
2328 | #define STV090x_P2_FBERCPT0 STV090x_Px_FBERCPT0(2) | ||
2329 | #define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0 | ||
2330 | #define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8 | ||
2331 | |||
2332 | #define STV090x_Px_FBERERRy(__x, __y) (0xF5AF - (__x - 1) * 0x200 - __y * 0x1) | ||
2333 | #define STV090x_P1_FBERERR0 STV090x_Px_FBERERRy(1, 0) | ||
2334 | #define STV090x_P1_FBERERR1 STV090x_Px_FBERERRy(1, 1) | ||
2335 | #define STV090x_P1_FBERERR2 STV090x_Px_FBERERRy(1, 2) | ||
2336 | #define STV090x_P2_FBERERR0 STV090x_Px_FBERERRy(2, 0) | ||
2337 | #define STV090x_P2_FBERERR1 STV090x_Px_FBERERRy(2, 1) | ||
2338 | #define STV090x_P2_FBERERR2 STV090x_Px_FBERERRy(2, 2) | ||
2339 | #define STV090x_OFFST_Px_FBERMETER_CPT_ERR_FIELD 0 | ||
2340 | #define STV090x_WIDTH_Px_FBERMETER_CPT_ERR_FIELD 8 | ||
2341 | |||
2342 | #define STV090x_Px_FSPYBER(__x) (0xF5B2 - (__x - 1) * 0x200) | ||
2343 | #define STV090x_P1_FSPYBER STV090x_Px_FSPYBER(1) | ||
2344 | #define STV090x_P2_FSPYBER STV090x_Px_FSPYBER(2) | ||
2345 | #define STV090x_OFFST_Px_FSPYBER_SYNCBYTE_FIELD 4 | ||
2346 | #define STV090x_WIDTH_Px_FSPYBER_SYNCBYTE_FIELD 1 | ||
2347 | #define STV090x_OFFST_Px_FSPYBER_UNSYNC_FIELD 3 | ||
2348 | #define STV090x_WIDTH_Px_FSPYBER_UNSYNC_FIELD 1 | ||
2349 | #define STV090x_OFFST_Px_FSPYBER_CTIME_FIELD 0 | ||
2350 | #define STV090x_WIDTH_Px_FSPYBER_CTIME_FIELD 3 | ||
2351 | |||
2352 | #define STV090x_RCCFGH 0xf600 | ||
2353 | |||
2354 | #define STV090x_TSGENERAL 0xF630 | ||
2355 | #define STV090x_OFFST_Px_MUXSTREAM_OUT_FIELD 3 | ||
2356 | #define STV090x_WIDTH_Px_MUXSTREAM_OUT_FIELD 1 | ||
2357 | #define STV090x_OFFST_Px_TSFIFO_PERMPARAL_FIELD 1 | ||
2358 | #define STV090x_WIDTH_Px_TSFIFO_PERMPARAL_FIELD 2 | ||
2359 | |||
2360 | #define STV090x_TSGENERAL1X 0xf670 | ||
2361 | #define STV090x_CFGEXT 0xfa80 | ||
2362 | |||
2363 | #define STV090x_TSTRES0 0xFF11 | ||
2364 | #define STV090x_OFFST_FRESFEC_FIELD 7 | ||
2365 | #define STV090x_WIDTH_FRESFEC_FIELD 1 | ||
2366 | |||
2367 | #define STV090x_Px_TSTDISRX(__x) (0xFF67 - (__x - 1) * 0x2) | ||
2368 | #define STV090x_P1_TSTDISRX STV090x_Px_TSTDISRX(1) | ||
2369 | #define STV090x_P2_TSTDISRX STV090x_Px_TSTDISRX(2) | ||
2370 | #define STV090x_OFFST_Px_TSTDISRX_SELECT_FIELD 3 | ||
2371 | #define STV090x_WIDTH_Px_TSTDISRX_SELECT_FIELD 1 | ||
2372 | |||
2373 | #endif /* __STV090x_REG_H */ | ||
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c new file mode 100644 index 000000000000..3d8a2e01c9c4 --- /dev/null +++ b/drivers/media/dvb/frontends/stv6110x.c | |||
@@ -0,0 +1,373 @@ | |||
1 | /* | ||
2 | STV6110(A) Silicon tuner driver | ||
3 | |||
4 | Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||
5 | |||
6 | Copyright (C) ST Microelectronics | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
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 | 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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/init.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/string.h> | ||
27 | |||
28 | #include "dvb_frontend.h" | ||
29 | |||
30 | #include "stv6110x_reg.h" | ||
31 | #include "stv6110x.h" | ||
32 | #include "stv6110x_priv.h" | ||
33 | |||
34 | static unsigned int verbose; | ||
35 | module_param(verbose, int, 0644); | ||
36 | MODULE_PARM_DESC(verbose, "Set Verbosity level"); | ||
37 | |||
38 | static u8 stv6110x_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; | ||
39 | |||
40 | static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) | ||
41 | { | ||
42 | int ret; | ||
43 | const struct stv6110x_config *config = stv6110x->config; | ||
44 | u8 b0[] = { reg }; | ||
45 | u8 b1[] = { 0 }; | ||
46 | struct i2c_msg msg[] = { | ||
47 | { .addr = config->addr, .flags = 0, .buf = b0, .len = 1 }, | ||
48 | { .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 } | ||
49 | }; | ||
50 | |||
51 | ret = i2c_transfer(stv6110x->i2c, msg, 2); | ||
52 | if (ret != 2) { | ||
53 | dprintk(FE_ERROR, 1, "I/O Error"); | ||
54 | return -EREMOTEIO; | ||
55 | } | ||
56 | *data = b1[0]; | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) | ||
62 | { | ||
63 | int ret; | ||
64 | const struct stv6110x_config *config = stv6110x->config; | ||
65 | u8 buf[] = { reg, data }; | ||
66 | struct i2c_msg msg = { .addr = config->addr, .flags = 0, . buf = buf, .len = 2 }; | ||
67 | |||
68 | ret = i2c_transfer(stv6110x->i2c, &msg, 1); | ||
69 | if (ret != 1) { | ||
70 | dprintk(FE_ERROR, 1, "I/O Error"); | ||
71 | return -EREMOTEIO; | ||
72 | } | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int stv6110x_init(struct dvb_frontend *fe) | ||
78 | { | ||
79 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
80 | int ret; | ||
81 | u8 i; | ||
82 | |||
83 | for (i = 0; i < ARRAY_SIZE(stv6110x_regs); i++) { | ||
84 | ret = stv6110x_write_reg(stv6110x, i, stv6110x_regs[i]); | ||
85 | if (ret < 0) { | ||
86 | dprintk(FE_ERROR, 1, "Initialization failed"); | ||
87 | return -1; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) | ||
95 | { | ||
96 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
97 | u32 rDiv, divider; | ||
98 | s32 pVal, pCalc, rDivOpt = 0; | ||
99 | u8 i; | ||
100 | |||
101 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); | ||
102 | |||
103 | if (frequency <= 1023000) { | ||
104 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); | ||
105 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); | ||
106 | pVal = 40; | ||
107 | } else if (frequency <= 1300000) { | ||
108 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); | ||
109 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); | ||
110 | pVal = 40; | ||
111 | } else if (frequency <= 2046000) { | ||
112 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); | ||
113 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); | ||
114 | pVal = 20; | ||
115 | } else { | ||
116 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); | ||
117 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); | ||
118 | pVal = 20; | ||
119 | } | ||
120 | |||
121 | for (rDiv = 0; rDiv <= 3; rDiv++) { | ||
122 | pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv); | ||
123 | |||
124 | if ((abs((s32)(pCalc - pVal))) < (abs((s32)(1000 - pVal)))) | ||
125 | rDivOpt = rDiv; | ||
126 | } | ||
127 | |||
128 | divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; | ||
129 | divider = (divider + 5) / 10; | ||
130 | |||
131 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt); | ||
132 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider)); | ||
133 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider)); | ||
134 | |||
135 | /* VCO Auto calibration */ | ||
136 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1); | ||
137 | |||
138 | stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]); | ||
139 | stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x_regs[STV6110x_TNG1]); | ||
140 | stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x_regs[STV6110x_TNG0]); | ||
141 | stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]); | ||
142 | |||
143 | for (i = 0; i < TRIALS; i++) { | ||
144 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); | ||
145 | if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x_regs[STV6110x_STAT1])) | ||
146 | break; | ||
147 | msleep(1); | ||
148 | } | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
154 | { | ||
155 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
156 | |||
157 | stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x_regs[STV6110x_TNG1]); | ||
158 | stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x_regs[STV6110x_TNG0]); | ||
159 | |||
160 | *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x_regs[STV6110x_TNG1]), | ||
161 | STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x_regs[STV6110x_TNG0]))) * REFCLOCK_kHz; | ||
162 | |||
163 | *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x_regs[STV6110x_TNG1]) + | ||
164 | STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x_regs[STV6110x_TNG1]))); | ||
165 | |||
166 | *frequency >>= 2; | ||
167 | |||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) | ||
172 | { | ||
173 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
174 | u32 halfbw; | ||
175 | u8 i; | ||
176 | |||
177 | halfbw = bandwidth >> 1; | ||
178 | |||
179 | if (halfbw > 36000000) | ||
180 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */ | ||
181 | else if (halfbw < 5000000) | ||
182 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */ | ||
183 | else | ||
184 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */ | ||
185 | |||
186 | |||
187 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */ | ||
188 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */ | ||
189 | |||
190 | stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]); | ||
191 | stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]); | ||
192 | |||
193 | for (i = 0; i < TRIALS; i++) { | ||
194 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); | ||
195 | if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x_regs[STV6110x_STAT1])) | ||
196 | break; | ||
197 | msleep(1); | ||
198 | } | ||
199 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */ | ||
200 | stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | ||
206 | { | ||
207 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
208 | |||
209 | stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x_regs[STV6110x_CTRL3]); | ||
210 | *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x_regs[STV6110x_CTRL3]) + 5) * 2000000; | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock) | ||
216 | { | ||
217 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
218 | |||
219 | /* setup divider */ | ||
220 | switch (refclock) { | ||
221 | default: | ||
222 | case 1: | ||
223 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); | ||
224 | break; | ||
225 | case 2: | ||
226 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); | ||
227 | break; | ||
228 | case 4: | ||
229 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); | ||
230 | break; | ||
231 | case 8: | ||
232 | case 0: | ||
233 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); | ||
234 | break; | ||
235 | } | ||
236 | stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain) | ||
242 | { | ||
243 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
244 | |||
245 | stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x_regs[STV6110x_CTRL2]); | ||
246 | *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x_regs[STV6110x_CTRL2]); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain) | ||
252 | { | ||
253 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
254 | |||
255 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2); | ||
256 | stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode) | ||
262 | { | ||
263 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
264 | int ret; | ||
265 | |||
266 | switch (mode) { | ||
267 | case TUNER_SLEEP: | ||
268 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 0); | ||
269 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 0); | ||
270 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 0); | ||
271 | break; | ||
272 | |||
273 | case TUNER_WAKE: | ||
274 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 1); | ||
275 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 1); | ||
276 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 1); | ||
277 | break; | ||
278 | } | ||
279 | |||
280 | ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]); | ||
281 | if (ret < 0) { | ||
282 | dprintk(FE_ERROR, 1, "I/O Error"); | ||
283 | return -EIO; | ||
284 | } | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int stv6110x_sleep(struct dvb_frontend *fe) | ||
290 | { | ||
291 | return stv6110x_set_mode(fe, TUNER_SLEEP); | ||
292 | } | ||
293 | |||
294 | static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) | ||
295 | { | ||
296 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
297 | |||
298 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); | ||
299 | |||
300 | if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x_regs[STV6110x_STAT1])) | ||
301 | *status = TUNER_PHASELOCKED; | ||
302 | else | ||
303 | *status = 0; | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | |||
309 | static int stv6110x_release(struct dvb_frontend *fe) | ||
310 | { | ||
311 | struct stv6110x_state *stv6110x = fe->tuner_priv; | ||
312 | |||
313 | fe->tuner_priv = NULL; | ||
314 | kfree(stv6110x); | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static struct dvb_tuner_ops stv6110x_ops = { | ||
320 | .info = { | ||
321 | .name = "STV6110(A) Silicon Tuner", | ||
322 | .frequency_min = 950000, | ||
323 | .frequency_max = 2150000, | ||
324 | .frequency_step = 0, | ||
325 | }, | ||
326 | |||
327 | .init = stv6110x_init, | ||
328 | .sleep = stv6110x_sleep, | ||
329 | .release = stv6110x_release | ||
330 | }; | ||
331 | |||
332 | static struct stv6110x_devctl stv6110x_ctl = { | ||
333 | .tuner_init = stv6110x_init, | ||
334 | .tuner_set_mode = stv6110x_set_mode, | ||
335 | .tuner_set_frequency = stv6110x_set_frequency, | ||
336 | .tuner_get_frequency = stv6110x_get_frequency, | ||
337 | .tuner_set_bandwidth = stv6110x_set_bandwidth, | ||
338 | .tuner_get_bandwidth = stv6110x_get_bandwidth, | ||
339 | .tuner_set_bbgain = stv6110x_set_bbgain, | ||
340 | .tuner_get_bbgain = stv6110x_get_bbgain, | ||
341 | .tuner_set_refclk = stv6110x_set_refclock, | ||
342 | .tuner_get_status = stv6110x_get_status, | ||
343 | }; | ||
344 | |||
345 | struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | ||
346 | const struct stv6110x_config *config, | ||
347 | struct i2c_adapter *i2c) | ||
348 | { | ||
349 | struct stv6110x_state *stv6110x; | ||
350 | |||
351 | stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); | ||
352 | if (stv6110x == NULL) | ||
353 | goto error; | ||
354 | |||
355 | stv6110x->i2c = i2c; | ||
356 | stv6110x->config = config; | ||
357 | stv6110x->devctl = &stv6110x_ctl; | ||
358 | |||
359 | fe->tuner_priv = stv6110x; | ||
360 | fe->ops.tuner_ops = stv6110x_ops; | ||
361 | |||
362 | printk("%s: Attaching STV6110x \n", __func__); | ||
363 | return stv6110x->devctl; | ||
364 | |||
365 | error: | ||
366 | kfree(stv6110x); | ||
367 | return NULL; | ||
368 | } | ||
369 | EXPORT_SYMBOL(stv6110x_attach); | ||
370 | |||
371 | MODULE_AUTHOR("Manu Abraham"); | ||
372 | MODULE_DESCRIPTION("STV6110x Silicon tuner"); | ||
373 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb/frontends/stv6110x.h new file mode 100644 index 000000000000..a38257080e01 --- /dev/null +++ b/drivers/media/dvb/frontends/stv6110x.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | STV6110(A) Silicon tuner driver | ||
3 | |||
4 | Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||
5 | |||
6 | Copyright (C) ST Microelectronics | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
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 | 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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #ifndef __STV6110x_H | ||
24 | #define __STV6110x_H | ||
25 | |||
26 | struct stv6110x_config { | ||
27 | u8 addr; | ||
28 | u32 refclk; | ||
29 | }; | ||
30 | |||
31 | enum tuner_mode { | ||
32 | TUNER_SLEEP = 1, | ||
33 | TUNER_WAKE, | ||
34 | }; | ||
35 | |||
36 | enum tuner_status { | ||
37 | TUNER_PHASELOCKED = 1, | ||
38 | }; | ||
39 | |||
40 | struct stv6110x_devctl { | ||
41 | int (*tuner_init) (struct dvb_frontend *fe); | ||
42 | int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); | ||
43 | int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); | ||
44 | int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency); | ||
45 | int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth); | ||
46 | int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth); | ||
47 | int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain); | ||
48 | int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain); | ||
49 | int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk); | ||
50 | int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status); | ||
51 | }; | ||
52 | |||
53 | |||
54 | #if defined(CONFIG_DVB_STV6110x) || (defined(CONFIG_DVB_STV6110x_MODULE) && defined(MODULE)) | ||
55 | |||
56 | extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | ||
57 | const struct stv6110x_config *config, | ||
58 | struct i2c_adapter *i2c); | ||
59 | |||
60 | #else | ||
61 | static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | ||
62 | const struct stv6110x_config *config, | ||
63 | struct i2c_adapter *i2c) | ||
64 | { | ||
65 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
66 | return NULL; | ||
67 | } | ||
68 | |||
69 | #endif /* CONFIG_DVB_STV6110x */ | ||
70 | |||
71 | #endif /* __STV6110x_H */ | ||
diff --git a/drivers/media/dvb/frontends/stv6110x_priv.h b/drivers/media/dvb/frontends/stv6110x_priv.h new file mode 100644 index 000000000000..7260da633d49 --- /dev/null +++ b/drivers/media/dvb/frontends/stv6110x_priv.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | STV6110(A) Silicon tuner driver | ||
3 | |||
4 | Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||
5 | |||
6 | Copyright (C) ST Microelectronics | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
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 | 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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #ifndef __STV6110x_PRIV_H | ||
24 | #define __STV6110x_PRIV_H | ||
25 | |||
26 | #define FE_ERROR 0 | ||
27 | #define FE_NOTICE 1 | ||
28 | #define FE_INFO 2 | ||
29 | #define FE_DEBUG 3 | ||
30 | #define FE_DEBUGREG 4 | ||
31 | |||
32 | #define dprintk(__y, __z, format, arg...) do { \ | ||
33 | if (__z) { \ | ||
34 | if ((verbose > FE_ERROR) && (verbose > __y)) \ | ||
35 | printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ | ||
36 | else if ((verbose > FE_NOTICE) && (verbose > __y)) \ | ||
37 | printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ | ||
38 | else if ((verbose > FE_INFO) && (verbose > __y)) \ | ||
39 | printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ | ||
40 | else if ((verbose > FE_DEBUG) && (verbose > __y)) \ | ||
41 | printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ | ||
42 | } else { \ | ||
43 | if (verbose > __y) \ | ||
44 | printk(format, ##arg); \ | ||
45 | } \ | ||
46 | } while (0) | ||
47 | |||
48 | |||
49 | #define STV6110x_SETFIELD(mask, bitf, val) \ | ||
50 | (mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) << \ | ||
51 | STV6110x_OFFST_##bitf))) | \ | ||
52 | (val << STV6110x_OFFST_##bitf)) | ||
53 | |||
54 | #define STV6110x_GETFIELD(bitf, val) \ | ||
55 | ((val >> STV6110x_OFFST_##bitf) & \ | ||
56 | ((1 << STV6110x_WIDTH_##bitf) - 1)) | ||
57 | |||
58 | #define MAKEWORD16(a, b) (((a) << 8) | (b)) | ||
59 | |||
60 | #define LSB(x) ((x & 0xff)) | ||
61 | #define MSB(y) ((y >> 8) & 0xff) | ||
62 | |||
63 | #define TRIALS 10 | ||
64 | #define R_DIV(__div) (1 << (__div + 1)) | ||
65 | #define REFCLOCK_kHz (stv6110x->config->refclk / 1000) | ||
66 | #define REFCLOCK_MHz (stv6110x->config->refclk / 1000000) | ||
67 | |||
68 | struct stv6110x_state { | ||
69 | struct i2c_adapter *i2c; | ||
70 | const struct stv6110x_config *config; | ||
71 | |||
72 | struct stv6110x_devctl *devctl; | ||
73 | }; | ||
74 | |||
75 | #endif /* __STV6110x_PRIV_H */ | ||
diff --git a/drivers/media/dvb/frontends/stv6110x_reg.h b/drivers/media/dvb/frontends/stv6110x_reg.h new file mode 100644 index 000000000000..93e5c70e5fd8 --- /dev/null +++ b/drivers/media/dvb/frontends/stv6110x_reg.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | STV6110(A) Silicon tuner driver | ||
3 | |||
4 | Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||
5 | |||
6 | Copyright (C) ST Microelectronics | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
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 | 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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #ifndef __STV6110x_REG_H | ||
24 | #define __STV6110x_REG_H | ||
25 | |||
26 | #define STV6110x_CTRL1 0x00 | ||
27 | #define STV6110x_OFFST_CTRL1_K 3 | ||
28 | #define STV6110x_WIDTH_CTRL1_K 5 | ||
29 | #define STV6110x_OFFST_CTRL1_LPT 2 | ||
30 | #define STV6110x_WIDTH_CTRL1_LPT 1 | ||
31 | #define STV6110x_OFFST_CTRL1_RX 1 | ||
32 | #define STV6110x_WIDTH_CTRL1_RX 1 | ||
33 | #define STV6110x_OFFST_CTRL1_SYN 0 | ||
34 | #define STV6110x_WIDTH_CTRL1_SYN 1 | ||
35 | |||
36 | #define STV6110x_CTRL2 0x01 | ||
37 | #define STV6110x_OFFST_CTRL2_CO_DIV 6 | ||
38 | #define STV6110x_WIDTH_CTRL2_CO_DIV 2 | ||
39 | #define STV6110x_OFFST_CTRL2_RSVD 5 | ||
40 | #define STV6110x_WIDTH_CTRL2_RSVD 1 | ||
41 | #define STV6110x_OFFST_CTRL2_REFOUT_SEL 4 | ||
42 | #define STV6110x_WIDTH_CTRL2_REFOUT_SEL 1 | ||
43 | #define STV6110x_OFFST_CTRL2_BBGAIN 0 | ||
44 | #define STV6110x_WIDTH_CTRL2_BBGAIN 4 | ||
45 | |||
46 | #define STV6110x_TNG0 0x02 | ||
47 | #define STV6110x_OFFST_TNG0_N_DIV_7_0 0 | ||
48 | #define STV6110x_WIDTH_TNG0_N_DIV_7_0 8 | ||
49 | |||
50 | #define STV6110x_TNG1 0x03 | ||
51 | #define STV6110x_OFFST_TNG1_R_DIV 6 | ||
52 | #define STV6110x_WIDTH_TNG1_R_DIV 2 | ||
53 | #define STV6110x_OFFST_TNG1_PRESC32_ON 5 | ||
54 | #define STV6110x_WIDTH_TNG1_PRESC32_ON 1 | ||
55 | #define STV6110x_OFFST_TNG1_DIV4SEL 4 | ||
56 | #define STV6110x_WIDTH_TNG1_DIV4SEL 1 | ||
57 | #define STV6110x_OFFST_TNG1_N_DIV_11_8 0 | ||
58 | #define STV6110x_WIDTH_TNG1_N_DIV_11_8 4 | ||
59 | |||
60 | |||
61 | #define STV6110x_CTRL3 0x04 | ||
62 | #define STV6110x_OFFST_CTRL3_DCLOOP_OFF 7 | ||
63 | #define STV6110x_WIDTH_CTRL3_DCLOOP_OFF 1 | ||
64 | #define STV6110x_OFFST_CTRL3_RCCLK_OFF 6 | ||
65 | #define STV6110x_WIDTH_CTRL3_RCCLK_OFF 1 | ||
66 | #define STV6110x_OFFST_CTRL3_ICP 5 | ||
67 | #define STV6110x_WIDTH_CTRL3_ICP 1 | ||
68 | #define STV6110x_OFFST_CTRL3_CF 0 | ||
69 | #define STV6110x_WIDTH_CTRL3_CF 5 | ||
70 | |||
71 | #define STV6110x_STAT1 0x05 | ||
72 | #define STV6110x_OFFST_STAT1_CALVCO_STRT 2 | ||
73 | #define STV6110x_WIDTH_STAT1_CALVCO_STRT 1 | ||
74 | #define STV6110x_OFFST_STAT1_CALRC_STRT 1 | ||
75 | #define STV6110x_WIDTH_STAT1_CALRC_STRT 1 | ||
76 | #define STV6110x_OFFST_STAT1_LOCK 0 | ||
77 | #define STV6110x_WIDTH_STAT1_LOCK 1 | ||
78 | |||
79 | #define STV6110x_STAT2 0x06 | ||
80 | #define STV6110x_STAT3 0x07 | ||
81 | |||
82 | #endif /* __STV6110x_REG_H */ | ||
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 2a8bbcd44cd0..4302c563a6b8 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | NXP TDA10048HN DVB OFDM demodulator driver | 2 | NXP TDA10048HN DVB OFDM demodulator driver |
3 | 3 | ||
4 | Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> | 4 | Copyright (C) 2009 Steven Toth <stoth@kernellabs.com> |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify | 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 | 7 | it under the terms of the GNU General Public License as published by |
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <asm/div64.h> | ||
28 | #include "dvb_frontend.h" | 29 | #include "dvb_frontend.h" |
29 | #include "dvb_math.h" | 30 | #include "dvb_math.h" |
30 | #include "tda10048.h" | 31 | #include "tda10048.h" |
@@ -138,11 +139,20 @@ struct tda10048_state { | |||
138 | 139 | ||
139 | struct i2c_adapter *i2c; | 140 | struct i2c_adapter *i2c; |
140 | 141 | ||
141 | /* configuration settings */ | 142 | /* We'll cache and update the attach config settings */ |
142 | const struct tda10048_config *config; | 143 | struct tda10048_config config; |
143 | struct dvb_frontend frontend; | 144 | struct dvb_frontend frontend; |
144 | 145 | ||
145 | int fwloaded; | 146 | int fwloaded; |
147 | |||
148 | u32 freq_if_hz; | ||
149 | u32 xtal_hz; | ||
150 | u32 pll_mfactor; | ||
151 | u32 pll_nfactor; | ||
152 | u32 pll_pfactor; | ||
153 | u32 sample_freq; | ||
154 | |||
155 | enum fe_bandwidth bandwidth; | ||
146 | }; | 156 | }; |
147 | 157 | ||
148 | static struct init_tab { | 158 | static struct init_tab { |
@@ -192,12 +202,26 @@ static struct init_tab { | |||
192 | { TDA10048_CONF_C4_2, 0x04 }, | 202 | { TDA10048_CONF_C4_2, 0x04 }, |
193 | }; | 203 | }; |
194 | 204 | ||
205 | static struct pll_tab { | ||
206 | u32 clk_freq_khz; | ||
207 | u32 if_freq_khz; | ||
208 | u8 m, n, p; | ||
209 | } pll_tab[] = { | ||
210 | { TDA10048_CLK_4000, TDA10048_IF_36130, 10, 0, 0 }, | ||
211 | { TDA10048_CLK_16000, TDA10048_IF_3300, 10, 3, 0 }, | ||
212 | { TDA10048_CLK_16000, TDA10048_IF_3500, 10, 3, 0 }, | ||
213 | { TDA10048_CLK_16000, TDA10048_IF_4000, 10, 3, 0 }, | ||
214 | { TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 }, | ||
215 | { TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 }, | ||
216 | }; | ||
217 | |||
195 | static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) | 218 | static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) |
196 | { | 219 | { |
220 | struct tda10048_config *config = &state->config; | ||
197 | int ret; | 221 | int ret; |
198 | u8 buf[] = { reg, data }; | 222 | u8 buf[] = { reg, data }; |
199 | struct i2c_msg msg = { | 223 | struct i2c_msg msg = { |
200 | .addr = state->config->demod_address, | 224 | .addr = config->demod_address, |
201 | .flags = 0, .buf = buf, .len = 2 }; | 225 | .flags = 0, .buf = buf, .len = 2 }; |
202 | 226 | ||
203 | dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data); | 227 | dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data); |
@@ -212,13 +236,14 @@ static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) | |||
212 | 236 | ||
213 | static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) | 237 | static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) |
214 | { | 238 | { |
239 | struct tda10048_config *config = &state->config; | ||
215 | int ret; | 240 | int ret; |
216 | u8 b0[] = { reg }; | 241 | u8 b0[] = { reg }; |
217 | u8 b1[] = { 0 }; | 242 | u8 b1[] = { 0 }; |
218 | struct i2c_msg msg[] = { | 243 | struct i2c_msg msg[] = { |
219 | { .addr = state->config->demod_address, | 244 | { .addr = config->demod_address, |
220 | .flags = 0, .buf = b0, .len = 1 }, | 245 | .flags = 0, .buf = b0, .len = 1 }, |
221 | { .addr = state->config->demod_address, | 246 | { .addr = config->demod_address, |
222 | .flags = I2C_M_RD, .buf = b1, .len = 1 } }; | 247 | .flags = I2C_M_RD, .buf = b1, .len = 1 } }; |
223 | 248 | ||
224 | dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg); | 249 | dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg); |
@@ -235,6 +260,7 @@ static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) | |||
235 | static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg, | 260 | static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg, |
236 | const u8 *data, u16 len) | 261 | const u8 *data, u16 len) |
237 | { | 262 | { |
263 | struct tda10048_config *config = &state->config; | ||
238 | int ret = -EREMOTEIO; | 264 | int ret = -EREMOTEIO; |
239 | struct i2c_msg msg; | 265 | struct i2c_msg msg; |
240 | u8 *buf; | 266 | u8 *buf; |
@@ -250,7 +276,7 @@ static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg, | |||
250 | *buf = reg; | 276 | *buf = reg; |
251 | memcpy(buf + 1, data, len); | 277 | memcpy(buf + 1, data, len); |
252 | 278 | ||
253 | msg.addr = state->config->demod_address; | 279 | msg.addr = config->demod_address; |
254 | msg.flags = 0; | 280 | msg.flags = 0; |
255 | msg.buf = buf; | 281 | msg.buf = buf; |
256 | msg.len = len + 1; | 282 | msg.len = len + 1; |
@@ -271,14 +297,206 @@ error: | |||
271 | return ret; | 297 | return ret; |
272 | } | 298 | } |
273 | 299 | ||
300 | static int tda10048_set_phy2(struct dvb_frontend *fe, u32 sample_freq_hz, | ||
301 | u32 if_hz) | ||
302 | { | ||
303 | struct tda10048_state *state = fe->demodulator_priv; | ||
304 | u64 t; | ||
305 | |||
306 | dprintk(1, "%s()\n", __func__); | ||
307 | |||
308 | if (sample_freq_hz == 0) | ||
309 | return -EINVAL; | ||
310 | |||
311 | if (if_hz < (sample_freq_hz / 2)) { | ||
312 | /* PHY2 = (if2/fs) * 2^15 */ | ||
313 | t = if_hz; | ||
314 | t *= 10; | ||
315 | t *= 32768; | ||
316 | do_div(t, sample_freq_hz); | ||
317 | t += 5; | ||
318 | do_div(t, 10); | ||
319 | } else { | ||
320 | /* PHY2 = ((IF1-fs)/fs) * 2^15 */ | ||
321 | t = sample_freq_hz - if_hz; | ||
322 | t *= 10; | ||
323 | t *= 32768; | ||
324 | do_div(t, sample_freq_hz); | ||
325 | t += 5; | ||
326 | do_div(t, 10); | ||
327 | t = ~t + 1; | ||
328 | } | ||
329 | |||
330 | tda10048_writereg(state, TDA10048_FREQ_PHY2_LSB, (u8)t); | ||
331 | tda10048_writereg(state, TDA10048_FREQ_PHY2_MSB, (u8)(t >> 8)); | ||
332 | |||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int tda10048_set_wref(struct dvb_frontend *fe, u32 sample_freq_hz, | ||
337 | u32 bw) | ||
338 | { | ||
339 | struct tda10048_state *state = fe->demodulator_priv; | ||
340 | u64 t, z; | ||
341 | u32 b = 8000000; | ||
342 | |||
343 | dprintk(1, "%s()\n", __func__); | ||
344 | |||
345 | if (sample_freq_hz == 0) | ||
346 | return -EINVAL; | ||
347 | |||
348 | if (bw == BANDWIDTH_6_MHZ) | ||
349 | b = 6000000; | ||
350 | else | ||
351 | if (bw == BANDWIDTH_7_MHZ) | ||
352 | b = 7000000; | ||
353 | |||
354 | /* WREF = (B / (7 * fs)) * 2^31 */ | ||
355 | t = b * 10; | ||
356 | /* avoid warning: this decimal constant is unsigned only in ISO C90 */ | ||
357 | /* t *= 2147483648 on 32bit platforms */ | ||
358 | t *= (2048 * 1024); | ||
359 | t *= 1024; | ||
360 | z = 7 * sample_freq_hz; | ||
361 | do_div(t, z); | ||
362 | t += 5; | ||
363 | do_div(t, 10); | ||
364 | |||
365 | tda10048_writereg(state, TDA10048_TIME_WREF_LSB, (u8)t); | ||
366 | tda10048_writereg(state, TDA10048_TIME_WREF_MID1, (u8)(t >> 8)); | ||
367 | tda10048_writereg(state, TDA10048_TIME_WREF_MID2, (u8)(t >> 16)); | ||
368 | tda10048_writereg(state, TDA10048_TIME_WREF_MSB, (u8)(t >> 24)); | ||
369 | |||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static int tda10048_set_invwref(struct dvb_frontend *fe, u32 sample_freq_hz, | ||
374 | u32 bw) | ||
375 | { | ||
376 | struct tda10048_state *state = fe->demodulator_priv; | ||
377 | u64 t; | ||
378 | u32 b = 8000000; | ||
379 | |||
380 | dprintk(1, "%s()\n", __func__); | ||
381 | |||
382 | if (sample_freq_hz == 0) | ||
383 | return -EINVAL; | ||
384 | |||
385 | if (bw == BANDWIDTH_6_MHZ) | ||
386 | b = 6000000; | ||
387 | else | ||
388 | if (bw == BANDWIDTH_7_MHZ) | ||
389 | b = 7000000; | ||
390 | |||
391 | /* INVWREF = ((7 * fs) / B) * 2^5 */ | ||
392 | t = sample_freq_hz; | ||
393 | t *= 7; | ||
394 | t *= 32; | ||
395 | t *= 10; | ||
396 | do_div(t, b); | ||
397 | t += 5; | ||
398 | do_div(t, 10); | ||
399 | |||
400 | tda10048_writereg(state, TDA10048_TIME_INVWREF_LSB, (u8)t); | ||
401 | tda10048_writereg(state, TDA10048_TIME_INVWREF_MSB, (u8)(t >> 8)); | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static int tda10048_set_bandwidth(struct dvb_frontend *fe, | ||
407 | enum fe_bandwidth bw) | ||
408 | { | ||
409 | struct tda10048_state *state = fe->demodulator_priv; | ||
410 | dprintk(1, "%s(bw=%d)\n", __func__, bw); | ||
411 | |||
412 | /* Bandwidth setting may need to be adjusted */ | ||
413 | switch (bw) { | ||
414 | case BANDWIDTH_6_MHZ: | ||
415 | case BANDWIDTH_7_MHZ: | ||
416 | case BANDWIDTH_8_MHZ: | ||
417 | tda10048_set_wref(fe, state->sample_freq, bw); | ||
418 | tda10048_set_invwref(fe, state->sample_freq, bw); | ||
419 | break; | ||
420 | default: | ||
421 | printk(KERN_ERR "%s() invalid bandwidth\n", __func__); | ||
422 | return -EINVAL; | ||
423 | } | ||
424 | |||
425 | state->bandwidth = bw; | ||
426 | |||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static int tda10048_set_if(struct dvb_frontend *fe, enum fe_bandwidth bw) | ||
431 | { | ||
432 | struct tda10048_state *state = fe->demodulator_priv; | ||
433 | struct tda10048_config *config = &state->config; | ||
434 | int i; | ||
435 | u32 if_freq_khz; | ||
436 | |||
437 | dprintk(1, "%s(bw = %d)\n", __func__, bw); | ||
438 | |||
439 | /* based on target bandwidth and clk we calculate pll factors */ | ||
440 | switch (bw) { | ||
441 | case BANDWIDTH_6_MHZ: | ||
442 | if_freq_khz = config->dtv6_if_freq_khz; | ||
443 | break; | ||
444 | case BANDWIDTH_7_MHZ: | ||
445 | if_freq_khz = config->dtv7_if_freq_khz; | ||
446 | break; | ||
447 | case BANDWIDTH_8_MHZ: | ||
448 | if_freq_khz = config->dtv8_if_freq_khz; | ||
449 | break; | ||
450 | default: | ||
451 | printk(KERN_ERR "%s() no default\n", __func__); | ||
452 | return -EINVAL; | ||
453 | } | ||
454 | |||
455 | for (i = 0; i < ARRAY_SIZE(pll_tab); i++) { | ||
456 | if ((pll_tab[i].clk_freq_khz == config->clk_freq_khz) && | ||
457 | (pll_tab[i].if_freq_khz == if_freq_khz)) { | ||
458 | |||
459 | state->freq_if_hz = pll_tab[i].if_freq_khz * 1000; | ||
460 | state->xtal_hz = pll_tab[i].clk_freq_khz * 1000; | ||
461 | state->pll_mfactor = pll_tab[i].m; | ||
462 | state->pll_nfactor = pll_tab[i].n; | ||
463 | state->pll_pfactor = pll_tab[i].p; | ||
464 | break; | ||
465 | } | ||
466 | } | ||
467 | if (i == ARRAY_SIZE(pll_tab)) { | ||
468 | printk(KERN_ERR "%s() Incorrect attach settings\n", | ||
469 | __func__); | ||
470 | return -EINVAL; | ||
471 | } | ||
472 | |||
473 | dprintk(1, "- freq_if_hz = %d\n", state->freq_if_hz); | ||
474 | dprintk(1, "- xtal_hz = %d\n", state->xtal_hz); | ||
475 | dprintk(1, "- pll_mfactor = %d\n", state->pll_mfactor); | ||
476 | dprintk(1, "- pll_nfactor = %d\n", state->pll_nfactor); | ||
477 | dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor); | ||
478 | |||
479 | /* Calculate the sample frequency */ | ||
480 | state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45); | ||
481 | state->sample_freq /= (state->pll_nfactor + 1); | ||
482 | state->sample_freq /= (state->pll_pfactor + 4); | ||
483 | dprintk(1, "- sample_freq = %d\n", state->sample_freq); | ||
484 | |||
485 | /* Update the I/F */ | ||
486 | tda10048_set_phy2(fe, state->sample_freq, state->freq_if_hz); | ||
487 | |||
488 | return 0; | ||
489 | } | ||
490 | |||
274 | static int tda10048_firmware_upload(struct dvb_frontend *fe) | 491 | static int tda10048_firmware_upload(struct dvb_frontend *fe) |
275 | { | 492 | { |
276 | struct tda10048_state *state = fe->demodulator_priv; | 493 | struct tda10048_state *state = fe->demodulator_priv; |
494 | struct tda10048_config *config = &state->config; | ||
277 | const struct firmware *fw; | 495 | const struct firmware *fw; |
278 | int ret; | 496 | int ret; |
279 | int pos = 0; | 497 | int pos = 0; |
280 | int cnt; | 498 | int cnt; |
281 | u8 wlen = state->config->fwbulkwritelen; | 499 | u8 wlen = config->fwbulkwritelen; |
282 | 500 | ||
283 | if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50)) | 501 | if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50)) |
284 | wlen = TDA10048_BULKWRITE_200; | 502 | wlen = TDA10048_BULKWRITE_200; |
@@ -289,7 +507,7 @@ static int tda10048_firmware_upload(struct dvb_frontend *fe) | |||
289 | TDA10048_DEFAULT_FIRMWARE); | 507 | TDA10048_DEFAULT_FIRMWARE); |
290 | 508 | ||
291 | ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE, | 509 | ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE, |
292 | &state->i2c->dev); | 510 | state->i2c->dev.parent); |
293 | if (ret) { | 511 | if (ret) { |
294 | printk(KERN_ERR "%s: Upload failed. (file not found?)\n", | 512 | printk(KERN_ERR "%s: Upload failed. (file not found?)\n", |
295 | __func__); | 513 | __func__); |
@@ -484,8 +702,12 @@ static int tda10048_get_tps(struct tda10048_state *state, | |||
484 | static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | 702 | static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
485 | { | 703 | { |
486 | struct tda10048_state *state = fe->demodulator_priv; | 704 | struct tda10048_state *state = fe->demodulator_priv; |
705 | struct tda10048_config *config = &state->config; | ||
487 | dprintk(1, "%s(%d)\n", __func__, enable); | 706 | dprintk(1, "%s(%d)\n", __func__, enable); |
488 | 707 | ||
708 | if (config->disable_gate_access) | ||
709 | return 0; | ||
710 | |||
489 | if (enable) | 711 | if (enable) |
490 | return tda10048_writereg(state, TDA10048_CONF_C4_1, | 712 | return tda10048_writereg(state, TDA10048_CONF_C4_1, |
491 | tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02); | 713 | tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02); |
@@ -523,6 +745,12 @@ static int tda10048_set_frontend(struct dvb_frontend *fe, | |||
523 | 745 | ||
524 | dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency); | 746 | dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency); |
525 | 747 | ||
748 | /* Update the I/F pll's if the bandwidth changes */ | ||
749 | if (p->u.ofdm.bandwidth != state->bandwidth) { | ||
750 | tda10048_set_if(fe, p->u.ofdm.bandwidth); | ||
751 | tda10048_set_bandwidth(fe, p->u.ofdm.bandwidth); | ||
752 | } | ||
753 | |||
526 | if (fe->ops.tuner_ops.set_params) { | 754 | if (fe->ops.tuner_ops.set_params) { |
527 | 755 | ||
528 | if (fe->ops.i2c_gate_ctrl) | 756 | if (fe->ops.i2c_gate_ctrl) |
@@ -544,6 +772,7 @@ static int tda10048_set_frontend(struct dvb_frontend *fe, | |||
544 | static int tda10048_init(struct dvb_frontend *fe) | 772 | static int tda10048_init(struct dvb_frontend *fe) |
545 | { | 773 | { |
546 | struct tda10048_state *state = fe->demodulator_priv; | 774 | struct tda10048_state *state = fe->demodulator_priv; |
775 | struct tda10048_config *config = &state->config; | ||
547 | int ret = 0, i; | 776 | int ret = 0, i; |
548 | 777 | ||
549 | dprintk(1, "%s()\n", __func__); | 778 | dprintk(1, "%s()\n", __func__); |
@@ -556,10 +785,14 @@ static int tda10048_init(struct dvb_frontend *fe) | |||
556 | ret = tda10048_firmware_upload(fe); | 785 | ret = tda10048_firmware_upload(fe); |
557 | 786 | ||
558 | /* Set either serial or parallel */ | 787 | /* Set either serial or parallel */ |
559 | tda10048_output_mode(fe, state->config->output_mode); | 788 | tda10048_output_mode(fe, config->output_mode); |
789 | |||
790 | /* Set inversion */ | ||
791 | tda10048_set_inversion(fe, config->inversion); | ||
560 | 792 | ||
561 | /* set inversion */ | 793 | /* Establish default RF values */ |
562 | tda10048_set_inversion(fe, state->config->inversion); | 794 | tda10048_set_if(fe, BANDWIDTH_8_MHZ); |
795 | tda10048_set_bandwidth(fe, BANDWIDTH_8_MHZ); | ||
563 | 796 | ||
564 | /* Ensure we leave the gate closed */ | 797 | /* Ensure we leave the gate closed */ |
565 | tda10048_i2c_gate_ctrl(fe, 0); | 798 | tda10048_i2c_gate_ctrl(fe, 0); |
@@ -812,6 +1045,45 @@ static void tda10048_release(struct dvb_frontend *fe) | |||
812 | kfree(state); | 1045 | kfree(state); |
813 | } | 1046 | } |
814 | 1047 | ||
1048 | static void tda10048_establish_defaults(struct dvb_frontend *fe) | ||
1049 | { | ||
1050 | struct tda10048_state *state = fe->demodulator_priv; | ||
1051 | struct tda10048_config *config = &state->config; | ||
1052 | |||
1053 | /* Validate/default the config */ | ||
1054 | if (config->dtv6_if_freq_khz == 0) { | ||
1055 | config->dtv6_if_freq_khz = TDA10048_IF_4300; | ||
1056 | printk(KERN_WARNING "%s() tda10048_config.dtv6_if_freq_khz " | ||
1057 | "is not set (defaulting to %d)\n", | ||
1058 | __func__, | ||
1059 | config->dtv6_if_freq_khz); | ||
1060 | } | ||
1061 | |||
1062 | if (config->dtv7_if_freq_khz == 0) { | ||
1063 | config->dtv7_if_freq_khz = TDA10048_IF_4300; | ||
1064 | printk(KERN_WARNING "%s() tda10048_config.dtv7_if_freq_khz " | ||
1065 | "is not set (defaulting to %d)\n", | ||
1066 | __func__, | ||
1067 | config->dtv7_if_freq_khz); | ||
1068 | } | ||
1069 | |||
1070 | if (config->dtv8_if_freq_khz == 0) { | ||
1071 | config->dtv8_if_freq_khz = TDA10048_IF_4300; | ||
1072 | printk(KERN_WARNING "%s() tda10048_config.dtv8_if_freq_khz " | ||
1073 | "is not set (defaulting to %d)\n", | ||
1074 | __func__, | ||
1075 | config->dtv8_if_freq_khz); | ||
1076 | } | ||
1077 | |||
1078 | if (config->clk_freq_khz == 0) { | ||
1079 | config->clk_freq_khz = TDA10048_CLK_16000; | ||
1080 | printk(KERN_WARNING "%s() tda10048_config.clk_freq_khz " | ||
1081 | "is not set (defaulting to %d)\n", | ||
1082 | __func__, | ||
1083 | config->clk_freq_khz); | ||
1084 | } | ||
1085 | } | ||
1086 | |||
815 | static struct dvb_frontend_ops tda10048_ops; | 1087 | static struct dvb_frontend_ops tda10048_ops; |
816 | 1088 | ||
817 | struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, | 1089 | struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, |
@@ -826,10 +1098,11 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, | |||
826 | if (state == NULL) | 1098 | if (state == NULL) |
827 | goto error; | 1099 | goto error; |
828 | 1100 | ||
829 | /* setup the state */ | 1101 | /* setup the state and clone the config */ |
830 | state->config = config; | 1102 | memcpy(&state->config, config, sizeof(*config)); |
831 | state->i2c = i2c; | 1103 | state->i2c = i2c; |
832 | state->fwloaded = 0; | 1104 | state->fwloaded = 0; |
1105 | state->bandwidth = BANDWIDTH_8_MHZ; | ||
833 | 1106 | ||
834 | /* check if the demod is present */ | 1107 | /* check if the demod is present */ |
835 | if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048) | 1108 | if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048) |
@@ -840,6 +1113,17 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, | |||
840 | sizeof(struct dvb_frontend_ops)); | 1113 | sizeof(struct dvb_frontend_ops)); |
841 | state->frontend.demodulator_priv = state; | 1114 | state->frontend.demodulator_priv = state; |
842 | 1115 | ||
1116 | /* Establish any defaults the the user didn't pass */ | ||
1117 | tda10048_establish_defaults(&state->frontend); | ||
1118 | |||
1119 | /* Set the xtal and freq defaults */ | ||
1120 | if (tda10048_set_if(&state->frontend, BANDWIDTH_8_MHZ) != 0) | ||
1121 | goto error; | ||
1122 | |||
1123 | /* Default bandwidth */ | ||
1124 | if (tda10048_set_bandwidth(&state->frontend, BANDWIDTH_8_MHZ) != 0) | ||
1125 | goto error; | ||
1126 | |||
843 | /* Leave the gate closed */ | 1127 | /* Leave the gate closed */ |
844 | tda10048_i2c_gate_ctrl(&state->frontend, 0); | 1128 | tda10048_i2c_gate_ctrl(&state->frontend, 0); |
845 | 1129 | ||
diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h index 0457b24601fa..8828ceaf74bb 100644 --- a/drivers/media/dvb/frontends/tda10048.h +++ b/drivers/media/dvb/frontends/tda10048.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | NXP TDA10048HN DVB OFDM demodulator driver | 2 | NXP TDA10048HN DVB OFDM demodulator driver |
3 | 3 | ||
4 | Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> | 4 | Copyright (C) 2009 Steven Toth <stoth@kernellabs.com> |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify | 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 | 7 | it under the terms of the GNU General Public License as published by |
@@ -43,6 +43,25 @@ struct tda10048_config { | |||
43 | #define TDA10048_INVERSION_OFF 0 | 43 | #define TDA10048_INVERSION_OFF 0 |
44 | #define TDA10048_INVERSION_ON 1 | 44 | #define TDA10048_INVERSION_ON 1 |
45 | u8 inversion; | 45 | u8 inversion; |
46 | |||
47 | #define TDA10048_IF_3300 3300 | ||
48 | #define TDA10048_IF_3500 3500 | ||
49 | #define TDA10048_IF_3800 3800 | ||
50 | #define TDA10048_IF_4000 4000 | ||
51 | #define TDA10048_IF_4300 4300 | ||
52 | #define TDA10048_IF_4500 4500 | ||
53 | #define TDA10048_IF_4750 4750 | ||
54 | #define TDA10048_IF_36130 36130 | ||
55 | u16 dtv6_if_freq_khz; | ||
56 | u16 dtv7_if_freq_khz; | ||
57 | u16 dtv8_if_freq_khz; | ||
58 | |||
59 | #define TDA10048_CLK_4000 4000 | ||
60 | #define TDA10048_CLK_16000 16000 | ||
61 | u16 clk_freq_khz; | ||
62 | |||
63 | /* Disable I2C gate access */ | ||
64 | u8 disable_gate_access; | ||
46 | }; | 65 | }; |
47 | 66 | ||
48 | #if defined(CONFIG_DVB_TDA10048) || \ | 67 | #if defined(CONFIG_DVB_TDA10048) || \ |
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile index bcf93f4828b2..c6644d909433 100644 --- a/drivers/media/dvb/siano/Makefile +++ b/drivers/media/dvb/siano/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | sms1xxx-objs := smscoreapi.o sms-cards.o | 1 | sms1xxx-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o |
2 | 2 | ||
3 | obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o | 3 | obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o |
4 | obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o | 4 | obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o |
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 63e4d0ec6583..d8b15d583bde 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include "sms-cards.h" | 20 | #include "sms-cards.h" |
21 | #include "smsir.h" | ||
21 | 22 | ||
22 | static int sms_dbg; | 23 | static int sms_dbg; |
23 | module_param_named(cards_dbg, sms_dbg, int, 0644); | 24 | module_param_named(cards_dbg, sms_dbg, int, 0644); |
@@ -30,17 +31,14 @@ static struct sms_board sms_boards[] = { | |||
30 | [SMS1XXX_BOARD_SIANO_STELLAR] = { | 31 | [SMS1XXX_BOARD_SIANO_STELLAR] = { |
31 | .name = "Siano Stellar Digital Receiver", | 32 | .name = "Siano Stellar Digital Receiver", |
32 | .type = SMS_STELLAR, | 33 | .type = SMS_STELLAR, |
33 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw", | ||
34 | }, | 34 | }, |
35 | [SMS1XXX_BOARD_SIANO_NOVA_A] = { | 35 | [SMS1XXX_BOARD_SIANO_NOVA_A] = { |
36 | .name = "Siano Nova A Digital Receiver", | 36 | .name = "Siano Nova A Digital Receiver", |
37 | .type = SMS_NOVA_A0, | 37 | .type = SMS_NOVA_A0, |
38 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw", | ||
39 | }, | 38 | }, |
40 | [SMS1XXX_BOARD_SIANO_NOVA_B] = { | 39 | [SMS1XXX_BOARD_SIANO_NOVA_B] = { |
41 | .name = "Siano Nova B Digital Receiver", | 40 | .name = "Siano Nova B Digital Receiver", |
42 | .type = SMS_NOVA_B0, | 41 | .type = SMS_NOVA_B0, |
43 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw", | ||
44 | }, | 42 | }, |
45 | [SMS1XXX_BOARD_SIANO_VEGA] = { | 43 | [SMS1XXX_BOARD_SIANO_VEGA] = { |
46 | .name = "Siano Vega Digital Receiver", | 44 | .name = "Siano Vega Digital Receiver", |
@@ -65,6 +63,9 @@ static struct sms_board sms_boards[] = { | |||
65 | .name = "Hauppauge WinTV MiniStick", | 63 | .name = "Hauppauge WinTV MiniStick", |
66 | .type = SMS_NOVA_B0, | 64 | .type = SMS_NOVA_B0, |
67 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", | 65 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", |
66 | .board_cfg.leds_power = 26, | ||
67 | .board_cfg.led0 = 27, | ||
68 | .board_cfg.led1 = 28, | ||
68 | .led_power = 26, | 69 | .led_power = 26, |
69 | .led_lo = 27, | 70 | .led_lo = 27, |
70 | .led_hi = 28, | 71 | .led_hi = 28, |
@@ -74,7 +75,9 @@ static struct sms_board sms_boards[] = { | |||
74 | .type = SMS_NOVA_B0, | 75 | .type = SMS_NOVA_B0, |
75 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", | 76 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", |
76 | .lna_ctrl = 29, | 77 | .lna_ctrl = 29, |
78 | .board_cfg.foreign_lna0_ctrl = 29, | ||
77 | .rf_switch = 17, | 79 | .rf_switch = 17, |
80 | .board_cfg.rf_switch_uhf = 17, | ||
78 | }, | 81 | }, |
79 | [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = { | 82 | [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = { |
80 | .name = "Hauppauge WinTV MiniCard", | 83 | .name = "Hauppauge WinTV MiniCard", |
@@ -82,6 +85,16 @@ static struct sms_board sms_boards[] = { | |||
82 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", | 85 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", |
83 | .lna_ctrl = -1, | 86 | .lna_ctrl = -1, |
84 | }, | 87 | }, |
88 | [SMS1XXX_BOARD_SIANO_NICE] = { | ||
89 | /* 11 */ | ||
90 | .name = "Siano Nice Digital Receiver", | ||
91 | .type = SMS_NOVA_B0, | ||
92 | }, | ||
93 | [SMS1XXX_BOARD_SIANO_VENICE] = { | ||
94 | /* 12 */ | ||
95 | .name = "Siano Venice Digital Receiver", | ||
96 | .type = SMS_VEGA, | ||
97 | }, | ||
85 | }; | 98 | }; |
86 | 99 | ||
87 | struct sms_board *sms_get_board(int id) | 100 | struct sms_board *sms_get_board(int id) |
@@ -91,12 +104,179 @@ struct sms_board *sms_get_board(int id) | |||
91 | return &sms_boards[id]; | 104 | return &sms_boards[id]; |
92 | } | 105 | } |
93 | EXPORT_SYMBOL_GPL(sms_get_board); | 106 | EXPORT_SYMBOL_GPL(sms_get_board); |
107 | static inline void sms_gpio_assign_11xx_default_led_config( | ||
108 | struct smscore_gpio_config *pGpioConfig) { | ||
109 | pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT; | ||
110 | pGpioConfig->InputCharacteristics = | ||
111 | SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL; | ||
112 | pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA; | ||
113 | pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS; | ||
114 | pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE; | ||
115 | } | ||
116 | |||
117 | int sms_board_event(struct smscore_device_t *coredev, | ||
118 | enum SMS_BOARD_EVENTS gevent) { | ||
119 | int board_id = smscore_get_board_id(coredev); | ||
120 | struct sms_board *board = sms_get_board(board_id); | ||
121 | struct smscore_gpio_config MyGpioConfig; | ||
122 | |||
123 | sms_gpio_assign_11xx_default_led_config(&MyGpioConfig); | ||
124 | |||
125 | switch (gevent) { | ||
126 | case BOARD_EVENT_POWER_INIT: /* including hotplug */ | ||
127 | switch (board_id) { | ||
128 | case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: | ||
129 | /* set I/O and turn off all LEDs */ | ||
130 | smscore_gpio_configure(coredev, | ||
131 | board->board_cfg.leds_power, | ||
132 | &MyGpioConfig); | ||
133 | smscore_gpio_set_level(coredev, | ||
134 | board->board_cfg.leds_power, 0); | ||
135 | smscore_gpio_configure(coredev, board->board_cfg.led0, | ||
136 | &MyGpioConfig); | ||
137 | smscore_gpio_set_level(coredev, | ||
138 | board->board_cfg.led0, 0); | ||
139 | smscore_gpio_configure(coredev, board->board_cfg.led1, | ||
140 | &MyGpioConfig); | ||
141 | smscore_gpio_set_level(coredev, | ||
142 | board->board_cfg.led1, 0); | ||
143 | break; | ||
144 | case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: | ||
145 | case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: | ||
146 | /* set I/O and turn off LNA */ | ||
147 | smscore_gpio_configure(coredev, | ||
148 | board->board_cfg.foreign_lna0_ctrl, | ||
149 | &MyGpioConfig); | ||
150 | smscore_gpio_set_level(coredev, | ||
151 | board->board_cfg.foreign_lna0_ctrl, | ||
152 | 0); | ||
153 | break; | ||
154 | } | ||
155 | break; /* BOARD_EVENT_BIND */ | ||
156 | |||
157 | case BOARD_EVENT_POWER_SUSPEND: | ||
158 | switch (board_id) { | ||
159 | case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: | ||
160 | smscore_gpio_set_level(coredev, | ||
161 | board->board_cfg.leds_power, 0); | ||
162 | smscore_gpio_set_level(coredev, | ||
163 | board->board_cfg.led0, 0); | ||
164 | smscore_gpio_set_level(coredev, | ||
165 | board->board_cfg.led1, 0); | ||
166 | break; | ||
167 | case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: | ||
168 | case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: | ||
169 | smscore_gpio_set_level(coredev, | ||
170 | board->board_cfg.foreign_lna0_ctrl, | ||
171 | 0); | ||
172 | break; | ||
173 | } | ||
174 | break; /* BOARD_EVENT_POWER_SUSPEND */ | ||
175 | |||
176 | case BOARD_EVENT_POWER_RESUME: | ||
177 | switch (board_id) { | ||
178 | case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: | ||
179 | smscore_gpio_set_level(coredev, | ||
180 | board->board_cfg.leds_power, 1); | ||
181 | smscore_gpio_set_level(coredev, | ||
182 | board->board_cfg.led0, 1); | ||
183 | smscore_gpio_set_level(coredev, | ||
184 | board->board_cfg.led1, 0); | ||
185 | break; | ||
186 | case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: | ||
187 | case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: | ||
188 | smscore_gpio_set_level(coredev, | ||
189 | board->board_cfg.foreign_lna0_ctrl, | ||
190 | 1); | ||
191 | break; | ||
192 | } | ||
193 | break; /* BOARD_EVENT_POWER_RESUME */ | ||
194 | |||
195 | case BOARD_EVENT_BIND: | ||
196 | switch (board_id) { | ||
197 | case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: | ||
198 | smscore_gpio_set_level(coredev, | ||
199 | board->board_cfg.leds_power, 1); | ||
200 | smscore_gpio_set_level(coredev, | ||
201 | board->board_cfg.led0, 1); | ||
202 | smscore_gpio_set_level(coredev, | ||
203 | board->board_cfg.led1, 0); | ||
204 | break; | ||
205 | case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: | ||
206 | case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: | ||
207 | smscore_gpio_set_level(coredev, | ||
208 | board->board_cfg.foreign_lna0_ctrl, | ||
209 | 1); | ||
210 | break; | ||
211 | } | ||
212 | break; /* BOARD_EVENT_BIND */ | ||
213 | |||
214 | case BOARD_EVENT_SCAN_PROG: | ||
215 | break; /* BOARD_EVENT_SCAN_PROG */ | ||
216 | case BOARD_EVENT_SCAN_COMP: | ||
217 | break; /* BOARD_EVENT_SCAN_COMP */ | ||
218 | case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL: | ||
219 | break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */ | ||
220 | case BOARD_EVENT_FE_LOCK: | ||
221 | switch (board_id) { | ||
222 | case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: | ||
223 | smscore_gpio_set_level(coredev, | ||
224 | board->board_cfg.led1, 1); | ||
225 | break; | ||
226 | } | ||
227 | break; /* BOARD_EVENT_FE_LOCK */ | ||
228 | case BOARD_EVENT_FE_UNLOCK: | ||
229 | switch (board_id) { | ||
230 | case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: | ||
231 | smscore_gpio_set_level(coredev, | ||
232 | board->board_cfg.led1, 0); | ||
233 | break; | ||
234 | } | ||
235 | break; /* BOARD_EVENT_FE_UNLOCK */ | ||
236 | case BOARD_EVENT_DEMOD_LOCK: | ||
237 | break; /* BOARD_EVENT_DEMOD_LOCK */ | ||
238 | case BOARD_EVENT_DEMOD_UNLOCK: | ||
239 | break; /* BOARD_EVENT_DEMOD_UNLOCK */ | ||
240 | case BOARD_EVENT_RECEPTION_MAX_4: | ||
241 | break; /* BOARD_EVENT_RECEPTION_MAX_4 */ | ||
242 | case BOARD_EVENT_RECEPTION_3: | ||
243 | break; /* BOARD_EVENT_RECEPTION_3 */ | ||
244 | case BOARD_EVENT_RECEPTION_2: | ||
245 | break; /* BOARD_EVENT_RECEPTION_2 */ | ||
246 | case BOARD_EVENT_RECEPTION_1: | ||
247 | break; /* BOARD_EVENT_RECEPTION_1 */ | ||
248 | case BOARD_EVENT_RECEPTION_LOST_0: | ||
249 | break; /* BOARD_EVENT_RECEPTION_LOST_0 */ | ||
250 | case BOARD_EVENT_MULTIPLEX_OK: | ||
251 | switch (board_id) { | ||
252 | case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: | ||
253 | smscore_gpio_set_level(coredev, | ||
254 | board->board_cfg.led1, 1); | ||
255 | break; | ||
256 | } | ||
257 | break; /* BOARD_EVENT_MULTIPLEX_OK */ | ||
258 | case BOARD_EVENT_MULTIPLEX_ERRORS: | ||
259 | switch (board_id) { | ||
260 | case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: | ||
261 | smscore_gpio_set_level(coredev, | ||
262 | board->board_cfg.led1, 0); | ||
263 | break; | ||
264 | } | ||
265 | break; /* BOARD_EVENT_MULTIPLEX_ERRORS */ | ||
266 | |||
267 | default: | ||
268 | sms_err("Unknown SMS board event"); | ||
269 | break; | ||
270 | } | ||
271 | return 0; | ||
272 | } | ||
273 | EXPORT_SYMBOL_GPL(sms_board_event); | ||
94 | 274 | ||
95 | static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) | 275 | static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) |
96 | { | 276 | { |
97 | int lvl, ret; | 277 | int lvl, ret; |
98 | u32 gpio; | 278 | u32 gpio; |
99 | struct smscore_gpio_config gpioconfig = { | 279 | struct smscore_config_gpio gpioconfig = { |
100 | .direction = SMS_GPIO_DIRECTION_OUTPUT, | 280 | .direction = SMS_GPIO_DIRECTION_OUTPUT, |
101 | .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, | 281 | .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, |
102 | .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, | 282 | .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, |
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index 64d74c59c33f..38f062f6ad68 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <linux/usb.h> | 23 | #include <linux/usb.h> |
24 | #include "smscoreapi.h" | 24 | #include "smscoreapi.h" |
25 | #include "smsir.h" | ||
25 | 26 | ||
26 | #define SMS_BOARD_UNKNOWN 0 | 27 | #define SMS_BOARD_UNKNOWN 0 |
27 | #define SMS1XXX_BOARD_SIANO_STELLAR 1 | 28 | #define SMS1XXX_BOARD_SIANO_STELLAR 1 |
@@ -34,10 +35,47 @@ | |||
34 | #define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8 | 35 | #define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8 |
35 | #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9 | 36 | #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9 |
36 | #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10 | 37 | #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10 |
38 | #define SMS1XXX_BOARD_SIANO_NICE 11 | ||
39 | #define SMS1XXX_BOARD_SIANO_VENICE 12 | ||
40 | |||
41 | struct sms_board_gpio_cfg { | ||
42 | int lna_vhf_exist; | ||
43 | int lna_vhf_ctrl; | ||
44 | int lna_uhf_exist; | ||
45 | int lna_uhf_ctrl; | ||
46 | int lna_uhf_d_ctrl; | ||
47 | int lna_sband_exist; | ||
48 | int lna_sband_ctrl; | ||
49 | int lna_sband_d_ctrl; | ||
50 | int foreign_lna0_ctrl; | ||
51 | int foreign_lna1_ctrl; | ||
52 | int foreign_lna2_ctrl; | ||
53 | int rf_switch_vhf; | ||
54 | int rf_switch_uhf; | ||
55 | int rf_switch_sband; | ||
56 | int leds_power; | ||
57 | int led0; | ||
58 | int led1; | ||
59 | int led2; | ||
60 | int led3; | ||
61 | int led4; | ||
62 | int ir; | ||
63 | int eeprom_wp; | ||
64 | int mrc_sense; | ||
65 | int mrc_pdn_resetn; | ||
66 | int mrc_gp0; /* mrcs spi int */ | ||
67 | int mrc_gp1; | ||
68 | int mrc_gp2; | ||
69 | int mrc_gp3; | ||
70 | int mrc_gp4; | ||
71 | int host_spi_gsp_ts_int; | ||
72 | }; | ||
37 | 73 | ||
38 | struct sms_board { | 74 | struct sms_board { |
39 | enum sms_device_type_st type; | 75 | enum sms_device_type_st type; |
40 | char *name, *fw[DEVICE_MODE_MAX]; | 76 | char *name, *fw[DEVICE_MODE_MAX]; |
77 | struct sms_board_gpio_cfg board_cfg; | ||
78 | enum ir_kb_type ir_kb_type; | ||
41 | 79 | ||
42 | /* gpios */ | 80 | /* gpios */ |
43 | int led_power, led_hi, led_lo, lna_ctrl, rf_switch; | 81 | int led_power, led_hi, led_lo, lna_ctrl, rf_switch; |
@@ -45,6 +83,32 @@ struct sms_board { | |||
45 | 83 | ||
46 | struct sms_board *sms_get_board(int id); | 84 | struct sms_board *sms_get_board(int id); |
47 | 85 | ||
86 | extern struct smscore_device_t *coredev; | ||
87 | |||
88 | enum SMS_BOARD_EVENTS { | ||
89 | BOARD_EVENT_POWER_INIT, | ||
90 | BOARD_EVENT_POWER_SUSPEND, | ||
91 | BOARD_EVENT_POWER_RESUME, | ||
92 | BOARD_EVENT_BIND, | ||
93 | BOARD_EVENT_SCAN_PROG, | ||
94 | BOARD_EVENT_SCAN_COMP, | ||
95 | BOARD_EVENT_EMERGENCY_WARNING_SIGNAL, | ||
96 | BOARD_EVENT_FE_LOCK, | ||
97 | BOARD_EVENT_FE_UNLOCK, | ||
98 | BOARD_EVENT_DEMOD_LOCK, | ||
99 | BOARD_EVENT_DEMOD_UNLOCK, | ||
100 | BOARD_EVENT_RECEPTION_MAX_4, | ||
101 | BOARD_EVENT_RECEPTION_3, | ||
102 | BOARD_EVENT_RECEPTION_2, | ||
103 | BOARD_EVENT_RECEPTION_1, | ||
104 | BOARD_EVENT_RECEPTION_LOST_0, | ||
105 | BOARD_EVENT_MULTIPLEX_OK, | ||
106 | BOARD_EVENT_MULTIPLEX_ERRORS | ||
107 | }; | ||
108 | |||
109 | int sms_board_event(struct smscore_device_t *coredev, | ||
110 | enum SMS_BOARD_EVENTS gevent); | ||
111 | |||
48 | int sms_board_setup(struct smscore_device_t *coredev); | 112 | int sms_board_setup(struct smscore_device_t *coredev); |
49 | 113 | ||
50 | #define SMS_LED_OFF 0 | 114 | #define SMS_LED_OFF 0 |
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 7bd4d1dee2b3..32be382f0e97 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c | |||
@@ -30,9 +30,13 @@ | |||
30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
31 | 31 | ||
32 | #include <linux/firmware.h> | 32 | #include <linux/firmware.h> |
33 | #include <linux/wait.h> | ||
34 | #include <asm/byteorder.h> | ||
33 | 35 | ||
34 | #include "smscoreapi.h" | 36 | #include "smscoreapi.h" |
35 | #include "sms-cards.h" | 37 | #include "sms-cards.h" |
38 | #include "smsir.h" | ||
39 | #include "smsendian.h" | ||
36 | 40 | ||
37 | static int sms_dbg; | 41 | static int sms_dbg; |
38 | module_param_named(debug, sms_dbg, int, 0644); | 42 | module_param_named(debug, sms_dbg, int, 0644); |
@@ -58,42 +62,6 @@ struct smscore_client_t { | |||
58 | onremove_t onremove_handler; | 62 | onremove_t onremove_handler; |
59 | }; | 63 | }; |
60 | 64 | ||
61 | struct smscore_device_t { | ||
62 | struct list_head entry; | ||
63 | |||
64 | struct list_head clients; | ||
65 | struct list_head subclients; | ||
66 | spinlock_t clientslock; | ||
67 | |||
68 | struct list_head buffers; | ||
69 | spinlock_t bufferslock; | ||
70 | int num_buffers; | ||
71 | |||
72 | void *common_buffer; | ||
73 | int common_buffer_size; | ||
74 | dma_addr_t common_buffer_phys; | ||
75 | |||
76 | void *context; | ||
77 | struct device *device; | ||
78 | |||
79 | char devpath[32]; | ||
80 | unsigned long device_flags; | ||
81 | |||
82 | setmode_t setmode_handler; | ||
83 | detectmode_t detectmode_handler; | ||
84 | sendrequest_t sendrequest_handler; | ||
85 | preload_t preload_handler; | ||
86 | postload_t postload_handler; | ||
87 | |||
88 | int mode, modes_supported; | ||
89 | |||
90 | struct completion version_ex_done, data_download_done, trigger_done; | ||
91 | struct completion init_device_done, reload_start_done, resume_done; | ||
92 | |||
93 | int board_id; | ||
94 | int led_state; | ||
95 | }; | ||
96 | |||
97 | void smscore_set_board_id(struct smscore_device_t *core, int id) | 65 | void smscore_set_board_id(struct smscore_device_t *core, int id) |
98 | { | 66 | { |
99 | core->board_id = id; | 67 | core->board_id = id; |
@@ -384,6 +352,13 @@ int smscore_register_device(struct smsdevice_params_t *params, | |||
384 | init_completion(&dev->init_device_done); | 352 | init_completion(&dev->init_device_done); |
385 | init_completion(&dev->reload_start_done); | 353 | init_completion(&dev->reload_start_done); |
386 | init_completion(&dev->resume_done); | 354 | init_completion(&dev->resume_done); |
355 | init_completion(&dev->gpio_configuration_done); | ||
356 | init_completion(&dev->gpio_set_level_done); | ||
357 | init_completion(&dev->gpio_get_level_done); | ||
358 | init_completion(&dev->ir_init_done); | ||
359 | |||
360 | /* Buffer management */ | ||
361 | init_waitqueue_head(&dev->buffer_mng_waitq); | ||
387 | 362 | ||
388 | /* alloc common buffer */ | 363 | /* alloc common buffer */ |
389 | dev->common_buffer_size = params->buffer_size * params->num_buffers; | 364 | dev->common_buffer_size = params->buffer_size * params->num_buffers; |
@@ -439,6 +414,71 @@ int smscore_register_device(struct smsdevice_params_t *params, | |||
439 | } | 414 | } |
440 | EXPORT_SYMBOL_GPL(smscore_register_device); | 415 | EXPORT_SYMBOL_GPL(smscore_register_device); |
441 | 416 | ||
417 | |||
418 | static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, | ||
419 | void *buffer, size_t size, struct completion *completion) { | ||
420 | int rc = coredev->sendrequest_handler(coredev->context, buffer, size); | ||
421 | if (rc < 0) { | ||
422 | sms_info("sendrequest returned error %d", rc); | ||
423 | return rc; | ||
424 | } | ||
425 | |||
426 | return wait_for_completion_timeout(completion, | ||
427 | msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ? | ||
428 | 0 : -ETIME; | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * Starts & enables IR operations | ||
433 | * | ||
434 | * @return 0 on success, < 0 on error. | ||
435 | */ | ||
436 | static int smscore_init_ir(struct smscore_device_t *coredev) | ||
437 | { | ||
438 | int ir_io; | ||
439 | int rc; | ||
440 | void *buffer; | ||
441 | |||
442 | coredev->ir.input_dev = NULL; | ||
443 | ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir; | ||
444 | if (ir_io) {/* only if IR port exist we use IR sub-module */ | ||
445 | sms_info("IR loading"); | ||
446 | rc = sms_ir_init(coredev); | ||
447 | |||
448 | if (rc != 0) | ||
449 | sms_err("Error initialization DTV IR sub-module"); | ||
450 | else { | ||
451 | buffer = kmalloc(sizeof(struct SmsMsgData_ST2) + | ||
452 | SMS_DMA_ALIGNMENT, | ||
453 | GFP_KERNEL | GFP_DMA); | ||
454 | if (buffer) { | ||
455 | struct SmsMsgData_ST2 *msg = | ||
456 | (struct SmsMsgData_ST2 *) | ||
457 | SMS_ALIGN_ADDRESS(buffer); | ||
458 | |||
459 | SMS_INIT_MSG(&msg->xMsgHeader, | ||
460 | MSG_SMS_START_IR_REQ, | ||
461 | sizeof(struct SmsMsgData_ST2)); | ||
462 | msg->msgData[0] = coredev->ir.controller; | ||
463 | msg->msgData[1] = coredev->ir.timeout; | ||
464 | |||
465 | smsendian_handle_tx_message( | ||
466 | (struct SmsMsgHdr_ST2 *)msg); | ||
467 | rc = smscore_sendrequest_and_wait(coredev, msg, | ||
468 | msg->xMsgHeader. msgLength, | ||
469 | &coredev->ir_init_done); | ||
470 | |||
471 | kfree(buffer); | ||
472 | } else | ||
473 | sms_err | ||
474 | ("Sending IR initialization message failed"); | ||
475 | } | ||
476 | } else | ||
477 | sms_info("IR port has not been detected"); | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
442 | /** | 482 | /** |
443 | * sets initial device mode and notifies client hotplugs that device is ready | 483 | * sets initial device mode and notifies client hotplugs that device is ready |
444 | * | 484 | * |
@@ -459,6 +499,7 @@ int smscore_start_device(struct smscore_device_t *coredev) | |||
459 | kmutex_lock(&g_smscore_deviceslock); | 499 | kmutex_lock(&g_smscore_deviceslock); |
460 | 500 | ||
461 | rc = smscore_notify_callbacks(coredev, coredev->device, 1); | 501 | rc = smscore_notify_callbacks(coredev, coredev->device, 1); |
502 | smscore_init_ir(coredev); | ||
462 | 503 | ||
463 | sms_info("device %p started, rc %d", coredev, rc); | 504 | sms_info("device %p started, rc %d", coredev, rc); |
464 | 505 | ||
@@ -468,29 +509,19 @@ int smscore_start_device(struct smscore_device_t *coredev) | |||
468 | } | 509 | } |
469 | EXPORT_SYMBOL_GPL(smscore_start_device); | 510 | EXPORT_SYMBOL_GPL(smscore_start_device); |
470 | 511 | ||
471 | static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, | ||
472 | void *buffer, size_t size, | ||
473 | struct completion *completion) | ||
474 | { | ||
475 | int rc = coredev->sendrequest_handler(coredev->context, buffer, size); | ||
476 | if (rc < 0) { | ||
477 | sms_info("sendrequest returned error %d", rc); | ||
478 | return rc; | ||
479 | } | ||
480 | |||
481 | return wait_for_completion_timeout(completion, | ||
482 | msecs_to_jiffies(10000)) ? | ||
483 | 0 : -ETIME; | ||
484 | } | ||
485 | 512 | ||
486 | static int smscore_load_firmware_family2(struct smscore_device_t *coredev, | 513 | static int smscore_load_firmware_family2(struct smscore_device_t *coredev, |
487 | void *buffer, size_t size) | 514 | void *buffer, size_t size) |
488 | { | 515 | { |
489 | struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; | 516 | struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; |
490 | struct SmsMsgHdr_ST *msg; | 517 | struct SmsMsgHdr_ST *msg; |
491 | u32 mem_address = firmware->StartAddress; | 518 | u32 mem_address; |
492 | u8 *payload = firmware->Payload; | 519 | u8 *payload = firmware->Payload; |
493 | int rc = 0; | 520 | int rc = 0; |
521 | firmware->StartAddress = le32_to_cpu(firmware->StartAddress); | ||
522 | firmware->Length = le32_to_cpu(firmware->Length); | ||
523 | |||
524 | mem_address = firmware->StartAddress; | ||
494 | 525 | ||
495 | sms_info("loading FW to addr 0x%x size %d", | 526 | sms_info("loading FW to addr 0x%x size %d", |
496 | mem_address, firmware->Length); | 527 | mem_address, firmware->Length); |
@@ -657,6 +688,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev) | |||
657 | 688 | ||
658 | kmutex_lock(&g_smscore_deviceslock); | 689 | kmutex_lock(&g_smscore_deviceslock); |
659 | 690 | ||
691 | /* Release input device (IR) resources */ | ||
692 | sms_ir_exit(coredev); | ||
693 | |||
660 | smscore_notify_clients(coredev); | 694 | smscore_notify_clients(coredev); |
661 | smscore_notify_callbacks(coredev, NULL, 0); | 695 | smscore_notify_callbacks(coredev, NULL, 0); |
662 | 696 | ||
@@ -664,7 +698,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev) | |||
664 | * onresponse must no longer be called */ | 698 | * onresponse must no longer be called */ |
665 | 699 | ||
666 | while (1) { | 700 | while (1) { |
667 | while ((cb = smscore_getbuffer(coredev))) { | 701 | while (!list_empty(&coredev->buffers)) { |
702 | cb = (struct smscore_buffer_t *) coredev->buffers.next; | ||
703 | list_del(&cb->entry); | ||
668 | kfree(cb); | 704 | kfree(cb); |
669 | num_buffers++; | 705 | num_buffers++; |
670 | } | 706 | } |
@@ -685,8 +721,10 @@ void smscore_unregister_device(struct smscore_device_t *coredev) | |||
685 | 721 | ||
686 | if (coredev->common_buffer) | 722 | if (coredev->common_buffer) |
687 | dma_free_coherent(NULL, coredev->common_buffer_size, | 723 | dma_free_coherent(NULL, coredev->common_buffer_size, |
688 | coredev->common_buffer, | 724 | coredev->common_buffer, coredev->common_buffer_phys); |
689 | coredev->common_buffer_phys); | 725 | |
726 | if (coredev->fw_buf != NULL) | ||
727 | kfree(coredev->fw_buf); | ||
690 | 728 | ||
691 | list_del(&coredev->entry); | 729 | list_del(&coredev->entry); |
692 | kfree(coredev); | 730 | kfree(coredev); |
@@ -746,7 +784,7 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { | |||
746 | /*BDA*/ | 784 | /*BDA*/ |
747 | {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, | 785 | {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, |
748 | /*ISDBT*/ | 786 | /*ISDBT*/ |
749 | {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"}, | 787 | {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, |
750 | /*ISDBTBDA*/ | 788 | /*ISDBTBDA*/ |
751 | {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, | 789 | {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, |
752 | /*CMMB*/ | 790 | /*CMMB*/ |
@@ -870,7 +908,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) | |||
870 | coredev->device_flags &= ~SMS_DEVICE_NOT_READY; | 908 | coredev->device_flags &= ~SMS_DEVICE_NOT_READY; |
871 | } | 909 | } |
872 | 910 | ||
873 | if (rc != 0) | 911 | if (rc < 0) |
874 | sms_err("return error code %d.", rc); | 912 | sms_err("return error code %d.", rc); |
875 | return rc; | 913 | return rc; |
876 | } | 914 | } |
@@ -940,14 +978,11 @@ smscore_client_t *smscore_find_client(struct smscore_device_t *coredev, | |||
940 | * | 978 | * |
941 | */ | 979 | */ |
942 | void smscore_onresponse(struct smscore_device_t *coredev, | 980 | void smscore_onresponse(struct smscore_device_t *coredev, |
943 | struct smscore_buffer_t *cb) | 981 | struct smscore_buffer_t *cb) { |
944 | { | 982 | struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p |
945 | struct SmsMsgHdr_ST *phdr = | 983 | + cb->offset); |
946 | (struct SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset); | 984 | struct smscore_client_t *client; |
947 | struct smscore_client_t *client = | ||
948 | smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); | ||
949 | int rc = -EBUSY; | 985 | int rc = -EBUSY; |
950 | |||
951 | static unsigned long last_sample_time; /* = 0; */ | 986 | static unsigned long last_sample_time; /* = 0; */ |
952 | static int data_total; /* = 0; */ | 987 | static int data_total; /* = 0; */ |
953 | unsigned long time_now = jiffies_to_msecs(jiffies); | 988 | unsigned long time_now = jiffies_to_msecs(jiffies); |
@@ -965,6 +1000,16 @@ void smscore_onresponse(struct smscore_device_t *coredev, | |||
965 | } | 1000 | } |
966 | 1001 | ||
967 | data_total += cb->size; | 1002 | data_total += cb->size; |
1003 | /* Do we need to re-route? */ | ||
1004 | if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) || | ||
1005 | (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) { | ||
1006 | if (coredev->mode == DEVICE_MODE_DVBT_BDA) | ||
1007 | phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID; | ||
1008 | } | ||
1009 | |||
1010 | |||
1011 | client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); | ||
1012 | |||
968 | /* If no client registered for type & id, | 1013 | /* If no client registered for type & id, |
969 | * check for control client where type is not registered */ | 1014 | * check for control client where type is not registered */ |
970 | if (client) | 1015 | if (client) |
@@ -1009,6 +1054,35 @@ void smscore_onresponse(struct smscore_device_t *coredev, | |||
1009 | case MSG_SMS_SLEEP_RESUME_COMP_IND: | 1054 | case MSG_SMS_SLEEP_RESUME_COMP_IND: |
1010 | complete(&coredev->resume_done); | 1055 | complete(&coredev->resume_done); |
1011 | break; | 1056 | break; |
1057 | case MSG_SMS_GPIO_CONFIG_EX_RES: | ||
1058 | sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES"); | ||
1059 | complete(&coredev->gpio_configuration_done); | ||
1060 | break; | ||
1061 | case MSG_SMS_GPIO_SET_LEVEL_RES: | ||
1062 | sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES"); | ||
1063 | complete(&coredev->gpio_set_level_done); | ||
1064 | break; | ||
1065 | case MSG_SMS_GPIO_GET_LEVEL_RES: | ||
1066 | { | ||
1067 | u32 *msgdata = (u32 *) phdr; | ||
1068 | coredev->gpio_get_res = msgdata[1]; | ||
1069 | sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d", | ||
1070 | coredev->gpio_get_res); | ||
1071 | complete(&coredev->gpio_get_level_done); | ||
1072 | break; | ||
1073 | } | ||
1074 | case MSG_SMS_START_IR_RES: | ||
1075 | complete(&coredev->ir_init_done); | ||
1076 | break; | ||
1077 | case MSG_SMS_IR_SAMPLES_IND: | ||
1078 | sms_ir_event(coredev, | ||
1079 | (const char *) | ||
1080 | ((char *)phdr | ||
1081 | + sizeof(struct SmsMsgHdr_ST)), | ||
1082 | (int)phdr->msgLength | ||
1083 | - sizeof(struct SmsMsgHdr_ST)); | ||
1084 | break; | ||
1085 | |||
1012 | default: | 1086 | default: |
1013 | break; | 1087 | break; |
1014 | } | 1088 | } |
@@ -1030,12 +1104,24 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) | |||
1030 | struct smscore_buffer_t *cb = NULL; | 1104 | struct smscore_buffer_t *cb = NULL; |
1031 | unsigned long flags; | 1105 | unsigned long flags; |
1032 | 1106 | ||
1107 | DEFINE_WAIT(wait); | ||
1108 | |||
1033 | spin_lock_irqsave(&coredev->bufferslock, flags); | 1109 | spin_lock_irqsave(&coredev->bufferslock, flags); |
1034 | 1110 | ||
1035 | if (!list_empty(&coredev->buffers)) { | 1111 | /* This function must return a valid buffer, since the buffer list is |
1036 | cb = (struct smscore_buffer_t *) coredev->buffers.next; | 1112 | * finite, we check that there is an available buffer, if not, we wait |
1037 | list_del(&cb->entry); | 1113 | * until such buffer become available. |
1038 | } | 1114 | */ |
1115 | |||
1116 | prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE); | ||
1117 | |||
1118 | if (list_empty(&coredev->buffers)) | ||
1119 | schedule(); | ||
1120 | |||
1121 | finish_wait(&coredev->buffer_mng_waitq, &wait); | ||
1122 | |||
1123 | cb = (struct smscore_buffer_t *) coredev->buffers.next; | ||
1124 | list_del(&cb->entry); | ||
1039 | 1125 | ||
1040 | spin_unlock_irqrestore(&coredev->bufferslock, flags); | 1126 | spin_unlock_irqrestore(&coredev->bufferslock, flags); |
1041 | 1127 | ||
@@ -1052,8 +1138,8 @@ EXPORT_SYMBOL_GPL(smscore_getbuffer); | |||
1052 | * | 1138 | * |
1053 | */ | 1139 | */ |
1054 | void smscore_putbuffer(struct smscore_device_t *coredev, | 1140 | void smscore_putbuffer(struct smscore_device_t *coredev, |
1055 | struct smscore_buffer_t *cb) | 1141 | struct smscore_buffer_t *cb) { |
1056 | { | 1142 | wake_up_interruptible(&coredev->buffer_mng_waitq); |
1057 | list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); | 1143 | list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); |
1058 | } | 1144 | } |
1059 | EXPORT_SYMBOL_GPL(smscore_putbuffer); | 1145 | EXPORT_SYMBOL_GPL(smscore_putbuffer); |
@@ -1210,8 +1296,9 @@ int smsclient_sendrequest(struct smscore_client_t *client, | |||
1210 | EXPORT_SYMBOL_GPL(smsclient_sendrequest); | 1296 | EXPORT_SYMBOL_GPL(smsclient_sendrequest); |
1211 | 1297 | ||
1212 | 1298 | ||
1299 | /* old GPIO managments implementation */ | ||
1213 | int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, | 1300 | int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, |
1214 | struct smscore_gpio_config *pinconfig) | 1301 | struct smscore_config_gpio *pinconfig) |
1215 | { | 1302 | { |
1216 | struct { | 1303 | struct { |
1217 | struct SmsMsgHdr_ST hdr; | 1304 | struct SmsMsgHdr_ST hdr; |
@@ -1280,35 +1367,254 @@ int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level) | |||
1280 | &msg, sizeof(msg)); | 1367 | &msg, sizeof(msg)); |
1281 | } | 1368 | } |
1282 | 1369 | ||
1283 | static int __init smscore_module_init(void) | 1370 | /* new GPIO managment implementation */ |
1284 | { | 1371 | static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum, |
1285 | int rc = 0; | 1372 | u32 *pGroupNum, u32 *pGroupCfg) { |
1373 | |||
1374 | *pGroupCfg = 1; | ||
1375 | |||
1376 | if (PinNum >= 0 && PinNum <= 1) { | ||
1377 | *pTranslatedPinNum = 0; | ||
1378 | *pGroupNum = 9; | ||
1379 | *pGroupCfg = 2; | ||
1380 | } else if (PinNum >= 2 && PinNum <= 6) { | ||
1381 | *pTranslatedPinNum = 2; | ||
1382 | *pGroupNum = 0; | ||
1383 | *pGroupCfg = 2; | ||
1384 | } else if (PinNum >= 7 && PinNum <= 11) { | ||
1385 | *pTranslatedPinNum = 7; | ||
1386 | *pGroupNum = 1; | ||
1387 | } else if (PinNum >= 12 && PinNum <= 15) { | ||
1388 | *pTranslatedPinNum = 12; | ||
1389 | *pGroupNum = 2; | ||
1390 | *pGroupCfg = 3; | ||
1391 | } else if (PinNum == 16) { | ||
1392 | *pTranslatedPinNum = 16; | ||
1393 | *pGroupNum = 23; | ||
1394 | } else if (PinNum >= 17 && PinNum <= 24) { | ||
1395 | *pTranslatedPinNum = 17; | ||
1396 | *pGroupNum = 3; | ||
1397 | } else if (PinNum == 25) { | ||
1398 | *pTranslatedPinNum = 25; | ||
1399 | *pGroupNum = 6; | ||
1400 | } else if (PinNum >= 26 && PinNum <= 28) { | ||
1401 | *pTranslatedPinNum = 26; | ||
1402 | *pGroupNum = 4; | ||
1403 | } else if (PinNum == 29) { | ||
1404 | *pTranslatedPinNum = 29; | ||
1405 | *pGroupNum = 5; | ||
1406 | *pGroupCfg = 2; | ||
1407 | } else if (PinNum == 30) { | ||
1408 | *pTranslatedPinNum = 30; | ||
1409 | *pGroupNum = 8; | ||
1410 | } else if (PinNum == 31) { | ||
1411 | *pTranslatedPinNum = 31; | ||
1412 | *pGroupNum = 17; | ||
1413 | } else | ||
1414 | return -1; | ||
1286 | 1415 | ||
1287 | INIT_LIST_HEAD(&g_smscore_notifyees); | 1416 | *pGroupCfg <<= 24; |
1288 | INIT_LIST_HEAD(&g_smscore_devices); | ||
1289 | kmutex_init(&g_smscore_deviceslock); | ||
1290 | 1417 | ||
1291 | INIT_LIST_HEAD(&g_smscore_registry); | 1418 | return 0; |
1292 | kmutex_init(&g_smscore_registrylock); | 1419 | } |
1420 | |||
1421 | int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, | ||
1422 | struct smscore_gpio_config *pGpioConfig) { | ||
1423 | |||
1424 | u32 totalLen; | ||
1425 | u32 TranslatedPinNum; | ||
1426 | u32 GroupNum; | ||
1427 | u32 ElectricChar; | ||
1428 | u32 groupCfg; | ||
1429 | void *buffer; | ||
1430 | int rc; | ||
1431 | |||
1432 | struct SetGpioMsg { | ||
1433 | struct SmsMsgHdr_ST xMsgHeader; | ||
1434 | u32 msgData[6]; | ||
1435 | } *pMsg; | ||
1436 | |||
1437 | |||
1438 | if (PinNum > MAX_GPIO_PIN_NUMBER) | ||
1439 | return -EINVAL; | ||
1440 | |||
1441 | if (pGpioConfig == NULL) | ||
1442 | return -EINVAL; | ||
1443 | |||
1444 | totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6); | ||
1445 | |||
1446 | buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, | ||
1447 | GFP_KERNEL | GFP_DMA); | ||
1448 | if (!buffer) | ||
1449 | return -ENOMEM; | ||
1450 | |||
1451 | pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); | ||
1452 | |||
1453 | pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; | ||
1454 | pMsg->xMsgHeader.msgDstId = HIF_TASK; | ||
1455 | pMsg->xMsgHeader.msgFlags = 0; | ||
1456 | pMsg->xMsgHeader.msgLength = (u16) totalLen; | ||
1457 | pMsg->msgData[0] = PinNum; | ||
1458 | |||
1459 | if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) { | ||
1460 | pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ; | ||
1461 | if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum, | ||
1462 | &groupCfg) != 0) | ||
1463 | return -EINVAL; | ||
1464 | |||
1465 | pMsg->msgData[1] = TranslatedPinNum; | ||
1466 | pMsg->msgData[2] = GroupNum; | ||
1467 | ElectricChar = (pGpioConfig->PullUpDown) | ||
1468 | | (pGpioConfig->InputCharacteristics << 2) | ||
1469 | | (pGpioConfig->OutputSlewRate << 3) | ||
1470 | | (pGpioConfig->OutputDriving << 4); | ||
1471 | pMsg->msgData[3] = ElectricChar; | ||
1472 | pMsg->msgData[4] = pGpioConfig->Direction; | ||
1473 | pMsg->msgData[5] = groupCfg; | ||
1474 | } else { | ||
1475 | pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ; | ||
1476 | pMsg->msgData[1] = pGpioConfig->PullUpDown; | ||
1477 | pMsg->msgData[2] = pGpioConfig->OutputSlewRate; | ||
1478 | pMsg->msgData[3] = pGpioConfig->OutputDriving; | ||
1479 | pMsg->msgData[4] = pGpioConfig->Direction; | ||
1480 | pMsg->msgData[5] = 0; | ||
1481 | } | ||
1482 | |||
1483 | smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); | ||
1484 | rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, | ||
1485 | &coredev->gpio_configuration_done); | ||
1486 | |||
1487 | if (rc != 0) { | ||
1488 | if (rc == -ETIME) | ||
1489 | sms_err("smscore_gpio_configure timeout"); | ||
1490 | else | ||
1491 | sms_err("smscore_gpio_configure error"); | ||
1492 | } | ||
1493 | kfree(buffer); | ||
1494 | |||
1495 | return rc; | ||
1496 | } | ||
1497 | |||
1498 | int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, | ||
1499 | u8 NewLevel) { | ||
1500 | |||
1501 | u32 totalLen; | ||
1502 | int rc; | ||
1503 | void *buffer; | ||
1504 | |||
1505 | struct SetGpioMsg { | ||
1506 | struct SmsMsgHdr_ST xMsgHeader; | ||
1507 | u32 msgData[3]; /* keep it 3 ! */ | ||
1508 | } *pMsg; | ||
1509 | |||
1510 | if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) || | ||
1511 | (PinNum > MAX_GPIO_PIN_NUMBER)) | ||
1512 | return -EINVAL; | ||
1293 | 1513 | ||
1514 | totalLen = sizeof(struct SmsMsgHdr_ST) + | ||
1515 | (3 * sizeof(u32)); /* keep it 3 ! */ | ||
1294 | 1516 | ||
1517 | buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, | ||
1518 | GFP_KERNEL | GFP_DMA); | ||
1519 | if (!buffer) | ||
1520 | return -ENOMEM; | ||
1295 | 1521 | ||
1522 | pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); | ||
1296 | 1523 | ||
1524 | pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; | ||
1525 | pMsg->xMsgHeader.msgDstId = HIF_TASK; | ||
1526 | pMsg->xMsgHeader.msgFlags = 0; | ||
1527 | pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ; | ||
1528 | pMsg->xMsgHeader.msgLength = (u16) totalLen; | ||
1529 | pMsg->msgData[0] = PinNum; | ||
1530 | pMsg->msgData[1] = NewLevel; | ||
1297 | 1531 | ||
1532 | /* Send message to SMS */ | ||
1533 | smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); | ||
1534 | rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, | ||
1535 | &coredev->gpio_set_level_done); | ||
1536 | |||
1537 | if (rc != 0) { | ||
1538 | if (rc == -ETIME) | ||
1539 | sms_err("smscore_gpio_set_level timeout"); | ||
1540 | else | ||
1541 | sms_err("smscore_gpio_set_level error"); | ||
1542 | } | ||
1543 | kfree(buffer); | ||
1298 | 1544 | ||
1299 | return rc; | 1545 | return rc; |
1300 | sms_debug("rc %d", rc); | 1546 | } |
1547 | |||
1548 | int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, | ||
1549 | u8 *level) { | ||
1550 | |||
1551 | u32 totalLen; | ||
1552 | int rc; | ||
1553 | void *buffer; | ||
1554 | |||
1555 | struct SetGpioMsg { | ||
1556 | struct SmsMsgHdr_ST xMsgHeader; | ||
1557 | u32 msgData[2]; | ||
1558 | } *pMsg; | ||
1559 | |||
1560 | |||
1561 | if (PinNum > MAX_GPIO_PIN_NUMBER) | ||
1562 | return -EINVAL; | ||
1563 | |||
1564 | totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32)); | ||
1565 | |||
1566 | buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, | ||
1567 | GFP_KERNEL | GFP_DMA); | ||
1568 | if (!buffer) | ||
1569 | return -ENOMEM; | ||
1570 | |||
1571 | pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); | ||
1572 | |||
1573 | pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; | ||
1574 | pMsg->xMsgHeader.msgDstId = HIF_TASK; | ||
1575 | pMsg->xMsgHeader.msgFlags = 0; | ||
1576 | pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ; | ||
1577 | pMsg->xMsgHeader.msgLength = (u16) totalLen; | ||
1578 | pMsg->msgData[0] = PinNum; | ||
1579 | pMsg->msgData[1] = 0; | ||
1580 | |||
1581 | /* Send message to SMS */ | ||
1582 | smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); | ||
1583 | rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, | ||
1584 | &coredev->gpio_get_level_done); | ||
1585 | |||
1586 | if (rc != 0) { | ||
1587 | if (rc == -ETIME) | ||
1588 | sms_err("smscore_gpio_get_level timeout"); | ||
1589 | else | ||
1590 | sms_err("smscore_gpio_get_level error"); | ||
1591 | } | ||
1592 | kfree(buffer); | ||
1593 | |||
1594 | /* Its a race between other gpio_get_level() and the copy of the single | ||
1595 | * global 'coredev->gpio_get_res' to the function's variable 'level' | ||
1596 | */ | ||
1597 | *level = coredev->gpio_get_res; | ||
1301 | 1598 | ||
1302 | return rc; | 1599 | return rc; |
1303 | } | 1600 | } |
1304 | 1601 | ||
1305 | static void __exit smscore_module_exit(void) | 1602 | static int __init smscore_module_init(void) |
1306 | { | 1603 | { |
1604 | int rc = 0; | ||
1307 | 1605 | ||
1606 | INIT_LIST_HEAD(&g_smscore_notifyees); | ||
1607 | INIT_LIST_HEAD(&g_smscore_devices); | ||
1608 | kmutex_init(&g_smscore_deviceslock); | ||
1308 | 1609 | ||
1610 | INIT_LIST_HEAD(&g_smscore_registry); | ||
1611 | kmutex_init(&g_smscore_registrylock); | ||
1309 | 1612 | ||
1613 | return rc; | ||
1614 | } | ||
1310 | 1615 | ||
1311 | 1616 | static void __exit smscore_module_exit(void) | |
1617 | { | ||
1312 | kmutex_lock(&g_smscore_deviceslock); | 1618 | kmutex_lock(&g_smscore_deviceslock); |
1313 | while (!list_empty(&g_smscore_notifyees)) { | 1619 | while (!list_empty(&g_smscore_notifyees)) { |
1314 | struct smscore_device_notifyee_t *notifyee = | 1620 | struct smscore_device_notifyee_t *notifyee = |
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 548de9056e8b..f1108c64e895 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h | |||
@@ -1,26 +1,26 @@ | |||
1 | /* | 1 | /**************************************************************** |
2 | * Driver for the Siano SMS1xxx USB dongle | 2 | |
3 | * | 3 | Siano Mobile Silicon, Inc. |
4 | * author: Anatoly Greenblat | 4 | MDTV receiver kernel modules. |
5 | * | 5 | Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat |
6 | * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. | 6 | |
7 | * | 7 | This program is free software: you can redistribute it and/or modify |
8 | * This program is free software; you can redistribute it and/or modify | 8 | it under the terms of the GNU General Public License as published by |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | the Free Software Foundation, either version 2 of the License, or |
10 | * published by the Free Software Foundation; | 10 | (at your option) any later version. |
11 | * | 11 | |
12 | * Software distributed under the License is distributed on an "AS IS" | 12 | This program is distributed in the hope that it will be useful, |
13 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * See the GNU General Public License for more details. | 15 | GNU General Public License for more details. |
16 | * | 16 | |
17 | * You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | |
20 | */ | 20 | ****************************************************************/ |
21 | 21 | ||
22 | #ifndef __smscoreapi_h__ | 22 | #ifndef __SMS_CORE_API_H__ |
23 | #define __smscoreapi_h__ | 23 | #define __SMS_CORE_API_H__ |
24 | 24 | ||
25 | #include <linux/version.h> | 25 | #include <linux/version.h> |
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
@@ -28,14 +28,13 @@ | |||
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/scatterlist.h> | 29 | #include <linux/scatterlist.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <asm/page.h> | ||
32 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
32 | #include <linux/wait.h> | ||
33 | #include <linux/timer.h> | ||
33 | 34 | ||
34 | #include "dmxdev.h" | 35 | #include <asm/page.h> |
35 | #include "dvbdev.h" | ||
36 | #include "dvb_demux.h" | ||
37 | #include "dvb_frontend.h" | ||
38 | 36 | ||
37 | #include "smsir.h" | ||
39 | 38 | ||
40 | #define kmutex_init(_p_) mutex_init(_p_) | 39 | #define kmutex_init(_p_) mutex_init(_p_) |
41 | #define kmutex_lock(_p_) mutex_lock(_p_) | 40 | #define kmutex_lock(_p_) mutex_lock(_p_) |
@@ -46,13 +45,14 @@ | |||
46 | #define min(a, b) (((a) < (b)) ? (a) : (b)) | 45 | #define min(a, b) (((a) < (b)) ? (a) : (b)) |
47 | #endif | 46 | #endif |
48 | 47 | ||
49 | #define SMS_ALLOC_ALIGNMENT 128 | 48 | #define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000) |
50 | #define SMS_DMA_ALIGNMENT 16 | 49 | #define SMS_ALLOC_ALIGNMENT 128 |
50 | #define SMS_DMA_ALIGNMENT 16 | ||
51 | #define SMS_ALIGN_ADDRESS(addr) \ | 51 | #define SMS_ALIGN_ADDRESS(addr) \ |
52 | ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) | 52 | ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) |
53 | 53 | ||
54 | #define SMS_DEVICE_FAMILY2 1 | 54 | #define SMS_DEVICE_FAMILY2 1 |
55 | #define SMS_ROM_NO_RESPONSE 2 | 55 | #define SMS_ROM_NO_RESPONSE 2 |
56 | #define SMS_DEVICE_NOT_READY 0x8000000 | 56 | #define SMS_DEVICE_NOT_READY 0x8000000 |
57 | 57 | ||
58 | enum sms_device_type_st { | 58 | enum sms_device_type_st { |
@@ -83,13 +83,13 @@ typedef void (*onremove_t)(void *context); | |||
83 | struct smscore_buffer_t { | 83 | struct smscore_buffer_t { |
84 | /* public members, once passed to clients can be changed freely */ | 84 | /* public members, once passed to clients can be changed freely */ |
85 | struct list_head entry; | 85 | struct list_head entry; |
86 | int size; | 86 | int size; |
87 | int offset; | 87 | int offset; |
88 | 88 | ||
89 | /* private members, read-only for clients */ | 89 | /* private members, read-only for clients */ |
90 | void *p; | 90 | void *p; |
91 | dma_addr_t phys; | 91 | dma_addr_t phys; |
92 | unsigned long offset_in_common; | 92 | unsigned long offset_in_common; |
93 | }; | 93 | }; |
94 | 94 | ||
95 | struct smsdevice_params_t { | 95 | struct smsdevice_params_t { |
@@ -116,10 +116,63 @@ struct smsclient_params_t { | |||
116 | int data_type; | 116 | int data_type; |
117 | onresponse_t onresponse_handler; | 117 | onresponse_t onresponse_handler; |
118 | onremove_t onremove_handler; | 118 | onremove_t onremove_handler; |
119 | |||
120 | void *context; | 119 | void *context; |
121 | }; | 120 | }; |
122 | 121 | ||
122 | struct smscore_device_t { | ||
123 | struct list_head entry; | ||
124 | |||
125 | struct list_head clients; | ||
126 | struct list_head subclients; | ||
127 | spinlock_t clientslock; | ||
128 | |||
129 | struct list_head buffers; | ||
130 | spinlock_t bufferslock; | ||
131 | int num_buffers; | ||
132 | |||
133 | void *common_buffer; | ||
134 | int common_buffer_size; | ||
135 | dma_addr_t common_buffer_phys; | ||
136 | |||
137 | void *context; | ||
138 | struct device *device; | ||
139 | |||
140 | char devpath[32]; | ||
141 | unsigned long device_flags; | ||
142 | |||
143 | setmode_t setmode_handler; | ||
144 | detectmode_t detectmode_handler; | ||
145 | sendrequest_t sendrequest_handler; | ||
146 | preload_t preload_handler; | ||
147 | postload_t postload_handler; | ||
148 | |||
149 | int mode, modes_supported; | ||
150 | |||
151 | /* host <--> device messages */ | ||
152 | struct completion version_ex_done, data_download_done, trigger_done; | ||
153 | struct completion init_device_done, reload_start_done, resume_done; | ||
154 | struct completion gpio_configuration_done, gpio_set_level_done; | ||
155 | struct completion gpio_get_level_done, ir_init_done; | ||
156 | |||
157 | /* Buffer management */ | ||
158 | wait_queue_head_t buffer_mng_waitq; | ||
159 | |||
160 | /* GPIO */ | ||
161 | int gpio_get_res; | ||
162 | |||
163 | /* Target hardware board */ | ||
164 | int board_id; | ||
165 | |||
166 | /* Firmware */ | ||
167 | u8 *fw_buf; | ||
168 | u32 fw_buf_size; | ||
169 | |||
170 | /* Infrared (IR) */ | ||
171 | struct ir_t ir; | ||
172 | |||
173 | int led_state; | ||
174 | }; | ||
175 | |||
123 | /* GPIO definitions for antenna frequency domain control (SMS8021) */ | 176 | /* GPIO definitions for antenna frequency domain control (SMS8021) */ |
124 | #define SMS_ANTENNA_GPIO_0 1 | 177 | #define SMS_ANTENNA_GPIO_0 1 |
125 | #define SMS_ANTENNA_GPIO_1 0 | 178 | #define SMS_ANTENNA_GPIO_1 0 |
@@ -154,18 +207,15 @@ struct smsclient_params_t { | |||
154 | #define MSG_SMS_INIT_DEVICE_RES 579 | 207 | #define MSG_SMS_INIT_DEVICE_RES 579 |
155 | #define MSG_SMS_ADD_PID_FILTER_REQ 601 | 208 | #define MSG_SMS_ADD_PID_FILTER_REQ 601 |
156 | #define MSG_SMS_ADD_PID_FILTER_RES 602 | 209 | #define MSG_SMS_ADD_PID_FILTER_RES 602 |
157 | #define MSG_SMS_REMOVE_PID_FILTER_REQ 603 | 210 | #define MSG_SMS_REMOVE_PID_FILTER_REQ 603 |
158 | #define MSG_SMS_REMOVE_PID_FILTER_RES 604 | 211 | #define MSG_SMS_REMOVE_PID_FILTER_RES 604 |
159 | #define MSG_SMS_DAB_CHANNEL 607 | 212 | #define MSG_SMS_DAB_CHANNEL 607 |
160 | #define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 | 213 | #define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 |
161 | #define MSG_SMS_GET_PID_FILTER_LIST_RES 609 | 214 | #define MSG_SMS_GET_PID_FILTER_LIST_RES 609 |
162 | #define MSG_SMS_GET_STATISTICS_REQ 615 | 215 | #define MSG_SMS_HO_PER_SLICES_IND 630 |
163 | #define MSG_SMS_GET_STATISTICS_RES 616 | 216 | #define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 |
164 | #define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 | 217 | #define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 |
165 | #define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 | 218 | #define MSG_SMS_SLEEP_RESUME_COMP_IND 655 |
166 | #define MSG_SMS_GET_STATISTICS_EX_REQ 653 | ||
167 | #define MSG_SMS_GET_STATISTICS_EX_RES 654 | ||
168 | #define MSG_SMS_SLEEP_RESUME_COMP_IND 655 | ||
169 | #define MSG_SMS_DATA_DOWNLOAD_REQ 660 | 219 | #define MSG_SMS_DATA_DOWNLOAD_REQ 660 |
170 | #define MSG_SMS_DATA_DOWNLOAD_RES 661 | 220 | #define MSG_SMS_DATA_DOWNLOAD_RES 661 |
171 | #define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 | 221 | #define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 |
@@ -190,14 +240,31 @@ struct smsclient_params_t { | |||
190 | #define MSG_SMS_GPIO_CONFIG_EX_RES 713 | 240 | #define MSG_SMS_GPIO_CONFIG_EX_RES 713 |
191 | #define MSG_SMS_ISDBT_TUNE_REQ 776 | 241 | #define MSG_SMS_ISDBT_TUNE_REQ 776 |
192 | #define MSG_SMS_ISDBT_TUNE_RES 777 | 242 | #define MSG_SMS_ISDBT_TUNE_RES 777 |
243 | #define MSG_SMS_TRANSMISSION_IND 782 | ||
244 | #define MSG_SMS_START_IR_REQ 800 | ||
245 | #define MSG_SMS_START_IR_RES 801 | ||
246 | #define MSG_SMS_IR_SAMPLES_IND 802 | ||
247 | #define MSG_SMS_SIGNAL_DETECTED_IND 827 | ||
248 | #define MSG_SMS_NO_SIGNAL_IND 828 | ||
193 | 249 | ||
194 | #define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ | 250 | #define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ |
195 | (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ | 251 | (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ |
196 | (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ | 252 | (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ |
197 | } while (0) | 253 | } while (0) |
254 | |||
198 | #define SMS_INIT_MSG(ptr, type, len) \ | 255 | #define SMS_INIT_MSG(ptr, type, len) \ |
199 | SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) | 256 | SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) |
200 | 257 | ||
258 | enum SMS_DVB3_EVENTS { | ||
259 | DVB3_EVENT_INIT = 0, | ||
260 | DVB3_EVENT_SLEEP, | ||
261 | DVB3_EVENT_HOTPLUG, | ||
262 | DVB3_EVENT_FE_LOCK, | ||
263 | DVB3_EVENT_FE_UNLOCK, | ||
264 | DVB3_EVENT_UNC_OK, | ||
265 | DVB3_EVENT_UNC_ERR | ||
266 | }; | ||
267 | |||
201 | enum SMS_DEVICE_MODE { | 268 | enum SMS_DEVICE_MODE { |
202 | DEVICE_MODE_NONE = -1, | 269 | DEVICE_MODE_NONE = -1, |
203 | DEVICE_MODE_DVBT = 0, | 270 | DEVICE_MODE_DVBT = 0, |
@@ -221,8 +288,13 @@ struct SmsMsgHdr_ST { | |||
221 | }; | 288 | }; |
222 | 289 | ||
223 | struct SmsMsgData_ST { | 290 | struct SmsMsgData_ST { |
224 | struct SmsMsgHdr_ST xMsgHeader; | 291 | struct SmsMsgHdr_ST xMsgHeader; |
225 | u32 msgData[1]; | 292 | u32 msgData[1]; |
293 | }; | ||
294 | |||
295 | struct SmsMsgData_ST2 { | ||
296 | struct SmsMsgHdr_ST xMsgHeader; | ||
297 | u32 msgData[2]; | ||
226 | }; | 298 | }; |
227 | 299 | ||
228 | struct SmsDataDownload_ST { | 300 | struct SmsDataDownload_ST { |
@@ -238,11 +310,12 @@ struct SmsVersionRes_ST { | |||
238 | u8 Step; /* 0 - Step A */ | 310 | u8 Step; /* 0 - Step A */ |
239 | u8 MetalFix; /* 0 - Metal 0 */ | 311 | u8 MetalFix; /* 0 - Metal 0 */ |
240 | 312 | ||
241 | u8 FirmwareId; /* 0xFF � ROM, otherwise the | 313 | /* FirmwareId 0xFF if ROM, otherwise the |
242 | * value indicated by | 314 | * value indicated by SMSHOSTLIB_DEVICE_MODES_E */ |
243 | * SMSHOSTLIB_DEVICE_MODES_E */ | 315 | u8 FirmwareId; |
244 | u8 SupportedProtocols; /* Bitwise OR combination of | 316 | /* SupportedProtocols Bitwise OR combination of |
245 | * supported protocols */ | 317 | * supported protocols */ |
318 | u8 SupportedProtocols; | ||
246 | 319 | ||
247 | u8 VersionMajor; | 320 | u8 VersionMajor; |
248 | u8 VersionMinor; | 321 | u8 VersionMinor; |
@@ -264,86 +337,219 @@ struct SmsFirmware_ST { | |||
264 | u8 Payload[1]; | 337 | u8 Payload[1]; |
265 | }; | 338 | }; |
266 | 339 | ||
267 | struct SMSHOSTLIB_STATISTICS_ST { | 340 | /* Statistics information returned as response for |
268 | u32 Reserved; /* Reserved */ | 341 | * SmsHostApiGetStatistics_Req */ |
342 | struct SMSHOSTLIB_STATISTICS_S { | ||
343 | u32 Reserved; /* Reserved */ | ||
269 | 344 | ||
270 | /* Common parameters */ | 345 | /* Common parameters */ |
271 | u32 IsRfLocked; /* 0 - not locked, 1 - locked */ | 346 | u32 IsRfLocked; /* 0 - not locked, 1 - locked */ |
272 | u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ | 347 | u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ |
273 | u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ | 348 | u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ |
274 | 349 | ||
275 | /* Reception quality */ | 350 | /* Reception quality */ |
276 | s32 SNR; /* dB */ | 351 | s32 SNR; /* dB */ |
277 | u32 BER; /* Post Viterbi BER [1E-5] */ | 352 | u32 BER; /* Post Viterbi BER [1E-5] */ |
278 | u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ | 353 | u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ |
279 | u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A, | 354 | u32 TS_PER; /* Transport stream PER, |
280 | * valid only for DVB-T/H */ | 355 | 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */ |
281 | u32 MFER; /* DVB-H frame error rate in percentage, | 356 | u32 MFER; /* DVB-H frame error rate in percentage, |
282 | * 0xFFFFFFFF indicate N/A, valid only for DVB-H */ | 357 | 0xFFFFFFFF indicate N/A, valid only for DVB-H */ |
283 | s32 RSSI; /* dBm */ | 358 | s32 RSSI; /* dBm */ |
284 | s32 InBandPwr; /* In band power in dBM */ | 359 | s32 InBandPwr; /* In band power in dBM */ |
285 | s32 CarrierOffset; /* Carrier Offset in bin/1024 */ | 360 | s32 CarrierOffset; /* Carrier Offset in bin/1024 */ |
286 | 361 | ||
287 | /* Transmission parameters, valid only for DVB-T/H */ | 362 | /* Transmission parameters */ |
288 | u32 Frequency; /* Frequency in Hz */ | 363 | u32 Frequency; /* Frequency in Hz */ |
289 | u32 Bandwidth; /* Bandwidth in MHz */ | 364 | u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */ |
290 | u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, | 365 | u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, |
291 | * for DVB-T/H FFT mode carriers in Kilos */ | 366 | for DVB-T/H FFT mode carriers in Kilos */ |
292 | u32 ModemState; /* from SMS_DvbModemState_ET */ | 367 | u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET, |
293 | u32 GuardInterval; /* Guard Interval, 1 divided by value */ | 368 | valid only for DVB-T/H */ |
294 | u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET */ | 369 | u32 GuardInterval; /* Guard Interval from |
295 | u32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET */ | 370 | SMSHOSTLIB_GUARD_INTERVALS_ET, valid only for DVB-T/H */ |
296 | u32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET */ | 371 | u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, |
297 | u32 Constellation; /* Constellation from SMS_Constellation_ET */ | 372 | valid only for DVB-T/H */ |
373 | u32 LPCodeRate; /* Low Priority Code Rate from | ||
374 | SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */ | ||
375 | u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET, | ||
376 | valid only for DVB-T/H */ | ||
377 | u32 Constellation; /* Constellation from | ||
378 | SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */ | ||
298 | 379 | ||
299 | /* Burst parameters, valid only for DVB-H */ | 380 | /* Burst parameters, valid only for DVB-H */ |
300 | u32 BurstSize; /* Current burst size in bytes */ | 381 | u32 BurstSize; /* Current burst size in bytes, |
301 | u32 BurstDuration; /* Current burst duration in mSec */ | 382 | valid only for DVB-H */ |
302 | u32 BurstCycleTime; /* Current burst cycle time in mSec */ | 383 | u32 BurstDuration; /* Current burst duration in mSec, |
303 | u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, | 384 | valid only for DVB-H */ |
304 | * as calculated by demodulator */ | 385 | u32 BurstCycleTime; /* Current burst cycle time in mSec, |
305 | u32 NumOfRows; /* Number of rows in MPE table */ | 386 | valid only for DVB-H */ |
306 | u32 NumOfPaddCols; /* Number of padding columns in MPE table */ | 387 | u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec, |
307 | u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */ | 388 | as calculated by demodulator, valid only for DVB-H */ |
308 | /* Burst parameters */ | 389 | u32 NumOfRows; /* Number of rows in MPE table, |
309 | u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ | 390 | valid only for DVB-H */ |
310 | u32 TotalTSPackets; /* Total number of transport-stream packets */ | 391 | u32 NumOfPaddCols; /* Number of padding columns in MPE table, |
311 | u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include | 392 | valid only for DVB-H */ |
312 | * errors after MPE RS decoding */ | 393 | u32 NumOfPunctCols; /* Number of puncturing columns in MPE table, |
313 | u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors | 394 | valid only for DVB-H */ |
314 | * after MPE RS decoding */ | 395 | u32 ErrorTSPackets; /* Number of erroneous |
315 | u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected | 396 | transport-stream packets */ |
316 | * by MPE RS decoding */ | 397 | u32 TotalTSPackets; /* Total number of transport-stream packets */ |
317 | 398 | u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include | |
399 | errors after MPE RS decoding */ | ||
400 | u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors | ||
401 | after MPE RS decoding */ | ||
402 | u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were | ||
403 | corrected by MPE RS decoding */ | ||
318 | /* Common params */ | 404 | /* Common params */ |
319 | u32 BERErrorCount; /* Number of errornous SYNC bits. */ | 405 | u32 BERErrorCount; /* Number of errornous SYNC bits. */ |
320 | u32 BERBitCount; /* Total number of SYNC bits. */ | 406 | u32 BERBitCount; /* Total number of SYNC bits. */ |
321 | 407 | ||
322 | /* Interface information */ | 408 | /* Interface information */ |
323 | u32 SmsToHostTxErrors; /* Total number of transmission errors. */ | 409 | u32 SmsToHostTxErrors; /* Total number of transmission errors. */ |
324 | 410 | ||
325 | /* DAB/T-DMB */ | 411 | /* DAB/T-DMB */ |
326 | u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ | 412 | u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ |
327 | 413 | ||
328 | /* DVB-H TPS parameters */ | 414 | /* DVB-H TPS parameters */ |
329 | u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; | 415 | u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; |
330 | * if set to 0xFFFFFFFF cell_id not yet recovered */ | 416 | if set to 0xFFFFFFFF cell_id not yet recovered */ |
417 | u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - | ||
418 | Time Slicing indicator, bit 0 - MPE-FEC indicator */ | ||
419 | u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - | ||
420 | Time Slicing indicator, bit 0 - MPE-FEC indicator */ | ||
331 | 421 | ||
422 | u32 NumMPEReceived; /* DVB-H, Num MPE section received */ | ||
423 | |||
424 | u32 ReservedFields[10]; /* Reserved */ | ||
332 | }; | 425 | }; |
333 | 426 | ||
334 | struct SmsMsgStatisticsInfo_ST { | 427 | struct PID_STATISTICS_DATA_S { |
335 | u32 RequestResult; | 428 | struct PID_BURST_S { |
429 | u32 size; | ||
430 | u32 padding_cols; | ||
431 | u32 punct_cols; | ||
432 | u32 duration; | ||
433 | u32 cycle; | ||
434 | u32 calc_cycle; | ||
435 | } burst; | ||
436 | |||
437 | u32 tot_tbl_cnt; | ||
438 | u32 invalid_tbl_cnt; | ||
439 | u32 tot_cor_tbl; | ||
440 | }; | ||
336 | 441 | ||
337 | struct SMSHOSTLIB_STATISTICS_ST Stat; | 442 | struct PID_DATA_S { |
443 | u32 pid; | ||
444 | u32 num_rows; | ||
445 | struct PID_STATISTICS_DATA_S pid_statistics; | ||
446 | }; | ||
338 | 447 | ||
339 | /* Split the calc of the SNR in DAB */ | 448 | #define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1) |
340 | u32 Signal; /* dB */ | 449 | #define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth) |
341 | u32 Noise; /* dB */ | 450 | #define CORRECT_STAT_TRANSMISSON_MODE(_stat) \ |
451 | if (_stat.TransmissionMode == 0) \ | ||
452 | _stat.TransmissionMode = 2; \ | ||
453 | else if (_stat.TransmissionMode == 1) \ | ||
454 | _stat.TransmissionMode = 8; \ | ||
455 | else \ | ||
456 | _stat.TransmissionMode = 4; | ||
457 | |||
458 | struct TRANSMISSION_STATISTICS_S { | ||
459 | u32 Frequency; /* Frequency in Hz */ | ||
460 | u32 Bandwidth; /* Bandwidth in MHz */ | ||
461 | u32 TransmissionMode; /* FFT mode carriers in Kilos */ | ||
462 | u32 GuardInterval; /* Guard Interval from | ||
463 | SMSHOSTLIB_GUARD_INTERVALS_ET */ | ||
464 | u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */ | ||
465 | u32 LPCodeRate; /* Low Priority Code Rate from | ||
466 | SMSHOSTLIB_CODE_RATE_ET */ | ||
467 | u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */ | ||
468 | u32 Constellation; /* Constellation from | ||
469 | SMSHOSTLIB_CONSTELLATION_ET */ | ||
342 | 470 | ||
471 | /* DVB-H TPS parameters */ | ||
472 | u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; | ||
473 | if set to 0xFFFFFFFF cell_id not yet recovered */ | ||
474 | u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - | ||
475 | Time Slicing indicator, bit 0 - MPE-FEC indicator */ | ||
476 | u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - | ||
477 | Time Slicing indicator, bit 0 - MPE-FEC indicator */ | ||
478 | u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ | ||
343 | }; | 479 | }; |
344 | 480 | ||
481 | struct RECEPTION_STATISTICS_S { | ||
482 | u32 IsRfLocked; /* 0 - not locked, 1 - locked */ | ||
483 | u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ | ||
484 | u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ | ||
485 | |||
486 | u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ | ||
487 | s32 SNR; /* dB */ | ||
488 | u32 BER; /* Post Viterbi BER [1E-5] */ | ||
489 | u32 BERErrorCount; /* Number of erronous SYNC bits. */ | ||
490 | u32 BERBitCount; /* Total number of SYNC bits. */ | ||
491 | u32 TS_PER; /* Transport stream PER, | ||
492 | 0xFFFFFFFF indicate N/A */ | ||
493 | u32 MFER; /* DVB-H frame error rate in percentage, | ||
494 | 0xFFFFFFFF indicate N/A, valid only for DVB-H */ | ||
495 | s32 RSSI; /* dBm */ | ||
496 | s32 InBandPwr; /* In band power in dBM */ | ||
497 | s32 CarrierOffset; /* Carrier Offset in bin/1024 */ | ||
498 | u32 ErrorTSPackets; /* Number of erroneous | ||
499 | transport-stream packets */ | ||
500 | u32 TotalTSPackets; /* Total number of transport-stream packets */ | ||
501 | |||
502 | s32 MRC_SNR; /* dB */ | ||
503 | s32 MRC_RSSI; /* dBm */ | ||
504 | s32 MRC_InBandPwr; /* In band power in dBM */ | ||
505 | }; | ||
345 | 506 | ||
346 | struct smscore_gpio_config { | 507 | |
508 | /* Statistics information returned as response for | ||
509 | * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */ | ||
510 | struct SMSHOSTLIB_STATISTICS_DVB_S { | ||
511 | /* Reception */ | ||
512 | struct RECEPTION_STATISTICS_S ReceptionData; | ||
513 | |||
514 | /* Transmission parameters */ | ||
515 | struct TRANSMISSION_STATISTICS_S TransmissionData; | ||
516 | |||
517 | /* Burst parameters, valid only for DVB-H */ | ||
518 | #define SRVM_MAX_PID_FILTERS 8 | ||
519 | struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS]; | ||
520 | }; | ||
521 | |||
522 | struct SRVM_SIGNAL_STATUS_S { | ||
523 | u32 result; | ||
524 | u32 snr; | ||
525 | u32 tsPackets; | ||
526 | u32 etsPackets; | ||
527 | u32 constellation; | ||
528 | u32 hpCode; | ||
529 | u32 tpsSrvIndLP; | ||
530 | u32 tpsSrvIndHP; | ||
531 | u32 cellId; | ||
532 | u32 reason; | ||
533 | |||
534 | s32 inBandPower; | ||
535 | u32 requestId; | ||
536 | }; | ||
537 | |||
538 | struct SMSHOSTLIB_I2C_REQ_ST { | ||
539 | u32 DeviceAddress; /* I2c device address */ | ||
540 | u32 WriteCount; /* number of bytes to write */ | ||
541 | u32 ReadCount; /* number of bytes to read */ | ||
542 | u8 Data[1]; | ||
543 | }; | ||
544 | |||
545 | struct SMSHOSTLIB_I2C_RES_ST { | ||
546 | u32 Status; /* non-zero value in case of failure */ | ||
547 | u32 ReadCount; /* number of bytes read */ | ||
548 | u8 Data[1]; | ||
549 | }; | ||
550 | |||
551 | |||
552 | struct smscore_config_gpio { | ||
347 | #define SMS_GPIO_DIRECTION_INPUT 0 | 553 | #define SMS_GPIO_DIRECTION_INPUT 0 |
348 | #define SMS_GPIO_DIRECTION_OUTPUT 1 | 554 | #define SMS_GPIO_DIRECTION_OUTPUT 1 |
349 | u8 direction; | 555 | u8 direction; |
@@ -369,6 +575,47 @@ struct smscore_gpio_config { | |||
369 | u8 outputdriving; | 575 | u8 outputdriving; |
370 | }; | 576 | }; |
371 | 577 | ||
578 | struct smscore_gpio_config { | ||
579 | #define SMS_GPIO_DIRECTION_INPUT 0 | ||
580 | #define SMS_GPIO_DIRECTION_OUTPUT 1 | ||
581 | u8 Direction; | ||
582 | |||
583 | #define SMS_GPIO_PULL_UP_DOWN_NONE 0 | ||
584 | #define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1 | ||
585 | #define SMS_GPIO_PULL_UP_DOWN_PULLUP 2 | ||
586 | #define SMS_GPIO_PULL_UP_DOWN_KEEPER 3 | ||
587 | u8 PullUpDown; | ||
588 | |||
589 | #define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0 | ||
590 | #define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1 | ||
591 | u8 InputCharacteristics; | ||
592 | |||
593 | #define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */ | ||
594 | #define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */ | ||
595 | |||
596 | |||
597 | #define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */ | ||
598 | #define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */ | ||
599 | #define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */ | ||
600 | #define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */ | ||
601 | u8 OutputSlewRate; | ||
602 | |||
603 | #define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */ | ||
604 | #define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */ | ||
605 | #define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */ | ||
606 | #define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */ | ||
607 | |||
608 | #define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */ | ||
609 | #define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */ | ||
610 | #define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */ | ||
611 | #define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */ | ||
612 | #define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */ | ||
613 | #define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */ | ||
614 | #define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */ | ||
615 | #define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */ | ||
616 | u8 OutputDriving; | ||
617 | }; | ||
618 | |||
372 | extern void smscore_registry_setmode(char *devpath, int mode); | 619 | extern void smscore_registry_setmode(char *devpath, int mode); |
373 | extern int smscore_registry_getmode(char *devpath); | 620 | extern int smscore_registry_getmode(char *devpath); |
374 | 621 | ||
@@ -410,10 +657,19 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); | |||
410 | extern void smscore_putbuffer(struct smscore_device_t *coredev, | 657 | extern void smscore_putbuffer(struct smscore_device_t *coredev, |
411 | struct smscore_buffer_t *cb); | 658 | struct smscore_buffer_t *cb); |
412 | 659 | ||
660 | /* old GPIO managment */ | ||
413 | int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, | 661 | int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, |
414 | struct smscore_gpio_config *pinconfig); | 662 | struct smscore_config_gpio *pinconfig); |
415 | int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); | 663 | int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); |
416 | 664 | ||
665 | /* new GPIO managment */ | ||
666 | extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, | ||
667 | struct smscore_gpio_config *pGpioConfig); | ||
668 | extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, | ||
669 | u8 NewLevel); | ||
670 | extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, | ||
671 | u8 *level); | ||
672 | |||
417 | void smscore_set_board_id(struct smscore_device_t *core, int id); | 673 | void smscore_set_board_id(struct smscore_device_t *core, int id); |
418 | int smscore_get_board_id(struct smscore_device_t *core); | 674 | int smscore_get_board_id(struct smscore_device_t *core); |
419 | 675 | ||
@@ -442,4 +698,4 @@ int smscore_led_state(struct smscore_device_t *core, int led); | |||
442 | dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg) | 698 | dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg) |
443 | 699 | ||
444 | 700 | ||
445 | #endif /* __smscoreapi_h__ */ | 701 | #endif /* __SMS_CORE_API_H__ */ |
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index ba080b95befb..3ee1c3902c56 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c | |||
@@ -1,28 +1,34 @@ | |||
1 | /* | 1 | /**************************************************************** |
2 | * Driver for the Siano SMS1xxx USB dongle | 2 | |
3 | * | 3 | Siano Mobile Silicon, Inc. |
4 | * Author: Uri Shkolni | 4 | MDTV receiver kernel modules. |
5 | * | 5 | Copyright (C) 2006-2008, Uri Shkolnik |
6 | * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. | 6 | |
7 | * | 7 | This program is free software: you can redistribute it and/or modify |
8 | * This program is free software; you can redistribute it and/or modify | 8 | it under the terms of the GNU General Public License as published by |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | the Free Software Foundation, either version 2 of the License, or |
10 | * published by the Free Software Foundation; | 10 | (at your option) any later version. |
11 | * | 11 | |
12 | * Software distributed under the License is distributed on an "AS IS" | 12 | This program is distributed in the hope that it will be useful, |
13 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * See the GNU General Public License for more details. | 15 | GNU General Public License for more details. |
16 | * | 16 | |
17 | * You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | |
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 | 24 | ||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | |||
25 | #include "smscoreapi.h" | 30 | #include "smscoreapi.h" |
31 | #include "smsendian.h" | ||
26 | #include "sms-cards.h" | 32 | #include "sms-cards.h" |
27 | 33 | ||
28 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 34 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
@@ -39,12 +45,15 @@ struct smsdvb_client_t { | |||
39 | struct dvb_frontend frontend; | 45 | struct dvb_frontend frontend; |
40 | 46 | ||
41 | fe_status_t fe_status; | 47 | fe_status_t fe_status; |
42 | int fe_ber, fe_snr, fe_unc, fe_signal_strength; | ||
43 | 48 | ||
44 | struct completion tune_done, stat_done; | 49 | struct completion tune_done; |
45 | 50 | ||
46 | /* todo: save freq/band instead whole struct */ | 51 | /* todo: save freq/band instead whole struct */ |
47 | struct dvb_frontend_parameters fe_params; | 52 | struct dvb_frontend_parameters fe_params; |
53 | |||
54 | struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb; | ||
55 | int event_fe_state; | ||
56 | int event_unc_state; | ||
48 | }; | 57 | }; |
49 | 58 | ||
50 | static struct list_head g_smsdvb_clients; | 59 | static struct list_head g_smsdvb_clients; |
@@ -54,11 +63,69 @@ static int sms_dbg; | |||
54 | module_param_named(debug, sms_dbg, int, 0644); | 63 | module_param_named(debug, sms_dbg, int, 0644); |
55 | MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); | 64 | MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); |
56 | 65 | ||
66 | /* Events that may come from DVB v3 adapter */ | ||
67 | static void sms_board_dvb3_event(struct smsdvb_client_t *client, | ||
68 | enum SMS_DVB3_EVENTS event) { | ||
69 | |||
70 | struct smscore_device_t *coredev = client->coredev; | ||
71 | switch (event) { | ||
72 | case DVB3_EVENT_INIT: | ||
73 | sms_debug("DVB3_EVENT_INIT"); | ||
74 | sms_board_event(coredev, BOARD_EVENT_BIND); | ||
75 | break; | ||
76 | case DVB3_EVENT_SLEEP: | ||
77 | sms_debug("DVB3_EVENT_SLEEP"); | ||
78 | sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND); | ||
79 | break; | ||
80 | case DVB3_EVENT_HOTPLUG: | ||
81 | sms_debug("DVB3_EVENT_HOTPLUG"); | ||
82 | sms_board_event(coredev, BOARD_EVENT_POWER_INIT); | ||
83 | break; | ||
84 | case DVB3_EVENT_FE_LOCK: | ||
85 | if (client->event_fe_state != DVB3_EVENT_FE_LOCK) { | ||
86 | client->event_fe_state = DVB3_EVENT_FE_LOCK; | ||
87 | sms_debug("DVB3_EVENT_FE_LOCK"); | ||
88 | sms_board_event(coredev, BOARD_EVENT_FE_LOCK); | ||
89 | } | ||
90 | break; | ||
91 | case DVB3_EVENT_FE_UNLOCK: | ||
92 | if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) { | ||
93 | client->event_fe_state = DVB3_EVENT_FE_UNLOCK; | ||
94 | sms_debug("DVB3_EVENT_FE_UNLOCK"); | ||
95 | sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); | ||
96 | } | ||
97 | break; | ||
98 | case DVB3_EVENT_UNC_OK: | ||
99 | if (client->event_unc_state != DVB3_EVENT_UNC_OK) { | ||
100 | client->event_unc_state = DVB3_EVENT_UNC_OK; | ||
101 | sms_debug("DVB3_EVENT_UNC_OK"); | ||
102 | sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); | ||
103 | } | ||
104 | break; | ||
105 | case DVB3_EVENT_UNC_ERR: | ||
106 | if (client->event_unc_state != DVB3_EVENT_UNC_ERR) { | ||
107 | client->event_unc_state = DVB3_EVENT_UNC_ERR; | ||
108 | sms_debug("DVB3_EVENT_UNC_ERR"); | ||
109 | sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS); | ||
110 | } | ||
111 | break; | ||
112 | |||
113 | default: | ||
114 | sms_err("Unknown dvb3 api event"); | ||
115 | break; | ||
116 | } | ||
117 | } | ||
118 | |||
57 | static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) | 119 | static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) |
58 | { | 120 | { |
59 | struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; | 121 | struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; |
60 | struct SmsMsgHdr_ST *phdr = | 122 | struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p) |
61 | (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); | 123 | + cb->offset); |
124 | u32 *pMsgData = (u32 *) phdr + 1; | ||
125 | /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/ | ||
126 | bool is_status_update = false; | ||
127 | |||
128 | smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr); | ||
62 | 129 | ||
63 | switch (phdr->msgType) { | 130 | switch (phdr->msgType) { |
64 | case MSG_SMS_DVBT_BDA_DATA: | 131 | case MSG_SMS_DVBT_BDA_DATA: |
@@ -70,43 +137,110 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) | |||
70 | complete(&client->tune_done); | 137 | complete(&client->tune_done); |
71 | break; | 138 | break; |
72 | 139 | ||
73 | case MSG_SMS_GET_STATISTICS_RES: | 140 | case MSG_SMS_SIGNAL_DETECTED_IND: |
74 | { | 141 | sms_info("MSG_SMS_SIGNAL_DETECTED_IND"); |
75 | struct SmsMsgStatisticsInfo_ST *p = | 142 | client->sms_stat_dvb.TransmissionData.IsDemodLocked = true; |
76 | (struct SmsMsgStatisticsInfo_ST *)(phdr + 1); | 143 | is_status_update = true; |
77 | 144 | break; | |
78 | if (p->Stat.IsDemodLocked) { | 145 | |
79 | client->fe_status = FE_HAS_SIGNAL | | 146 | case MSG_SMS_NO_SIGNAL_IND: |
80 | FE_HAS_CARRIER | | 147 | sms_info("MSG_SMS_NO_SIGNAL_IND"); |
81 | FE_HAS_VITERBI | | 148 | client->sms_stat_dvb.TransmissionData.IsDemodLocked = false; |
82 | FE_HAS_SYNC | | 149 | is_status_update = true; |
83 | FE_HAS_LOCK; | 150 | break; |
84 | 151 | ||
85 | client->fe_snr = p->Stat.SNR; | 152 | case MSG_SMS_TRANSMISSION_IND: { |
86 | client->fe_ber = p->Stat.BER; | 153 | sms_info("MSG_SMS_TRANSMISSION_IND"); |
87 | client->fe_unc = p->Stat.BERErrorCount; | 154 | |
88 | 155 | pMsgData++; | |
89 | if (p->Stat.InBandPwr < -95) | 156 | memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData, |
90 | client->fe_signal_strength = 0; | 157 | sizeof(struct TRANSMISSION_STATISTICS_S)); |
91 | else if (p->Stat.InBandPwr > -29) | 158 | |
92 | client->fe_signal_strength = 100; | 159 | /* Mo need to correct guard interval |
93 | else | 160 | * (as opposed to old statistics message). |
94 | client->fe_signal_strength = | 161 | */ |
95 | (p->Stat.InBandPwr + 95) * 3 / 2; | 162 | CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData); |
163 | CORRECT_STAT_TRANSMISSON_MODE( | ||
164 | client->sms_stat_dvb.TransmissionData); | ||
165 | is_status_update = true; | ||
166 | break; | ||
167 | } | ||
168 | case MSG_SMS_HO_PER_SLICES_IND: { | ||
169 | struct RECEPTION_STATISTICS_S *pReceptionData = | ||
170 | &client->sms_stat_dvb.ReceptionData; | ||
171 | struct SRVM_SIGNAL_STATUS_S SignalStatusData; | ||
172 | |||
173 | /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/ | ||
174 | pMsgData++; | ||
175 | SignalStatusData.result = pMsgData[0]; | ||
176 | SignalStatusData.snr = pMsgData[1]; | ||
177 | SignalStatusData.inBandPower = (s32) pMsgData[2]; | ||
178 | SignalStatusData.tsPackets = pMsgData[3]; | ||
179 | SignalStatusData.etsPackets = pMsgData[4]; | ||
180 | SignalStatusData.constellation = pMsgData[5]; | ||
181 | SignalStatusData.hpCode = pMsgData[6]; | ||
182 | SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03; | ||
183 | SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03; | ||
184 | SignalStatusData.cellId = pMsgData[9] & 0xFFFF; | ||
185 | SignalStatusData.reason = pMsgData[10]; | ||
186 | SignalStatusData.requestId = pMsgData[11]; | ||
187 | pReceptionData->IsRfLocked = pMsgData[16]; | ||
188 | pReceptionData->IsDemodLocked = pMsgData[17]; | ||
189 | pReceptionData->ModemState = pMsgData[12]; | ||
190 | pReceptionData->SNR = pMsgData[1]; | ||
191 | pReceptionData->BER = pMsgData[13]; | ||
192 | pReceptionData->RSSI = pMsgData[14]; | ||
193 | CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData); | ||
194 | |||
195 | pReceptionData->InBandPwr = (s32) pMsgData[2]; | ||
196 | pReceptionData->CarrierOffset = (s32) pMsgData[15]; | ||
197 | pReceptionData->TotalTSPackets = pMsgData[3]; | ||
198 | pReceptionData->ErrorTSPackets = pMsgData[4]; | ||
199 | |||
200 | /* TS PER */ | ||
201 | if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets) | ||
202 | > 0) { | ||
203 | pReceptionData->TS_PER = (SignalStatusData.etsPackets | ||
204 | * 100) / (SignalStatusData.tsPackets | ||
205 | + SignalStatusData.etsPackets); | ||
96 | } else { | 206 | } else { |
97 | client->fe_status = 0; | 207 | pReceptionData->TS_PER = 0; |
98 | client->fe_snr = | ||
99 | client->fe_ber = | ||
100 | client->fe_unc = | ||
101 | client->fe_signal_strength = 0; | ||
102 | } | 208 | } |
103 | 209 | ||
104 | complete(&client->stat_done); | 210 | pReceptionData->BERBitCount = pMsgData[18]; |
105 | break; | 211 | pReceptionData->BERErrorCount = pMsgData[19]; |
106 | } } | ||
107 | 212 | ||
213 | pReceptionData->MRC_SNR = pMsgData[20]; | ||
214 | pReceptionData->MRC_InBandPwr = pMsgData[21]; | ||
215 | pReceptionData->MRC_RSSI = pMsgData[22]; | ||
216 | |||
217 | is_status_update = true; | ||
218 | break; | ||
219 | } | ||
220 | } | ||
108 | smscore_putbuffer(client->coredev, cb); | 221 | smscore_putbuffer(client->coredev, cb); |
109 | 222 | ||
223 | if (is_status_update) { | ||
224 | if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) { | ||
225 | client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | ||
226 | | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
227 | sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); | ||
228 | if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets | ||
229 | == 0) | ||
230 | sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); | ||
231 | else | ||
232 | sms_board_dvb3_event(client, | ||
233 | DVB3_EVENT_UNC_ERR); | ||
234 | |||
235 | } else { | ||
236 | /*client->fe_status = | ||
237 | (phdr->msgType == MSG_SMS_NO_SIGNAL_IND) ? | ||
238 | 0 : FE_HAS_SIGNAL;*/ | ||
239 | client->fe_status = 0; | ||
240 | sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); | ||
241 | } | ||
242 | } | ||
243 | |||
110 | return 0; | 244 | return 0; |
111 | } | 245 | } |
112 | 246 | ||
@@ -149,6 +283,7 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) | |||
149 | PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); | 283 | PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); |
150 | PidMsg.msgData[0] = feed->pid; | 284 | PidMsg.msgData[0] = feed->pid; |
151 | 285 | ||
286 | smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg); | ||
152 | return smsclient_sendrequest(client->smsclient, | 287 | return smsclient_sendrequest(client->smsclient, |
153 | &PidMsg, sizeof(PidMsg)); | 288 | &PidMsg, sizeof(PidMsg)); |
154 | } | 289 | } |
@@ -169,6 +304,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) | |||
169 | PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); | 304 | PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); |
170 | PidMsg.msgData[0] = feed->pid; | 305 | PidMsg.msgData[0] = feed->pid; |
171 | 306 | ||
307 | smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg); | ||
172 | return smsclient_sendrequest(client->smsclient, | 308 | return smsclient_sendrequest(client->smsclient, |
173 | &PidMsg, sizeof(PidMsg)); | 309 | &PidMsg, sizeof(PidMsg)); |
174 | } | 310 | } |
@@ -177,7 +313,10 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, | |||
177 | void *buffer, size_t size, | 313 | void *buffer, size_t size, |
178 | struct completion *completion) | 314 | struct completion *completion) |
179 | { | 315 | { |
180 | int rc = smsclient_sendrequest(client->smsclient, buffer, size); | 316 | int rc; |
317 | |||
318 | smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer); | ||
319 | rc = smsclient_sendrequest(client->smsclient, buffer, size); | ||
181 | if (rc < 0) | 320 | if (rc < 0) |
182 | return rc; | 321 | return rc; |
183 | 322 | ||
@@ -186,83 +325,61 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, | |||
186 | 0 : -ETIME; | 325 | 0 : -ETIME; |
187 | } | 326 | } |
188 | 327 | ||
189 | static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) | ||
190 | { | ||
191 | struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, | ||
192 | DVBT_BDA_CONTROL_MSG_ID, | ||
193 | HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 }; | ||
194 | int ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), | ||
195 | &client->stat_done); | ||
196 | if (ret < 0) | ||
197 | return ret; | ||
198 | |||
199 | if (client->fe_status & FE_HAS_LOCK) | ||
200 | sms_board_led_feedback(client->coredev, | ||
201 | (client->fe_unc == 0) ? | ||
202 | SMS_LED_HI : SMS_LED_LO); | ||
203 | else | ||
204 | sms_board_led_feedback(client->coredev, SMS_LED_OFF); | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) | 328 | static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) |
209 | { | 329 | { |
210 | struct smsdvb_client_t *client = | 330 | struct smsdvb_client_t *client; |
211 | container_of(fe, struct smsdvb_client_t, frontend); | 331 | client = container_of(fe, struct smsdvb_client_t, frontend); |
212 | int rc = smsdvb_send_statistics_request(client); | ||
213 | 332 | ||
214 | if (!rc) | 333 | *stat = client->fe_status; |
215 | *stat = client->fe_status; | ||
216 | 334 | ||
217 | return rc; | 335 | return 0; |
218 | } | 336 | } |
219 | 337 | ||
220 | static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) | 338 | static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) |
221 | { | 339 | { |
222 | struct smsdvb_client_t *client = | 340 | struct smsdvb_client_t *client; |
223 | container_of(fe, struct smsdvb_client_t, frontend); | 341 | client = container_of(fe, struct smsdvb_client_t, frontend); |
224 | int rc = smsdvb_send_statistics_request(client); | ||
225 | 342 | ||
226 | if (!rc) | 343 | *ber = client->sms_stat_dvb.ReceptionData.BER; |
227 | *ber = client->fe_ber; | ||
228 | 344 | ||
229 | return rc; | 345 | return 0; |
230 | } | 346 | } |
231 | 347 | ||
232 | static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | 348 | static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) |
233 | { | 349 | { |
234 | struct smsdvb_client_t *client = | 350 | struct smsdvb_client_t *client; |
235 | container_of(fe, struct smsdvb_client_t, frontend); | 351 | client = container_of(fe, struct smsdvb_client_t, frontend); |
236 | int rc = smsdvb_send_statistics_request(client); | ||
237 | 352 | ||
238 | if (!rc) | 353 | if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95) |
239 | *strength = client->fe_signal_strength; | 354 | *strength = 0; |
355 | else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29) | ||
356 | *strength = 100; | ||
357 | else | ||
358 | *strength = | ||
359 | (client->sms_stat_dvb.ReceptionData.InBandPwr | ||
360 | + 95) * 3 / 2; | ||
240 | 361 | ||
241 | return rc; | 362 | return 0; |
242 | } | 363 | } |
243 | 364 | ||
244 | static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) | 365 | static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) |
245 | { | 366 | { |
246 | struct smsdvb_client_t *client = | 367 | struct smsdvb_client_t *client; |
247 | container_of(fe, struct smsdvb_client_t, frontend); | 368 | client = container_of(fe, struct smsdvb_client_t, frontend); |
248 | int rc = smsdvb_send_statistics_request(client); | ||
249 | 369 | ||
250 | if (!rc) | 370 | *snr = client->sms_stat_dvb.ReceptionData.SNR; |
251 | *snr = client->fe_snr; | ||
252 | 371 | ||
253 | return rc; | 372 | return 0; |
254 | } | 373 | } |
255 | 374 | ||
256 | static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 375 | static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
257 | { | 376 | { |
258 | struct smsdvb_client_t *client = | 377 | struct smsdvb_client_t *client; |
259 | container_of(fe, struct smsdvb_client_t, frontend); | 378 | client = container_of(fe, struct smsdvb_client_t, frontend); |
260 | int rc = smsdvb_send_statistics_request(client); | ||
261 | 379 | ||
262 | if (!rc) | 380 | *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets; |
263 | *ucblocks = client->fe_unc; | ||
264 | 381 | ||
265 | return rc; | 382 | return 0; |
266 | } | 383 | } |
267 | 384 | ||
268 | static int smsdvb_get_tune_settings(struct dvb_frontend *fe, | 385 | static int smsdvb_get_tune_settings(struct dvb_frontend *fe, |
@@ -286,12 +403,15 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, | |||
286 | struct SmsMsgHdr_ST Msg; | 403 | struct SmsMsgHdr_ST Msg; |
287 | u32 Data[3]; | 404 | u32 Data[3]; |
288 | } Msg; | 405 | } Msg; |
289 | int ret; | ||
290 | 406 | ||
291 | Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; | 407 | client->fe_status = FE_HAS_SIGNAL; |
292 | Msg.Msg.msgDstId = HIF_TASK; | 408 | client->event_fe_state = -1; |
293 | Msg.Msg.msgFlags = 0; | 409 | client->event_unc_state = -1; |
294 | Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; | 410 | |
411 | Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; | ||
412 | Msg.Msg.msgDstId = HIF_TASK; | ||
413 | Msg.Msg.msgFlags = 0; | ||
414 | Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; | ||
295 | Msg.Msg.msgLength = sizeof(Msg); | 415 | Msg.Msg.msgLength = sizeof(Msg); |
296 | Msg.Data[0] = fep->frequency; | 416 | Msg.Data[0] = fep->frequency; |
297 | Msg.Data[2] = 12000000; | 417 | Msg.Data[2] = 12000000; |
@@ -307,24 +427,6 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, | |||
307 | default: return -EINVAL; | 427 | default: return -EINVAL; |
308 | } | 428 | } |
309 | 429 | ||
310 | /* Disable LNA, if any. An error is returned if no LNA is present */ | ||
311 | ret = sms_board_lna_control(client->coredev, 0); | ||
312 | if (ret == 0) { | ||
313 | fe_status_t status; | ||
314 | |||
315 | /* tune with LNA off at first */ | ||
316 | ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), | ||
317 | &client->tune_done); | ||
318 | |||
319 | smsdvb_read_status(fe, &status); | ||
320 | |||
321 | if (status & FE_HAS_LOCK) | ||
322 | return ret; | ||
323 | |||
324 | /* previous tune didnt lock - enable LNA and tune again */ | ||
325 | sms_board_lna_control(client->coredev, 1); | ||
326 | } | ||
327 | |||
328 | return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), | 430 | return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), |
329 | &client->tune_done); | 431 | &client->tune_done); |
330 | } | 432 | } |
@@ -349,8 +451,7 @@ static int smsdvb_init(struct dvb_frontend *fe) | |||
349 | struct smsdvb_client_t *client = | 451 | struct smsdvb_client_t *client = |
350 | container_of(fe, struct smsdvb_client_t, frontend); | 452 | container_of(fe, struct smsdvb_client_t, frontend); |
351 | 453 | ||
352 | sms_board_power(client->coredev, 1); | 454 | sms_board_dvb3_event(client, DVB3_EVENT_INIT); |
353 | |||
354 | return 0; | 455 | return 0; |
355 | } | 456 | } |
356 | 457 | ||
@@ -359,8 +460,7 @@ static int smsdvb_sleep(struct dvb_frontend *fe) | |||
359 | struct smsdvb_client_t *client = | 460 | struct smsdvb_client_t *client = |
360 | container_of(fe, struct smsdvb_client_t, frontend); | 461 | container_of(fe, struct smsdvb_client_t, frontend); |
361 | 462 | ||
362 | sms_board_led_feedback(client->coredev, SMS_LED_OFF); | 463 | sms_board_dvb3_event(client, DVB3_EVENT_SLEEP); |
363 | sms_board_power(client->coredev, 0); | ||
364 | 464 | ||
365 | return 0; | 465 | return 0; |
366 | } | 466 | } |
@@ -485,7 +585,6 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
485 | client->coredev = coredev; | 585 | client->coredev = coredev; |
486 | 586 | ||
487 | init_completion(&client->tune_done); | 587 | init_completion(&client->tune_done); |
488 | init_completion(&client->stat_done); | ||
489 | 588 | ||
490 | kmutex_lock(&g_smsdvb_clientslock); | 589 | kmutex_lock(&g_smsdvb_clientslock); |
491 | 590 | ||
@@ -493,8 +592,11 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
493 | 592 | ||
494 | kmutex_unlock(&g_smsdvb_clientslock); | 593 | kmutex_unlock(&g_smsdvb_clientslock); |
495 | 594 | ||
496 | sms_info("success"); | 595 | client->event_fe_state = -1; |
596 | client->event_unc_state = -1; | ||
597 | sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); | ||
497 | 598 | ||
599 | sms_info("success"); | ||
498 | sms_board_setup(coredev); | 600 | sms_board_setup(coredev); |
499 | 601 | ||
500 | return 0; | 602 | return 0; |
@@ -547,5 +649,5 @@ module_init(smsdvb_module_init); | |||
547 | module_exit(smsdvb_module_exit); | 649 | module_exit(smsdvb_module_exit); |
548 | 650 | ||
549 | MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); | 651 | MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); |
550 | MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); | 652 | MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); |
551 | MODULE_LICENSE("GPL"); | 653 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/siano/smsendian.c b/drivers/media/dvb/siano/smsendian.c new file mode 100644 index 000000000000..457b6d02ef85 --- /dev/null +++ b/drivers/media/dvb/siano/smsendian.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /**************************************************************** | ||
2 | |||
3 | Siano Mobile Silicon, Inc. | ||
4 | MDTV receiver kernel modules. | ||
5 | Copyright (C) 2006-2009, Uri Shkolnik | ||
6 | |||
7 | This program is free software: you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation, either version 2 of the License, or | ||
10 | (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 General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | |||
20 | ****************************************************************/ | ||
21 | |||
22 | #include <asm/byteorder.h> | ||
23 | |||
24 | #include "smsendian.h" | ||
25 | #include "smscoreapi.h" | ||
26 | |||
27 | void smsendian_handle_tx_message(void *buffer) | ||
28 | { | ||
29 | #ifdef __BIG_ENDIAN | ||
30 | struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer; | ||
31 | int i; | ||
32 | int msgWords; | ||
33 | |||
34 | switch (msg->xMsgHeader.msgType) { | ||
35 | case MSG_SMS_DATA_DOWNLOAD_REQ: | ||
36 | { | ||
37 | msg->msgData[0] = le32_to_cpu(msg->msgData[0]); | ||
38 | break; | ||
39 | } | ||
40 | |||
41 | default: | ||
42 | msgWords = (msg->xMsgHeader.msgLength - | ||
43 | sizeof(struct SmsMsgHdr_ST))/4; | ||
44 | |||
45 | for (i = 0; i < msgWords; i++) | ||
46 | msg->msgData[i] = le32_to_cpu(msg->msgData[i]); | ||
47 | |||
48 | break; | ||
49 | } | ||
50 | #endif /* __BIG_ENDIAN */ | ||
51 | } | ||
52 | EXPORT_SYMBOL_GPL(smsendian_handle_tx_message); | ||
53 | |||
54 | void smsendian_handle_rx_message(void *buffer) | ||
55 | { | ||
56 | #ifdef __BIG_ENDIAN | ||
57 | struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer; | ||
58 | int i; | ||
59 | int msgWords; | ||
60 | |||
61 | switch (msg->xMsgHeader.msgType) { | ||
62 | case MSG_SMS_GET_VERSION_EX_RES: | ||
63 | { | ||
64 | struct SmsVersionRes_ST *ver = | ||
65 | (struct SmsVersionRes_ST *) msg; | ||
66 | ver->ChipModel = le16_to_cpu(ver->ChipModel); | ||
67 | break; | ||
68 | } | ||
69 | |||
70 | case MSG_SMS_DVBT_BDA_DATA: | ||
71 | case MSG_SMS_DAB_CHANNEL: | ||
72 | case MSG_SMS_DATA_MSG: | ||
73 | { | ||
74 | break; | ||
75 | } | ||
76 | |||
77 | default: | ||
78 | { | ||
79 | msgWords = (msg->xMsgHeader.msgLength - | ||
80 | sizeof(struct SmsMsgHdr_ST))/4; | ||
81 | |||
82 | for (i = 0; i < msgWords; i++) | ||
83 | msg->msgData[i] = le32_to_cpu(msg->msgData[i]); | ||
84 | |||
85 | break; | ||
86 | } | ||
87 | } | ||
88 | #endif /* __BIG_ENDIAN */ | ||
89 | } | ||
90 | EXPORT_SYMBOL_GPL(smsendian_handle_rx_message); | ||
91 | |||
92 | void smsendian_handle_message_header(void *msg) | ||
93 | { | ||
94 | #ifdef __BIG_ENDIAN | ||
95 | struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg; | ||
96 | |||
97 | phdr->msgType = le16_to_cpu(phdr->msgType); | ||
98 | phdr->msgLength = le16_to_cpu(phdr->msgLength); | ||
99 | phdr->msgFlags = le16_to_cpu(phdr->msgFlags); | ||
100 | #endif /* __BIG_ENDIAN */ | ||
101 | } | ||
102 | EXPORT_SYMBOL_GPL(smsendian_handle_message_header); | ||
diff --git a/drivers/media/dvb/siano/smsendian.h b/drivers/media/dvb/siano/smsendian.h new file mode 100644 index 000000000000..1624d6fd367b --- /dev/null +++ b/drivers/media/dvb/siano/smsendian.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /**************************************************************** | ||
2 | |||
3 | Siano Mobile Silicon, Inc. | ||
4 | MDTV receiver kernel modules. | ||
5 | Copyright (C) 2006-2009, Uri Shkolnik | ||
6 | |||
7 | This program is free software: you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation, either version 2 of the License, or | ||
10 | (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 General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | |||
20 | ****************************************************************/ | ||
21 | |||
22 | #ifndef __SMS_ENDIAN_H__ | ||
23 | #define __SMS_ENDIAN_H__ | ||
24 | |||
25 | #include <asm/byteorder.h> | ||
26 | |||
27 | extern void smsendian_handle_tx_message(void *buffer); | ||
28 | extern void smsendian_handle_rx_message(void *buffer); | ||
29 | extern void smsendian_handle_message_header(void *msg); | ||
30 | |||
31 | #endif /* __SMS_ENDIAN_H__ */ | ||
32 | |||
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c new file mode 100644 index 000000000000..e3d776feeaca --- /dev/null +++ b/drivers/media/dvb/siano/smsir.c | |||
@@ -0,0 +1,301 @@ | |||
1 | /**************************************************************** | ||
2 | |||
3 | Siano Mobile Silicon, Inc. | ||
4 | MDTV receiver kernel modules. | ||
5 | Copyright (C) 2006-2009, Uri Shkolnik | ||
6 | |||
7 | This program is free software: you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation, either version 2 of the License, or | ||
10 | (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 General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | |||
20 | ****************************************************************/ | ||
21 | |||
22 | |||
23 | #include <linux/types.h> | ||
24 | #include <linux/input.h> | ||
25 | |||
26 | #include "smscoreapi.h" | ||
27 | #include "smsir.h" | ||
28 | #include "sms-cards.h" | ||
29 | |||
30 | /* In order to add new IR remote control - | ||
31 | * 1) Add it to the <enum ir_kb_type> @ smsir,h, | ||
32 | * 2) Add its map to keyboard_layout_maps below | ||
33 | * 3) Set your board (sms-cards sub-module) to use it | ||
34 | */ | ||
35 | |||
36 | static struct keyboard_layout_map_t keyboard_layout_maps[] = { | ||
37 | [SMS_IR_KB_DEFAULT_TV] = { | ||
38 | .ir_protocol = IR_RC5, | ||
39 | .rc5_kbd_address = KEYBOARD_ADDRESS_TV1, | ||
40 | .keyboard_layout_map = { | ||
41 | KEY_0, KEY_1, KEY_2, | ||
42 | KEY_3, KEY_4, KEY_5, | ||
43 | KEY_6, KEY_7, KEY_8, | ||
44 | KEY_9, 0, 0, KEY_POWER, | ||
45 | KEY_MUTE, 0, 0, | ||
46 | KEY_VOLUMEUP, KEY_VOLUMEDOWN, | ||
47 | KEY_BRIGHTNESSUP, | ||
48 | KEY_BRIGHTNESSDOWN, KEY_CHANNELUP, | ||
49 | KEY_CHANNELDOWN, | ||
50 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
51 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
52 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
53 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
54 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
55 | } | ||
56 | }, | ||
57 | [SMS_IR_KB_HCW_SILVER] = { | ||
58 | .ir_protocol = IR_RC5, | ||
59 | .rc5_kbd_address = KEYBOARD_ADDRESS_LIGHTING1, | ||
60 | .keyboard_layout_map = { | ||
61 | KEY_0, KEY_1, KEY_2, | ||
62 | KEY_3, KEY_4, KEY_5, | ||
63 | KEY_6, KEY_7, KEY_8, | ||
64 | KEY_9, KEY_TEXT, KEY_RED, | ||
65 | KEY_RADIO, KEY_MENU, | ||
66 | KEY_SUBTITLE, | ||
67 | KEY_MUTE, KEY_VOLUMEUP, | ||
68 | KEY_VOLUMEDOWN, KEY_PREVIOUS, 0, | ||
69 | KEY_UP, KEY_DOWN, KEY_LEFT, | ||
70 | KEY_RIGHT, KEY_VIDEO, KEY_AUDIO, | ||
71 | KEY_MHP, KEY_EPG, KEY_TV, | ||
72 | 0, KEY_NEXTSONG, KEY_EXIT, | ||
73 | KEY_CHANNELUP, KEY_CHANNELDOWN, | ||
74 | KEY_CHANNEL, 0, | ||
75 | KEY_PREVIOUSSONG, KEY_ENTER, | ||
76 | KEY_SLEEP, 0, 0, KEY_BLUE, | ||
77 | 0, 0, 0, 0, KEY_GREEN, 0, | ||
78 | KEY_PAUSE, 0, KEY_REWIND, | ||
79 | 0, KEY_FASTFORWARD, KEY_PLAY, | ||
80 | KEY_STOP, KEY_RECORD, | ||
81 | KEY_YELLOW, 0, 0, KEY_SELECT, | ||
82 | KEY_ZOOM, KEY_POWER, 0, 0 | ||
83 | } | ||
84 | }, | ||
85 | { } /* Terminating entry */ | ||
86 | }; | ||
87 | |||
88 | u32 ir_pos; | ||
89 | u32 ir_word; | ||
90 | u32 ir_toggle; | ||
91 | |||
92 | #define RC5_PUSH_BIT(dst, bit, pos) \ | ||
93 | { dst <<= 1; dst |= bit; pos++; } | ||
94 | |||
95 | |||
96 | static void sms_ir_rc5_event(struct smscore_device_t *coredev, | ||
97 | u32 toggle, u32 addr, u32 cmd) | ||
98 | { | ||
99 | bool toggle_changed; | ||
100 | u16 keycode; | ||
101 | |||
102 | sms_log("IR RC5 word: address %d, command %d, toggle %d", | ||
103 | addr, cmd, toggle); | ||
104 | |||
105 | toggle_changed = ir_toggle != toggle; | ||
106 | /* keep toggle */ | ||
107 | ir_toggle = toggle; | ||
108 | |||
109 | if (addr != | ||
110 | keyboard_layout_maps[coredev->ir.ir_kb_type].rc5_kbd_address) | ||
111 | return; /* Check for valid address */ | ||
112 | |||
113 | keycode = | ||
114 | keyboard_layout_maps | ||
115 | [coredev->ir.ir_kb_type].keyboard_layout_map[cmd]; | ||
116 | |||
117 | if (!toggle_changed && | ||
118 | (keycode != KEY_VOLUMEUP && keycode != KEY_VOLUMEDOWN)) | ||
119 | return; /* accept only repeated volume, reject other keys */ | ||
120 | |||
121 | sms_log("kernel input keycode (from ir) %d", keycode); | ||
122 | input_report_key(coredev->ir.input_dev, keycode, 1); | ||
123 | input_sync(coredev->ir.input_dev); | ||
124 | |||
125 | } | ||
126 | |||
127 | /* decode raw bit pattern to RC5 code */ | ||
128 | /* taken from ir-functions.c */ | ||
129 | static u32 ir_rc5_decode(unsigned int code) | ||
130 | { | ||
131 | /* unsigned int org_code = code;*/ | ||
132 | unsigned int pair; | ||
133 | unsigned int rc5 = 0; | ||
134 | int i; | ||
135 | |||
136 | for (i = 0; i < 14; ++i) { | ||
137 | pair = code & 0x3; | ||
138 | code >>= 2; | ||
139 | |||
140 | rc5 <<= 1; | ||
141 | switch (pair) { | ||
142 | case 0: | ||
143 | case 2: | ||
144 | break; | ||
145 | case 1: | ||
146 | rc5 |= 1; | ||
147 | break; | ||
148 | case 3: | ||
149 | /* dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);*/ | ||
150 | sms_log("bad code"); | ||
151 | return 0; | ||
152 | } | ||
153 | } | ||
154 | /* | ||
155 | dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, | ||
156 | toggle=%x, address=%x, " | ||
157 | "instr=%x\n", rc5, org_code, RC5_START(rc5), | ||
158 | RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); | ||
159 | */ | ||
160 | return rc5; | ||
161 | } | ||
162 | |||
163 | static void sms_rc5_parse_word(struct smscore_device_t *coredev) | ||
164 | { | ||
165 | #define RC5_START(x) (((x)>>12)&3) | ||
166 | #define RC5_TOGGLE(x) (((x)>>11)&1) | ||
167 | #define RC5_ADDR(x) (((x)>>6)&0x1F) | ||
168 | #define RC5_INSTR(x) ((x)&0x3F) | ||
169 | |||
170 | int i, j; | ||
171 | u32 rc5_word = 0; | ||
172 | |||
173 | /* Reverse the IR word direction */ | ||
174 | for (i = 0 ; i < 28 ; i++) | ||
175 | RC5_PUSH_BIT(rc5_word, (ir_word>>i)&1, j) | ||
176 | |||
177 | rc5_word = ir_rc5_decode(rc5_word); | ||
178 | /* sms_log("temp = 0x%x, rc5_code = 0x%x", ir_word, rc5_word); */ | ||
179 | |||
180 | sms_ir_rc5_event(coredev, | ||
181 | RC5_TOGGLE(rc5_word), | ||
182 | RC5_ADDR(rc5_word), | ||
183 | RC5_INSTR(rc5_word)); | ||
184 | } | ||
185 | |||
186 | |||
187 | static void sms_rc5_accumulate_bits(struct smscore_device_t *coredev, | ||
188 | s32 ir_sample) | ||
189 | { | ||
190 | #define RC5_TIME_GRANULARITY 200 | ||
191 | #define RC5_DEF_BIT_TIME 889 | ||
192 | #define RC5_MAX_SAME_BIT_CONT 4 | ||
193 | #define RC5_WORD_LEN 27 /* 28 bit */ | ||
194 | |||
195 | u32 i, j; | ||
196 | s32 delta_time; | ||
197 | u32 time = (ir_sample > 0) ? ir_sample : (0-ir_sample); | ||
198 | u32 level = (ir_sample < 0) ? 0 : 1; | ||
199 | |||
200 | for (i = RC5_MAX_SAME_BIT_CONT; i > 0; i--) { | ||
201 | delta_time = time - (i*RC5_DEF_BIT_TIME) + RC5_TIME_GRANULARITY; | ||
202 | if (delta_time < 0) | ||
203 | continue; /* not so many consecutive bits */ | ||
204 | if (delta_time > (2 * RC5_TIME_GRANULARITY)) { | ||
205 | /* timeout */ | ||
206 | if (ir_pos == (RC5_WORD_LEN-1)) | ||
207 | /* complete last bit */ | ||
208 | RC5_PUSH_BIT(ir_word, level, ir_pos) | ||
209 | |||
210 | if (ir_pos == RC5_WORD_LEN) | ||
211 | sms_rc5_parse_word(coredev); | ||
212 | else if (ir_pos) /* timeout within a word */ | ||
213 | sms_log("IR error parsing a word"); | ||
214 | |||
215 | ir_pos = 0; | ||
216 | ir_word = 0; | ||
217 | /* sms_log("timeout %d", time); */ | ||
218 | break; | ||
219 | } | ||
220 | /* The time is within the range of this number of bits */ | ||
221 | for (j = 0 ; j < i ; j++) | ||
222 | RC5_PUSH_BIT(ir_word, level, ir_pos) | ||
223 | |||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) | ||
229 | { | ||
230 | #define IR_DATA_RECEIVE_MAX_LEN 520 /* 128*4 + 4 + 4 */ | ||
231 | u32 i; | ||
232 | enum ir_protocol ir_protocol = | ||
233 | keyboard_layout_maps[coredev->ir.ir_kb_type] | ||
234 | .ir_protocol; | ||
235 | s32 *samples; | ||
236 | int count = len>>2; | ||
237 | |||
238 | samples = (s32 *)buf; | ||
239 | /* sms_log("IR buffer received, length = %d", count);*/ | ||
240 | |||
241 | for (i = 0; i < count; i++) | ||
242 | if (ir_protocol == IR_RC5) | ||
243 | sms_rc5_accumulate_bits(coredev, samples[i]); | ||
244 | /* IR_RCMM not implemented */ | ||
245 | } | ||
246 | |||
247 | int sms_ir_init(struct smscore_device_t *coredev) | ||
248 | { | ||
249 | struct input_dev *input_dev; | ||
250 | |||
251 | sms_log("Allocating input device"); | ||
252 | input_dev = input_allocate_device(); | ||
253 | if (!input_dev) { | ||
254 | sms_err("Not enough memory"); | ||
255 | return -ENOMEM; | ||
256 | } | ||
257 | |||
258 | coredev->ir.input_dev = input_dev; | ||
259 | coredev->ir.ir_kb_type = | ||
260 | sms_get_board(smscore_get_board_id(coredev))->ir_kb_type; | ||
261 | coredev->ir.keyboard_layout_map = | ||
262 | keyboard_layout_maps[coredev->ir.ir_kb_type]. | ||
263 | keyboard_layout_map; | ||
264 | sms_log("IR remote keyboard type is %d", coredev->ir.ir_kb_type); | ||
265 | |||
266 | coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ | ||
267 | coredev->ir.timeout = IR_DEFAULT_TIMEOUT; | ||
268 | sms_log("IR port %d, timeout %d ms", | ||
269 | coredev->ir.controller, coredev->ir.timeout); | ||
270 | |||
271 | snprintf(coredev->ir.name, | ||
272 | IR_DEV_NAME_MAX_LEN, | ||
273 | "SMS IR w/kbd type %d", | ||
274 | coredev->ir.ir_kb_type); | ||
275 | input_dev->name = coredev->ir.name; | ||
276 | input_dev->phys = coredev->ir.name; | ||
277 | input_dev->dev.parent = coredev->device; | ||
278 | |||
279 | /* Key press events only */ | ||
280 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
281 | input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); | ||
282 | |||
283 | sms_log("Input device (IR) %s is set for key events", input_dev->name); | ||
284 | |||
285 | if (input_register_device(input_dev)) { | ||
286 | sms_err("Failed to register device"); | ||
287 | input_free_device(input_dev); | ||
288 | return -EACCES; | ||
289 | } | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | void sms_ir_exit(struct smscore_device_t *coredev) | ||
295 | { | ||
296 | if (coredev->ir.input_dev) | ||
297 | input_unregister_device(coredev->ir.input_dev); | ||
298 | |||
299 | sms_log(""); | ||
300 | } | ||
301 | |||
diff --git a/drivers/media/dvb/siano/smsir.h b/drivers/media/dvb/siano/smsir.h new file mode 100644 index 000000000000..b7d703e2d338 --- /dev/null +++ b/drivers/media/dvb/siano/smsir.h | |||
@@ -0,0 +1,93 @@ | |||
1 | /**************************************************************** | ||
2 | |||
3 | Siano Mobile Silicon, Inc. | ||
4 | MDTV receiver kernel modules. | ||
5 | Copyright (C) 2006-2009, Uri Shkolnik | ||
6 | |||
7 | This program is free software: you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation, either version 2 of the License, or | ||
10 | (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 General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | |||
20 | ****************************************************************/ | ||
21 | |||
22 | #ifndef __SMS_IR_H__ | ||
23 | #define __SMS_IR_H__ | ||
24 | |||
25 | #include <linux/input.h> | ||
26 | |||
27 | #define IR_DEV_NAME_MAX_LEN 23 /* "SMS IR kbd type nn\0" */ | ||
28 | #define IR_KEYBOARD_LAYOUT_SIZE 64 | ||
29 | #define IR_DEFAULT_TIMEOUT 100 | ||
30 | |||
31 | enum ir_kb_type { | ||
32 | SMS_IR_KB_DEFAULT_TV, | ||
33 | SMS_IR_KB_HCW_SILVER | ||
34 | }; | ||
35 | |||
36 | enum rc5_keyboard_address { | ||
37 | KEYBOARD_ADDRESS_TV1 = 0, | ||
38 | KEYBOARD_ADDRESS_TV2 = 1, | ||
39 | KEYBOARD_ADDRESS_TELETEXT = 2, | ||
40 | KEYBOARD_ADDRESS_VIDEO = 3, | ||
41 | KEYBOARD_ADDRESS_LV1 = 4, | ||
42 | KEYBOARD_ADDRESS_VCR1 = 5, | ||
43 | KEYBOARD_ADDRESS_VCR2 = 6, | ||
44 | KEYBOARD_ADDRESS_EXPERIMENTAL = 7, | ||
45 | KEYBOARD_ADDRESS_SAT1 = 8, | ||
46 | KEYBOARD_ADDRESS_CAMERA = 9, | ||
47 | KEYBOARD_ADDRESS_SAT2 = 10, | ||
48 | KEYBOARD_ADDRESS_CDV = 12, | ||
49 | KEYBOARD_ADDRESS_CAMCORDER = 13, | ||
50 | KEYBOARD_ADDRESS_PRE_AMP = 16, | ||
51 | KEYBOARD_ADDRESS_TUNER = 17, | ||
52 | KEYBOARD_ADDRESS_RECORDER1 = 18, | ||
53 | KEYBOARD_ADDRESS_PRE_AMP1 = 19, | ||
54 | KEYBOARD_ADDRESS_CD_PLAYER = 20, | ||
55 | KEYBOARD_ADDRESS_PHONO = 21, | ||
56 | KEYBOARD_ADDRESS_SATA = 22, | ||
57 | KEYBOARD_ADDRESS_RECORDER2 = 23, | ||
58 | KEYBOARD_ADDRESS_CDR = 26, | ||
59 | KEYBOARD_ADDRESS_LIGHTING = 29, | ||
60 | KEYBOARD_ADDRESS_LIGHTING1 = 30, /* KEYBOARD_ADDRESS_HCW_SILVER */ | ||
61 | KEYBOARD_ADDRESS_PHONE = 31, | ||
62 | KEYBOARD_ADDRESS_NOT_RC5 = 0xFFFF | ||
63 | }; | ||
64 | |||
65 | enum ir_protocol { | ||
66 | IR_RC5, | ||
67 | IR_RCMM | ||
68 | }; | ||
69 | |||
70 | struct keyboard_layout_map_t { | ||
71 | enum ir_protocol ir_protocol; | ||
72 | enum rc5_keyboard_address rc5_kbd_address; | ||
73 | u16 keyboard_layout_map[IR_KEYBOARD_LAYOUT_SIZE]; | ||
74 | }; | ||
75 | |||
76 | struct smscore_device_t; | ||
77 | |||
78 | struct ir_t { | ||
79 | struct input_dev *input_dev; | ||
80 | enum ir_kb_type ir_kb_type; | ||
81 | char name[IR_DEV_NAME_MAX_LEN+1]; | ||
82 | u16 *keyboard_layout_map; | ||
83 | u32 timeout; | ||
84 | u32 controller; | ||
85 | }; | ||
86 | |||
87 | int sms_ir_init(struct smscore_device_t *coredev); | ||
88 | void sms_ir_exit(struct smscore_device_t *coredev); | ||
89 | void sms_ir_event(struct smscore_device_t *coredev, | ||
90 | const char *buf, int len); | ||
91 | |||
92 | #endif /* __SMS_IR_H__ */ | ||
93 | |||
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c new file mode 100644 index 000000000000..dfaa49a53f32 --- /dev/null +++ b/drivers/media/dvb/siano/smssdio.c | |||
@@ -0,0 +1,357 @@ | |||
1 | /* | ||
2 | * smssdio.c - Siano 1xxx SDIO interface driver | ||
3 | * | ||
4 | * Copyright 2008 Pierre Ossman | ||
5 | * | ||
6 | * Based on code by Siano Mobile Silicon, Inc., | ||
7 | * Copyright (C) 2006-2008, Uri Shkolnik | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or (at | ||
12 | * your option) any later version. | ||
13 | * | ||
14 | * | ||
15 | * This hardware is a bit odd in that all transfers should be done | ||
16 | * to/from the SMSSDIO_DATA register, yet the "increase address" bit | ||
17 | * always needs to be set. | ||
18 | * | ||
19 | * Also, buffers from the card are always aligned to 128 byte | ||
20 | * boundaries. | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * General cleanup notes: | ||
25 | * | ||
26 | * - only typedefs should be name *_t | ||
27 | * | ||
28 | * - use ERR_PTR and friends for smscore_register_device() | ||
29 | * | ||
30 | * - smscore_getbuffer should zero fields | ||
31 | * | ||
32 | * Fix stop command | ||
33 | */ | ||
34 | |||
35 | #include <linux/moduleparam.h> | ||
36 | #include <linux/firmware.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include <linux/mmc/card.h> | ||
39 | #include <linux/mmc/sdio_func.h> | ||
40 | #include <linux/mmc/sdio_ids.h> | ||
41 | |||
42 | #include "smscoreapi.h" | ||
43 | #include "sms-cards.h" | ||
44 | |||
45 | /* Registers */ | ||
46 | |||
47 | #define SMSSDIO_DATA 0x00 | ||
48 | #define SMSSDIO_INT 0x04 | ||
49 | |||
50 | static const struct sdio_device_id smssdio_ids[] = { | ||
51 | {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR), | ||
52 | .driver_data = SMS1XXX_BOARD_SIANO_STELLAR}, | ||
53 | {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0), | ||
54 | .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A}, | ||
55 | {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0), | ||
56 | .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B}, | ||
57 | {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0), | ||
58 | .driver_data = SMS1XXX_BOARD_SIANO_VEGA}, | ||
59 | {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE), | ||
60 | .driver_data = SMS1XXX_BOARD_SIANO_VEGA}, | ||
61 | { /* end: all zeroes */ }, | ||
62 | }; | ||
63 | |||
64 | MODULE_DEVICE_TABLE(sdio, smssdio_ids); | ||
65 | |||
66 | struct smssdio_device { | ||
67 | struct sdio_func *func; | ||
68 | |||
69 | struct smscore_device_t *coredev; | ||
70 | |||
71 | struct smscore_buffer_t *split_cb; | ||
72 | }; | ||
73 | |||
74 | /*******************************************************************/ | ||
75 | /* Siano core callbacks */ | ||
76 | /*******************************************************************/ | ||
77 | |||
78 | static int smssdio_sendrequest(void *context, void *buffer, size_t size) | ||
79 | { | ||
80 | int ret; | ||
81 | struct smssdio_device *smsdev; | ||
82 | |||
83 | smsdev = context; | ||
84 | |||
85 | sdio_claim_host(smsdev->func); | ||
86 | |||
87 | while (size >= smsdev->func->cur_blksize) { | ||
88 | ret = sdio_write_blocks(smsdev->func, SMSSDIO_DATA, buffer, 1); | ||
89 | if (ret) | ||
90 | goto out; | ||
91 | |||
92 | buffer += smsdev->func->cur_blksize; | ||
93 | size -= smsdev->func->cur_blksize; | ||
94 | } | ||
95 | |||
96 | if (size) { | ||
97 | ret = sdio_write_bytes(smsdev->func, SMSSDIO_DATA, | ||
98 | buffer, size); | ||
99 | } | ||
100 | |||
101 | out: | ||
102 | sdio_release_host(smsdev->func); | ||
103 | |||
104 | return ret; | ||
105 | } | ||
106 | |||
107 | /*******************************************************************/ | ||
108 | /* SDIO callbacks */ | ||
109 | /*******************************************************************/ | ||
110 | |||
111 | static void smssdio_interrupt(struct sdio_func *func) | ||
112 | { | ||
113 | int ret, isr; | ||
114 | |||
115 | struct smssdio_device *smsdev; | ||
116 | struct smscore_buffer_t *cb; | ||
117 | struct SmsMsgHdr_ST *hdr; | ||
118 | size_t size; | ||
119 | |||
120 | smsdev = sdio_get_drvdata(func); | ||
121 | |||
122 | /* | ||
123 | * The interrupt register has no defined meaning. It is just | ||
124 | * a way of turning of the level triggered interrupt. | ||
125 | */ | ||
126 | isr = sdio_readb(func, SMSSDIO_INT, &ret); | ||
127 | if (ret) { | ||
128 | dev_err(&smsdev->func->dev, | ||
129 | "Unable to read interrupt register!\n"); | ||
130 | return; | ||
131 | } | ||
132 | |||
133 | if (smsdev->split_cb == NULL) { | ||
134 | cb = smscore_getbuffer(smsdev->coredev); | ||
135 | if (!cb) { | ||
136 | dev_err(&smsdev->func->dev, | ||
137 | "Unable to allocate data buffer!\n"); | ||
138 | return; | ||
139 | } | ||
140 | |||
141 | ret = sdio_read_blocks(smsdev->func, cb->p, SMSSDIO_DATA, 1); | ||
142 | if (ret) { | ||
143 | dev_err(&smsdev->func->dev, | ||
144 | "Error %d reading initial block!\n", ret); | ||
145 | return; | ||
146 | } | ||
147 | |||
148 | hdr = cb->p; | ||
149 | |||
150 | if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) { | ||
151 | smsdev->split_cb = cb; | ||
152 | return; | ||
153 | } | ||
154 | |||
155 | size = hdr->msgLength - smsdev->func->cur_blksize; | ||
156 | } else { | ||
157 | cb = smsdev->split_cb; | ||
158 | hdr = cb->p; | ||
159 | |||
160 | size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST); | ||
161 | |||
162 | smsdev->split_cb = NULL; | ||
163 | } | ||
164 | |||
165 | if (hdr->msgLength > smsdev->func->cur_blksize) { | ||
166 | void *buffer; | ||
167 | |||
168 | size = ALIGN(size, 128); | ||
169 | buffer = cb->p + hdr->msgLength; | ||
170 | |||
171 | BUG_ON(smsdev->func->cur_blksize != 128); | ||
172 | |||
173 | /* | ||
174 | * First attempt to transfer all of it in one go... | ||
175 | */ | ||
176 | ret = sdio_read_blocks(smsdev->func, buffer, | ||
177 | SMSSDIO_DATA, size / 128); | ||
178 | if (ret && ret != -EINVAL) { | ||
179 | smscore_putbuffer(smsdev->coredev, cb); | ||
180 | dev_err(&smsdev->func->dev, | ||
181 | "Error %d reading data from card!\n", ret); | ||
182 | return; | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * ..then fall back to one block at a time if that is | ||
187 | * not possible... | ||
188 | * | ||
189 | * (we have to do this manually because of the | ||
190 | * problem with the "increase address" bit) | ||
191 | */ | ||
192 | if (ret == -EINVAL) { | ||
193 | while (size) { | ||
194 | ret = sdio_read_blocks(smsdev->func, | ||
195 | buffer, SMSSDIO_DATA, 1); | ||
196 | if (ret) { | ||
197 | smscore_putbuffer(smsdev->coredev, cb); | ||
198 | dev_err(&smsdev->func->dev, | ||
199 | "Error %d reading " | ||
200 | "data from card!\n", ret); | ||
201 | return; | ||
202 | } | ||
203 | |||
204 | buffer += smsdev->func->cur_blksize; | ||
205 | if (size > smsdev->func->cur_blksize) | ||
206 | size -= smsdev->func->cur_blksize; | ||
207 | else | ||
208 | size = 0; | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | |||
213 | cb->size = hdr->msgLength; | ||
214 | cb->offset = 0; | ||
215 | |||
216 | smscore_onresponse(smsdev->coredev, cb); | ||
217 | } | ||
218 | |||
219 | static int smssdio_probe(struct sdio_func *func, | ||
220 | const struct sdio_device_id *id) | ||
221 | { | ||
222 | int ret; | ||
223 | |||
224 | int board_id; | ||
225 | struct smssdio_device *smsdev; | ||
226 | struct smsdevice_params_t params; | ||
227 | |||
228 | board_id = id->driver_data; | ||
229 | |||
230 | smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL); | ||
231 | if (!smsdev) | ||
232 | return -ENOMEM; | ||
233 | |||
234 | smsdev->func = func; | ||
235 | |||
236 | memset(¶ms, 0, sizeof(struct smsdevice_params_t)); | ||
237 | |||
238 | params.device = &func->dev; | ||
239 | params.buffer_size = 0x5000; /* ?? */ | ||
240 | params.num_buffers = 22; /* ?? */ | ||
241 | params.context = smsdev; | ||
242 | |||
243 | snprintf(params.devpath, sizeof(params.devpath), | ||
244 | "sdio\\%s", sdio_func_id(func)); | ||
245 | |||
246 | params.sendrequest_handler = smssdio_sendrequest; | ||
247 | |||
248 | params.device_type = sms_get_board(board_id)->type; | ||
249 | |||
250 | if (params.device_type != SMS_STELLAR) | ||
251 | params.flags |= SMS_DEVICE_FAMILY2; | ||
252 | else { | ||
253 | /* | ||
254 | * FIXME: Stellar needs special handling... | ||
255 | */ | ||
256 | ret = -ENODEV; | ||
257 | goto free; | ||
258 | } | ||
259 | |||
260 | ret = smscore_register_device(¶ms, &smsdev->coredev); | ||
261 | if (ret < 0) | ||
262 | goto free; | ||
263 | |||
264 | smscore_set_board_id(smsdev->coredev, board_id); | ||
265 | |||
266 | sdio_claim_host(func); | ||
267 | |||
268 | ret = sdio_enable_func(func); | ||
269 | if (ret) | ||
270 | goto release; | ||
271 | |||
272 | ret = sdio_set_block_size(func, 128); | ||
273 | if (ret) | ||
274 | goto disable; | ||
275 | |||
276 | ret = sdio_claim_irq(func, smssdio_interrupt); | ||
277 | if (ret) | ||
278 | goto disable; | ||
279 | |||
280 | sdio_set_drvdata(func, smsdev); | ||
281 | |||
282 | sdio_release_host(func); | ||
283 | |||
284 | ret = smscore_start_device(smsdev->coredev); | ||
285 | if (ret < 0) | ||
286 | goto reclaim; | ||
287 | |||
288 | return 0; | ||
289 | |||
290 | reclaim: | ||
291 | sdio_claim_host(func); | ||
292 | sdio_release_irq(func); | ||
293 | disable: | ||
294 | sdio_disable_func(func); | ||
295 | release: | ||
296 | sdio_release_host(func); | ||
297 | smscore_unregister_device(smsdev->coredev); | ||
298 | free: | ||
299 | kfree(smsdev); | ||
300 | |||
301 | return ret; | ||
302 | } | ||
303 | |||
304 | static void smssdio_remove(struct sdio_func *func) | ||
305 | { | ||
306 | struct smssdio_device *smsdev; | ||
307 | |||
308 | smsdev = sdio_get_drvdata(func); | ||
309 | |||
310 | /* FIXME: racy! */ | ||
311 | if (smsdev->split_cb) | ||
312 | smscore_putbuffer(smsdev->coredev, smsdev->split_cb); | ||
313 | |||
314 | smscore_unregister_device(smsdev->coredev); | ||
315 | |||
316 | sdio_claim_host(func); | ||
317 | sdio_release_irq(func); | ||
318 | sdio_disable_func(func); | ||
319 | sdio_release_host(func); | ||
320 | |||
321 | kfree(smsdev); | ||
322 | } | ||
323 | |||
324 | static struct sdio_driver smssdio_driver = { | ||
325 | .name = "smssdio", | ||
326 | .id_table = smssdio_ids, | ||
327 | .probe = smssdio_probe, | ||
328 | .remove = smssdio_remove, | ||
329 | }; | ||
330 | |||
331 | /*******************************************************************/ | ||
332 | /* Module functions */ | ||
333 | /*******************************************************************/ | ||
334 | |||
335 | int smssdio_module_init(void) | ||
336 | { | ||
337 | int ret = 0; | ||
338 | |||
339 | printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n"); | ||
340 | printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n"); | ||
341 | |||
342 | ret = sdio_register_driver(&smssdio_driver); | ||
343 | |||
344 | return ret; | ||
345 | } | ||
346 | |||
347 | void smssdio_module_exit(void) | ||
348 | { | ||
349 | sdio_unregister_driver(&smssdio_driver); | ||
350 | } | ||
351 | |||
352 | module_init(smssdio_module_init); | ||
353 | module_exit(smssdio_module_exit); | ||
354 | |||
355 | MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver"); | ||
356 | MODULE_AUTHOR("Pierre Ossman"); | ||
357 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 71c65f544c07..cb8a358b7310 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c | |||
@@ -1,23 +1,23 @@ | |||
1 | /* | 1 | /**************************************************************** |
2 | * Driver for the Siano SMS1xxx USB dongle | 2 | |
3 | * | 3 | Siano Mobile Silicon, Inc. |
4 | * author: Anatoly Greenblat | 4 | MDTV receiver kernel modules. |
5 | * | 5 | Copyright (C) 2005-2009, Uri Shkolnik, Anatoly Greenblat |
6 | * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. | 6 | |
7 | * | 7 | This program is free software: you can redistribute it and/or modify |
8 | * This program is free software; you can redistribute it and/or modify | 8 | it under the terms of the GNU General Public License as published by |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | the Free Software Foundation, either version 2 of the License, or |
10 | * published by the Free Software Foundation; | 10 | (at your option) any later version. |
11 | * | 11 | |
12 | * Software distributed under the License is distributed on an "AS IS" | 12 | This program is distributed in the hope that it will be useful, |
13 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * See the GNU General Public License for more details. | 15 | GNU General Public License for more details. |
16 | * | 16 | |
17 | * You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | |
20 | */ | 20 | ****************************************************************/ |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include "smscoreapi.h" | 27 | #include "smscoreapi.h" |
28 | #include "sms-cards.h" | 28 | #include "sms-cards.h" |
29 | #include "smsendian.h" | ||
29 | 30 | ||
30 | static int sms_dbg; | 31 | static int sms_dbg; |
31 | module_param_named(debug, sms_dbg, int, 0644); | 32 | module_param_named(debug, sms_dbg, int, 0644); |
@@ -64,15 +65,16 @@ static void smsusb_onresponse(struct urb *urb) | |||
64 | struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; | 65 | struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; |
65 | struct smsusb_device_t *dev = surb->dev; | 66 | struct smsusb_device_t *dev = surb->dev; |
66 | 67 | ||
67 | if (urb->status < 0) { | 68 | if (urb->status == -ESHUTDOWN) { |
68 | sms_err("error, urb status %d, %d bytes", | 69 | sms_err("error, urb status %d (-ESHUTDOWN), %d bytes", |
69 | urb->status, urb->actual_length); | 70 | urb->status, urb->actual_length); |
70 | return; | 71 | return; |
71 | } | 72 | } |
72 | 73 | ||
73 | if (urb->actual_length > 0) { | 74 | if ((urb->actual_length > 0) && (urb->status == 0)) { |
74 | struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) surb->cb->p; | 75 | struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)surb->cb->p; |
75 | 76 | ||
77 | smsendian_handle_message_header(phdr); | ||
76 | if (urb->actual_length >= phdr->msgLength) { | 78 | if (urb->actual_length >= phdr->msgLength) { |
77 | surb->cb->size = phdr->msgLength; | 79 | surb->cb->size = phdr->msgLength; |
78 | 80 | ||
@@ -109,7 +111,10 @@ static void smsusb_onresponse(struct urb *urb) | |||
109 | "msglen %d actual %d", | 111 | "msglen %d actual %d", |
110 | phdr->msgLength, urb->actual_length); | 112 | phdr->msgLength, urb->actual_length); |
111 | } | 113 | } |
112 | } | 114 | } else |
115 | sms_err("error, urb status %d, %d bytes", | ||
116 | urb->status, urb->actual_length); | ||
117 | |||
113 | 118 | ||
114 | exit_and_resubmit: | 119 | exit_and_resubmit: |
115 | smsusb_submit_urb(dev, surb); | 120 | smsusb_submit_urb(dev, surb); |
@@ -176,6 +181,7 @@ static int smsusb_sendrequest(void *context, void *buffer, size_t size) | |||
176 | struct smsusb_device_t *dev = (struct smsusb_device_t *) context; | 181 | struct smsusb_device_t *dev = (struct smsusb_device_t *) context; |
177 | int dummy; | 182 | int dummy; |
178 | 183 | ||
184 | smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer); | ||
179 | return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), | 185 | return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), |
180 | buffer, size, &dummy, 1000); | 186 | buffer, size, &dummy, 1000); |
181 | } | 187 | } |
@@ -333,8 +339,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) | |||
333 | case SMS_VEGA: | 339 | case SMS_VEGA: |
334 | dev->buffer_size = USB2_BUFFER_SIZE; | 340 | dev->buffer_size = USB2_BUFFER_SIZE; |
335 | dev->response_alignment = | 341 | dev->response_alignment = |
336 | dev->udev->ep_in[1]->desc.wMaxPacketSize - | 342 | le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) - |
337 | sizeof(struct SmsMsgHdr_ST); | 343 | sizeof(struct SmsMsgHdr_ST); |
338 | 344 | ||
339 | params.flags |= SMS_DEVICE_FAMILY2; | 345 | params.flags |= SMS_DEVICE_FAMILY2; |
340 | break; | 346 | break; |
@@ -479,7 +485,6 @@ static int smsusb_resume(struct usb_interface *intf) | |||
479 | } | 485 | } |
480 | 486 | ||
481 | struct usb_device_id smsusb_id_table[] = { | 487 | struct usb_device_id smsusb_id_table[] = { |
482 | #ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS | ||
483 | { USB_DEVICE(0x187f, 0x0010), | 488 | { USB_DEVICE(0x187f, 0x0010), |
484 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, | 489 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, |
485 | { USB_DEVICE(0x187f, 0x0100), | 490 | { USB_DEVICE(0x187f, 0x0100), |
@@ -490,7 +495,6 @@ struct usb_device_id smsusb_id_table[] = { | |||
490 | .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, | 495 | .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, |
491 | { USB_DEVICE(0x187f, 0x0300), | 496 | { USB_DEVICE(0x187f, 0x0300), |
492 | .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, | 497 | .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, |
493 | #endif | ||
494 | { USB_DEVICE(0x2040, 0x1700), | 498 | { USB_DEVICE(0x2040, 0x1700), |
495 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, | 499 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, |
496 | { USB_DEVICE(0x2040, 0x1800), | 500 | { USB_DEVICE(0x2040, 0x1800), |
@@ -521,8 +525,13 @@ struct usb_device_id smsusb_id_table[] = { | |||
521 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | 525 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, |
522 | { USB_DEVICE(0x2040, 0x5590), | 526 | { USB_DEVICE(0x2040, 0x5590), |
523 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | 527 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, |
524 | { } /* Terminating entry */ | 528 | { USB_DEVICE(0x187f, 0x0202), |
525 | }; | 529 | .driver_info = SMS1XXX_BOARD_SIANO_NICE }, |
530 | { USB_DEVICE(0x187f, 0x0301), | ||
531 | .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, | ||
532 | { } /* Terminating entry */ | ||
533 | }; | ||
534 | |||
526 | MODULE_DEVICE_TABLE(usb, smsusb_id_table); | 535 | MODULE_DEVICE_TABLE(usb, smsusb_id_table); |
527 | 536 | ||
528 | static struct usb_driver smsusb_driver = { | 537 | static struct usb_driver smsusb_driver = { |
@@ -548,14 +557,14 @@ int smsusb_module_init(void) | |||
548 | 557 | ||
549 | void smsusb_module_exit(void) | 558 | void smsusb_module_exit(void) |
550 | { | 559 | { |
551 | sms_debug(""); | ||
552 | /* Regular USB Cleanup */ | 560 | /* Regular USB Cleanup */ |
553 | usb_deregister(&smsusb_driver); | 561 | usb_deregister(&smsusb_driver); |
562 | sms_info("end"); | ||
554 | } | 563 | } |
555 | 564 | ||
556 | module_init(smsusb_module_init); | 565 | module_init(smsusb_module_init); |
557 | module_exit(smsusb_module_exit); | 566 | module_exit(smsusb_module_exit); |
558 | 567 | ||
559 | MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); | 568 | MODULE_DESCRIPTION("Driver for the Siano SMS1xxx USB dongle"); |
560 | MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); | 569 | MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); |
561 | MODULE_LICENSE("GPL"); | 570 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index e4d0900d5121..53884814161c 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -89,6 +89,7 @@ | |||
89 | 89 | ||
90 | static void p_to_t(u8 const *buf, long int length, u16 pid, | 90 | static void p_to_t(u8 const *buf, long int length, u16 pid, |
91 | u8 *counter, struct dvb_demux_feed *feed); | 91 | u8 *counter, struct dvb_demux_feed *feed); |
92 | static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len); | ||
92 | 93 | ||
93 | 94 | ||
94 | int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) | 95 | int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) |
@@ -192,8 +193,6 @@ int av7110_av_start_play(struct av7110 *av7110, int av) | |||
192 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); | 193 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); |
193 | break; | 194 | break; |
194 | } | 195 | } |
195 | if (!ret) | ||
196 | ret = av7110->playing; | ||
197 | return ret; | 196 | return ret; |
198 | } | 197 | } |
199 | 198 | ||
@@ -437,6 +436,45 @@ static void play_audio_cb(u8 *buf, int count, void *priv) | |||
437 | aux_ring_buffer_write(&av7110->aout, buf, count); | 436 | aux_ring_buffer_write(&av7110->aout, buf, count); |
438 | } | 437 | } |
439 | 438 | ||
439 | |||
440 | #define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096) | ||
441 | |||
442 | static ssize_t ts_play(struct av7110 *av7110, const char __user *buf, | ||
443 | unsigned long count, int nonblock, int type) | ||
444 | { | ||
445 | struct dvb_ringbuffer *rb; | ||
446 | u8 *kb; | ||
447 | unsigned long todo = count; | ||
448 | |||
449 | dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count); | ||
450 | |||
451 | rb = (type) ? &av7110->avout : &av7110->aout; | ||
452 | kb = av7110->kbuf[type]; | ||
453 | |||
454 | if (!kb) | ||
455 | return -ENOBUFS; | ||
456 | |||
457 | if (nonblock && !FREE_COND_TS) | ||
458 | return -EWOULDBLOCK; | ||
459 | |||
460 | while (todo >= TS_SIZE) { | ||
461 | if (!FREE_COND_TS) { | ||
462 | if (nonblock) | ||
463 | return count - todo; | ||
464 | if (wait_event_interruptible(rb->queue, FREE_COND_TS)) | ||
465 | return count - todo; | ||
466 | } | ||
467 | if (copy_from_user(kb, buf, TS_SIZE)) | ||
468 | return -EFAULT; | ||
469 | write_ts_to_decoder(av7110, type, kb, TS_SIZE); | ||
470 | todo -= TS_SIZE; | ||
471 | buf += TS_SIZE; | ||
472 | } | ||
473 | |||
474 | return count - todo; | ||
475 | } | ||
476 | |||
477 | |||
440 | #define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ | 478 | #define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ |
441 | dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) | 479 | dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) |
442 | 480 | ||
@@ -780,11 +818,37 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, | |||
780 | } | 818 | } |
781 | 819 | ||
782 | 820 | ||
821 | static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len) | ||
822 | { | ||
823 | struct ipack *ipack = &av7110->ipack[type]; | ||
824 | |||
825 | if (buf[1] & TRANS_ERROR) { | ||
826 | av7110_ipack_reset(ipack); | ||
827 | return -1; | ||
828 | } | ||
829 | |||
830 | if (!(buf[3] & PAYLOAD)) | ||
831 | return -1; | ||
832 | |||
833 | if (buf[1] & PAY_START) | ||
834 | av7110_ipack_flush(ipack); | ||
835 | |||
836 | if (buf[3] & ADAPT_FIELD) { | ||
837 | len -= buf[4] + 1; | ||
838 | buf += buf[4] + 1; | ||
839 | if (!len) | ||
840 | return 0; | ||
841 | } | ||
842 | |||
843 | av7110_ipack_instant_repack(buf + 4, len - 4, ipack); | ||
844 | return 0; | ||
845 | } | ||
846 | |||
847 | |||
783 | int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) | 848 | int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) |
784 | { | 849 | { |
785 | struct dvb_demux *demux = feed->demux; | 850 | struct dvb_demux *demux = feed->demux; |
786 | struct av7110 *av7110 = (struct av7110 *) demux->priv; | 851 | struct av7110 *av7110 = (struct av7110 *) demux->priv; |
787 | struct ipack *ipack = &av7110->ipack[feed->pes_type]; | ||
788 | 852 | ||
789 | dprintk(2, "av7110:%p, \n", av7110); | 853 | dprintk(2, "av7110:%p, \n", av7110); |
790 | 854 | ||
@@ -804,20 +868,7 @@ int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t l | |||
804 | return -1; | 868 | return -1; |
805 | } | 869 | } |
806 | 870 | ||
807 | if (!(buf[3] & 0x10)) /* no payload? */ | 871 | return write_ts_to_decoder(av7110, feed->pes_type, buf, len); |
808 | return -1; | ||
809 | if (buf[1] & 0x40) | ||
810 | av7110_ipack_flush(ipack); | ||
811 | |||
812 | if (buf[3] & 0x20) { /* adaptation field? */ | ||
813 | len -= buf[4] + 1; | ||
814 | buf += buf[4] + 1; | ||
815 | if (!len) | ||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | av7110_ipack_instant_repack(buf + 4, len - 4, &av7110->ipack[feed->pes_type]); | ||
820 | return 0; | ||
821 | } | 872 | } |
822 | 873 | ||
823 | 874 | ||
@@ -916,6 +967,7 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf, | |||
916 | { | 967 | { |
917 | struct dvb_device *dvbdev = file->private_data; | 968 | struct dvb_device *dvbdev = file->private_data; |
918 | struct av7110 *av7110 = dvbdev->priv; | 969 | struct av7110 *av7110 = dvbdev->priv; |
970 | unsigned char c; | ||
919 | 971 | ||
920 | dprintk(2, "av7110:%p, \n", av7110); | 972 | dprintk(2, "av7110:%p, \n", av7110); |
921 | 973 | ||
@@ -925,7 +977,12 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf, | |||
925 | if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) | 977 | if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) |
926 | return -EPERM; | 978 | return -EPERM; |
927 | 979 | ||
928 | return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); | 980 | if (get_user(c, buf)) |
981 | return -EFAULT; | ||
982 | if (c == 0x47 && count % TS_SIZE == 0) | ||
983 | return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); | ||
984 | else | ||
985 | return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); | ||
929 | } | 986 | } |
930 | 987 | ||
931 | static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) | 988 | static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) |
@@ -952,6 +1009,7 @@ static ssize_t dvb_audio_write(struct file *file, const char __user *buf, | |||
952 | { | 1009 | { |
953 | struct dvb_device *dvbdev = file->private_data; | 1010 | struct dvb_device *dvbdev = file->private_data; |
954 | struct av7110 *av7110 = dvbdev->priv; | 1011 | struct av7110 *av7110 = dvbdev->priv; |
1012 | unsigned char c; | ||
955 | 1013 | ||
956 | dprintk(2, "av7110:%p, \n", av7110); | 1014 | dprintk(2, "av7110:%p, \n", av7110); |
957 | 1015 | ||
@@ -959,7 +1017,13 @@ static ssize_t dvb_audio_write(struct file *file, const char __user *buf, | |||
959 | printk(KERN_ERR "not audio source memory\n"); | 1017 | printk(KERN_ERR "not audio source memory\n"); |
960 | return -EPERM; | 1018 | return -EPERM; |
961 | } | 1019 | } |
962 | return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); | 1020 | |
1021 | if (get_user(c, buf)) | ||
1022 | return -EFAULT; | ||
1023 | if (c == 0x47 && count % TS_SIZE == 0) | ||
1024 | return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); | ||
1025 | else | ||
1026 | return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); | ||
963 | } | 1027 | } |
964 | 1028 | ||
965 | static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; | 1029 | static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; |
@@ -1062,7 +1126,6 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1062 | if (ret) | 1126 | if (ret) |
1063 | break; | 1127 | break; |
1064 | } | 1128 | } |
1065 | |||
1066 | if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { | 1129 | if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { |
1067 | if (av7110->playing == RP_AV) { | 1130 | if (av7110->playing == RP_AV) { |
1068 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); | 1131 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); |
@@ -1122,20 +1185,16 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1122 | case VIDEO_SET_DISPLAY_FORMAT: | 1185 | case VIDEO_SET_DISPLAY_FORMAT: |
1123 | { | 1186 | { |
1124 | video_displayformat_t format = (video_displayformat_t) arg; | 1187 | video_displayformat_t format = (video_displayformat_t) arg; |
1125 | |||
1126 | switch (format) { | 1188 | switch (format) { |
1127 | case VIDEO_PAN_SCAN: | 1189 | case VIDEO_PAN_SCAN: |
1128 | av7110->display_panscan = VID_PAN_SCAN_PREF; | 1190 | av7110->display_panscan = VID_PAN_SCAN_PREF; |
1129 | break; | 1191 | break; |
1130 | |||
1131 | case VIDEO_LETTER_BOX: | 1192 | case VIDEO_LETTER_BOX: |
1132 | av7110->display_panscan = VID_VC_AND_PS_PREF; | 1193 | av7110->display_panscan = VID_VC_AND_PS_PREF; |
1133 | break; | 1194 | break; |
1134 | |||
1135 | case VIDEO_CENTER_CUT_OUT: | 1195 | case VIDEO_CENTER_CUT_OUT: |
1136 | av7110->display_panscan = VID_CENTRE_CUT_PREF; | 1196 | av7110->display_panscan = VID_CENTRE_CUT_PREF; |
1137 | break; | 1197 | break; |
1138 | |||
1139 | default: | 1198 | default: |
1140 | ret = -EINVAL; | 1199 | ret = -EINVAL; |
1141 | } | 1200 | } |
@@ -1183,7 +1242,8 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1183 | 1242 | ||
1184 | case VIDEO_SLOWMOTION: | 1243 | case VIDEO_SLOWMOTION: |
1185 | if (av7110->playing&RP_VIDEO) { | 1244 | if (av7110->playing&RP_VIDEO) { |
1186 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); | 1245 | if (av7110->trickmode != TRICK_SLOW) |
1246 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); | ||
1187 | if (!ret) | 1247 | if (!ret) |
1188 | ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); | 1248 | ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); |
1189 | } else { | 1249 | } else { |
@@ -1207,7 +1267,6 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1207 | case VIDEO_CLEAR_BUFFER: | 1267 | case VIDEO_CLEAR_BUFFER: |
1208 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); | 1268 | dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); |
1209 | av7110_ipack_reset(&av7110->ipack[1]); | 1269 | av7110_ipack_reset(&av7110->ipack[1]); |
1210 | |||
1211 | if (av7110->playing == RP_AV) { | 1270 | if (av7110->playing == RP_AV) { |
1212 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, | 1271 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, |
1213 | __Play, 2, AV_PES, 0); | 1272 | __Play, 2, AV_PES, 0); |
@@ -1228,13 +1287,13 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1228 | break; | 1287 | break; |
1229 | 1288 | ||
1230 | case VIDEO_SET_STREAMTYPE: | 1289 | case VIDEO_SET_STREAMTYPE: |
1231 | |||
1232 | break; | 1290 | break; |
1233 | 1291 | ||
1234 | default: | 1292 | default: |
1235 | ret = -ENOIOCTLCMD; | 1293 | ret = -ENOIOCTLCMD; |
1236 | break; | 1294 | break; |
1237 | } | 1295 | } |
1296 | |||
1238 | return ret; | 1297 | return ret; |
1239 | } | 1298 | } |
1240 | 1299 | ||
@@ -1309,7 +1368,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1309 | 1368 | ||
1310 | case AUDIO_CHANNEL_SELECT: | 1369 | case AUDIO_CHANNEL_SELECT: |
1311 | av7110->audiostate.channel_select = (audio_channel_select_t) arg; | 1370 | av7110->audiostate.channel_select = (audio_channel_select_t) arg; |
1312 | |||
1313 | switch(av7110->audiostate.channel_select) { | 1371 | switch(av7110->audiostate.channel_select) { |
1314 | case AUDIO_STEREO: | 1372 | case AUDIO_STEREO: |
1315 | ret = audcom(av7110, AUDIO_CMD_STEREO); | 1373 | ret = audcom(av7110, AUDIO_CMD_STEREO); |
@@ -1320,7 +1378,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1320 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); | 1378 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); |
1321 | } | 1379 | } |
1322 | break; | 1380 | break; |
1323 | |||
1324 | case AUDIO_MONO_LEFT: | 1381 | case AUDIO_MONO_LEFT: |
1325 | ret = audcom(av7110, AUDIO_CMD_MONO_L); | 1382 | ret = audcom(av7110, AUDIO_CMD_MONO_L); |
1326 | if (!ret) { | 1383 | if (!ret) { |
@@ -1330,7 +1387,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1330 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); | 1387 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); |
1331 | } | 1388 | } |
1332 | break; | 1389 | break; |
1333 | |||
1334 | case AUDIO_MONO_RIGHT: | 1390 | case AUDIO_MONO_RIGHT: |
1335 | ret = audcom(av7110, AUDIO_CMD_MONO_R); | 1391 | ret = audcom(av7110, AUDIO_CMD_MONO_R); |
1336 | if (!ret) { | 1392 | if (!ret) { |
@@ -1340,7 +1396,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1340 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); | 1396 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); |
1341 | } | 1397 | } |
1342 | break; | 1398 | break; |
1343 | |||
1344 | default: | 1399 | default: |
1345 | ret = -EINVAL; | 1400 | ret = -EINVAL; |
1346 | break; | 1401 | break; |
@@ -1366,21 +1421,24 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1366 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, | 1421 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, |
1367 | __Play, 2, AV_PES, 0); | 1422 | __Play, 2, AV_PES, 0); |
1368 | break; | 1423 | break; |
1369 | case AUDIO_SET_ID: | ||
1370 | 1424 | ||
1425 | case AUDIO_SET_ID: | ||
1371 | break; | 1426 | break; |
1427 | |||
1372 | case AUDIO_SET_MIXER: | 1428 | case AUDIO_SET_MIXER: |
1373 | { | 1429 | { |
1374 | struct audio_mixer *amix = (struct audio_mixer *)parg; | 1430 | struct audio_mixer *amix = (struct audio_mixer *)parg; |
1375 | |||
1376 | ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); | 1431 | ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); |
1377 | break; | 1432 | break; |
1378 | } | 1433 | } |
1434 | |||
1379 | case AUDIO_SET_STREAMTYPE: | 1435 | case AUDIO_SET_STREAMTYPE: |
1380 | break; | 1436 | break; |
1437 | |||
1381 | default: | 1438 | default: |
1382 | ret = -ENOIOCTLCMD; | 1439 | ret = -ENOIOCTLCMD; |
1383 | } | 1440 | } |
1441 | |||
1384 | return ret; | 1442 | return ret; |
1385 | } | 1443 | } |
1386 | 1444 | ||
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index 5e3f88911a1d..e162691b515d 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c | |||
@@ -1089,7 +1089,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) | |||
1089 | else { | 1089 | else { |
1090 | int i, len = dc->x0-dc->color+1; | 1090 | int i, len = dc->x0-dc->color+1; |
1091 | u8 __user *colors = (u8 __user *)dc->data; | 1091 | u8 __user *colors = (u8 __user *)dc->data; |
1092 | u8 r, g, b, blend; | 1092 | u8 r, g = 0, b = 0, blend = 0; |
1093 | ret = 0; | 1093 | ret = 0; |
1094 | for (i = 0; i<len; i++) { | 1094 | for (i = 0; i<len; i++) { |
1095 | if (get_user(r, colors + i * 4) || | 1095 | if (get_user(r, colors + i * 4) || |
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index 2210cff738e6..ce64c6214cc4 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c | |||
@@ -458,7 +458,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) | |||
458 | dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); | 458 | dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); |
459 | 459 | ||
460 | if (av7110->analog_tuner_flags) { | 460 | if (av7110->analog_tuner_flags) { |
461 | if (i->index < 0 || i->index >= 4) | 461 | if (i->index >= 4) |
462 | return -EINVAL; | 462 | return -EINVAL; |
463 | } else { | 463 | } else { |
464 | if (i->index != 0) | 464 | if (i->index != 0) |
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 855fe74b640b..8ea915227674 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
@@ -1413,7 +1413,7 @@ static struct v4l2_input knc1_inputs[KNC1_INPUTS] = { | |||
1413 | static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) | 1413 | static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) |
1414 | { | 1414 | { |
1415 | dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index); | 1415 | dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index); |
1416 | if (i->index < 0 || i->index >= KNC1_INPUTS) | 1416 | if (i->index >= KNC1_INPUTS) |
1417 | return -EINVAL; | 1417 | return -EINVAL; |
1418 | memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); | 1418 | memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); |
1419 | return 0; | 1419 | return 0; |
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index 83e9e7750c8c..e48380c48990 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
@@ -47,6 +47,9 @@ | |||
47 | #include "bsru6.h" | 47 | #include "bsru6.h" |
48 | #include "bsbe1.h" | 48 | #include "bsbe1.h" |
49 | #include "tdhd1.h" | 49 | #include "tdhd1.h" |
50 | #include "stv6110x.h" | ||
51 | #include "stv090x.h" | ||
52 | #include "isl6423.h" | ||
50 | 53 | ||
51 | static int diseqc_method; | 54 | static int diseqc_method; |
52 | module_param(diseqc_method, int, 0444); | 55 | module_param(diseqc_method, int, 0444); |
@@ -425,6 +428,44 @@ static u8 read_pwm(struct budget* budget) | |||
425 | return pwm; | 428 | return pwm; |
426 | } | 429 | } |
427 | 430 | ||
431 | static struct stv090x_config tt1600_stv090x_config = { | ||
432 | .device = STV0903, | ||
433 | .demod_mode = STV090x_SINGLE, | ||
434 | .clk_mode = STV090x_CLK_EXT, | ||
435 | |||
436 | .xtal = 27000000, | ||
437 | .address = 0x68, | ||
438 | .ref_clk = 27000000, | ||
439 | |||
440 | .ts1_mode = STV090x_TSMODE_DVBCI, | ||
441 | .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, | ||
442 | |||
443 | .repeater_level = STV090x_RPTLEVEL_16, | ||
444 | |||
445 | .tuner_init = NULL, | ||
446 | .tuner_set_mode = NULL, | ||
447 | .tuner_set_frequency = NULL, | ||
448 | .tuner_get_frequency = NULL, | ||
449 | .tuner_set_bandwidth = NULL, | ||
450 | .tuner_get_bandwidth = NULL, | ||
451 | .tuner_set_bbgain = NULL, | ||
452 | .tuner_get_bbgain = NULL, | ||
453 | .tuner_set_refclk = NULL, | ||
454 | .tuner_get_status = NULL, | ||
455 | }; | ||
456 | |||
457 | static struct stv6110x_config tt1600_stv6110x_config = { | ||
458 | .addr = 0x60, | ||
459 | .refclk = 27000000, | ||
460 | }; | ||
461 | |||
462 | static struct isl6423_config tt1600_isl6423_config = { | ||
463 | .current_max = SEC_CURRENT_515m, | ||
464 | .curlim = SEC_CURRENT_LIM_ON, | ||
465 | .mod_extern = 1, | ||
466 | .addr = 0x08, | ||
467 | }; | ||
468 | |||
428 | static void frontend_init(struct budget *budget) | 469 | static void frontend_init(struct budget *budget) |
429 | { | 470 | { |
430 | (void)alps_bsbe1_config; /* avoid warning */ | 471 | (void)alps_bsbe1_config; /* avoid warning */ |
@@ -566,6 +607,48 @@ static void frontend_init(struct budget *budget) | |||
566 | } | 607 | } |
567 | break; | 608 | break; |
568 | } | 609 | } |
610 | |||
611 | case 0x101c: { /* TT S2-1600 */ | ||
612 | struct stv6110x_devctl *ctl; | ||
613 | saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); | ||
614 | msleep(50); | ||
615 | saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); | ||
616 | msleep(250); | ||
617 | |||
618 | budget->dvb_frontend = dvb_attach(stv090x_attach, | ||
619 | &tt1600_stv090x_config, | ||
620 | &budget->i2c_adap, | ||
621 | STV090x_DEMODULATOR_0); | ||
622 | |||
623 | if (budget->dvb_frontend) { | ||
624 | |||
625 | ctl = dvb_attach(stv6110x_attach, | ||
626 | budget->dvb_frontend, | ||
627 | &tt1600_stv6110x_config, | ||
628 | &budget->i2c_adap); | ||
629 | |||
630 | tt1600_stv090x_config.tuner_init = ctl->tuner_init; | ||
631 | tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; | ||
632 | tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; | ||
633 | tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; | ||
634 | tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; | ||
635 | tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; | ||
636 | tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; | ||
637 | tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; | ||
638 | tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; | ||
639 | tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; | ||
640 | |||
641 | dvb_attach(isl6423_attach, | ||
642 | budget->dvb_frontend, | ||
643 | &budget->i2c_adap, | ||
644 | &tt1600_isl6423_config); | ||
645 | |||
646 | } else { | ||
647 | dvb_frontend_detach(budget->dvb_frontend); | ||
648 | budget->dvb_frontend = NULL; | ||
649 | } | ||
650 | } | ||
651 | break; | ||
569 | } | 652 | } |
570 | 653 | ||
571 | if (budget->dvb_frontend == NULL) { | 654 | if (budget->dvb_frontend == NULL) { |
@@ -641,6 +724,7 @@ MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); | |||
641 | MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); | 724 | MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); |
642 | MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); | 725 | MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); |
643 | MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); | 726 | MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); |
727 | MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT); | ||
644 | MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); | 728 | MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); |
645 | MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); | 729 | MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); |
646 | MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); | 730 | MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); |
@@ -653,6 +737,7 @@ static struct pci_device_id pci_tbl[] = { | |||
653 | MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), | 737 | MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), |
654 | MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), | 738 | MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), |
655 | MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), | 739 | MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), |
740 | MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c), | ||
656 | MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), | 741 | MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), |
657 | MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), | 742 | MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), |
658 | MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60), | 743 | MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60), |
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 613576202294..ed9cd7ad0604 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c | |||
@@ -33,6 +33,10 @@ | |||
33 | 33 | ||
34 | History: | 34 | History: |
35 | 35 | ||
36 | Version 0.46: | ||
37 | Removed usb_dsbr100_open/close calls and radio->users counter. Also, | ||
38 | radio->muted changed to radio->status and suspend/resume calls updated. | ||
39 | |||
36 | Version 0.45: | 40 | Version 0.45: |
37 | Converted to v4l2_device. | 41 | Converted to v4l2_device. |
38 | 42 | ||
@@ -100,8 +104,8 @@ | |||
100 | */ | 104 | */ |
101 | #include <linux/version.h> /* for KERNEL_VERSION MACRO */ | 105 | #include <linux/version.h> /* for KERNEL_VERSION MACRO */ |
102 | 106 | ||
103 | #define DRIVER_VERSION "v0.45" | 107 | #define DRIVER_VERSION "v0.46" |
104 | #define RADIO_VERSION KERNEL_VERSION(0, 4, 5) | 108 | #define RADIO_VERSION KERNEL_VERSION(0, 4, 6) |
105 | 109 | ||
106 | #define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>" | 110 | #define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>" |
107 | #define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver" | 111 | #define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver" |
@@ -121,13 +125,15 @@ devices, that would be 76 and 91. */ | |||
121 | #define FREQ_MAX 108.0 | 125 | #define FREQ_MAX 108.0 |
122 | #define FREQ_MUL 16000 | 126 | #define FREQ_MUL 16000 |
123 | 127 | ||
128 | /* defines for radio->status */ | ||
129 | #define STARTED 0 | ||
130 | #define STOPPED 1 | ||
131 | |||
124 | #define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev) | 132 | #define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev) |
125 | 133 | ||
126 | static int usb_dsbr100_probe(struct usb_interface *intf, | 134 | static int usb_dsbr100_probe(struct usb_interface *intf, |
127 | const struct usb_device_id *id); | 135 | const struct usb_device_id *id); |
128 | static void usb_dsbr100_disconnect(struct usb_interface *intf); | 136 | static void usb_dsbr100_disconnect(struct usb_interface *intf); |
129 | static int usb_dsbr100_open(struct file *file); | ||
130 | static int usb_dsbr100_close(struct file *file); | ||
131 | static int usb_dsbr100_suspend(struct usb_interface *intf, | 137 | static int usb_dsbr100_suspend(struct usb_interface *intf, |
132 | pm_message_t message); | 138 | pm_message_t message); |
133 | static int usb_dsbr100_resume(struct usb_interface *intf); | 139 | static int usb_dsbr100_resume(struct usb_interface *intf); |
@@ -145,9 +151,8 @@ struct dsbr100_device { | |||
145 | struct mutex lock; /* buffer locking */ | 151 | struct mutex lock; /* buffer locking */ |
146 | int curfreq; | 152 | int curfreq; |
147 | int stereo; | 153 | int stereo; |
148 | int users; | ||
149 | int removed; | 154 | int removed; |
150 | int muted; | 155 | int status; |
151 | }; | 156 | }; |
152 | 157 | ||
153 | static struct usb_device_id usb_dsbr100_device_table [] = { | 158 | static struct usb_device_id usb_dsbr100_device_table [] = { |
@@ -201,7 +206,7 @@ static int dsbr100_start(struct dsbr100_device *radio) | |||
201 | goto usb_control_msg_failed; | 206 | goto usb_control_msg_failed; |
202 | } | 207 | } |
203 | 208 | ||
204 | radio->muted = 0; | 209 | radio->status = STARTED; |
205 | mutex_unlock(&radio->lock); | 210 | mutex_unlock(&radio->lock); |
206 | return (radio->transfer_buffer)[0]; | 211 | return (radio->transfer_buffer)[0]; |
207 | 212 | ||
@@ -244,7 +249,7 @@ static int dsbr100_stop(struct dsbr100_device *radio) | |||
244 | goto usb_control_msg_failed; | 249 | goto usb_control_msg_failed; |
245 | } | 250 | } |
246 | 251 | ||
247 | radio->muted = 1; | 252 | radio->status = STOPPED; |
248 | mutex_unlock(&radio->lock); | 253 | mutex_unlock(&radio->lock); |
249 | return (radio->transfer_buffer)[0]; | 254 | return (radio->transfer_buffer)[0]; |
250 | 255 | ||
@@ -258,12 +263,12 @@ usb_control_msg_failed: | |||
258 | } | 263 | } |
259 | 264 | ||
260 | /* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ | 265 | /* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ |
261 | static int dsbr100_setfreq(struct dsbr100_device *radio, int freq) | 266 | static int dsbr100_setfreq(struct dsbr100_device *radio) |
262 | { | 267 | { |
263 | int retval; | 268 | int retval; |
264 | int request; | 269 | int request; |
270 | int freq = (radio->curfreq / 16 * 80) / 1000 + 856; | ||
265 | 271 | ||
266 | freq = (freq / 16 * 80) / 1000 + 856; | ||
267 | mutex_lock(&radio->lock); | 272 | mutex_lock(&radio->lock); |
268 | 273 | ||
269 | retval = usb_control_msg(radio->usbdev, | 274 | retval = usb_control_msg(radio->usbdev, |
@@ -431,7 +436,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
431 | radio->curfreq = f->frequency; | 436 | radio->curfreq = f->frequency; |
432 | mutex_unlock(&radio->lock); | 437 | mutex_unlock(&radio->lock); |
433 | 438 | ||
434 | retval = dsbr100_setfreq(radio, radio->curfreq); | 439 | retval = dsbr100_setfreq(radio); |
435 | if (retval < 0) | 440 | if (retval < 0) |
436 | dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); | 441 | dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); |
437 | return 0; | 442 | return 0; |
@@ -473,7 +478,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
473 | 478 | ||
474 | switch (ctrl->id) { | 479 | switch (ctrl->id) { |
475 | case V4L2_CID_AUDIO_MUTE: | 480 | case V4L2_CID_AUDIO_MUTE: |
476 | ctrl->value = radio->muted; | 481 | ctrl->value = radio->status; |
477 | return 0; | 482 | return 0; |
478 | } | 483 | } |
479 | return -EINVAL; | 484 | return -EINVAL; |
@@ -543,65 +548,27 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
543 | return 0; | 548 | return 0; |
544 | } | 549 | } |
545 | 550 | ||
546 | static int usb_dsbr100_open(struct file *file) | ||
547 | { | ||
548 | struct dsbr100_device *radio = video_drvdata(file); | ||
549 | int retval; | ||
550 | |||
551 | lock_kernel(); | ||
552 | radio->users = 1; | ||
553 | radio->muted = 1; | ||
554 | |||
555 | retval = dsbr100_start(radio); | ||
556 | if (retval < 0) { | ||
557 | dev_warn(&radio->usbdev->dev, | ||
558 | "Radio did not start up properly\n"); | ||
559 | radio->users = 0; | ||
560 | unlock_kernel(); | ||
561 | return -EIO; | ||
562 | } | ||
563 | |||
564 | retval = dsbr100_setfreq(radio, radio->curfreq); | ||
565 | if (retval < 0) | ||
566 | dev_warn(&radio->usbdev->dev, | ||
567 | "set frequency failed\n"); | ||
568 | |||
569 | unlock_kernel(); | ||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | static int usb_dsbr100_close(struct file *file) | ||
574 | { | ||
575 | struct dsbr100_device *radio = video_drvdata(file); | ||
576 | int retval; | ||
577 | |||
578 | if (!radio) | ||
579 | return -ENODEV; | ||
580 | |||
581 | mutex_lock(&radio->lock); | ||
582 | radio->users = 0; | ||
583 | mutex_unlock(&radio->lock); | ||
584 | |||
585 | if (!radio->removed) { | ||
586 | retval = dsbr100_stop(radio); | ||
587 | if (retval < 0) { | ||
588 | dev_warn(&radio->usbdev->dev, | ||
589 | "dsbr100_stop failed\n"); | ||
590 | } | ||
591 | |||
592 | } | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | /* Suspend device - stop device. */ | 551 | /* Suspend device - stop device. */ |
597 | static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message) | 552 | static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message) |
598 | { | 553 | { |
599 | struct dsbr100_device *radio = usb_get_intfdata(intf); | 554 | struct dsbr100_device *radio = usb_get_intfdata(intf); |
600 | int retval; | 555 | int retval; |
601 | 556 | ||
602 | retval = dsbr100_stop(radio); | 557 | if (radio->status == STARTED) { |
603 | if (retval < 0) | 558 | retval = dsbr100_stop(radio); |
604 | dev_warn(&intf->dev, "dsbr100_stop failed\n"); | 559 | if (retval < 0) |
560 | dev_warn(&intf->dev, "dsbr100_stop failed\n"); | ||
561 | |||
562 | /* After dsbr100_stop() status set to STOPPED. | ||
563 | * If we want driver to start radio on resume | ||
564 | * we set status equal to STARTED. | ||
565 | * On resume we will check status and run radio if needed. | ||
566 | */ | ||
567 | |||
568 | mutex_lock(&radio->lock); | ||
569 | radio->status = STARTED; | ||
570 | mutex_unlock(&radio->lock); | ||
571 | } | ||
605 | 572 | ||
606 | dev_info(&intf->dev, "going into suspend..\n"); | 573 | dev_info(&intf->dev, "going into suspend..\n"); |
607 | 574 | ||
@@ -614,9 +581,11 @@ static int usb_dsbr100_resume(struct usb_interface *intf) | |||
614 | struct dsbr100_device *radio = usb_get_intfdata(intf); | 581 | struct dsbr100_device *radio = usb_get_intfdata(intf); |
615 | int retval; | 582 | int retval; |
616 | 583 | ||
617 | retval = dsbr100_start(radio); | 584 | if (radio->status == STARTED) { |
618 | if (retval < 0) | 585 | retval = dsbr100_start(radio); |
619 | dev_warn(&intf->dev, "dsbr100_start failed\n"); | 586 | if (retval < 0) |
587 | dev_warn(&intf->dev, "dsbr100_start failed\n"); | ||
588 | } | ||
620 | 589 | ||
621 | dev_info(&intf->dev, "coming out of suspend..\n"); | 590 | dev_info(&intf->dev, "coming out of suspend..\n"); |
622 | 591 | ||
@@ -636,8 +605,6 @@ static void usb_dsbr100_video_device_release(struct video_device *videodev) | |||
636 | /* File system interface */ | 605 | /* File system interface */ |
637 | static const struct v4l2_file_operations usb_dsbr100_fops = { | 606 | static const struct v4l2_file_operations usb_dsbr100_fops = { |
638 | .owner = THIS_MODULE, | 607 | .owner = THIS_MODULE, |
639 | .open = usb_dsbr100_open, | ||
640 | .release = usb_dsbr100_close, | ||
641 | .ioctl = video_ioctl2, | 608 | .ioctl = video_ioctl2, |
642 | }; | 609 | }; |
643 | 610 | ||
@@ -695,9 +662,9 @@ static int usb_dsbr100_probe(struct usb_interface *intf, | |||
695 | mutex_init(&radio->lock); | 662 | mutex_init(&radio->lock); |
696 | 663 | ||
697 | radio->removed = 0; | 664 | radio->removed = 0; |
698 | radio->users = 0; | ||
699 | radio->usbdev = interface_to_usbdev(intf); | 665 | radio->usbdev = interface_to_usbdev(intf); |
700 | radio->curfreq = FREQ_MIN * FREQ_MUL; | 666 | radio->curfreq = FREQ_MIN * FREQ_MUL; |
667 | radio->status = STOPPED; | ||
701 | 668 | ||
702 | video_set_drvdata(&radio->videodev, radio); | 669 | video_set_drvdata(&radio->videodev, radio); |
703 | 670 | ||
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index cab19d05e02f..837467f93805 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <media/v4l2-ioctl.h> | 64 | #include <media/v4l2-ioctl.h> |
65 | #include <linux/usb.h> | 65 | #include <linux/usb.h> |
66 | #include <linux/version.h> /* for KERNEL_VERSION MACRO */ | 66 | #include <linux/version.h> /* for KERNEL_VERSION MACRO */ |
67 | #include <linux/mutex.h> | ||
67 | 68 | ||
68 | /* driver and module definitions */ | 69 | /* driver and module definitions */ |
69 | #define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>" | 70 | #define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>" |
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 5cf6c45b91fe..49c4aab95dab 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
@@ -49,7 +49,6 @@ struct fmi | |||
49 | int io; | 49 | int io; |
50 | int curvol; /* 1 or 0 */ | 50 | int curvol; /* 1 or 0 */ |
51 | unsigned long curfreq; /* freq in kHz */ | 51 | unsigned long curfreq; /* freq in kHz */ |
52 | __u32 flags; | ||
53 | struct mutex lock; | 52 | struct mutex lock; |
54 | }; | 53 | }; |
55 | 54 | ||
@@ -57,7 +56,7 @@ static struct fmi fmi_card; | |||
57 | static struct pnp_dev *dev; | 56 | static struct pnp_dev *dev; |
58 | 57 | ||
59 | /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ | 58 | /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ |
60 | /* It is only useful to give freq in intervall of 800 (=0.05Mhz), | 59 | /* It is only useful to give freq in interval of 800 (=0.05Mhz), |
61 | * other bits will be truncated, e.g 92.7400016 -> 92.7, but | 60 | * other bits will be truncated, e.g 92.7400016 -> 92.7, but |
62 | * 92.7400017 -> 92.75 | 61 | * 92.7400017 -> 92.75 |
63 | */ | 62 | */ |
@@ -142,7 +141,6 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
142 | static int vidioc_g_tuner(struct file *file, void *priv, | 141 | static int vidioc_g_tuner(struct file *file, void *priv, |
143 | struct v4l2_tuner *v) | 142 | struct v4l2_tuner *v) |
144 | { | 143 | { |
145 | int mult; | ||
146 | struct fmi *fmi = video_drvdata(file); | 144 | struct fmi *fmi = video_drvdata(file); |
147 | 145 | ||
148 | if (v->index > 0) | 146 | if (v->index > 0) |
@@ -150,11 +148,10 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
150 | 148 | ||
151 | strlcpy(v->name, "FM", sizeof(v->name)); | 149 | strlcpy(v->name, "FM", sizeof(v->name)); |
152 | v->type = V4L2_TUNER_RADIO; | 150 | v->type = V4L2_TUNER_RADIO; |
153 | mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; | 151 | v->rangelow = RSF16_MINFREQ; |
154 | v->rangelow = RSF16_MINFREQ / mult; | 152 | v->rangehigh = RSF16_MAXFREQ; |
155 | v->rangehigh = RSF16_MAXFREQ / mult; | ||
156 | v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | 153 | v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; |
157 | v->capability = fmi->flags & V4L2_TUNER_CAP_LOW; | 154 | v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW; |
158 | v->audmode = V4L2_TUNER_MODE_STEREO; | 155 | v->audmode = V4L2_TUNER_MODE_STEREO; |
159 | v->signal = fmi_getsigstr(fmi); | 156 | v->signal = fmi_getsigstr(fmi); |
160 | return 0; | 157 | return 0; |
@@ -171,8 +168,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
171 | { | 168 | { |
172 | struct fmi *fmi = video_drvdata(file); | 169 | struct fmi *fmi = video_drvdata(file); |
173 | 170 | ||
174 | if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) | ||
175 | f->frequency *= 1000; | ||
176 | if (f->frequency < RSF16_MINFREQ || | 171 | if (f->frequency < RSF16_MINFREQ || |
177 | f->frequency > RSF16_MAXFREQ) | 172 | f->frequency > RSF16_MAXFREQ) |
178 | return -EINVAL; | 173 | return -EINVAL; |
@@ -189,8 +184,6 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
189 | 184 | ||
190 | f->type = V4L2_TUNER_RADIO; | 185 | f->type = V4L2_TUNER_RADIO; |
191 | f->frequency = fmi->curfreq; | 186 | f->frequency = fmi->curfreq; |
192 | if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) | ||
193 | f->frequency /= 1000; | ||
194 | return 0; | 187 | return 0; |
195 | } | 188 | } |
196 | 189 | ||
@@ -347,7 +340,6 @@ static int __init fmi_init(void) | |||
347 | return res; | 340 | return res; |
348 | } | 341 | } |
349 | 342 | ||
350 | fmi->flags = V4L2_TUNER_CAP_LOW; | ||
351 | strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name)); | 343 | strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name)); |
352 | fmi->vdev.v4l2_dev = v4l2_dev; | 344 | fmi->vdev.v4l2_dev = v4l2_dev; |
353 | fmi->vdev.fops = &fmi_fops; | 345 | fmi->vdev.fops = &fmi_fops; |
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 935ff9bcdfcc..a11414f648d4 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
@@ -61,13 +61,12 @@ struct fmr2 | |||
61 | int stereo; /* card is producing stereo audio */ | 61 | int stereo; /* card is producing stereo audio */ |
62 | unsigned long curfreq; /* freq in kHz */ | 62 | unsigned long curfreq; /* freq in kHz */ |
63 | int card_type; | 63 | int card_type; |
64 | u32 flags; | ||
65 | }; | 64 | }; |
66 | 65 | ||
67 | static struct fmr2 fmr2_card; | 66 | static struct fmr2 fmr2_card; |
68 | 67 | ||
69 | /* hw precision is 12.5 kHz | 68 | /* hw precision is 12.5 kHz |
70 | * It is only useful to give freq in intervall of 200 (=0.0125Mhz), | 69 | * It is only useful to give freq in interval of 200 (=0.0125Mhz), |
71 | * other bits will be truncated | 70 | * other bits will be truncated |
72 | */ | 71 | */ |
73 | #define RSF16_ENCODE(x) ((x) / 200 + 856) | 72 | #define RSF16_ENCODE(x) ((x) / 200 + 856) |
@@ -221,7 +220,6 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
221 | static int vidioc_g_tuner(struct file *file, void *priv, | 220 | static int vidioc_g_tuner(struct file *file, void *priv, |
222 | struct v4l2_tuner *v) | 221 | struct v4l2_tuner *v) |
223 | { | 222 | { |
224 | int mult; | ||
225 | struct fmr2 *fmr2 = video_drvdata(file); | 223 | struct fmr2 *fmr2 = video_drvdata(file); |
226 | 224 | ||
227 | if (v->index > 0) | 225 | if (v->index > 0) |
@@ -230,13 +228,12 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
230 | strlcpy(v->name, "FM", sizeof(v->name)); | 228 | strlcpy(v->name, "FM", sizeof(v->name)); |
231 | v->type = V4L2_TUNER_RADIO; | 229 | v->type = V4L2_TUNER_RADIO; |
232 | 230 | ||
233 | mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; | 231 | v->rangelow = RSF16_MINFREQ; |
234 | v->rangelow = RSF16_MINFREQ / mult; | 232 | v->rangehigh = RSF16_MAXFREQ; |
235 | v->rangehigh = RSF16_MAXFREQ / mult; | 233 | v->rxsubchans = fmr2->stereo ? V4L2_TUNER_SUB_STEREO : |
236 | v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | 234 | V4L2_TUNER_SUB_MONO; |
237 | v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW; | 235 | v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW; |
238 | v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO: | 236 | v->audmode = V4L2_TUNER_MODE_STEREO; |
239 | V4L2_TUNER_MODE_MONO; | ||
240 | mutex_lock(&fmr2->lock); | 237 | mutex_lock(&fmr2->lock); |
241 | v->signal = fmr2_getsigstr(fmr2); | 238 | v->signal = fmr2_getsigstr(fmr2); |
242 | mutex_unlock(&fmr2->lock); | 239 | mutex_unlock(&fmr2->lock); |
@@ -254,8 +251,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
254 | { | 251 | { |
255 | struct fmr2 *fmr2 = video_drvdata(file); | 252 | struct fmr2 *fmr2 = video_drvdata(file); |
256 | 253 | ||
257 | if (!(fmr2->flags & V4L2_TUNER_CAP_LOW)) | ||
258 | f->frequency *= 1000; | ||
259 | if (f->frequency < RSF16_MINFREQ || | 254 | if (f->frequency < RSF16_MINFREQ || |
260 | f->frequency > RSF16_MAXFREQ) | 255 | f->frequency > RSF16_MAXFREQ) |
261 | return -EINVAL; | 256 | return -EINVAL; |
@@ -279,8 +274,6 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
279 | 274 | ||
280 | f->type = V4L2_TUNER_RADIO; | 275 | f->type = V4L2_TUNER_RADIO; |
281 | f->frequency = fmr2->curfreq; | 276 | f->frequency = fmr2->curfreq; |
282 | if (!(fmr2->flags & V4L2_TUNER_CAP_LOW)) | ||
283 | f->frequency /= 1000; | ||
284 | return 0; | 277 | return 0; |
285 | } | 278 | } |
286 | 279 | ||
@@ -406,7 +399,6 @@ static int __init fmr2_init(void) | |||
406 | strlcpy(v4l2_dev->name, "sf16fmr2", sizeof(v4l2_dev->name)); | 399 | strlcpy(v4l2_dev->name, "sf16fmr2", sizeof(v4l2_dev->name)); |
407 | fmr2->io = io; | 400 | fmr2->io = io; |
408 | fmr2->stereo = 1; | 401 | fmr2->stereo = 1; |
409 | fmr2->flags = V4L2_TUNER_CAP_LOW; | ||
410 | mutex_init(&fmr2->lock); | 402 | mutex_init(&fmr2->lock); |
411 | 403 | ||
412 | if (!request_region(fmr2->io, 2, "sf16fmr2")) { | 404 | if (!request_region(fmr2->io, 2, "sf16fmr2")) { |
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index bd945d04dc90..640421ceb24a 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c | |||
@@ -1214,7 +1214,6 @@ static int si470x_fops_release(struct file *file) | |||
1214 | usb_autopm_put_interface(radio->intf); | 1214 | usb_autopm_put_interface(radio->intf); |
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | unlock: | ||
1218 | mutex_unlock(&radio->disconnect_lock); | 1217 | mutex_unlock(&radio->disconnect_lock); |
1219 | 1218 | ||
1220 | done: | 1219 | done: |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 57835f5715fc..94f440535c64 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -440,6 +440,24 @@ config VIDEO_ADV7175 | |||
440 | To compile this driver as a module, choose M here: the | 440 | To compile this driver as a module, choose M here: the |
441 | module will be called adv7175. | 441 | module will be called adv7175. |
442 | 442 | ||
443 | config VIDEO_THS7303 | ||
444 | tristate "THS7303 Video Amplifier" | ||
445 | depends on I2C | ||
446 | help | ||
447 | Support for TI THS7303 video amplifier | ||
448 | |||
449 | To compile this driver as a module, choose M here: the | ||
450 | module will be called ths7303. | ||
451 | |||
452 | config VIDEO_ADV7343 | ||
453 | tristate "ADV7343 video encoder" | ||
454 | depends on I2C | ||
455 | help | ||
456 | Support for Analog Devices I2C bus based ADV7343 encoder. | ||
457 | |||
458 | To compile this driver as a module, choose M here: the | ||
459 | module will be called adv7343. | ||
460 | |||
443 | comment "Video improvement chips" | 461 | comment "Video improvement chips" |
444 | 462 | ||
445 | config VIDEO_UPD64031A | 463 | config VIDEO_UPD64031A |
@@ -694,7 +712,7 @@ config VIDEO_CAFE_CCIC | |||
694 | 712 | ||
695 | config SOC_CAMERA | 713 | config SOC_CAMERA |
696 | tristate "SoC camera support" | 714 | tristate "SoC camera support" |
697 | depends on VIDEO_V4L2 && HAS_DMA | 715 | depends on VIDEO_V4L2 && HAS_DMA && I2C |
698 | select VIDEOBUF_GEN | 716 | select VIDEOBUF_GEN |
699 | help | 717 | help |
700 | SoC Camera is a common API to several cameras, not connecting | 718 | SoC Camera is a common API to several cameras, not connecting |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 3f1a0350a569..7fb3add1b387 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -12,6 +12,8 @@ omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o | |||
12 | 12 | ||
13 | videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o | 13 | videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o |
14 | 14 | ||
15 | # V4L2 core modules | ||
16 | |||
15 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o | 17 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o |
16 | ifeq ($(CONFIG_COMPAT),y) | 18 | ifeq ($(CONFIG_COMPAT),y) |
17 | obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o | 19 | obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o |
@@ -23,21 +25,15 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) | |||
23 | obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o | 25 | obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o |
24 | endif | 26 | endif |
25 | 27 | ||
26 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o | 28 | # All i2c modules must come first: |
27 | 29 | ||
28 | obj-$(CONFIG_VIDEO_BT848) += bt8xx/ | 30 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o |
29 | obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o | ||
30 | obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o | 31 | obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o |
31 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o | 32 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o |
32 | obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o | 33 | obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o |
33 | |||
34 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o | 34 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o |
35 | obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o | 35 | obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o |
36 | obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o | 36 | obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o |
37 | obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o | ||
38 | obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o | ||
39 | obj-$(CONFIG_VIDEO_W9966) += w9966.o | ||
40 | |||
41 | obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o | 37 | obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o |
42 | obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o | 38 | obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o |
43 | obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o | 39 | obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o |
@@ -49,16 +45,47 @@ obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o | |||
49 | obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o | 45 | obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o |
50 | obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o | 46 | obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o |
51 | obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o | 47 | obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o |
48 | obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o | ||
52 | obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o | 49 | obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o |
53 | obj-$(CONFIG_VIDEO_BT819) += bt819.o | 50 | obj-$(CONFIG_VIDEO_BT819) += bt819.o |
54 | obj-$(CONFIG_VIDEO_BT856) += bt856.o | 51 | obj-$(CONFIG_VIDEO_BT856) += bt856.o |
55 | obj-$(CONFIG_VIDEO_BT866) += bt866.o | 52 | obj-$(CONFIG_VIDEO_BT866) += bt866.o |
56 | obj-$(CONFIG_VIDEO_KS0127) += ks0127.o | 53 | obj-$(CONFIG_VIDEO_KS0127) += ks0127.o |
54 | obj-$(CONFIG_VIDEO_THS7303) += ths7303.o | ||
55 | obj-$(CONFIG_VIDEO_VINO) += indycam.o | ||
56 | obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o | ||
57 | obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o | ||
58 | obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o | ||
59 | obj-$(CONFIG_VIDEO_CS5345) += cs5345.o | ||
60 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o | ||
61 | obj-$(CONFIG_VIDEO_M52790) += m52790.o | ||
62 | obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o | ||
63 | obj-$(CONFIG_VIDEO_WM8775) += wm8775.o | ||
64 | obj-$(CONFIG_VIDEO_WM8739) += wm8739.o | ||
65 | obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o | ||
66 | obj-$(CONFIG_VIDEO_CX25840) += cx25840/ | ||
67 | obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o | ||
68 | obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o | ||
69 | obj-$(CONFIG_VIDEO_OV7670) += ov7670.o | ||
70 | obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o | ||
71 | obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o | ||
57 | 72 | ||
58 | obj-$(CONFIG_VIDEO_ZORAN) += zoran/ | 73 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o |
74 | obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o | ||
75 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o | ||
76 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o | ||
77 | obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o | ||
78 | obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o | ||
59 | 79 | ||
80 | # And now the v4l2 drivers: | ||
81 | |||
82 | obj-$(CONFIG_VIDEO_BT848) += bt8xx/ | ||
83 | obj-$(CONFIG_VIDEO_ZORAN) += zoran/ | ||
84 | obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o | ||
85 | obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o | ||
86 | obj-$(CONFIG_VIDEO_W9966) += w9966.o | ||
60 | obj-$(CONFIG_VIDEO_PMS) += pms.o | 87 | obj-$(CONFIG_VIDEO_PMS) += pms.o |
61 | obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o | 88 | obj-$(CONFIG_VIDEO_VINO) += vino.o |
62 | obj-$(CONFIG_VIDEO_STRADIS) += stradis.o | 89 | obj-$(CONFIG_VIDEO_STRADIS) += stradis.o |
63 | obj-$(CONFIG_VIDEO_CPIA) += cpia.o | 90 | obj-$(CONFIG_VIDEO_CPIA) += cpia.o |
64 | obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o | 91 | obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o |
@@ -69,17 +96,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/ | |||
69 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ | 96 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ |
70 | obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ | 97 | obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ |
71 | obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ | 98 | obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ |
72 | obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o | ||
73 | obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o | ||
74 | obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ | 99 | obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ |
75 | obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o | ||
76 | obj-$(CONFIG_VIDEO_CS5345) += cs5345.o | ||
77 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o | ||
78 | obj-$(CONFIG_VIDEO_M52790) += m52790.o | ||
79 | obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o | ||
80 | obj-$(CONFIG_VIDEO_WM8775) += wm8775.o | ||
81 | obj-$(CONFIG_VIDEO_WM8739) += wm8739.o | ||
82 | obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o | ||
83 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ | 100 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ |
84 | obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ | 101 | obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ |
85 | obj-$(CONFIG_VIDEO_MXB) += mxb.o | 102 | obj-$(CONFIG_VIDEO_MXB) += mxb.o |
@@ -92,19 +109,12 @@ obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o | |||
92 | obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o | 109 | obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o |
93 | obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o | 110 | obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o |
94 | obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o | 111 | obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o |
95 | obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o | ||
96 | 112 | ||
97 | obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o | 113 | obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o |
98 | 114 | ||
99 | obj-$(CONFIG_VIDEO_CX25840) += cx25840/ | ||
100 | obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o | ||
101 | obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o | ||
102 | obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o | 115 | obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o |
103 | 116 | ||
104 | obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o | 117 | obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o |
105 | obj-$(CONFIG_VIDEO_OV7670) += ov7670.o | ||
106 | |||
107 | obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o | ||
108 | 118 | ||
109 | obj-$(CONFIG_USB_DABUSB) += dabusb.o | 119 | obj-$(CONFIG_USB_DABUSB) += dabusb.o |
110 | obj-$(CONFIG_USB_OV511) += ov511.o | 120 | obj-$(CONFIG_USB_OV511) += ov511.o |
@@ -134,24 +144,21 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/ | |||
134 | obj-$(CONFIG_VIDEO_VIVI) += vivi.o | 144 | obj-$(CONFIG_VIDEO_VIVI) += vivi.o |
135 | obj-$(CONFIG_VIDEO_CX23885) += cx23885/ | 145 | obj-$(CONFIG_VIDEO_CX23885) += cx23885/ |
136 | 146 | ||
147 | obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o | ||
148 | obj-$(CONFIG_SOC_CAMERA) += soc_camera.o | ||
149 | obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o | ||
150 | # soc-camera host drivers have to be linked after camera drivers | ||
137 | obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o | 151 | obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o |
138 | obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o | 152 | obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o |
139 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o | 153 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o |
140 | obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o | 154 | obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o |
141 | obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o | ||
142 | obj-$(CONFIG_SOC_CAMERA) += soc_camera.o | ||
143 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o | ||
144 | obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o | ||
145 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o | ||
146 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o | ||
147 | obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o | ||
148 | obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o | ||
149 | obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o | ||
150 | 155 | ||
151 | obj-$(CONFIG_VIDEO_AU0828) += au0828/ | 156 | obj-$(CONFIG_VIDEO_AU0828) += au0828/ |
152 | 157 | ||
153 | obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/ | 158 | obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/ |
154 | 159 | ||
160 | obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o | ||
161 | |||
155 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 162 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
156 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 163 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
157 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | 164 | EXTRA_CFLAGS += -Idrivers/media/common/tuners |
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c new file mode 100644 index 000000000000..30f5caf5dda5 --- /dev/null +++ b/drivers/media/video/adv7343.c | |||
@@ -0,0 +1,534 @@ | |||
1 | /* | ||
2 | * adv7343 - ADV7343 Video Encoder Driver | ||
3 | * | ||
4 | * The encoder hardware does not support SECAM. | ||
5 | * | ||
6 | * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation version 2. | ||
11 | * | ||
12 | * This program is distributed .as is. WITHOUT ANY WARRANTY of any | ||
13 | * kind, whether express or implied; without even the implied warranty | ||
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/ctype.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/videodev2.h> | ||
26 | #include <linux/uaccess.h> | ||
27 | #include <linux/version.h> | ||
28 | |||
29 | #include <media/adv7343.h> | ||
30 | #include <media/v4l2-device.h> | ||
31 | #include <media/v4l2-chip-ident.h> | ||
32 | |||
33 | #include "adv7343_regs.h" | ||
34 | |||
35 | MODULE_DESCRIPTION("ADV7343 video encoder driver"); | ||
36 | MODULE_LICENSE("GPL"); | ||
37 | |||
38 | static int debug; | ||
39 | module_param(debug, int, 0644); | ||
40 | MODULE_PARM_DESC(debug, "Debug level 0-1"); | ||
41 | |||
42 | struct adv7343_state { | ||
43 | struct v4l2_subdev sd; | ||
44 | u8 reg00; | ||
45 | u8 reg01; | ||
46 | u8 reg02; | ||
47 | u8 reg35; | ||
48 | u8 reg80; | ||
49 | u8 reg82; | ||
50 | int bright; | ||
51 | int hue; | ||
52 | int gain; | ||
53 | u32 output; | ||
54 | v4l2_std_id std; | ||
55 | }; | ||
56 | |||
57 | static inline struct adv7343_state *to_state(struct v4l2_subdev *sd) | ||
58 | { | ||
59 | return container_of(sd, struct adv7343_state, sd); | ||
60 | } | ||
61 | |||
62 | static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value) | ||
63 | { | ||
64 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
65 | |||
66 | return i2c_smbus_write_byte_data(client, reg, value); | ||
67 | } | ||
68 | |||
69 | static const u8 adv7343_init_reg_val[] = { | ||
70 | ADV7343_SOFT_RESET, ADV7343_SOFT_RESET_DEFAULT, | ||
71 | ADV7343_POWER_MODE_REG, ADV7343_POWER_MODE_REG_DEFAULT, | ||
72 | |||
73 | ADV7343_HD_MODE_REG1, ADV7343_HD_MODE_REG1_DEFAULT, | ||
74 | ADV7343_HD_MODE_REG2, ADV7343_HD_MODE_REG2_DEFAULT, | ||
75 | ADV7343_HD_MODE_REG3, ADV7343_HD_MODE_REG3_DEFAULT, | ||
76 | ADV7343_HD_MODE_REG4, ADV7343_HD_MODE_REG4_DEFAULT, | ||
77 | ADV7343_HD_MODE_REG5, ADV7343_HD_MODE_REG5_DEFAULT, | ||
78 | ADV7343_HD_MODE_REG6, ADV7343_HD_MODE_REG6_DEFAULT, | ||
79 | ADV7343_HD_MODE_REG7, ADV7343_HD_MODE_REG7_DEFAULT, | ||
80 | |||
81 | ADV7343_SD_MODE_REG1, ADV7343_SD_MODE_REG1_DEFAULT, | ||
82 | ADV7343_SD_MODE_REG2, ADV7343_SD_MODE_REG2_DEFAULT, | ||
83 | ADV7343_SD_MODE_REG3, ADV7343_SD_MODE_REG3_DEFAULT, | ||
84 | ADV7343_SD_MODE_REG4, ADV7343_SD_MODE_REG4_DEFAULT, | ||
85 | ADV7343_SD_MODE_REG5, ADV7343_SD_MODE_REG5_DEFAULT, | ||
86 | ADV7343_SD_MODE_REG6, ADV7343_SD_MODE_REG6_DEFAULT, | ||
87 | ADV7343_SD_MODE_REG7, ADV7343_SD_MODE_REG7_DEFAULT, | ||
88 | ADV7343_SD_MODE_REG8, ADV7343_SD_MODE_REG8_DEFAULT, | ||
89 | |||
90 | ADV7343_SD_HUE_REG, ADV7343_SD_HUE_REG_DEFAULT, | ||
91 | ADV7343_SD_CGMS_WSS0, ADV7343_SD_CGMS_WSS0_DEFAULT, | ||
92 | ADV7343_SD_BRIGHTNESS_WSS, ADV7343_SD_BRIGHTNESS_WSS_DEFAULT, | ||
93 | }; | ||
94 | |||
95 | /* | ||
96 | * 2^32 | ||
97 | * FSC(reg) = FSC (HZ) * -------- | ||
98 | * 27000000 | ||
99 | */ | ||
100 | static const struct adv7343_std_info stdinfo[] = { | ||
101 | { | ||
102 | /* FSC(Hz) = 3,579,545.45 Hz */ | ||
103 | SD_STD_NTSC, 569408542, V4L2_STD_NTSC, | ||
104 | }, { | ||
105 | /* FSC(Hz) = 3,575,611.00 Hz */ | ||
106 | SD_STD_PAL_M, 568782678, V4L2_STD_PAL_M, | ||
107 | }, { | ||
108 | /* FSC(Hz) = 3,582,056.00 */ | ||
109 | SD_STD_PAL_N, 569807903, V4L2_STD_PAL_Nc, | ||
110 | }, { | ||
111 | /* FSC(Hz) = 4,433,618.75 Hz */ | ||
112 | SD_STD_PAL_N, 705268427, V4L2_STD_PAL_N, | ||
113 | }, { | ||
114 | /* FSC(Hz) = 4,433,618.75 Hz */ | ||
115 | SD_STD_PAL_BDGHI, 705268427, V4L2_STD_PAL, | ||
116 | }, { | ||
117 | /* FSC(Hz) = 4,433,618.75 Hz */ | ||
118 | SD_STD_NTSC, 705268427, V4L2_STD_NTSC_443, | ||
119 | }, { | ||
120 | /* FSC(Hz) = 4,433,618.75 Hz */ | ||
121 | SD_STD_PAL_M, 705268427, V4L2_STD_PAL_60, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | static int adv7343_setstd(struct v4l2_subdev *sd, v4l2_std_id std) | ||
126 | { | ||
127 | struct adv7343_state *state = to_state(sd); | ||
128 | struct adv7343_std_info *std_info; | ||
129 | int output_idx, num_std; | ||
130 | char *fsc_ptr; | ||
131 | u8 reg, val; | ||
132 | int err = 0; | ||
133 | int i = 0; | ||
134 | |||
135 | output_idx = state->output; | ||
136 | |||
137 | std_info = (struct adv7343_std_info *)stdinfo; | ||
138 | num_std = ARRAY_SIZE(stdinfo); | ||
139 | |||
140 | for (i = 0; i < num_std; i++) { | ||
141 | if (std_info[i].stdid & std) | ||
142 | break; | ||
143 | } | ||
144 | |||
145 | if (i == num_std) { | ||
146 | v4l2_dbg(1, debug, sd, | ||
147 | "Invalid std or std is not supported: %llx\n", | ||
148 | (unsigned long long)std); | ||
149 | return -EINVAL; | ||
150 | } | ||
151 | |||
152 | /* Set the standard */ | ||
153 | val = state->reg80 & (~(SD_STD_MASK)); | ||
154 | val |= std_info[i].standard_val3; | ||
155 | err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val); | ||
156 | if (err < 0) | ||
157 | goto setstd_exit; | ||
158 | |||
159 | state->reg80 = val; | ||
160 | |||
161 | /* Configure the input mode register */ | ||
162 | val = state->reg01 & (~((u8) INPUT_MODE_MASK)); | ||
163 | val |= SD_INPUT_MODE; | ||
164 | err = adv7343_write(sd, ADV7343_MODE_SELECT_REG, val); | ||
165 | if (err < 0) | ||
166 | goto setstd_exit; | ||
167 | |||
168 | state->reg01 = val; | ||
169 | |||
170 | /* Program the sub carrier frequency registers */ | ||
171 | fsc_ptr = (unsigned char *)&std_info[i].fsc_val; | ||
172 | reg = ADV7343_FSC_REG0; | ||
173 | for (i = 0; i < 4; i++, reg++, fsc_ptr++) { | ||
174 | err = adv7343_write(sd, reg, *fsc_ptr); | ||
175 | if (err < 0) | ||
176 | goto setstd_exit; | ||
177 | } | ||
178 | |||
179 | val = state->reg80; | ||
180 | |||
181 | /* Filter settings */ | ||
182 | if (std & (V4L2_STD_NTSC | V4L2_STD_NTSC_443)) | ||
183 | val &= 0x03; | ||
184 | else if (std & ~V4L2_STD_SECAM) | ||
185 | val |= 0x04; | ||
186 | |||
187 | err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val); | ||
188 | if (err < 0) | ||
189 | goto setstd_exit; | ||
190 | |||
191 | state->reg80 = val; | ||
192 | |||
193 | setstd_exit: | ||
194 | if (err != 0) | ||
195 | v4l2_err(sd, "Error setting std, write failed\n"); | ||
196 | |||
197 | return err; | ||
198 | } | ||
199 | |||
200 | static int adv7343_setoutput(struct v4l2_subdev *sd, u32 output_type) | ||
201 | { | ||
202 | struct adv7343_state *state = to_state(sd); | ||
203 | unsigned char val; | ||
204 | int err = 0; | ||
205 | |||
206 | if (output_type > ADV7343_SVIDEO_ID) { | ||
207 | v4l2_dbg(1, debug, sd, | ||
208 | "Invalid output type or output type not supported:%d\n", | ||
209 | output_type); | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | /* Enable Appropriate DAC */ | ||
214 | val = state->reg00 & 0x03; | ||
215 | |||
216 | if (output_type == ADV7343_COMPOSITE_ID) | ||
217 | val |= ADV7343_COMPOSITE_POWER_VALUE; | ||
218 | else if (output_type == ADV7343_COMPONENT_ID) | ||
219 | val |= ADV7343_COMPONENT_POWER_VALUE; | ||
220 | else | ||
221 | val |= ADV7343_SVIDEO_POWER_VALUE; | ||
222 | |||
223 | err = adv7343_write(sd, ADV7343_POWER_MODE_REG, val); | ||
224 | if (err < 0) | ||
225 | goto setoutput_exit; | ||
226 | |||
227 | state->reg00 = val; | ||
228 | |||
229 | /* Enable YUV output */ | ||
230 | val = state->reg02 | YUV_OUTPUT_SELECT; | ||
231 | err = adv7343_write(sd, ADV7343_MODE_REG0, val); | ||
232 | if (err < 0) | ||
233 | goto setoutput_exit; | ||
234 | |||
235 | state->reg02 = val; | ||
236 | |||
237 | /* configure SD DAC Output 2 and SD DAC Output 1 bit to zero */ | ||
238 | val = state->reg82 & (SD_DAC_1_DI & SD_DAC_2_DI); | ||
239 | err = adv7343_write(sd, ADV7343_SD_MODE_REG2, val); | ||
240 | if (err < 0) | ||
241 | goto setoutput_exit; | ||
242 | |||
243 | state->reg82 = val; | ||
244 | |||
245 | /* configure ED/HD Color DAC Swap and ED/HD RGB Input Enable bit to | ||
246 | * zero */ | ||
247 | val = state->reg35 & (HD_RGB_INPUT_DI & HD_DAC_SWAP_DI); | ||
248 | err = adv7343_write(sd, ADV7343_HD_MODE_REG6, val); | ||
249 | if (err < 0) | ||
250 | goto setoutput_exit; | ||
251 | |||
252 | state->reg35 = val; | ||
253 | |||
254 | setoutput_exit: | ||
255 | if (err != 0) | ||
256 | v4l2_err(sd, "Error setting output, write failed\n"); | ||
257 | |||
258 | return err; | ||
259 | } | ||
260 | |||
261 | static int adv7343_log_status(struct v4l2_subdev *sd) | ||
262 | { | ||
263 | struct adv7343_state *state = to_state(sd); | ||
264 | |||
265 | v4l2_info(sd, "Standard: %llx\n", (unsigned long long)state->std); | ||
266 | v4l2_info(sd, "Output: %s\n", (state->output == 0) ? "Composite" : | ||
267 | ((state->output == 1) ? "Component" : "S-Video")); | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static int adv7343_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | ||
272 | { | ||
273 | switch (qc->id) { | ||
274 | case V4L2_CID_BRIGHTNESS: | ||
275 | return v4l2_ctrl_query_fill(qc, ADV7343_BRIGHTNESS_MIN, | ||
276 | ADV7343_BRIGHTNESS_MAX, 1, | ||
277 | ADV7343_BRIGHTNESS_DEF); | ||
278 | case V4L2_CID_HUE: | ||
279 | return v4l2_ctrl_query_fill(qc, ADV7343_HUE_MIN, | ||
280 | ADV7343_HUE_MAX, 1 , | ||
281 | ADV7343_HUE_DEF); | ||
282 | case V4L2_CID_GAIN: | ||
283 | return v4l2_ctrl_query_fill(qc, ADV7343_GAIN_MIN, | ||
284 | ADV7343_GAIN_MAX, 1, | ||
285 | ADV7343_GAIN_DEF); | ||
286 | default: | ||
287 | break; | ||
288 | } | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static int adv7343_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
294 | { | ||
295 | struct adv7343_state *state = to_state(sd); | ||
296 | int err = 0; | ||
297 | |||
298 | switch (ctrl->id) { | ||
299 | case V4L2_CID_BRIGHTNESS: | ||
300 | if (ctrl->value < ADV7343_BRIGHTNESS_MIN || | ||
301 | ctrl->value > ADV7343_BRIGHTNESS_MAX) { | ||
302 | v4l2_dbg(1, debug, sd, | ||
303 | "invalid brightness settings %d\n", | ||
304 | ctrl->value); | ||
305 | return -ERANGE; | ||
306 | } | ||
307 | |||
308 | state->bright = ctrl->value; | ||
309 | err = adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS, | ||
310 | state->bright); | ||
311 | break; | ||
312 | |||
313 | case V4L2_CID_HUE: | ||
314 | if (ctrl->value < ADV7343_HUE_MIN || | ||
315 | ctrl->value > ADV7343_HUE_MAX) { | ||
316 | v4l2_dbg(1, debug, sd, "invalid hue settings %d\n", | ||
317 | ctrl->value); | ||
318 | return -ERANGE; | ||
319 | } | ||
320 | |||
321 | state->hue = ctrl->value; | ||
322 | err = adv7343_write(sd, ADV7343_SD_HUE_REG, state->hue); | ||
323 | break; | ||
324 | |||
325 | case V4L2_CID_GAIN: | ||
326 | if (ctrl->value < ADV7343_GAIN_MIN || | ||
327 | ctrl->value > ADV7343_GAIN_MAX) { | ||
328 | v4l2_dbg(1, debug, sd, "invalid gain settings %d\n", | ||
329 | ctrl->value); | ||
330 | return -ERANGE; | ||
331 | } | ||
332 | |||
333 | if ((ctrl->value > POSITIVE_GAIN_MAX) && | ||
334 | (ctrl->value < NEGATIVE_GAIN_MIN)) { | ||
335 | v4l2_dbg(1, debug, sd, | ||
336 | "gain settings not within the specified range\n"); | ||
337 | return -ERANGE; | ||
338 | } | ||
339 | |||
340 | state->gain = ctrl->value; | ||
341 | err = adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, state->gain); | ||
342 | break; | ||
343 | |||
344 | default: | ||
345 | return -EINVAL; | ||
346 | } | ||
347 | |||
348 | if (err < 0) | ||
349 | v4l2_err(sd, "Failed to set the encoder controls\n"); | ||
350 | |||
351 | return err; | ||
352 | } | ||
353 | |||
354 | static int adv7343_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
355 | { | ||
356 | struct adv7343_state *state = to_state(sd); | ||
357 | |||
358 | switch (ctrl->id) { | ||
359 | case V4L2_CID_BRIGHTNESS: | ||
360 | ctrl->value = state->bright; | ||
361 | break; | ||
362 | |||
363 | case V4L2_CID_HUE: | ||
364 | ctrl->value = state->hue; | ||
365 | break; | ||
366 | |||
367 | case V4L2_CID_GAIN: | ||
368 | ctrl->value = state->gain; | ||
369 | break; | ||
370 | |||
371 | default: | ||
372 | return -EINVAL; | ||
373 | } | ||
374 | |||
375 | return 0; | ||
376 | } | ||
377 | |||
378 | static int adv7343_g_chip_ident(struct v4l2_subdev *sd, | ||
379 | struct v4l2_dbg_chip_ident *chip) | ||
380 | { | ||
381 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
382 | |||
383 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0); | ||
384 | } | ||
385 | |||
386 | static const struct v4l2_subdev_core_ops adv7343_core_ops = { | ||
387 | .log_status = adv7343_log_status, | ||
388 | .g_chip_ident = adv7343_g_chip_ident, | ||
389 | .g_ctrl = adv7343_g_ctrl, | ||
390 | .s_ctrl = adv7343_s_ctrl, | ||
391 | .queryctrl = adv7343_queryctrl, | ||
392 | }; | ||
393 | |||
394 | static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) | ||
395 | { | ||
396 | struct adv7343_state *state = to_state(sd); | ||
397 | int err = 0; | ||
398 | |||
399 | if (state->std == std) | ||
400 | return 0; | ||
401 | |||
402 | err = adv7343_setstd(sd, std); | ||
403 | if (!err) | ||
404 | state->std = std; | ||
405 | |||
406 | return err; | ||
407 | } | ||
408 | |||
409 | static int adv7343_s_routing(struct v4l2_subdev *sd, | ||
410 | u32 input, u32 output, u32 config) | ||
411 | { | ||
412 | struct adv7343_state *state = to_state(sd); | ||
413 | int err = 0; | ||
414 | |||
415 | if (state->output == output) | ||
416 | return 0; | ||
417 | |||
418 | err = adv7343_setoutput(sd, output); | ||
419 | if (!err) | ||
420 | state->output = output; | ||
421 | |||
422 | return err; | ||
423 | } | ||
424 | |||
425 | static const struct v4l2_subdev_video_ops adv7343_video_ops = { | ||
426 | .s_std_output = adv7343_s_std_output, | ||
427 | .s_routing = adv7343_s_routing, | ||
428 | }; | ||
429 | |||
430 | static const struct v4l2_subdev_ops adv7343_ops = { | ||
431 | .core = &adv7343_core_ops, | ||
432 | .video = &adv7343_video_ops, | ||
433 | }; | ||
434 | |||
435 | static int adv7343_initialize(struct v4l2_subdev *sd) | ||
436 | { | ||
437 | struct adv7343_state *state = to_state(sd); | ||
438 | int err = 0; | ||
439 | int i; | ||
440 | |||
441 | for (i = 0; i < ARRAY_SIZE(adv7343_init_reg_val); i += 2) { | ||
442 | |||
443 | err = adv7343_write(sd, adv7343_init_reg_val[i], | ||
444 | adv7343_init_reg_val[i+1]); | ||
445 | if (err) { | ||
446 | v4l2_err(sd, "Error initializing\n"); | ||
447 | return err; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | /* Configure for default video standard */ | ||
452 | err = adv7343_setoutput(sd, state->output); | ||
453 | if (err < 0) { | ||
454 | v4l2_err(sd, "Error setting output during init\n"); | ||
455 | return -EINVAL; | ||
456 | } | ||
457 | |||
458 | err = adv7343_setstd(sd, state->std); | ||
459 | if (err < 0) { | ||
460 | v4l2_err(sd, "Error setting std during init\n"); | ||
461 | return -EINVAL; | ||
462 | } | ||
463 | |||
464 | return err; | ||
465 | } | ||
466 | |||
467 | static int adv7343_probe(struct i2c_client *client, | ||
468 | const struct i2c_device_id *id) | ||
469 | { | ||
470 | struct adv7343_state *state; | ||
471 | |||
472 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
473 | return -ENODEV; | ||
474 | |||
475 | v4l_info(client, "chip found @ 0x%x (%s)\n", | ||
476 | client->addr << 1, client->adapter->name); | ||
477 | |||
478 | state = kzalloc(sizeof(struct adv7343_state), GFP_KERNEL); | ||
479 | if (state == NULL) | ||
480 | return -ENOMEM; | ||
481 | |||
482 | state->reg00 = 0x80; | ||
483 | state->reg01 = 0x00; | ||
484 | state->reg02 = 0x20; | ||
485 | state->reg35 = 0x00; | ||
486 | state->reg80 = ADV7343_SD_MODE_REG1_DEFAULT; | ||
487 | state->reg82 = ADV7343_SD_MODE_REG2_DEFAULT; | ||
488 | |||
489 | state->output = ADV7343_COMPOSITE_ID; | ||
490 | state->std = V4L2_STD_NTSC; | ||
491 | |||
492 | v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops); | ||
493 | return adv7343_initialize(&state->sd); | ||
494 | } | ||
495 | |||
496 | static int adv7343_remove(struct i2c_client *client) | ||
497 | { | ||
498 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
499 | |||
500 | v4l2_device_unregister_subdev(sd); | ||
501 | kfree(to_state(sd)); | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static const struct i2c_device_id adv7343_id[] = { | ||
507 | {"adv7343", 0}, | ||
508 | {}, | ||
509 | }; | ||
510 | |||
511 | MODULE_DEVICE_TABLE(i2c, adv7343_id); | ||
512 | |||
513 | static struct i2c_driver adv7343_driver = { | ||
514 | .driver = { | ||
515 | .owner = THIS_MODULE, | ||
516 | .name = "adv7343", | ||
517 | }, | ||
518 | .probe = adv7343_probe, | ||
519 | .remove = adv7343_remove, | ||
520 | .id_table = adv7343_id, | ||
521 | }; | ||
522 | |||
523 | static __init int init_adv7343(void) | ||
524 | { | ||
525 | return i2c_add_driver(&adv7343_driver); | ||
526 | } | ||
527 | |||
528 | static __exit void exit_adv7343(void) | ||
529 | { | ||
530 | i2c_del_driver(&adv7343_driver); | ||
531 | } | ||
532 | |||
533 | module_init(init_adv7343); | ||
534 | module_exit(exit_adv7343); | ||
diff --git a/drivers/media/video/adv7343_regs.h b/drivers/media/video/adv7343_regs.h new file mode 100644 index 000000000000..3431045b33da --- /dev/null +++ b/drivers/media/video/adv7343_regs.h | |||
@@ -0,0 +1,185 @@ | |||
1 | /* | ||
2 | * ADV7343 encoder related structure and register definitions | ||
3 | * | ||
4 | * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ | ||
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 as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed .as is. WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef ADV7343_REG_H | ||
17 | #define ADV7343_REGS_H | ||
18 | |||
19 | struct adv7343_std_info { | ||
20 | u32 standard_val3; | ||
21 | u32 fsc_val; | ||
22 | v4l2_std_id stdid; | ||
23 | }; | ||
24 | |||
25 | /* Register offset macros */ | ||
26 | #define ADV7343_POWER_MODE_REG (0x00) | ||
27 | #define ADV7343_MODE_SELECT_REG (0x01) | ||
28 | #define ADV7343_MODE_REG0 (0x02) | ||
29 | |||
30 | #define ADV7343_DAC2_OUTPUT_LEVEL (0x0b) | ||
31 | |||
32 | #define ADV7343_SOFT_RESET (0x17) | ||
33 | |||
34 | #define ADV7343_HD_MODE_REG1 (0x30) | ||
35 | #define ADV7343_HD_MODE_REG2 (0x31) | ||
36 | #define ADV7343_HD_MODE_REG3 (0x32) | ||
37 | #define ADV7343_HD_MODE_REG4 (0x33) | ||
38 | #define ADV7343_HD_MODE_REG5 (0x34) | ||
39 | #define ADV7343_HD_MODE_REG6 (0x35) | ||
40 | |||
41 | #define ADV7343_HD_MODE_REG7 (0x39) | ||
42 | |||
43 | #define ADV7343_SD_MODE_REG1 (0x80) | ||
44 | #define ADV7343_SD_MODE_REG2 (0x82) | ||
45 | #define ADV7343_SD_MODE_REG3 (0x83) | ||
46 | #define ADV7343_SD_MODE_REG4 (0x84) | ||
47 | #define ADV7343_SD_MODE_REG5 (0x86) | ||
48 | #define ADV7343_SD_MODE_REG6 (0x87) | ||
49 | #define ADV7343_SD_MODE_REG7 (0x88) | ||
50 | #define ADV7343_SD_MODE_REG8 (0x89) | ||
51 | |||
52 | #define ADV7343_FSC_REG0 (0x8C) | ||
53 | #define ADV7343_FSC_REG1 (0x8D) | ||
54 | #define ADV7343_FSC_REG2 (0x8E) | ||
55 | #define ADV7343_FSC_REG3 (0x8F) | ||
56 | |||
57 | #define ADV7343_SD_CGMS_WSS0 (0x99) | ||
58 | |||
59 | #define ADV7343_SD_HUE_REG (0xA0) | ||
60 | #define ADV7343_SD_BRIGHTNESS_WSS (0xA1) | ||
61 | |||
62 | /* Default values for the registers */ | ||
63 | #define ADV7343_POWER_MODE_REG_DEFAULT (0x10) | ||
64 | #define ADV7343_HD_MODE_REG1_DEFAULT (0x3C) /* Changed Default | ||
65 | 720p EAVSAV code*/ | ||
66 | #define ADV7343_HD_MODE_REG2_DEFAULT (0x01) /* Changed Pixel data | ||
67 | valid */ | ||
68 | #define ADV7343_HD_MODE_REG3_DEFAULT (0x00) /* Color delay 0 clks */ | ||
69 | #define ADV7343_HD_MODE_REG4_DEFAULT (0xE8) /* Changed */ | ||
70 | #define ADV7343_HD_MODE_REG5_DEFAULT (0x08) | ||
71 | #define ADV7343_HD_MODE_REG6_DEFAULT (0x00) | ||
72 | #define ADV7343_HD_MODE_REG7_DEFAULT (0x00) | ||
73 | #define ADV7343_SD_MODE_REG8_DEFAULT (0x00) | ||
74 | #define ADV7343_SOFT_RESET_DEFAULT (0x02) | ||
75 | #define ADV7343_COMPOSITE_POWER_VALUE (0x80) | ||
76 | #define ADV7343_COMPONENT_POWER_VALUE (0x1C) | ||
77 | #define ADV7343_SVIDEO_POWER_VALUE (0x60) | ||
78 | #define ADV7343_SD_HUE_REG_DEFAULT (127) | ||
79 | #define ADV7343_SD_BRIGHTNESS_WSS_DEFAULT (0x03) | ||
80 | |||
81 | #define ADV7343_SD_CGMS_WSS0_DEFAULT (0x10) | ||
82 | |||
83 | #define ADV7343_SD_MODE_REG1_DEFAULT (0x00) | ||
84 | #define ADV7343_SD_MODE_REG2_DEFAULT (0xC9) | ||
85 | #define ADV7343_SD_MODE_REG3_DEFAULT (0x10) | ||
86 | #define ADV7343_SD_MODE_REG4_DEFAULT (0x01) | ||
87 | #define ADV7343_SD_MODE_REG5_DEFAULT (0x02) | ||
88 | #define ADV7343_SD_MODE_REG6_DEFAULT (0x0C) | ||
89 | #define ADV7343_SD_MODE_REG7_DEFAULT (0x04) | ||
90 | #define ADV7343_SD_MODE_REG8_DEFAULT (0x00) | ||
91 | |||
92 | /* Bit masks for Mode Select Register */ | ||
93 | #define INPUT_MODE_MASK (0x70) | ||
94 | #define SD_INPUT_MODE (0x00) | ||
95 | #define HD_720P_INPUT_MODE (0x10) | ||
96 | #define HD_1080I_INPUT_MODE (0x10) | ||
97 | |||
98 | /* Bit masks for Mode Register 0 */ | ||
99 | #define TEST_PATTERN_BLACK_BAR_EN (0x04) | ||
100 | #define YUV_OUTPUT_SELECT (0x20) | ||
101 | #define RGB_OUTPUT_SELECT (0xDF) | ||
102 | |||
103 | /* Bit masks for DAC output levels */ | ||
104 | #define DAC_OUTPUT_LEVEL_MASK (0xFF) | ||
105 | #define POSITIVE_GAIN_MAX (0x40) | ||
106 | #define POSITIVE_GAIN_MIN (0x00) | ||
107 | #define NEGATIVE_GAIN_MAX (0xFF) | ||
108 | #define NEGATIVE_GAIN_MIN (0xC0) | ||
109 | |||
110 | /* Bit masks for soft reset register */ | ||
111 | #define SOFT_RESET (0x02) | ||
112 | |||
113 | /* Bit masks for HD Mode Register 1 */ | ||
114 | #define OUTPUT_STD_MASK (0x03) | ||
115 | #define OUTPUT_STD_SHIFT (0) | ||
116 | #define OUTPUT_STD_EIA0_2 (0x00) | ||
117 | #define OUTPUT_STD_EIA0_1 (0x01) | ||
118 | #define OUTPUT_STD_FULL (0x02) | ||
119 | #define EMBEDDED_SYNC (0x04) | ||
120 | #define EXTERNAL_SYNC (0xFB) | ||
121 | #define STD_MODE_SHIFT (3) | ||
122 | #define STD_MODE_MASK (0x1F) | ||
123 | #define STD_MODE_720P (0x05) | ||
124 | #define STD_MODE_720P_25 (0x08) | ||
125 | #define STD_MODE_720P_30 (0x07) | ||
126 | #define STD_MODE_720P_50 (0x06) | ||
127 | #define STD_MODE_1080I (0x0D) | ||
128 | #define STD_MODE_1080I_25fps (0x0E) | ||
129 | #define STD_MODE_1080P_24 (0x12) | ||
130 | #define STD_MODE_1080P_25 (0x10) | ||
131 | #define STD_MODE_1080P_30 (0x0F) | ||
132 | #define STD_MODE_525P (0x00) | ||
133 | #define STD_MODE_625P (0x03) | ||
134 | |||
135 | /* Bit masks for SD Mode Register 1 */ | ||
136 | #define SD_STD_MASK (0x03) | ||
137 | #define SD_STD_NTSC (0x00) | ||
138 | #define SD_STD_PAL_BDGHI (0x01) | ||
139 | #define SD_STD_PAL_M (0x02) | ||
140 | #define SD_STD_PAL_N (0x03) | ||
141 | #define SD_LUMA_FLTR_MASK (0x7) | ||
142 | #define SD_LUMA_FLTR_SHIFT (0x2) | ||
143 | #define SD_CHROMA_FLTR_MASK (0x7) | ||
144 | #define SD_CHROMA_FLTR_SHIFT (0x5) | ||
145 | |||
146 | /* Bit masks for SD Mode Register 2 */ | ||
147 | #define SD_PBPR_SSAF_EN (0x01) | ||
148 | #define SD_PBPR_SSAF_DI (0xFE) | ||
149 | #define SD_DAC_1_DI (0xFD) | ||
150 | #define SD_DAC_2_DI (0xFB) | ||
151 | #define SD_PEDESTAL_EN (0x08) | ||
152 | #define SD_PEDESTAL_DI (0xF7) | ||
153 | #define SD_SQUARE_PIXEL_EN (0x10) | ||
154 | #define SD_SQUARE_PIXEL_DI (0xEF) | ||
155 | #define SD_PIXEL_DATA_VALID (0x40) | ||
156 | #define SD_ACTIVE_EDGE_EN (0x80) | ||
157 | #define SD_ACTIVE_EDGE_DI (0x7F) | ||
158 | |||
159 | /* Bit masks for HD Mode Register 6 */ | ||
160 | #define HD_RGB_INPUT_EN (0x02) | ||
161 | #define HD_RGB_INPUT_DI (0xFD) | ||
162 | #define HD_PBPR_SYNC_EN (0x04) | ||
163 | #define HD_PBPR_SYNC_DI (0xFB) | ||
164 | #define HD_DAC_SWAP_EN (0x08) | ||
165 | #define HD_DAC_SWAP_DI (0xF7) | ||
166 | #define HD_GAMMA_CURVE_A (0xEF) | ||
167 | #define HD_GAMMA_CURVE_B (0x10) | ||
168 | #define HD_GAMMA_EN (0x20) | ||
169 | #define HD_GAMMA_DI (0xDF) | ||
170 | #define HD_ADPT_FLTR_MODEB (0x40) | ||
171 | #define HD_ADPT_FLTR_MODEA (0xBF) | ||
172 | #define HD_ADPT_FLTR_EN (0x80) | ||
173 | #define HD_ADPT_FLTR_DI (0x7F) | ||
174 | |||
175 | #define ADV7343_BRIGHTNESS_MAX (127) | ||
176 | #define ADV7343_BRIGHTNESS_MIN (0) | ||
177 | #define ADV7343_BRIGHTNESS_DEF (3) | ||
178 | #define ADV7343_HUE_MAX (255) | ||
179 | #define ADV7343_HUE_MIN (0) | ||
180 | #define ADV7343_HUE_DEF (127) | ||
181 | #define ADV7343_GAIN_MAX (255) | ||
182 | #define ADV7343_GAIN_MIN (0) | ||
183 | #define ADV7343_GAIN_DEF (0) | ||
184 | |||
185 | #endif | ||
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 053bbe8c8e3a..830c4a933f63 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c | |||
@@ -136,9 +136,9 @@ int au0828_tuner_callback(void *priv, int component, int command, int arg) | |||
136 | /* Tuner Reset Command from xc5000 */ | 136 | /* Tuner Reset Command from xc5000 */ |
137 | /* Drive the tuner into reset and out */ | 137 | /* Drive the tuner into reset and out */ |
138 | au0828_clear(dev, REG_001, 2); | 138 | au0828_clear(dev, REG_001, 2); |
139 | mdelay(200); | 139 | mdelay(10); |
140 | au0828_set(dev, REG_001, 2); | 140 | au0828_set(dev, REG_001, 2); |
141 | mdelay(50); | 141 | mdelay(10); |
142 | return 0; | 142 | return 0; |
143 | } else { | 143 | } else { |
144 | printk(KERN_ERR | 144 | printk(KERN_ERR |
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c index a1e4c0d769a6..3544a2f12f13 100644 --- a/drivers/media/video/au0828/au0828-core.c +++ b/drivers/media/video/au0828/au0828-core.c | |||
@@ -36,6 +36,11 @@ int au0828_debug; | |||
36 | module_param_named(debug, au0828_debug, int, 0644); | 36 | module_param_named(debug, au0828_debug, int, 0644); |
37 | MODULE_PARM_DESC(debug, "enable debug messages"); | 37 | MODULE_PARM_DESC(debug, "enable debug messages"); |
38 | 38 | ||
39 | static unsigned int disable_usb_speed_check; | ||
40 | module_param(disable_usb_speed_check, int, 0444); | ||
41 | MODULE_PARM_DESC(disable_usb_speed_check, | ||
42 | "override min bandwidth requirement of 480M bps"); | ||
43 | |||
39 | #define _AU0828_BULKPIPE 0x03 | 44 | #define _AU0828_BULKPIPE 0x03 |
40 | #define _BULKPIPESIZE 0xffff | 45 | #define _BULKPIPESIZE 0xffff |
41 | 46 | ||
@@ -181,6 +186,18 @@ static int au0828_usb_probe(struct usb_interface *interface, | |||
181 | le16_to_cpu(usbdev->descriptor.idProduct), | 186 | le16_to_cpu(usbdev->descriptor.idProduct), |
182 | ifnum); | 187 | ifnum); |
183 | 188 | ||
189 | /* | ||
190 | * Make sure we have 480 Mbps of bandwidth, otherwise things like | ||
191 | * video stream wouldn't likely work, since 12 Mbps is generally | ||
192 | * not enough even for most Digital TV streams. | ||
193 | */ | ||
194 | if (usbdev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { | ||
195 | printk(KERN_ERR "au0828: Device initialization failed.\n"); | ||
196 | printk(KERN_ERR "au0828: Device must be connected to a " | ||
197 | "high-speed USB 2.0 port.\n"); | ||
198 | return -ENODEV; | ||
199 | } | ||
200 | |||
184 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 201 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
185 | if (dev == NULL) { | 202 | if (dev == NULL) { |
186 | printk(KERN_ERR "%s() Unable to allocate memory\n", __func__); | 203 | printk(KERN_ERR "%s() Unable to allocate memory\n", __func__); |
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index 27bedc6c7791..51527d7b55a7 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c | |||
@@ -829,6 +829,9 @@ static int au0828_v4l2_close(struct file *filp) | |||
829 | 829 | ||
830 | au0828_uninit_isoc(dev); | 830 | au0828_uninit_isoc(dev); |
831 | 831 | ||
832 | /* Save some power by putting tuner to sleep */ | ||
833 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby); | ||
834 | |||
832 | /* When close the device, set the usb intf0 into alt0 to free | 835 | /* When close the device, set the usb intf0 into alt0 to free |
833 | USB bandwidth */ | 836 | USB bandwidth */ |
834 | ret = usb_set_interface(dev->usbdev, 0, 0); | 837 | ret = usb_set_interface(dev->usbdev, 0, 0); |
@@ -910,11 +913,6 @@ static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
910 | 913 | ||
911 | rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); | 914 | rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); |
912 | 915 | ||
913 | dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n", | ||
914 | (unsigned long)vma->vm_start, | ||
915 | (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, | ||
916 | rc); | ||
917 | |||
918 | return rc; | 916 | return rc; |
919 | } | 917 | } |
920 | 918 | ||
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 23b7499b3185..5eb1464af670 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -3152,6 +3152,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3152 | struct bttv_fh *fh = file->private_data; | 3152 | struct bttv_fh *fh = file->private_data; |
3153 | struct bttv_buffer *buf; | 3153 | struct bttv_buffer *buf; |
3154 | enum v4l2_field field; | 3154 | enum v4l2_field field; |
3155 | unsigned int rc = POLLERR; | ||
3155 | 3156 | ||
3156 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { | 3157 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { |
3157 | if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) | 3158 | if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) |
@@ -3160,9 +3161,10 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3160 | } | 3161 | } |
3161 | 3162 | ||
3162 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { | 3163 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { |
3164 | mutex_lock(&fh->cap.vb_lock); | ||
3163 | /* streaming capture */ | 3165 | /* streaming capture */ |
3164 | if (list_empty(&fh->cap.stream)) | 3166 | if (list_empty(&fh->cap.stream)) |
3165 | return POLLERR; | 3167 | goto err; |
3166 | buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); | 3168 | buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); |
3167 | } else { | 3169 | } else { |
3168 | /* read() capture */ | 3170 | /* read() capture */ |
@@ -3191,11 +3193,12 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3191 | poll_wait(file, &buf->vb.done, wait); | 3193 | poll_wait(file, &buf->vb.done, wait); |
3192 | if (buf->vb.state == VIDEOBUF_DONE || | 3194 | if (buf->vb.state == VIDEOBUF_DONE || |
3193 | buf->vb.state == VIDEOBUF_ERROR) | 3195 | buf->vb.state == VIDEOBUF_ERROR) |
3194 | return POLLIN|POLLRDNORM; | 3196 | rc = POLLIN|POLLRDNORM; |
3195 | return 0; | 3197 | else |
3198 | rc = 0; | ||
3196 | err: | 3199 | err: |
3197 | mutex_unlock(&fh->cap.vb_lock); | 3200 | mutex_unlock(&fh->cap.vb_lock); |
3198 | return POLLERR; | 3201 | return rc; |
3199 | } | 3202 | } |
3200 | 3203 | ||
3201 | static int bttv_open(struct file *file) | 3204 | static int bttv_open(struct file *file) |
@@ -4166,7 +4169,6 @@ static struct video_device *vdev_init(struct bttv *btv, | |||
4166 | if (NULL == vfd) | 4169 | if (NULL == vfd) |
4167 | return NULL; | 4170 | return NULL; |
4168 | *vfd = *template; | 4171 | *vfd = *template; |
4169 | vfd->minor = -1; | ||
4170 | vfd->v4l2_dev = &btv->c.v4l2_dev; | 4172 | vfd->v4l2_dev = &btv->c.v4l2_dev; |
4171 | vfd->release = video_device_release; | 4173 | vfd->release = video_device_release; |
4172 | vfd->debug = bttv_debug; | 4174 | vfd->debug = bttv_debug; |
@@ -4629,7 +4631,7 @@ static int __init bttv_init_module(void) | |||
4629 | #endif | 4631 | #endif |
4630 | if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) | 4632 | if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) |
4631 | gbuffers = 2; | 4633 | gbuffers = 2; |
4632 | if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF) | 4634 | if (gbufsize > BTTV_MAX_FBUF) |
4633 | gbufsize = BTTV_MAX_FBUF; | 4635 | gbufsize = BTTV_MAX_FBUF; |
4634 | gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK; | 4636 | gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK; |
4635 | if (bttv_verbose) | 4637 | if (bttv_verbose) |
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index a99d92fac3dc..ebd1ee9dc871 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c | |||
@@ -389,6 +389,27 @@ int __devinit init_bttv_i2c(struct bttv *btv) | |||
389 | } | 389 | } |
390 | if (0 == btv->i2c_rc && i2c_scan) | 390 | if (0 == btv->i2c_rc && i2c_scan) |
391 | do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); | 391 | do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); |
392 | |||
393 | /* Instantiate the IR receiver device, if present */ | ||
394 | if (0 == btv->i2c_rc) { | ||
395 | struct i2c_board_info info; | ||
396 | /* The external IR receiver is at i2c address 0x34 (0x35 for | ||
397 | reads). Future Hauppauge cards will have an internal | ||
398 | receiver at 0x30 (0x31 for reads). In theory, both can be | ||
399 | fitted, and Hauppauge suggest an external overrides an | ||
400 | internal. | ||
401 | |||
402 | That's why we probe 0x1a (~0x34) first. CB | ||
403 | */ | ||
404 | const unsigned short addr_list[] = { | ||
405 | 0x1a, 0x18, 0x4b, 0x64, 0x30, | ||
406 | I2C_CLIENT_END | ||
407 | }; | ||
408 | |||
409 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
410 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
411 | i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list); | ||
412 | } | ||
392 | return btv->i2c_rc; | 413 | return btv->i2c_rc; |
393 | } | 414 | } |
394 | 415 | ||
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index d4099f5312ac..0b4a8f309cfa 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
@@ -1064,7 +1064,7 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam) | |||
1064 | 1064 | ||
1065 | switch(m->id) { | 1065 | switch(m->id) { |
1066 | case CPIA2_CID_FLICKER_MODE: | 1066 | case CPIA2_CID_FLICKER_MODE: |
1067 | if(m->index < 0 || m->index >= NUM_FLICKER_CONTROLS) | 1067 | if (m->index >= NUM_FLICKER_CONTROLS) |
1068 | return -EINVAL; | 1068 | return -EINVAL; |
1069 | 1069 | ||
1070 | strcpy(m->name, flicker_controls[m->index].name); | 1070 | strcpy(m->name, flicker_controls[m->index].name); |
@@ -1082,14 +1082,14 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam) | |||
1082 | maximum = i; | 1082 | maximum = i; |
1083 | } | 1083 | } |
1084 | } | 1084 | } |
1085 | if(m->index < 0 || m->index > maximum) | 1085 | if (m->index > maximum) |
1086 | return -EINVAL; | 1086 | return -EINVAL; |
1087 | 1087 | ||
1088 | strcpy(m->name, framerate_controls[m->index].name); | 1088 | strcpy(m->name, framerate_controls[m->index].name); |
1089 | break; | 1089 | break; |
1090 | } | 1090 | } |
1091 | case CPIA2_CID_LIGHTS: | 1091 | case CPIA2_CID_LIGHTS: |
1092 | if(m->index < 0 || m->index >= NUM_LIGHTS_CONTROLS) | 1092 | if (m->index >= NUM_LIGHTS_CONTROLS) |
1093 | return -EINVAL; | 1093 | return -EINVAL; |
1094 | 1094 | ||
1095 | strcpy(m->name, lights_controls[m->index].name); | 1095 | strcpy(m->name, lights_controls[m->index].name); |
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c index 7a8ad5963de8..35268923911c 100644 --- a/drivers/media/video/cx18/cx18-audio.c +++ b/drivers/media/video/cx18/cx18-audio.c | |||
@@ -26,14 +26,18 @@ | |||
26 | #include "cx18-cards.h" | 26 | #include "cx18-cards.h" |
27 | #include "cx18-audio.h" | 27 | #include "cx18-audio.h" |
28 | 28 | ||
29 | #define CX18_AUDIO_ENABLE 0xc72014 | 29 | #define CX18_AUDIO_ENABLE 0xc72014 |
30 | #define CX18_AI1_MUX_MASK 0x30 | ||
31 | #define CX18_AI1_MUX_I2S1 0x00 | ||
32 | #define CX18_AI1_MUX_I2S2 0x10 | ||
33 | #define CX18_AI1_MUX_843_I2S 0x20 | ||
30 | 34 | ||
31 | /* Selects the audio input and output according to the current | 35 | /* Selects the audio input and output according to the current |
32 | settings. */ | 36 | settings. */ |
33 | int cx18_audio_set_io(struct cx18 *cx) | 37 | int cx18_audio_set_io(struct cx18 *cx) |
34 | { | 38 | { |
35 | const struct cx18_card_audio_input *in; | 39 | const struct cx18_card_audio_input *in; |
36 | u32 val; | 40 | u32 u, v; |
37 | int err; | 41 | int err; |
38 | 42 | ||
39 | /* Determine which input to use */ | 43 | /* Determine which input to use */ |
@@ -52,9 +56,37 @@ int cx18_audio_set_io(struct cx18 *cx) | |||
52 | return err; | 56 | return err; |
53 | 57 | ||
54 | /* FIXME - this internal mux should be abstracted to a subdev */ | 58 | /* FIXME - this internal mux should be abstracted to a subdev */ |
55 | val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30; | 59 | u = cx18_read_reg(cx, CX18_AUDIO_ENABLE); |
56 | val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : | 60 | v = u & ~CX18_AI1_MUX_MASK; |
57 | (in->audio_input << 4); | 61 | switch (in->audio_input) { |
58 | cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30); | 62 | case CX18_AV_AUDIO_SERIAL1: |
63 | v |= CX18_AI1_MUX_I2S1; | ||
64 | break; | ||
65 | case CX18_AV_AUDIO_SERIAL2: | ||
66 | v |= CX18_AI1_MUX_I2S2; | ||
67 | break; | ||
68 | default: | ||
69 | v |= CX18_AI1_MUX_843_I2S; | ||
70 | break; | ||
71 | } | ||
72 | if (v == u) { | ||
73 | /* force a toggle of some AI1 MUX control bits */ | ||
74 | u &= ~CX18_AI1_MUX_MASK; | ||
75 | switch (in->audio_input) { | ||
76 | case CX18_AV_AUDIO_SERIAL1: | ||
77 | u |= CX18_AI1_MUX_843_I2S; | ||
78 | break; | ||
79 | case CX18_AV_AUDIO_SERIAL2: | ||
80 | u |= CX18_AI1_MUX_843_I2S; | ||
81 | break; | ||
82 | default: | ||
83 | u |= CX18_AI1_MUX_I2S1; | ||
84 | break; | ||
85 | } | ||
86 | cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE, | ||
87 | u, CX18_AI1_MUX_MASK); | ||
88 | } | ||
89 | cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE, | ||
90 | v, CX18_AI1_MUX_MASK); | ||
59 | return 0; | 91 | return 0; |
60 | } | 92 | } |
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index cf2bd888a429..536dedb23ba3 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c | |||
@@ -99,9 +99,39 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, | |||
99 | or_value); | 99 | or_value); |
100 | } | 100 | } |
101 | 101 | ||
102 | static void cx18_av_initialize(struct cx18 *cx) | 102 | static int cx18_av_init(struct v4l2_subdev *sd, u32 val) |
103 | { | 103 | { |
104 | struct cx18_av_state *state = &cx->av_state; | 104 | struct cx18 *cx = v4l2_get_subdevdata(sd); |
105 | |||
106 | /* | ||
107 | * The crystal freq used in calculations in this driver will be | ||
108 | * 28.636360 MHz. | ||
109 | * Aim to run the PLLs' VCOs near 400 MHz to minimze errors. | ||
110 | */ | ||
111 | |||
112 | /* | ||
113 | * VDCLK Integer = 0x0f, Post Divider = 0x04 | ||
114 | * AIMCLK Integer = 0x0e, Post Divider = 0x16 | ||
115 | */ | ||
116 | cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f); | ||
117 | |||
118 | /* VDCLK Fraction = 0x2be2fe */ | ||
119 | /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */ | ||
120 | cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe); | ||
121 | |||
122 | /* AIMCLK Fraction = 0x05227ad */ | ||
123 | /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/ | ||
124 | cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad); | ||
125 | |||
126 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ | ||
127 | cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static void cx18_av_initialize(struct v4l2_subdev *sd) | ||
132 | { | ||
133 | struct cx18_av_state *state = to_cx18_av_state(sd); | ||
134 | struct cx18 *cx = v4l2_get_subdevdata(sd); | ||
105 | u32 v; | 135 | u32 v; |
106 | 136 | ||
107 | cx18_av_loadfw(cx); | 137 | cx18_av_loadfw(cx); |
@@ -150,6 +180,26 @@ static void cx18_av_initialize(struct cx18 *cx) | |||
150 | cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000); | 180 | cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000); |
151 | cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0); | 181 | cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0); |
152 | 182 | ||
183 | /* | ||
184 | * Disable Video Auto-config of the Analog Front End and Video PLL. | ||
185 | * | ||
186 | * Since we only use BT.656 pixel mode, which works for both 525 and 625 | ||
187 | * line systems, it's just easier for us to set registers | ||
188 | * 0x102 (CXADEC_CHIP_CTRL), 0x104-0x106 (CXADEC_AFE_CTRL), | ||
189 | * 0x108-0x109 (CXADEC_PLL_CTRL1), and 0x10c-0x10f (CXADEC_VID_PLL_FRAC) | ||
190 | * ourselves, than to run around cleaning up after the auto-config. | ||
191 | * | ||
192 | * (Note: my CX23418 chip doesn't seem to let the ACFG_DIS bit | ||
193 | * get set to 1, but OTOH, it doesn't seem to do AFE and VID PLL | ||
194 | * autoconfig either.) | ||
195 | * | ||
196 | * As a default, also turn off Dual mode for ADC2 and set ADC2 to CH3. | ||
197 | */ | ||
198 | cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000); | ||
199 | |||
200 | /* Setup the Video and and Aux/Audio PLLs */ | ||
201 | cx18_av_init(sd, 0); | ||
202 | |||
153 | /* set video to auto-detect */ | 203 | /* set video to auto-detect */ |
154 | /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ | 204 | /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ |
155 | /* set the comb notch = 1 */ | 205 | /* set the comb notch = 1 */ |
@@ -176,12 +226,23 @@ static void cx18_av_initialize(struct cx18 *cx) | |||
176 | /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */ | 226 | /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */ |
177 | /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */ | 227 | /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */ |
178 | 228 | ||
179 | v = cx18_av_read4(cx, CXADEC_AFE_CTRL); | 229 | /* |
180 | v &= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */ | 230 | * Analog Front End (AFE) |
181 | v &= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */ | 231 | * Default to luma on ch1/ADC1, chroma on ch2/ADC2, SIF on ch3/ADC2 |
182 | v &= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */ | 232 | * bypass_ch[1-3] use filter |
183 | /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */ | 233 | * droop_comp_ch[1-3] disable |
184 | cx18_av_write4(cx, CXADEC_AFE_CTRL, v); | 234 | * clamp_en_ch[1-3] disable |
235 | * aud_in_sel ADC2 | ||
236 | * luma_in_sel ADC1 | ||
237 | * chroma_in_sel ADC2 | ||
238 | * clamp_sel_ch[2-3] midcode | ||
239 | * clamp_sel_ch1 video decoder | ||
240 | * vga_sel_ch3 audio decoder | ||
241 | * vga_sel_ch[1-2] video decoder | ||
242 | * half_bw_ch[1-3] disable | ||
243 | * +12db_ch[1-3] disable | ||
244 | */ | ||
245 | cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00); | ||
185 | 246 | ||
186 | /* if(dwEnable && dw3DCombAvailable) { */ | 247 | /* if(dwEnable && dw3DCombAvailable) { */ |
187 | /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */ | 248 | /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */ |
@@ -195,50 +256,18 @@ static void cx18_av_initialize(struct cx18 *cx) | |||
195 | 256 | ||
196 | static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) | 257 | static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) |
197 | { | 258 | { |
198 | struct cx18 *cx = v4l2_get_subdevdata(sd); | 259 | cx18_av_initialize(sd); |
199 | |||
200 | cx18_av_initialize(cx); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int cx18_av_init(struct v4l2_subdev *sd, u32 val) | ||
205 | { | ||
206 | struct cx18 *cx = v4l2_get_subdevdata(sd); | ||
207 | |||
208 | /* | ||
209 | * The crystal freq used in calculations in this driver will be | ||
210 | * 28.636360 MHz. | ||
211 | * Aim to run the PLLs' VCOs near 400 MHz to minimze errors. | ||
212 | */ | ||
213 | |||
214 | /* | ||
215 | * VDCLK Integer = 0x0f, Post Divider = 0x04 | ||
216 | * AIMCLK Integer = 0x0e, Post Divider = 0x16 | ||
217 | */ | ||
218 | cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f); | ||
219 | |||
220 | /* VDCLK Fraction = 0x2be2fe */ | ||
221 | /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */ | ||
222 | cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe); | ||
223 | |||
224 | /* AIMCLK Fraction = 0x05227ad */ | ||
225 | /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/ | ||
226 | cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad); | ||
227 | |||
228 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ | ||
229 | cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); | ||
230 | return 0; | 260 | return 0; |
231 | } | 261 | } |
232 | 262 | ||
233 | static int cx18_av_load_fw(struct v4l2_subdev *sd) | 263 | static int cx18_av_load_fw(struct v4l2_subdev *sd) |
234 | { | 264 | { |
235 | struct cx18_av_state *state = to_cx18_av_state(sd); | 265 | struct cx18_av_state *state = to_cx18_av_state(sd); |
236 | struct cx18 *cx = v4l2_get_subdevdata(sd); | ||
237 | 266 | ||
238 | if (!state->is_initialized) { | 267 | if (!state->is_initialized) { |
239 | /* initialize on first use */ | 268 | /* initialize on first use */ |
240 | state->is_initialized = 1; | 269 | state->is_initialized = 1; |
241 | cx18_av_initialize(cx); | 270 | cx18_av_initialize(sd); |
242 | } | 271 | } |
243 | return 0; | 272 | return 0; |
244 | } | 273 | } |
@@ -248,8 +277,15 @@ void cx18_av_std_setup(struct cx18 *cx) | |||
248 | struct cx18_av_state *state = &cx->av_state; | 277 | struct cx18_av_state *state = &cx->av_state; |
249 | struct v4l2_subdev *sd = &state->sd; | 278 | struct v4l2_subdev *sd = &state->sd; |
250 | v4l2_std_id std = state->std; | 279 | v4l2_std_id std = state->std; |
280 | |||
281 | /* | ||
282 | * Video ADC crystal clock to pixel clock SRC decimation ratio | ||
283 | * 28.636360 MHz/13.5 Mpps * 256 = 0x21f.07b | ||
284 | */ | ||
285 | const int src_decimation = 0x21f; | ||
286 | |||
251 | int hblank, hactive, burst, vblank, vactive, sc; | 287 | int hblank, hactive, burst, vblank, vactive, sc; |
252 | int vblank656, src_decimation; | 288 | int vblank656; |
253 | int luma_lpf, uv_lpf, comb; | 289 | int luma_lpf, uv_lpf, comb; |
254 | u32 pll_int, pll_frac, pll_post; | 290 | u32 pll_int, pll_frac, pll_post; |
255 | 291 | ||
@@ -259,40 +295,96 @@ void cx18_av_std_setup(struct cx18 *cx) | |||
259 | else | 295 | else |
260 | cx18_av_write(cx, 0x49f, 0x14); | 296 | cx18_av_write(cx, 0x49f, 0x14); |
261 | 297 | ||
298 | /* | ||
299 | * Note: At the end of a field, there are 3 sets of half line duration | ||
300 | * (double horizontal rate) pulses: | ||
301 | * | ||
302 | * 5 (625) or 6 (525) half-lines to blank for the vertical retrace | ||
303 | * 5 (625) or 6 (525) vertical sync pulses of half line duration | ||
304 | * 5 (625) or 6 (525) half-lines of equalization pulses | ||
305 | */ | ||
262 | if (std & V4L2_STD_625_50) { | 306 | if (std & V4L2_STD_625_50) { |
263 | /* FIXME - revisit these for Sliced VBI */ | 307 | /* |
308 | * The following relationships of half line counts should hold: | ||
309 | * 625 = vblank656 + vactive | ||
310 | * 10 = vblank656 - vblank = vsync pulses + equalization pulses | ||
311 | * | ||
312 | * vblank656: half lines after line 625/mid-313 of blanked video | ||
313 | * vblank: half lines, after line 5/317, of blanked video | ||
314 | * vactive: half lines of active video + | ||
315 | * 5 half lines after the end of active video | ||
316 | * | ||
317 | * As far as I can tell: | ||
318 | * vblank656 starts counting from the falling edge of the first | ||
319 | * vsync pulse (start of line 1 or mid-313) | ||
320 | * vblank starts counting from the after the 5 vsync pulses and | ||
321 | * 5 or 4 equalization pulses (start of line 6 or 318) | ||
322 | * | ||
323 | * For 625 line systems the driver will extract VBI information | ||
324 | * from lines 6-23 and lines 318-335 (but the slicer can only | ||
325 | * handle 17 lines, not the 18 in the vblank region). | ||
326 | * In addition, we need vblank656 and vblank to be one whole | ||
327 | * line longer, to cover line 24 and 336, so the SAV/EAV RP | ||
328 | * codes get generated such that the encoder can actually | ||
329 | * extract line 23 & 335 (WSS). We'll lose 1 line in each field | ||
330 | * at the top of the screen. | ||
331 | * | ||
332 | * It appears the 5 half lines that happen after active | ||
333 | * video must be included in vactive (579 instead of 574), | ||
334 | * otherwise the colors get badly displayed in various regions | ||
335 | * of the screen. I guess the chroma comb filter gets confused | ||
336 | * without them (at least when a PVR-350 is the PAL source). | ||
337 | */ | ||
338 | vblank656 = 48; /* lines 1 - 24 & 313 - 336 */ | ||
339 | vblank = 38; /* lines 6 - 24 & 318 - 336 */ | ||
340 | vactive = 579; /* lines 24 - 313 & 337 - 626 */ | ||
341 | |||
342 | /* | ||
343 | * For a 13.5 Mpps clock and 15,625 Hz line rate, a line is | ||
344 | * is 864 pixels = 720 active + 144 blanking. ITU-R BT.601 | ||
345 | * specifies 12 luma clock periods or ~ 0.9 * 13.5 Mpps after | ||
346 | * the end of active video to start a horizontal line, so that | ||
347 | * leaves 132 pixels of hblank to ignore. | ||
348 | */ | ||
264 | hblank = 132; | 349 | hblank = 132; |
265 | hactive = 720; | 350 | hactive = 720; |
266 | burst = 93; | ||
267 | vblank = 36; | ||
268 | vactive = 580; | ||
269 | vblank656 = 40; | ||
270 | src_decimation = 0x21f; | ||
271 | 351 | ||
352 | /* | ||
353 | * Burst gate delay (for 625 line systems) | ||
354 | * Hsync leading edge to color burst rise = 5.6 us | ||
355 | * Color burst width = 2.25 us | ||
356 | * Gate width = 4 pixel clocks | ||
357 | * (5.6 us + 2.25/2 us) * 13.5 Mpps + 4/2 clocks = 92.79 clocks | ||
358 | */ | ||
359 | burst = 93; | ||
272 | luma_lpf = 2; | 360 | luma_lpf = 2; |
273 | if (std & V4L2_STD_PAL) { | 361 | if (std & V4L2_STD_PAL) { |
274 | uv_lpf = 1; | 362 | uv_lpf = 1; |
275 | comb = 0x20; | 363 | comb = 0x20; |
276 | sc = 688739; | 364 | /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */ |
365 | sc = 688700; | ||
277 | } else if (std == V4L2_STD_PAL_Nc) { | 366 | } else if (std == V4L2_STD_PAL_Nc) { |
278 | uv_lpf = 1; | 367 | uv_lpf = 1; |
279 | comb = 0x20; | 368 | comb = 0x20; |
280 | sc = 556453; | 369 | /* sc = 3582056.25 * src_decimation/28636360 * 2^13 */ |
370 | sc = 556422; | ||
281 | } else { /* SECAM */ | 371 | } else { /* SECAM */ |
282 | uv_lpf = 0; | 372 | uv_lpf = 0; |
283 | comb = 0; | 373 | comb = 0; |
284 | sc = 672351; | 374 | /* (fr + fb)/2 = (4406260 + 4250000)/2 = 4328130 */ |
375 | /* sc = 4328130 * src_decimation/28636360 * 2^13 */ | ||
376 | sc = 672314; | ||
285 | } | 377 | } |
286 | } else { | 378 | } else { |
287 | /* | 379 | /* |
288 | * The following relationships of half line counts should hold: | 380 | * The following relationships of half line counts should hold: |
289 | * 525 = vsync + vactive + vblank656 | 381 | * 525 = prevsync + vblank656 + vactive |
290 | * 12 = vblank656 - vblank | 382 | * 12 = vblank656 - vblank = vsync pulses + equalization pulses |
291 | * | 383 | * |
292 | * vsync: always 6 half-lines of vsync pulses | 384 | * prevsync: 6 half-lines before the vsync pulses |
293 | * vactive: half lines of active video | ||
294 | * vblank656: half lines, after line 3/mid-266, of blanked video | 385 | * vblank656: half lines, after line 3/mid-266, of blanked video |
295 | * vblank: half lines, after line 9/272, of blanked video | 386 | * vblank: half lines, after line 9/272, of blanked video |
387 | * vactive: half lines of active video | ||
296 | * | 388 | * |
297 | * As far as I can tell: | 389 | * As far as I can tell: |
298 | * vblank656 starts counting from the falling edge of the first | 390 | * vblank656 starts counting from the falling edge of the first |
@@ -319,20 +411,30 @@ void cx18_av_std_setup(struct cx18 *cx) | |||
319 | luma_lpf = 1; | 411 | luma_lpf = 1; |
320 | uv_lpf = 1; | 412 | uv_lpf = 1; |
321 | 413 | ||
322 | src_decimation = 0x21f; | 414 | /* |
415 | * Burst gate delay (for 525 line systems) | ||
416 | * Hsync leading edge to color burst rise = 5.3 us | ||
417 | * Color burst width = 2.5 us | ||
418 | * Gate width = 4 pixel clocks | ||
419 | * (5.3 us + 2.5/2 us) * 13.5 Mpps + 4/2 clocks = 90.425 clocks | ||
420 | */ | ||
323 | if (std == V4L2_STD_PAL_60) { | 421 | if (std == V4L2_STD_PAL_60) { |
324 | burst = 0x5b; | 422 | burst = 90; |
325 | luma_lpf = 2; | 423 | luma_lpf = 2; |
326 | comb = 0x20; | 424 | comb = 0x20; |
327 | sc = 688739; | 425 | /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */ |
426 | sc = 688700; | ||
328 | } else if (std == V4L2_STD_PAL_M) { | 427 | } else if (std == V4L2_STD_PAL_M) { |
329 | burst = 0x61; | 428 | /* The 97 needs to be verified against PAL-M timings */ |
429 | burst = 97; | ||
330 | comb = 0x20; | 430 | comb = 0x20; |
331 | sc = 555452; | 431 | /* sc = 3575611.49 * src_decimation/28636360 * 2^13 */ |
432 | sc = 555421; | ||
332 | } else { | 433 | } else { |
333 | burst = 0x5b; | 434 | burst = 90; |
334 | comb = 0x66; | 435 | comb = 0x66; |
335 | sc = 556063; | 436 | /* sc = 3579545.45.. * src_decimation/28636360 * 2^13 */ |
437 | sc = 556032; | ||
336 | } | 438 | } |
337 | } | 439 | } |
338 | 440 | ||
@@ -344,23 +446,26 @@ void cx18_av_std_setup(struct cx18 *cx) | |||
344 | pll_int, pll_frac, pll_post); | 446 | pll_int, pll_frac, pll_post); |
345 | 447 | ||
346 | if (pll_post) { | 448 | if (pll_post) { |
347 | int fin, fsc, pll; | 449 | int fsc, pll; |
450 | u64 tmp; | ||
348 | 451 | ||
349 | pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25; | 452 | pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25; |
350 | pll /= pll_post; | 453 | pll /= pll_post; |
351 | CX18_DEBUG_INFO_DEV(sd, "PLL = %d.%06d MHz\n", | 454 | CX18_DEBUG_INFO_DEV(sd, "Video PLL = %d.%06d MHz\n", |
352 | pll / 1000000, pll % 1000000); | 455 | pll / 1000000, pll % 1000000); |
353 | CX18_DEBUG_INFO_DEV(sd, "PLL/8 = %d.%06d MHz\n", | 456 | CX18_DEBUG_INFO_DEV(sd, "Pixel rate = %d.%06d Mpixel/sec\n", |
354 | pll / 8000000, (pll / 8) % 1000000); | 457 | pll / 8000000, (pll / 8) % 1000000); |
355 | 458 | ||
356 | fin = ((u64)src_decimation * pll) >> 12; | 459 | CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio " |
357 | CX18_DEBUG_INFO_DEV(sd, "ADC Sampling freq = %d.%06d MHz\n", | 460 | "= %d.%03d\n", src_decimation / 256, |
358 | fin / 1000000, fin % 1000000); | 461 | ((src_decimation % 256) * 1000) / 256); |
359 | 462 | ||
360 | fsc = (((u64)sc) * pll) >> 24L; | 463 | tmp = 28636360 * (u64) sc; |
464 | do_div(tmp, src_decimation); | ||
465 | fsc = tmp >> 13; | ||
361 | CX18_DEBUG_INFO_DEV(sd, | 466 | CX18_DEBUG_INFO_DEV(sd, |
362 | "Chroma sub-carrier freq = %d.%06d MHz\n", | 467 | "Chroma sub-carrier initial freq = %d.%06d " |
363 | fsc / 1000000, fsc % 1000000); | 468 | "MHz\n", fsc / 1000000, fsc % 1000000); |
364 | 469 | ||
365 | CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, " | 470 | CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, " |
366 | "vactive %i, vblank656 %i, src_dec %i, " | 471 | "vactive %i, vblank656 %i, src_dec %i, " |
@@ -470,16 +575,23 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | |||
470 | { | 575 | { |
471 | struct cx18_av_state *state = &cx->av_state; | 576 | struct cx18_av_state *state = &cx->av_state; |
472 | struct v4l2_subdev *sd = &state->sd; | 577 | struct v4l2_subdev *sd = &state->sd; |
473 | u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 && | 578 | |
474 | vid_input <= CX18_AV_COMPOSITE8); | 579 | enum analog_signal_type { |
475 | u8 reg; | 580 | NONE, CVBS, Y, C, SIF, Pb, Pr |
476 | u8 v; | 581 | } ch[3] = {NONE, NONE, NONE}; |
582 | |||
583 | u8 afe_mux_cfg; | ||
584 | u8 adc2_cfg; | ||
585 | u32 afe_cfg; | ||
586 | int i; | ||
477 | 587 | ||
478 | CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n", | 588 | CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n", |
479 | vid_input, aud_input); | 589 | vid_input, aud_input); |
480 | 590 | ||
481 | if (is_composite) { | 591 | if (vid_input >= CX18_AV_COMPOSITE1 && |
482 | reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1); | 592 | vid_input <= CX18_AV_COMPOSITE8) { |
593 | afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1); | ||
594 | ch[0] = CVBS; | ||
483 | } else { | 595 | } else { |
484 | int luma = vid_input & 0xf0; | 596 | int luma = vid_input & 0xf0; |
485 | int chroma = vid_input & 0xf00; | 597 | int chroma = vid_input & 0xf00; |
@@ -493,26 +605,45 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | |||
493 | vid_input); | 605 | vid_input); |
494 | return -EINVAL; | 606 | return -EINVAL; |
495 | } | 607 | } |
496 | reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4); | 608 | afe_mux_cfg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4); |
609 | ch[0] = Y; | ||
497 | if (chroma >= CX18_AV_SVIDEO_CHROMA7) { | 610 | if (chroma >= CX18_AV_SVIDEO_CHROMA7) { |
498 | reg &= 0x3f; | 611 | afe_mux_cfg &= 0x3f; |
499 | reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2; | 612 | afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2; |
613 | ch[2] = C; | ||
500 | } else { | 614 | } else { |
501 | reg &= 0xcf; | 615 | afe_mux_cfg &= 0xcf; |
502 | reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4; | 616 | afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4; |
617 | ch[1] = C; | ||
503 | } | 618 | } |
504 | } | 619 | } |
620 | /* TODO: LeadTek WinFast DVR3100 H & WinFast PVR2100 can do Y/Pb/Pr */ | ||
505 | 621 | ||
506 | switch (aud_input) { | 622 | switch (aud_input) { |
507 | case CX18_AV_AUDIO_SERIAL1: | 623 | case CX18_AV_AUDIO_SERIAL1: |
508 | case CX18_AV_AUDIO_SERIAL2: | 624 | case CX18_AV_AUDIO_SERIAL2: |
509 | /* do nothing, use serial audio input */ | 625 | /* do nothing, use serial audio input */ |
510 | break; | 626 | break; |
511 | case CX18_AV_AUDIO4: reg &= ~0x30; break; | 627 | case CX18_AV_AUDIO4: |
512 | case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break; | 628 | afe_mux_cfg &= ~0x30; |
513 | case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break; | 629 | ch[1] = SIF; |
514 | case CX18_AV_AUDIO7: reg &= ~0xc0; break; | 630 | break; |
515 | case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; | 631 | case CX18_AV_AUDIO5: |
632 | afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x10; | ||
633 | ch[1] = SIF; | ||
634 | break; | ||
635 | case CX18_AV_AUDIO6: | ||
636 | afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x20; | ||
637 | ch[1] = SIF; | ||
638 | break; | ||
639 | case CX18_AV_AUDIO7: | ||
640 | afe_mux_cfg &= ~0xc0; | ||
641 | ch[2] = SIF; | ||
642 | break; | ||
643 | case CX18_AV_AUDIO8: | ||
644 | afe_mux_cfg = (afe_mux_cfg & ~0xc0) | 0x40; | ||
645 | ch[2] = SIF; | ||
646 | break; | ||
516 | 647 | ||
517 | default: | 648 | default: |
518 | CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n", | 649 | CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n", |
@@ -520,24 +651,65 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | |||
520 | return -EINVAL; | 651 | return -EINVAL; |
521 | } | 652 | } |
522 | 653 | ||
523 | cx18_av_write_expect(cx, 0x103, reg, reg, 0xf7); | 654 | /* Set up analog front end multiplexers */ |
655 | cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7); | ||
524 | /* Set INPUT_MODE to Composite (0) or S-Video (1) */ | 656 | /* Set INPUT_MODE to Composite (0) or S-Video (1) */ |
525 | cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); | 657 | cx18_av_and_or(cx, 0x401, ~0x6, ch[0] == CVBS ? 0 : 0x02); |
526 | 658 | ||
527 | /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ | 659 | /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ |
528 | v = cx18_av_read(cx, 0x102); | 660 | adc2_cfg = cx18_av_read(cx, 0x102); |
529 | if (reg & 0x80) | 661 | if (ch[2] == NONE) |
530 | v &= ~0x2; | 662 | adc2_cfg &= ~0x2; /* No sig on CH3, set ADC2 to CH2 for input */ |
531 | else | 663 | else |
532 | v |= 0x2; | 664 | adc2_cfg |= 0x2; /* Signal on CH3, set ADC2 to CH3 for input */ |
665 | |||
533 | /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ | 666 | /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ |
534 | if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) | 667 | if (ch[1] != NONE && ch[2] != NONE) |
535 | v |= 0x4; | 668 | adc2_cfg |= 0x4; /* Set dual mode */ |
536 | else | 669 | else |
537 | v &= ~0x4; | 670 | adc2_cfg &= ~0x4; /* Clear dual mode */ |
538 | cx18_av_write_expect(cx, 0x102, v, v, 0x17); | 671 | cx18_av_write_expect(cx, 0x102, adc2_cfg, adc2_cfg, 0x17); |
672 | |||
673 | /* Configure the analog front end */ | ||
674 | afe_cfg = cx18_av_read4(cx, CXADEC_AFE_CTRL); | ||
675 | afe_cfg &= 0xff000000; | ||
676 | afe_cfg |= 0x00005000; /* CHROMA_IN, AUD_IN: ADC2; LUMA_IN: ADC1 */ | ||
677 | if (ch[1] != NONE && ch[2] != NONE) | ||
678 | afe_cfg |= 0x00000030; /* half_bw_ch[2-3] since in dual mode */ | ||
679 | |||
680 | for (i = 0; i < 3; i++) { | ||
681 | switch (ch[i]) { | ||
682 | default: | ||
683 | case NONE: | ||
684 | /* CLAMP_SEL = Fixed to midcode clamp level */ | ||
685 | afe_cfg |= (0x00000200 << i); | ||
686 | break; | ||
687 | case CVBS: | ||
688 | case Y: | ||
689 | if (i > 0) | ||
690 | afe_cfg |= 0x00002000; /* LUMA_IN_SEL: ADC2 */ | ||
691 | break; | ||
692 | case C: | ||
693 | case Pb: | ||
694 | case Pr: | ||
695 | /* CLAMP_SEL = Fixed to midcode clamp level */ | ||
696 | afe_cfg |= (0x00000200 << i); | ||
697 | if (i == 0 && ch[i] == C) | ||
698 | afe_cfg &= ~0x00001000; /* CHROMA_IN_SEL ADC1 */ | ||
699 | break; | ||
700 | case SIF: | ||
701 | /* | ||
702 | * VGA_GAIN_SEL = Audio Decoder | ||
703 | * CLAMP_SEL = Fixed to midcode clamp level | ||
704 | */ | ||
705 | afe_cfg |= (0x00000240 << i); | ||
706 | if (i == 0) | ||
707 | afe_cfg &= ~0x00004000; /* AUD_IN_SEL ADC1 */ | ||
708 | break; | ||
709 | } | ||
710 | } | ||
539 | 711 | ||
540 | /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/ | 712 | cx18_av_write4(cx, CXADEC_AFE_CTRL, afe_cfg); |
541 | 713 | ||
542 | state->vid_input = vid_input; | 714 | state->vid_input = vid_input; |
543 | state->aud_input = aud_input; | 715 | state->aud_input = aud_input; |
@@ -858,9 +1030,9 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |||
858 | * cx18_av_std_setup(), above standard values: | 1030 | * cx18_av_std_setup(), above standard values: |
859 | * | 1031 | * |
860 | * 480 + 1 for 60 Hz systems | 1032 | * 480 + 1 for 60 Hz systems |
861 | * 576 + 4 for 50 Hz systems | 1033 | * 576 + 3 for 50 Hz systems |
862 | */ | 1034 | */ |
863 | Vlines = pix->height + (is_50Hz ? 4 : 1); | 1035 | Vlines = pix->height + (is_50Hz ? 3 : 1); |
864 | 1036 | ||
865 | /* | 1037 | /* |
866 | * Invalid height and width scaling requests are: | 1038 | * Invalid height and width scaling requests are: |
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c index 49a55cc8d839..b9e8cc5d264a 100644 --- a/drivers/media/video/cx18/cx18-av-firmware.c +++ b/drivers/media/video/cx18/cx18-av-firmware.c | |||
@@ -24,15 +24,63 @@ | |||
24 | #include "cx18-io.h" | 24 | #include "cx18-io.h" |
25 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
26 | 26 | ||
27 | #define CX18_AUDIO_ENABLE 0xc72014 | 27 | #define CX18_AUDIO_ENABLE 0xc72014 |
28 | #define CX18_AI1_MUX_MASK 0x30 | ||
29 | #define CX18_AI1_MUX_I2S1 0x00 | ||
30 | #define CX18_AI1_MUX_I2S2 0x10 | ||
31 | #define CX18_AI1_MUX_843_I2S 0x20 | ||
32 | #define CX18_AI1_MUX_INVALID 0x30 | ||
33 | |||
28 | #define FWFILE "v4l-cx23418-dig.fw" | 34 | #define FWFILE "v4l-cx23418-dig.fw" |
29 | 35 | ||
36 | static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw) | ||
37 | { | ||
38 | struct v4l2_subdev *sd = &cx->av_state.sd; | ||
39 | int ret = 0; | ||
40 | const u8 *data; | ||
41 | u32 size; | ||
42 | int addr; | ||
43 | u32 expected, dl_control; | ||
44 | |||
45 | /* Ensure we put the 8051 in reset and enable firmware upload mode */ | ||
46 | dl_control = cx18_av_read4(cx, CXADEC_DL_CTL); | ||
47 | do { | ||
48 | dl_control &= 0x00ffffff; | ||
49 | dl_control |= 0x0f000000; | ||
50 | cx18_av_write4_noretry(cx, CXADEC_DL_CTL, dl_control); | ||
51 | dl_control = cx18_av_read4(cx, CXADEC_DL_CTL); | ||
52 | } while ((dl_control & 0xff000000) != 0x0f000000); | ||
53 | |||
54 | /* Read and auto increment until at address 0x0000 */ | ||
55 | while (dl_control & 0x3fff) | ||
56 | dl_control = cx18_av_read4(cx, CXADEC_DL_CTL); | ||
57 | |||
58 | data = fw->data; | ||
59 | size = fw->size; | ||
60 | for (addr = 0; addr < size; addr++) { | ||
61 | dl_control &= 0xffff3fff; /* ignore top 2 bits of address */ | ||
62 | expected = 0x0f000000 | ((u32)data[addr] << 16) | addr; | ||
63 | if (expected != dl_control) { | ||
64 | CX18_ERR_DEV(sd, "verification of %s firmware load " | ||
65 | "failed: expected %#010x got %#010x\n", | ||
66 | FWFILE, expected, dl_control); | ||
67 | ret = -EIO; | ||
68 | break; | ||
69 | } | ||
70 | dl_control = cx18_av_read4(cx, CXADEC_DL_CTL); | ||
71 | } | ||
72 | if (ret == 0) | ||
73 | CX18_INFO_DEV(sd, "verified load of %s firmware (%d bytes)\n", | ||
74 | FWFILE, size); | ||
75 | return ret; | ||
76 | } | ||
77 | |||
30 | int cx18_av_loadfw(struct cx18 *cx) | 78 | int cx18_av_loadfw(struct cx18 *cx) |
31 | { | 79 | { |
32 | struct v4l2_subdev *sd = &cx->av_state.sd; | 80 | struct v4l2_subdev *sd = &cx->av_state.sd; |
33 | const struct firmware *fw = NULL; | 81 | const struct firmware *fw = NULL; |
34 | u32 size; | 82 | u32 size; |
35 | u32 v; | 83 | u32 u, v; |
36 | const u8 *ptr; | 84 | const u8 *ptr; |
37 | int i; | 85 | int i; |
38 | int retries1 = 0; | 86 | int retries1 = 0; |
@@ -95,6 +143,12 @@ int cx18_av_loadfw(struct cx18 *cx) | |||
95 | } | 143 | } |
96 | 144 | ||
97 | cx18_av_write4_expect(cx, CXADEC_DL_CTL, | 145 | cx18_av_write4_expect(cx, CXADEC_DL_CTL, |
146 | 0x03000000 | fw->size, 0x03000000, 0x13000000); | ||
147 | |||
148 | CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size); | ||
149 | |||
150 | if (cx18_av_verifyfw(cx, fw) == 0) | ||
151 | cx18_av_write4_expect(cx, CXADEC_DL_CTL, | ||
98 | 0x13000000 | fw->size, 0x13000000, 0x13000000); | 152 | 0x13000000 | fw->size, 0x13000000, 0x13000000); |
99 | 153 | ||
100 | /* Output to the 416 */ | 154 | /* Output to the 416 */ |
@@ -135,6 +189,28 @@ int cx18_av_loadfw(struct cx18 *cx) | |||
135 | cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE, | 189 | cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE, |
136 | 0, 0x400); | 190 | 0, 0x400); |
137 | 191 | ||
192 | /* Toggle the AI1 MUX */ | ||
193 | v = cx18_read_reg(cx, CX18_AUDIO_ENABLE); | ||
194 | u = v & CX18_AI1_MUX_MASK; | ||
195 | v &= ~CX18_AI1_MUX_MASK; | ||
196 | if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) { | ||
197 | /* Switch to I2S1 */ | ||
198 | v |= CX18_AI1_MUX_I2S1; | ||
199 | cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE, | ||
200 | v, CX18_AI1_MUX_MASK); | ||
201 | /* Switch back to the A/V decoder core I2S output */ | ||
202 | v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S; | ||
203 | } else { | ||
204 | /* Switch to the A/V decoder core I2S output */ | ||
205 | v |= CX18_AI1_MUX_843_I2S; | ||
206 | cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE, | ||
207 | v, CX18_AI1_MUX_MASK); | ||
208 | /* Switch back to I2S1 or I2S2 */ | ||
209 | v = (v & ~CX18_AI1_MUX_MASK) | u; | ||
210 | } | ||
211 | cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE, | ||
212 | v, CX18_AI1_MUX_MASK); | ||
213 | |||
138 | /* Enable WW auto audio standard detection */ | 214 | /* Enable WW auto audio standard detection */ |
139 | v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); | 215 | v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); |
140 | v |= 0xFF; /* Auto by default */ | 216 | v |= 0xFF; /* Auto by default */ |
@@ -143,7 +219,5 @@ int cx18_av_loadfw(struct cx18 *cx) | |||
143 | cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF); | 219 | cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF); |
144 | 220 | ||
145 | release_firmware(fw); | 221 | release_firmware(fw); |
146 | |||
147 | CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size); | ||
148 | return 0; | 222 | return 0; |
149 | } | 223 | } |
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c index 23b31670bf1d..a51732bcca4b 100644 --- a/drivers/media/video/cx18/cx18-av-vbi.c +++ b/drivers/media/video/cx18/cx18-av-vbi.c | |||
@@ -255,8 +255,8 @@ int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | cx18_av_write(cx, 0x43c, 0x16); | 257 | cx18_av_write(cx, 0x43c, 0x16); |
258 | /* FIXME - should match vblank set in cx18_av_std_setup() */ | 258 | /* Should match vblank set in cx18_av_std_setup() */ |
259 | cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26); | 259 | cx18_av_write(cx, 0x474, is_pal ? 38 : 26); |
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
262 | 262 | ||
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 9bc221837847..c92a25036f0e 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c | |||
@@ -340,13 +340,12 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = { | |||
340 | 340 | ||
341 | static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = { | 341 | static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = { |
342 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */ | 342 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */ |
343 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */ | ||
344 | { 0, 0, 0 } | 343 | { 0, 0, 0 } |
345 | }; | 344 | }; |
346 | 345 | ||
347 | static const struct cx18_card cx18_card_leadtek_pvr2100 = { | 346 | static const struct cx18_card cx18_card_leadtek_pvr2100 = { |
348 | .type = CX18_CARD_LEADTEK_PVR2100, | 347 | .type = CX18_CARD_LEADTEK_PVR2100, |
349 | .name = "Leadtek WinFast PVR2100/DVR3100 H", | 348 | .name = "Leadtek WinFast PVR2100", |
350 | .comment = "Experimenters and photos needed for device to work well.\n" | 349 | .comment = "Experimenters and photos needed for device to work well.\n" |
351 | "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", | 350 | "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", |
352 | .v4l2_capabilities = CX18_CAP_ENCODER, | 351 | .v4l2_capabilities = CX18_CAP_ENCODER, |
@@ -365,15 +364,12 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = { | |||
365 | { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, | 364 | { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, |
366 | }, | 365 | }, |
367 | .tuners = { | 366 | .tuners = { |
368 | /* XC3028 tuner */ | 367 | /* XC2028 tuner */ |
369 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | 368 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, |
370 | }, | 369 | }, |
371 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, | 370 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, |
372 | .ddr = { | 371 | .ddr = { |
373 | /* | 372 | /* Pointer to proper DDR config values provided by Terry Wu */ |
374 | * Pointer to proper DDR config values provided by | ||
375 | * Terry Wu <terrywu at leadtek.com.tw> | ||
376 | */ | ||
377 | .chip_config = 0x303, | 373 | .chip_config = 0x303, |
378 | .refresh = 0x3bb, | 374 | .refresh = 0x3bb, |
379 | .timing1 = 0x24220e83, | 375 | .timing1 = 0x24220e83, |
@@ -392,6 +388,58 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = { | |||
392 | 388 | ||
393 | /* ------------------------------------------------------------------------- */ | 389 | /* ------------------------------------------------------------------------- */ |
394 | 390 | ||
391 | /* Leadtek WinFast DVR3100 H */ | ||
392 | |||
393 | static const struct cx18_card_pci_info cx18_pci_leadtek_dvr3100h[] = { | ||
394 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */ | ||
395 | { 0, 0, 0 } | ||
396 | }; | ||
397 | |||
398 | static const struct cx18_card cx18_card_leadtek_dvr3100h = { | ||
399 | .type = CX18_CARD_LEADTEK_DVR3100H, | ||
400 | .name = "Leadtek WinFast DVR3100 H", | ||
401 | .comment = "Simultaneous DVB-T and Analog capture supported,\n" | ||
402 | "\texcept when capturing Analog from the antenna input.\n", | ||
403 | .v4l2_capabilities = CX18_CAP_ENCODER, | ||
404 | .hw_audio_ctrl = CX18_HW_418_AV, | ||
405 | .hw_muxer = CX18_HW_GPIO_MUX, | ||
406 | .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX | | ||
407 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL, | ||
408 | .video_inputs = { | ||
409 | { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, | ||
410 | { CX18_CARD_INPUT_SVIDEO1, 1, | ||
411 | CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, | ||
412 | { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 }, | ||
413 | }, | ||
414 | .audio_inputs = { | ||
415 | { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, | ||
416 | { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, | ||
417 | }, | ||
418 | .tuners = { | ||
419 | /* XC3028 tuner */ | ||
420 | { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, | ||
421 | }, | ||
422 | .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, | ||
423 | .ddr = { | ||
424 | /* Pointer to proper DDR config values provided by Terry Wu */ | ||
425 | .chip_config = 0x303, | ||
426 | .refresh = 0x3bb, | ||
427 | .timing1 = 0x24220e83, | ||
428 | .timing2 = 0x1f, | ||
429 | .tune_lane = 0, | ||
430 | .initial_emrs = 0x2, | ||
431 | }, | ||
432 | .gpio_init.initial_value = 0x6, | ||
433 | .gpio_init.direction = 0x7, | ||
434 | .gpio_audio_input = { .mask = 0x7, | ||
435 | .tuner = 0x6, .linein = 0x2, .radio = 0x2 }, | ||
436 | .xceive_pin = 1, | ||
437 | .pci_list = cx18_pci_leadtek_dvr3100h, | ||
438 | .i2c = &cx18_i2c_std, | ||
439 | }; | ||
440 | |||
441 | /* ------------------------------------------------------------------------- */ | ||
442 | |||
395 | static const struct cx18_card *cx18_card_list[] = { | 443 | static const struct cx18_card *cx18_card_list[] = { |
396 | &cx18_card_hvr1600_esmt, | 444 | &cx18_card_hvr1600_esmt, |
397 | &cx18_card_hvr1600_samsung, | 445 | &cx18_card_hvr1600_samsung, |
@@ -400,6 +448,7 @@ static const struct cx18_card *cx18_card_list[] = { | |||
400 | &cx18_card_cnxt_raptor_pal, | 448 | &cx18_card_cnxt_raptor_pal, |
401 | &cx18_card_toshiba_qosmio_dvbt, | 449 | &cx18_card_toshiba_qosmio_dvbt, |
402 | &cx18_card_leadtek_pvr2100, | 450 | &cx18_card_leadtek_pvr2100, |
451 | &cx18_card_leadtek_dvr3100h, | ||
403 | }; | 452 | }; |
404 | 453 | ||
405 | const struct cx18_card *cx18_get_card(u16 index) | 454 | const struct cx18_card *cx18_get_card(u16 index) |
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c index 82fc2f9d4021..8e35c3aed544 100644 --- a/drivers/media/video/cx18/cx18-controls.c +++ b/drivers/media/video/cx18/cx18-controls.c | |||
@@ -176,8 +176,10 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, | |||
176 | return -EBUSY; | 176 | return -EBUSY; |
177 | 177 | ||
178 | if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV || | 178 | if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV || |
179 | type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) { | 179 | !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS || |
180 | /* We don't do VBI insertion aside from IVTV format in a PS */ | 180 | type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD || |
181 | type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) { | ||
182 | /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */ | ||
181 | cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE; | 183 | cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE; |
182 | CX18_DEBUG_INFO("disabled insertion of sliced VBI data into " | 184 | CX18_DEBUG_INFO("disabled insertion of sliced VBI data into " |
183 | "the MPEG stream\n"); | 185 | "the MPEG stream\n"); |
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 49b1c3d7b1a8..92026e82e10e 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "cx18-irq.h" | 30 | #include "cx18-irq.h" |
31 | #include "cx18-gpio.h" | 31 | #include "cx18-gpio.h" |
32 | #include "cx18-firmware.h" | 32 | #include "cx18-firmware.h" |
33 | #include "cx18-queue.h" | ||
33 | #include "cx18-streams.h" | 34 | #include "cx18-streams.h" |
34 | #include "cx18-av-core.h" | 35 | #include "cx18-av-core.h" |
35 | #include "cx18-scb.h" | 36 | #include "cx18-scb.h" |
@@ -151,7 +152,8 @@ MODULE_PARM_DESC(cardtype, | |||
151 | "\t\t\t 4 = Yuan MPC718\n" | 152 | "\t\t\t 4 = Yuan MPC718\n" |
152 | "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" | 153 | "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" |
153 | "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" | 154 | "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" |
154 | "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n" | 155 | "\t\t\t 7 = Leadtek WinFast PVR2100\n" |
156 | "\t\t\t 8 = Leadtek WinFast DVR3100 H\n" | ||
155 | "\t\t\t 0 = Autodetect (default)\n" | 157 | "\t\t\t 0 = Autodetect (default)\n" |
156 | "\t\t\t-1 = Ignore this card\n\t\t"); | 158 | "\t\t\t-1 = Ignore this card\n\t\t"); |
157 | MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); | 159 | MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); |
@@ -312,7 +314,7 @@ static void cx18_process_eeprom(struct cx18 *cx) | |||
312 | CX18_INFO("Autodetected %s\n", cx->card_name); | 314 | CX18_INFO("Autodetected %s\n", cx->card_name); |
313 | 315 | ||
314 | if (tv.tuner_type == TUNER_ABSENT) | 316 | if (tv.tuner_type == TUNER_ABSENT) |
315 | CX18_ERR("tveeprom cannot autodetect tuner!"); | 317 | CX18_ERR("tveeprom cannot autodetect tuner!\n"); |
316 | 318 | ||
317 | if (cx->options.tuner == -1) | 319 | if (cx->options.tuner == -1) |
318 | cx->options.tuner = tv.tuner_type; | 320 | cx->options.tuner = tv.tuner_type; |
@@ -546,6 +548,40 @@ done: | |||
546 | cx->card_i2c = cx->card->i2c; | 548 | cx->card_i2c = cx->card->i2c; |
547 | } | 549 | } |
548 | 550 | ||
551 | static int __devinit cx18_create_in_workq(struct cx18 *cx) | ||
552 | { | ||
553 | snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in", | ||
554 | cx->v4l2_dev.name); | ||
555 | cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name); | ||
556 | if (cx->in_work_queue == NULL) { | ||
557 | CX18_ERR("Unable to create incoming mailbox handler thread\n"); | ||
558 | return -ENOMEM; | ||
559 | } | ||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | static int __devinit cx18_create_out_workq(struct cx18 *cx) | ||
564 | { | ||
565 | snprintf(cx->out_workq_name, sizeof(cx->out_workq_name), "%s-out", | ||
566 | cx->v4l2_dev.name); | ||
567 | cx->out_work_queue = create_workqueue(cx->out_workq_name); | ||
568 | if (cx->out_work_queue == NULL) { | ||
569 | CX18_ERR("Unable to create outgoing mailbox handler threads\n"); | ||
570 | return -ENOMEM; | ||
571 | } | ||
572 | return 0; | ||
573 | } | ||
574 | |||
575 | static void __devinit cx18_init_in_work_orders(struct cx18 *cx) | ||
576 | { | ||
577 | int i; | ||
578 | for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) { | ||
579 | cx->in_work_order[i].cx = cx; | ||
580 | cx->in_work_order[i].str = cx->epu_debug_str; | ||
581 | INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler); | ||
582 | } | ||
583 | } | ||
584 | |||
549 | /* Precondition: the cx18 structure has been memset to 0. Only | 585 | /* Precondition: the cx18 structure has been memset to 0. Only |
550 | the dev and instance fields have been filled in. | 586 | the dev and instance fields have been filled in. |
551 | No assumptions on the card type may be made here (see cx18_init_struct2 | 587 | No assumptions on the card type may be made here (see cx18_init_struct2 |
@@ -553,7 +589,7 @@ done: | |||
553 | */ | 589 | */ |
554 | static int __devinit cx18_init_struct1(struct cx18 *cx) | 590 | static int __devinit cx18_init_struct1(struct cx18 *cx) |
555 | { | 591 | { |
556 | int i; | 592 | int ret; |
557 | 593 | ||
558 | cx->base_addr = pci_resource_start(cx->pci_dev, 0); | 594 | cx->base_addr = pci_resource_start(cx->pci_dev, 0); |
559 | 595 | ||
@@ -562,18 +598,18 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) | |||
562 | mutex_init(&cx->epu2apu_mb_lock); | 598 | mutex_init(&cx->epu2apu_mb_lock); |
563 | mutex_init(&cx->epu2cpu_mb_lock); | 599 | mutex_init(&cx->epu2cpu_mb_lock); |
564 | 600 | ||
565 | cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name); | 601 | ret = cx18_create_out_workq(cx); |
566 | if (cx->work_queue == NULL) { | 602 | if (ret) |
567 | CX18_ERR("Unable to create work hander thread\n"); | 603 | return ret; |
568 | return -ENOMEM; | ||
569 | } | ||
570 | 604 | ||
571 | for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { | 605 | ret = cx18_create_in_workq(cx); |
572 | cx->epu_work_order[i].cx = cx; | 606 | if (ret) { |
573 | cx->epu_work_order[i].str = cx->epu_debug_str; | 607 | destroy_workqueue(cx->out_work_queue); |
574 | INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler); | 608 | return ret; |
575 | } | 609 | } |
576 | 610 | ||
611 | cx18_init_in_work_orders(cx); | ||
612 | |||
577 | /* start counting open_id at 1 */ | 613 | /* start counting open_id at 1 */ |
578 | cx->open_id = 1; | 614 | cx->open_id = 1; |
579 | 615 | ||
@@ -759,17 +795,17 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, | |||
759 | retval = -ENODEV; | 795 | retval = -ENODEV; |
760 | goto err; | 796 | goto err; |
761 | } | 797 | } |
762 | if (cx18_init_struct1(cx)) { | 798 | |
763 | retval = -ENOMEM; | 799 | retval = cx18_init_struct1(cx); |
800 | if (retval) | ||
764 | goto err; | 801 | goto err; |
765 | } | ||
766 | 802 | ||
767 | CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); | 803 | CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); |
768 | 804 | ||
769 | /* PCI Device Setup */ | 805 | /* PCI Device Setup */ |
770 | retval = cx18_setup_pci(cx, pci_dev, pci_id); | 806 | retval = cx18_setup_pci(cx, pci_dev, pci_id); |
771 | if (retval != 0) | 807 | if (retval != 0) |
772 | goto free_workqueue; | 808 | goto free_workqueues; |
773 | 809 | ||
774 | /* map io memory */ | 810 | /* map io memory */ |
775 | CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", | 811 | CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", |
@@ -943,8 +979,9 @@ free_map: | |||
943 | cx18_iounmap(cx); | 979 | cx18_iounmap(cx); |
944 | free_mem: | 980 | free_mem: |
945 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); | 981 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); |
946 | free_workqueue: | 982 | free_workqueues: |
947 | destroy_workqueue(cx->work_queue); | 983 | destroy_workqueue(cx->in_work_queue); |
984 | destroy_workqueue(cx->out_work_queue); | ||
948 | err: | 985 | err: |
949 | if (retval == 0) | 986 | if (retval == 0) |
950 | retval = -ENODEV; | 987 | retval = -ENODEV; |
@@ -1053,11 +1090,19 @@ int cx18_init_on_first_open(struct cx18 *cx) | |||
1053 | return 0; | 1090 | return 0; |
1054 | } | 1091 | } |
1055 | 1092 | ||
1056 | static void cx18_cancel_epu_work_orders(struct cx18 *cx) | 1093 | static void cx18_cancel_in_work_orders(struct cx18 *cx) |
1057 | { | 1094 | { |
1058 | int i; | 1095 | int i; |
1059 | for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) | 1096 | for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) |
1060 | cancel_work_sync(&cx->epu_work_order[i].work); | 1097 | cancel_work_sync(&cx->in_work_order[i].work); |
1098 | } | ||
1099 | |||
1100 | static void cx18_cancel_out_work_orders(struct cx18 *cx) | ||
1101 | { | ||
1102 | int i; | ||
1103 | for (i = 0; i < CX18_MAX_STREAMS; i++) | ||
1104 | if (&cx->streams[i].video_dev != NULL) | ||
1105 | cancel_work_sync(&cx->streams[i].out_work_order); | ||
1061 | } | 1106 | } |
1062 | 1107 | ||
1063 | static void cx18_remove(struct pci_dev *pci_dev) | 1108 | static void cx18_remove(struct pci_dev *pci_dev) |
@@ -1073,15 +1118,20 @@ static void cx18_remove(struct pci_dev *pci_dev) | |||
1073 | if (atomic_read(&cx->tot_capturing) > 0) | 1118 | if (atomic_read(&cx->tot_capturing) > 0) |
1074 | cx18_stop_all_captures(cx); | 1119 | cx18_stop_all_captures(cx); |
1075 | 1120 | ||
1076 | /* Interrupts */ | 1121 | /* Stop interrupts that cause incoming work to be queued */ |
1077 | cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); | 1122 | cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); |
1123 | |||
1124 | /* Incoming work can cause outgoing work, so clean up incoming first */ | ||
1125 | cx18_cancel_in_work_orders(cx); | ||
1126 | cx18_cancel_out_work_orders(cx); | ||
1127 | |||
1128 | /* Stop ack interrupts that may have been needed for work to finish */ | ||
1078 | cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); | 1129 | cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); |
1079 | 1130 | ||
1080 | cx18_halt_firmware(cx); | 1131 | cx18_halt_firmware(cx); |
1081 | 1132 | ||
1082 | cx18_cancel_epu_work_orders(cx); | 1133 | destroy_workqueue(cx->in_work_queue); |
1083 | 1134 | destroy_workqueue(cx->out_work_queue); | |
1084 | destroy_workqueue(cx->work_queue); | ||
1085 | 1135 | ||
1086 | cx18_streams_cleanup(cx, 1); | 1136 | cx18_streams_cleanup(cx, 1); |
1087 | 1137 | ||
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index ece4f281ef42..c6a1e907f63a 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -80,8 +80,9 @@ | |||
80 | #define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ | 80 | #define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ |
81 | #define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ | 81 | #define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ |
82 | #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ | 82 | #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ |
83 | #define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100/DVR3100 H */ | 83 | #define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ |
84 | #define CX18_CARD_LAST 6 | 84 | #define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */ |
85 | #define CX18_CARD_LAST 7 | ||
85 | 86 | ||
86 | #define CX18_ENC_STREAM_TYPE_MPG 0 | 87 | #define CX18_ENC_STREAM_TYPE_MPG 0 |
87 | #define CX18_ENC_STREAM_TYPE_TS 1 | 88 | #define CX18_ENC_STREAM_TYPE_TS 1 |
@@ -254,6 +255,7 @@ struct cx18_options { | |||
254 | #define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ | 255 | #define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ |
255 | #define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ | 256 | #define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ |
256 | #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ | 257 | #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ |
258 | #define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */ | ||
257 | 259 | ||
258 | /* per-cx18, i_flags */ | 260 | /* per-cx18, i_flags */ |
259 | #define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ | 261 | #define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ |
@@ -285,6 +287,7 @@ struct cx18_queue { | |||
285 | struct list_head list; | 287 | struct list_head list; |
286 | atomic_t buffers; | 288 | atomic_t buffers; |
287 | u32 bytesused; | 289 | u32 bytesused; |
290 | spinlock_t lock; | ||
288 | }; | 291 | }; |
289 | 292 | ||
290 | struct cx18_dvb { | 293 | struct cx18_dvb { |
@@ -305,7 +308,7 @@ struct cx18_scb; /* forward reference */ | |||
305 | 308 | ||
306 | 309 | ||
307 | #define CX18_MAX_MDL_ACKS 2 | 310 | #define CX18_MAX_MDL_ACKS 2 |
308 | #define CX18_MAX_EPU_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7) | 311 | #define CX18_MAX_IN_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7) |
309 | /* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */ | 312 | /* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */ |
310 | 313 | ||
311 | #define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1 | 314 | #define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1 |
@@ -313,7 +316,7 @@ struct cx18_scb; /* forward reference */ | |||
313 | #define CX18_F_EWO_MB_STALE \ | 316 | #define CX18_F_EWO_MB_STALE \ |
314 | (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC) | 317 | (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC) |
315 | 318 | ||
316 | struct cx18_epu_work_order { | 319 | struct cx18_in_work_order { |
317 | struct work_struct work; | 320 | struct work_struct work; |
318 | atomic_t pending; | 321 | atomic_t pending; |
319 | struct cx18 *cx; | 322 | struct cx18 *cx; |
@@ -337,7 +340,6 @@ struct cx18_stream { | |||
337 | unsigned mdl_offset; | 340 | unsigned mdl_offset; |
338 | 341 | ||
339 | u32 id; | 342 | u32 id; |
340 | struct mutex qlock; /* locks access to the queues */ | ||
341 | unsigned long s_flags; /* status flags, see above */ | 343 | unsigned long s_flags; /* status flags, see above */ |
342 | int dma; /* can be PCI_DMA_TODEVICE, | 344 | int dma; /* can be PCI_DMA_TODEVICE, |
343 | PCI_DMA_FROMDEVICE or | 345 | PCI_DMA_FROMDEVICE or |
@@ -353,6 +355,8 @@ struct cx18_stream { | |||
353 | struct cx18_queue q_busy; /* busy buffers - in use by firmware */ | 355 | struct cx18_queue q_busy; /* busy buffers - in use by firmware */ |
354 | struct cx18_queue q_full; /* full buffers - data for user apps */ | 356 | struct cx18_queue q_full; /* full buffers - data for user apps */ |
355 | 357 | ||
358 | struct work_struct out_work_order; | ||
359 | |||
356 | /* DVB / Digital Transport */ | 360 | /* DVB / Digital Transport */ |
357 | struct cx18_dvb dvb; | 361 | struct cx18_dvb dvb; |
358 | }; | 362 | }; |
@@ -568,10 +572,14 @@ struct cx18 { | |||
568 | u32 sw2_irq_mask; | 572 | u32 sw2_irq_mask; |
569 | u32 hw2_irq_mask; | 573 | u32 hw2_irq_mask; |
570 | 574 | ||
571 | struct workqueue_struct *work_queue; | 575 | struct workqueue_struct *in_work_queue; |
572 | struct cx18_epu_work_order epu_work_order[CX18_MAX_EPU_WORK_ORDERS]; | 576 | char in_workq_name[11]; /* "cx18-NN-in" */ |
577 | struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS]; | ||
573 | char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */ | 578 | char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */ |
574 | 579 | ||
580 | struct workqueue_struct *out_work_queue; | ||
581 | char out_workq_name[12]; /* "cx18-NN-out" */ | ||
582 | |||
575 | /* i2c */ | 583 | /* i2c */ |
576 | struct i2c_adapter i2c_adap[2]; | 584 | struct i2c_adapter i2c_adap[2]; |
577 | struct i2c_algo_bit_data i2c_algo[2]; | 585 | struct i2c_algo_bit_data i2c_algo[2]; |
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index 3b86f57cd15a..6ea3fe623ef4 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c | |||
@@ -23,14 +23,20 @@ | |||
23 | #include "cx18-version.h" | 23 | #include "cx18-version.h" |
24 | #include "cx18-dvb.h" | 24 | #include "cx18-dvb.h" |
25 | #include "cx18-io.h" | 25 | #include "cx18-io.h" |
26 | #include "cx18-queue.h" | ||
26 | #include "cx18-streams.h" | 27 | #include "cx18-streams.h" |
27 | #include "cx18-cards.h" | 28 | #include "cx18-cards.h" |
29 | #include "cx18-gpio.h" | ||
28 | #include "s5h1409.h" | 30 | #include "s5h1409.h" |
29 | #include "mxl5005s.h" | 31 | #include "mxl5005s.h" |
32 | #include "zl10353.h" | ||
33 | #include "tuner-xc2028.h" | ||
30 | 34 | ||
31 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 35 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
32 | 36 | ||
33 | #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 | 37 | #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 |
38 | #define CX18_CLOCK_ENABLE2 0xc71024 | ||
39 | #define CX18_DMUX_CLK_MASK 0x0080 | ||
34 | 40 | ||
35 | static struct mxl5005s_config hauppauge_hvr1600_tuner = { | 41 | static struct mxl5005s_config hauppauge_hvr1600_tuner = { |
36 | .i2c_address = 0xC6 >> 1, | 42 | .i2c_address = 0xC6 >> 1, |
@@ -57,7 +63,15 @@ static struct s5h1409_config hauppauge_hvr1600_config = { | |||
57 | .inversion = S5H1409_INVERSION_OFF, | 63 | .inversion = S5H1409_INVERSION_OFF, |
58 | .status_mode = S5H1409_DEMODLOCKING, | 64 | .status_mode = S5H1409_DEMODLOCKING, |
59 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK | 65 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK |
66 | }; | ||
60 | 67 | ||
68 | /* Information/confirmation of proper config values provided by Terry Wu */ | ||
69 | static struct zl10353_config leadtek_dvr3100h_demod = { | ||
70 | .demod_address = 0x1e >> 1, /* Datasheet suggested straps */ | ||
71 | .if2 = 45600, /* 4.560 MHz IF from the XC3028 */ | ||
72 | .parallel_ts = 1, /* Not a serial TS */ | ||
73 | .no_tuner = 1, /* XC3028 is not behind the gate */ | ||
74 | .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */ | ||
61 | }; | 75 | }; |
62 | 76 | ||
63 | static int dvb_register(struct cx18_stream *stream); | 77 | static int dvb_register(struct cx18_stream *stream); |
@@ -98,6 +112,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) | |||
98 | cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); | 112 | cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); |
99 | break; | 113 | break; |
100 | 114 | ||
115 | case CX18_CARD_LEADTEK_DVR3100H: | ||
101 | default: | 116 | default: |
102 | /* Assumption - Parallel transport - Signalling | 117 | /* Assumption - Parallel transport - Signalling |
103 | * undefined or default. | 118 | * undefined or default. |
@@ -267,8 +282,7 @@ void cx18_dvb_unregister(struct cx18_stream *stream) | |||
267 | } | 282 | } |
268 | 283 | ||
269 | /* All the DVB attach calls go here, this function get's modified | 284 | /* All the DVB attach calls go here, this function get's modified |
270 | * for each new card. No other function in this file needs | 285 | * for each new card. cx18_dvb_start_feed() will also need changes. |
271 | * to change. | ||
272 | */ | 286 | */ |
273 | static int dvb_register(struct cx18_stream *stream) | 287 | static int dvb_register(struct cx18_stream *stream) |
274 | { | 288 | { |
@@ -289,6 +303,29 @@ static int dvb_register(struct cx18_stream *stream) | |||
289 | ret = 0; | 303 | ret = 0; |
290 | } | 304 | } |
291 | break; | 305 | break; |
306 | case CX18_CARD_LEADTEK_DVR3100H: | ||
307 | dvb->fe = dvb_attach(zl10353_attach, | ||
308 | &leadtek_dvr3100h_demod, | ||
309 | &cx->i2c_adap[1]); | ||
310 | if (dvb->fe != NULL) { | ||
311 | struct dvb_frontend *fe; | ||
312 | struct xc2028_config cfg = { | ||
313 | .i2c_adap = &cx->i2c_adap[1], | ||
314 | .i2c_addr = 0xc2 >> 1, | ||
315 | .ctrl = NULL, | ||
316 | }; | ||
317 | static struct xc2028_ctrl ctrl = { | ||
318 | .fname = XC2028_DEFAULT_FIRMWARE, | ||
319 | .max_len = 64, | ||
320 | .demod = XC3028_FE_ZARLINK456, | ||
321 | .type = XC2028_AUTO, | ||
322 | }; | ||
323 | |||
324 | fe = dvb_attach(xc2028_attach, dvb->fe, &cfg); | ||
325 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | ||
326 | fe->ops.tuner_ops.set_config(fe, &ctrl); | ||
327 | } | ||
328 | break; | ||
292 | default: | 329 | default: |
293 | /* No Digital Tv Support */ | 330 | /* No Digital Tv Support */ |
294 | break; | 331 | break; |
@@ -299,6 +336,8 @@ static int dvb_register(struct cx18_stream *stream) | |||
299 | return -1; | 336 | return -1; |
300 | } | 337 | } |
301 | 338 | ||
339 | dvb->fe->callback = cx18_reset_tuner_gpio; | ||
340 | |||
302 | ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe); | 341 | ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe); |
303 | if (ret < 0) { | 342 | if (ret < 0) { |
304 | if (dvb->fe->ops.release) | 343 | if (dvb->fe->ops.release) |
@@ -306,5 +345,16 @@ static int dvb_register(struct cx18_stream *stream) | |||
306 | return ret; | 345 | return ret; |
307 | } | 346 | } |
308 | 347 | ||
348 | /* | ||
349 | * The firmware seems to enable the TS DMUX clock | ||
350 | * under various circumstances. However, since we know we | ||
351 | * might use it, let's just turn it on ourselves here. | ||
352 | */ | ||
353 | cx18_write_reg_expect(cx, | ||
354 | (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK, | ||
355 | CX18_CLOCK_ENABLE2, | ||
356 | CX18_DMUX_CLK_MASK, | ||
357 | (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK); | ||
358 | |||
309 | return ret; | 359 | return ret; |
310 | } | 360 | } |
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index b3889c0b2697..29969c18949c 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
@@ -265,8 +265,13 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s, | |||
265 | * an MPEG-2 Program Pack start code, and provide only | 265 | * an MPEG-2 Program Pack start code, and provide only |
266 | * up to that point to the user, so it's easy to insert VBI data | 266 | * up to that point to the user, so it's easy to insert VBI data |
267 | * the next time around. | 267 | * the next time around. |
268 | * | ||
269 | * This will not work for an MPEG-2 TS and has only been | ||
270 | * verified by analysis to work for an MPEG-2 PS. Helen Buus | ||
271 | * pointed out this works for the CX23416 MPEG-2 DVD compatible | ||
272 | * stream, and research indicates both the MPEG 2 SVCD and DVD | ||
273 | * stream types use an MPEG-2 PS container. | ||
268 | */ | 274 | */ |
269 | /* FIXME - This only works for an MPEG-2 PS, not a TS */ | ||
270 | /* | 275 | /* |
271 | * An MPEG-2 Program Stream (PS) is a series of | 276 | * An MPEG-2 Program Stream (PS) is a series of |
272 | * MPEG-2 Program Packs terminated by an | 277 | * MPEG-2 Program Packs terminated by an |
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 2226e5791e99..afe46c3d4057 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c | |||
@@ -131,7 +131,7 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name) | |||
131 | * Functions that run in a work_queue work handling context | 131 | * Functions that run in a work_queue work handling context |
132 | */ | 132 | */ |
133 | 133 | ||
134 | static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order) | 134 | static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) |
135 | { | 135 | { |
136 | u32 handle, mdl_ack_count, id; | 136 | u32 handle, mdl_ack_count, id; |
137 | struct cx18_mailbox *mb; | 137 | struct cx18_mailbox *mb; |
@@ -191,29 +191,30 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
191 | if (buf == NULL) { | 191 | if (buf == NULL) { |
192 | CX18_WARN("Could not find buf %d for stream %s\n", | 192 | CX18_WARN("Could not find buf %d for stream %s\n", |
193 | id, s->name); | 193 | id, s->name); |
194 | /* Put as many buffers as possible back into fw use */ | ||
195 | cx18_stream_load_fw_queue(s); | ||
196 | continue; | 194 | continue; |
197 | } | 195 | } |
198 | 196 | ||
199 | if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { | 197 | CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", |
200 | CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n", | 198 | s->name, buf->bytesused); |
201 | buf->bytesused); | 199 | |
202 | dvb_dmx_swfilter(&s->dvb.demux, buf->buf, | 200 | if (s->type != CX18_ENC_STREAM_TYPE_TS) |
203 | buf->bytesused); | 201 | cx18_enqueue(s, buf, &s->q_full); |
202 | else { | ||
203 | if (s->dvb.enabled) | ||
204 | dvb_dmx_swfilter(&s->dvb.demux, buf->buf, | ||
205 | buf->bytesused); | ||
206 | cx18_enqueue(s, buf, &s->q_free); | ||
204 | } | 207 | } |
205 | /* Put as many buffers as possible back into fw use */ | ||
206 | cx18_stream_load_fw_queue(s); | ||
207 | /* Put back TS buffer, since it was removed from all queues */ | ||
208 | if (s->type == CX18_ENC_STREAM_TYPE_TS) | ||
209 | cx18_stream_put_buf_fw(s, buf); | ||
210 | } | 208 | } |
209 | /* Put as many buffers as possible back into fw use */ | ||
210 | cx18_stream_load_fw_queue(s); | ||
211 | |||
211 | wake_up(&cx->dma_waitq); | 212 | wake_up(&cx->dma_waitq); |
212 | if (s->id != -1) | 213 | if (s->id != -1) |
213 | wake_up(&s->waitq); | 214 | wake_up(&s->waitq); |
214 | } | 215 | } |
215 | 216 | ||
216 | static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order) | 217 | static void epu_debug(struct cx18 *cx, struct cx18_in_work_order *order) |
217 | { | 218 | { |
218 | char *p; | 219 | char *p; |
219 | char *str = order->str; | 220 | char *str = order->str; |
@@ -224,7 +225,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
224 | CX18_INFO("FW version: %s\n", p - 1); | 225 | CX18_INFO("FW version: %s\n", p - 1); |
225 | } | 226 | } |
226 | 227 | ||
227 | static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order) | 228 | static void epu_cmd(struct cx18 *cx, struct cx18_in_work_order *order) |
228 | { | 229 | { |
229 | switch (order->rpu) { | 230 | switch (order->rpu) { |
230 | case CPU: | 231 | case CPU: |
@@ -253,18 +254,18 @@ static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
253 | } | 254 | } |
254 | 255 | ||
255 | static | 256 | static |
256 | void free_epu_work_order(struct cx18 *cx, struct cx18_epu_work_order *order) | 257 | void free_in_work_order(struct cx18 *cx, struct cx18_in_work_order *order) |
257 | { | 258 | { |
258 | atomic_set(&order->pending, 0); | 259 | atomic_set(&order->pending, 0); |
259 | } | 260 | } |
260 | 261 | ||
261 | void cx18_epu_work_handler(struct work_struct *work) | 262 | void cx18_in_work_handler(struct work_struct *work) |
262 | { | 263 | { |
263 | struct cx18_epu_work_order *order = | 264 | struct cx18_in_work_order *order = |
264 | container_of(work, struct cx18_epu_work_order, work); | 265 | container_of(work, struct cx18_in_work_order, work); |
265 | struct cx18 *cx = order->cx; | 266 | struct cx18 *cx = order->cx; |
266 | epu_cmd(cx, order); | 267 | epu_cmd(cx, order); |
267 | free_epu_work_order(cx, order); | 268 | free_in_work_order(cx, order); |
268 | } | 269 | } |
269 | 270 | ||
270 | 271 | ||
@@ -272,7 +273,7 @@ void cx18_epu_work_handler(struct work_struct *work) | |||
272 | * Functions that run in an interrupt handling context | 273 | * Functions that run in an interrupt handling context |
273 | */ | 274 | */ |
274 | 275 | ||
275 | static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | 276 | static void mb_ack_irq(struct cx18 *cx, struct cx18_in_work_order *order) |
276 | { | 277 | { |
277 | struct cx18_mailbox __iomem *ack_mb; | 278 | struct cx18_mailbox __iomem *ack_mb; |
278 | u32 ack_irq, req; | 279 | u32 ack_irq, req; |
@@ -308,7 +309,7 @@ static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
308 | return; | 309 | return; |
309 | } | 310 | } |
310 | 311 | ||
311 | static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | 312 | static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order) |
312 | { | 313 | { |
313 | u32 handle, mdl_ack_offset, mdl_ack_count; | 314 | u32 handle, mdl_ack_offset, mdl_ack_count; |
314 | struct cx18_mailbox *mb; | 315 | struct cx18_mailbox *mb; |
@@ -334,7 +335,7 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
334 | } | 335 | } |
335 | 336 | ||
336 | static | 337 | static |
337 | int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | 338 | int epu_debug_irq(struct cx18 *cx, struct cx18_in_work_order *order) |
338 | { | 339 | { |
339 | u32 str_offset; | 340 | u32 str_offset; |
340 | char *str = order->str; | 341 | char *str = order->str; |
@@ -355,7 +356,7 @@ int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
355 | } | 356 | } |
356 | 357 | ||
357 | static inline | 358 | static inline |
358 | int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | 359 | int epu_cmd_irq(struct cx18 *cx, struct cx18_in_work_order *order) |
359 | { | 360 | { |
360 | int ret = -1; | 361 | int ret = -1; |
361 | 362 | ||
@@ -387,12 +388,12 @@ int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order) | |||
387 | } | 388 | } |
388 | 389 | ||
389 | static inline | 390 | static inline |
390 | struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx) | 391 | struct cx18_in_work_order *alloc_in_work_order_irq(struct cx18 *cx) |
391 | { | 392 | { |
392 | int i; | 393 | int i; |
393 | struct cx18_epu_work_order *order = NULL; | 394 | struct cx18_in_work_order *order = NULL; |
394 | 395 | ||
395 | for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { | 396 | for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) { |
396 | /* | 397 | /* |
397 | * We only need "pending" atomic to inspect its contents, | 398 | * We only need "pending" atomic to inspect its contents, |
398 | * and need not do a check and set because: | 399 | * and need not do a check and set because: |
@@ -401,8 +402,8 @@ struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx) | |||
401 | * 2. "pending" is only set here, and we're serialized because | 402 | * 2. "pending" is only set here, and we're serialized because |
402 | * we're called in an IRQ handler context. | 403 | * we're called in an IRQ handler context. |
403 | */ | 404 | */ |
404 | if (atomic_read(&cx->epu_work_order[i].pending) == 0) { | 405 | if (atomic_read(&cx->in_work_order[i].pending) == 0) { |
405 | order = &cx->epu_work_order[i]; | 406 | order = &cx->in_work_order[i]; |
406 | atomic_set(&order->pending, 1); | 407 | atomic_set(&order->pending, 1); |
407 | break; | 408 | break; |
408 | } | 409 | } |
@@ -414,7 +415,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) | |||
414 | { | 415 | { |
415 | struct cx18_mailbox __iomem *mb; | 416 | struct cx18_mailbox __iomem *mb; |
416 | struct cx18_mailbox *order_mb; | 417 | struct cx18_mailbox *order_mb; |
417 | struct cx18_epu_work_order *order; | 418 | struct cx18_in_work_order *order; |
418 | int submit; | 419 | int submit; |
419 | 420 | ||
420 | switch (rpu) { | 421 | switch (rpu) { |
@@ -428,7 +429,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) | |||
428 | return; | 429 | return; |
429 | } | 430 | } |
430 | 431 | ||
431 | order = alloc_epu_work_order_irq(cx); | 432 | order = alloc_in_work_order_irq(cx); |
432 | if (order == NULL) { | 433 | if (order == NULL) { |
433 | CX18_WARN("Unable to find blank work order form to schedule " | 434 | CX18_WARN("Unable to find blank work order form to schedule " |
434 | "incoming mailbox command processing\n"); | 435 | "incoming mailbox command processing\n"); |
@@ -461,7 +462,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) | |||
461 | */ | 462 | */ |
462 | submit = epu_cmd_irq(cx, order); | 463 | submit = epu_cmd_irq(cx, order); |
463 | if (submit > 0) { | 464 | if (submit > 0) { |
464 | queue_work(cx->work_queue, &order->work); | 465 | queue_work(cx->in_work_queue, &order->work); |
465 | } | 466 | } |
466 | } | 467 | } |
467 | 468 | ||
@@ -478,9 +479,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) | |||
478 | u32 __iomem *xpu_state; | 479 | u32 __iomem *xpu_state; |
479 | wait_queue_head_t *waitq; | 480 | wait_queue_head_t *waitq; |
480 | struct mutex *mb_lock; | 481 | struct mutex *mb_lock; |
481 | long int timeout, ret; | 482 | unsigned long int t0, timeout, ret; |
482 | int i; | 483 | int i; |
483 | char argstr[MAX_MB_ARGUMENTS*11+1]; | 484 | char argstr[MAX_MB_ARGUMENTS*11+1]; |
485 | DEFINE_WAIT(w); | ||
484 | 486 | ||
485 | if (info == NULL) { | 487 | if (info == NULL) { |
486 | CX18_WARN("unknown cmd %x\n", cmd); | 488 | CX18_WARN("unknown cmd %x\n", cmd); |
@@ -562,25 +564,49 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) | |||
562 | 564 | ||
563 | CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n", | 565 | CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n", |
564 | irq, info->name); | 566 | irq, info->name); |
567 | |||
568 | /* So we don't miss the wakeup, prepare to wait before notifying fw */ | ||
569 | prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE); | ||
565 | cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); | 570 | cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); |
566 | 571 | ||
567 | ret = wait_event_timeout( | 572 | t0 = jiffies; |
568 | *waitq, | 573 | ack = cx18_readl(cx, &mb->ack); |
569 | cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request), | 574 | if (ack != req) { |
570 | timeout); | 575 | schedule_timeout(timeout); |
576 | ret = jiffies - t0; | ||
577 | ack = cx18_readl(cx, &mb->ack); | ||
578 | } else { | ||
579 | ret = jiffies - t0; | ||
580 | } | ||
571 | 581 | ||
572 | if (ret == 0) { | 582 | finish_wait(waitq, &w); |
573 | /* Timed out */ | 583 | |
584 | if (req != ack) { | ||
574 | mutex_unlock(mb_lock); | 585 | mutex_unlock(mb_lock); |
575 | CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU " | 586 | if (ret >= timeout) { |
576 | "acknowledgement\n", | 587 | /* Timed out */ |
577 | info->name, jiffies_to_msecs(timeout)); | 588 | CX18_DEBUG_WARN("sending %s timed out waiting %d msecs " |
589 | "for RPU acknowledgement\n", | ||
590 | info->name, jiffies_to_msecs(ret)); | ||
591 | } else { | ||
592 | CX18_DEBUG_WARN("woken up before mailbox ack was ready " | ||
593 | "after submitting %s to RPU. only " | ||
594 | "waited %d msecs on req %u but awakened" | ||
595 | " with unmatched ack %u\n", | ||
596 | info->name, | ||
597 | jiffies_to_msecs(ret), | ||
598 | req, ack); | ||
599 | } | ||
578 | return -EINVAL; | 600 | return -EINVAL; |
579 | } | 601 | } |
580 | 602 | ||
581 | if (ret != timeout) | 603 | if (ret >= timeout) |
604 | CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment " | ||
605 | "sending %s; timed out waiting %d msecs\n", | ||
606 | info->name, jiffies_to_msecs(ret)); | ||
607 | else | ||
582 | CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n", | 608 | CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n", |
583 | jiffies_to_msecs(timeout-ret), info->name); | 609 | jiffies_to_msecs(ret), info->name); |
584 | 610 | ||
585 | /* Collect data returned by the XPU */ | 611 | /* Collect data returned by the XPU */ |
586 | for (i = 0; i < MAX_MB_ARGUMENTS; i++) | 612 | for (i = 0; i < MAX_MB_ARGUMENTS; i++) |
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h index ce2b6686aa00..e23aaac5b280 100644 --- a/drivers/media/video/cx18/cx18-mailbox.h +++ b/drivers/media/video/cx18/cx18-mailbox.h | |||
@@ -95,6 +95,6 @@ int cx18_api_func(void *priv, u32 cmd, int in, int out, | |||
95 | 95 | ||
96 | void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu); | 96 | void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu); |
97 | 97 | ||
98 | void cx18_epu_work_handler(struct work_struct *work); | 98 | void cx18_in_work_handler(struct work_struct *work); |
99 | 99 | ||
100 | #endif | 100 | #endif |
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index 3046b8e74345..fa1ed7897d97 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c | |||
@@ -23,8 +23,8 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "cx18-driver.h" | 25 | #include "cx18-driver.h" |
26 | #include "cx18-streams.h" | ||
27 | #include "cx18-queue.h" | 26 | #include "cx18-queue.h" |
27 | #include "cx18-streams.h" | ||
28 | #include "cx18-scb.h" | 28 | #include "cx18-scb.h" |
29 | 29 | ||
30 | void cx18_buf_swap(struct cx18_buffer *buf) | 30 | void cx18_buf_swap(struct cx18_buffer *buf) |
@@ -53,13 +53,13 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, | |||
53 | buf->skipped = 0; | 53 | buf->skipped = 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | mutex_lock(&s->qlock); | ||
57 | |||
58 | /* q_busy is restricted to a max buffer count imposed by firmware */ | 56 | /* q_busy is restricted to a max buffer count imposed by firmware */ |
59 | if (q == &s->q_busy && | 57 | if (q == &s->q_busy && |
60 | atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) | 58 | atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) |
61 | q = &s->q_free; | 59 | q = &s->q_free; |
62 | 60 | ||
61 | spin_lock(&q->lock); | ||
62 | |||
63 | if (to_front) | 63 | if (to_front) |
64 | list_add(&buf->list, &q->list); /* LIFO */ | 64 | list_add(&buf->list, &q->list); /* LIFO */ |
65 | else | 65 | else |
@@ -67,7 +67,7 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, | |||
67 | q->bytesused += buf->bytesused - buf->readpos; | 67 | q->bytesused += buf->bytesused - buf->readpos; |
68 | atomic_inc(&q->buffers); | 68 | atomic_inc(&q->buffers); |
69 | 69 | ||
70 | mutex_unlock(&s->qlock); | 70 | spin_unlock(&q->lock); |
71 | return q; | 71 | return q; |
72 | } | 72 | } |
73 | 73 | ||
@@ -75,7 +75,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) | |||
75 | { | 75 | { |
76 | struct cx18_buffer *buf = NULL; | 76 | struct cx18_buffer *buf = NULL; |
77 | 77 | ||
78 | mutex_lock(&s->qlock); | 78 | spin_lock(&q->lock); |
79 | if (!list_empty(&q->list)) { | 79 | if (!list_empty(&q->list)) { |
80 | buf = list_first_entry(&q->list, struct cx18_buffer, list); | 80 | buf = list_first_entry(&q->list, struct cx18_buffer, list); |
81 | list_del_init(&buf->list); | 81 | list_del_init(&buf->list); |
@@ -83,7 +83,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) | |||
83 | buf->skipped = 0; | 83 | buf->skipped = 0; |
84 | atomic_dec(&q->buffers); | 84 | atomic_dec(&q->buffers); |
85 | } | 85 | } |
86 | mutex_unlock(&s->qlock); | 86 | spin_unlock(&q->lock); |
87 | return buf; | 87 | return buf; |
88 | } | 88 | } |
89 | 89 | ||
@@ -94,9 +94,23 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, | |||
94 | struct cx18_buffer *buf; | 94 | struct cx18_buffer *buf; |
95 | struct cx18_buffer *tmp; | 95 | struct cx18_buffer *tmp; |
96 | struct cx18_buffer *ret = NULL; | 96 | struct cx18_buffer *ret = NULL; |
97 | 97 | LIST_HEAD(sweep_up); | |
98 | mutex_lock(&s->qlock); | 98 | |
99 | /* | ||
100 | * We don't have to acquire multiple q locks here, because we are | ||
101 | * serialized by the single threaded work handler. | ||
102 | * Buffers from the firmware will thus remain in order as | ||
103 | * they are moved from q_busy to q_full or to the dvb ring buffer. | ||
104 | */ | ||
105 | spin_lock(&s->q_busy.lock); | ||
99 | list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) { | 106 | list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) { |
107 | /* | ||
108 | * We should find what the firmware told us is done, | ||
109 | * right at the front of the queue. If we don't, we likely have | ||
110 | * missed a buffer done message from the firmware. | ||
111 | * Once we skip a buffer repeatedly, relative to the size of | ||
112 | * q_busy, we have high confidence we've missed it. | ||
113 | */ | ||
100 | if (buf->id != id) { | 114 | if (buf->id != id) { |
101 | buf->skipped++; | 115 | buf->skipped++; |
102 | if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) { | 116 | if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) { |
@@ -105,38 +119,41 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, | |||
105 | "times - it must have dropped out of " | 119 | "times - it must have dropped out of " |
106 | "rotation\n", s->name, buf->id, | 120 | "rotation\n", s->name, buf->id, |
107 | buf->skipped); | 121 | buf->skipped); |
108 | /* move it to q_free */ | 122 | /* Sweep it up to put it back into rotation */ |
109 | list_move_tail(&buf->list, &s->q_free.list); | 123 | list_move_tail(&buf->list, &sweep_up); |
110 | buf->bytesused = buf->readpos = buf->b_flags = | ||
111 | buf->skipped = 0; | ||
112 | atomic_dec(&s->q_busy.buffers); | 124 | atomic_dec(&s->q_busy.buffers); |
113 | atomic_inc(&s->q_free.buffers); | ||
114 | } | 125 | } |
115 | continue; | 126 | continue; |
116 | } | 127 | } |
117 | 128 | /* | |
118 | buf->bytesused = bytesused; | 129 | * We pull the desired buffer off of the queue here. Something |
119 | /* Sync the buffer before we release the qlock */ | 130 | * will have to put it back on a queue later. |
120 | cx18_buf_sync_for_cpu(s, buf); | 131 | */ |
121 | if (s->type == CX18_ENC_STREAM_TYPE_TS) { | 132 | list_del_init(&buf->list); |
122 | /* | ||
123 | * TS doesn't use q_full. As we pull the buffer off of | ||
124 | * the queue here, the caller will have to put it back. | ||
125 | */ | ||
126 | list_del_init(&buf->list); | ||
127 | } else { | ||
128 | /* Move buffer from q_busy to q_full */ | ||
129 | list_move_tail(&buf->list, &s->q_full.list); | ||
130 | set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); | ||
131 | s->q_full.bytesused += buf->bytesused; | ||
132 | atomic_inc(&s->q_full.buffers); | ||
133 | } | ||
134 | atomic_dec(&s->q_busy.buffers); | 133 | atomic_dec(&s->q_busy.buffers); |
135 | |||
136 | ret = buf; | 134 | ret = buf; |
137 | break; | 135 | break; |
138 | } | 136 | } |
139 | mutex_unlock(&s->qlock); | 137 | spin_unlock(&s->q_busy.lock); |
138 | |||
139 | /* | ||
140 | * We found the buffer for which we were looking. Get it ready for | ||
141 | * the caller to put on q_full or in the dvb ring buffer. | ||
142 | */ | ||
143 | if (ret != NULL) { | ||
144 | ret->bytesused = bytesused; | ||
145 | ret->skipped = 0; | ||
146 | /* readpos and b_flags were 0'ed when the buf went on q_busy */ | ||
147 | cx18_buf_sync_for_cpu(s, ret); | ||
148 | if (s->type != CX18_ENC_STREAM_TYPE_TS) | ||
149 | set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags); | ||
150 | } | ||
151 | |||
152 | /* Put any buffers the firmware is ignoring back into normal rotation */ | ||
153 | list_for_each_entry_safe(buf, tmp, &sweep_up, list) { | ||
154 | list_del_init(&buf->list); | ||
155 | cx18_enqueue(s, buf, &s->q_free); | ||
156 | } | ||
140 | return ret; | 157 | return ret; |
141 | } | 158 | } |
142 | 159 | ||
@@ -148,7 +165,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) | |||
148 | if (q == &s->q_free) | 165 | if (q == &s->q_free) |
149 | return; | 166 | return; |
150 | 167 | ||
151 | mutex_lock(&s->qlock); | 168 | spin_lock(&q->lock); |
152 | while (!list_empty(&q->list)) { | 169 | while (!list_empty(&q->list)) { |
153 | buf = list_first_entry(&q->list, struct cx18_buffer, list); | 170 | buf = list_first_entry(&q->list, struct cx18_buffer, list); |
154 | list_move_tail(&buf->list, &s->q_free.list); | 171 | list_move_tail(&buf->list, &s->q_free.list); |
@@ -156,7 +173,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) | |||
156 | atomic_inc(&s->q_free.buffers); | 173 | atomic_inc(&s->q_free.buffers); |
157 | } | 174 | } |
158 | cx18_queue_init(q); | 175 | cx18_queue_init(q); |
159 | mutex_unlock(&s->qlock); | 176 | spin_unlock(&q->lock); |
160 | } | 177 | } |
161 | 178 | ||
162 | void cx18_flush_queues(struct cx18_stream *s) | 179 | void cx18_flush_queues(struct cx18_stream *s) |
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 0932b76b2373..54d248e16d85 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -116,12 +116,16 @@ static void cx18_stream_init(struct cx18 *cx, int type) | |||
116 | s->buffers = cx->stream_buffers[type]; | 116 | s->buffers = cx->stream_buffers[type]; |
117 | s->buf_size = cx->stream_buf_size[type]; | 117 | s->buf_size = cx->stream_buf_size[type]; |
118 | 118 | ||
119 | mutex_init(&s->qlock); | ||
120 | init_waitqueue_head(&s->waitq); | 119 | init_waitqueue_head(&s->waitq); |
121 | s->id = -1; | 120 | s->id = -1; |
121 | spin_lock_init(&s->q_free.lock); | ||
122 | cx18_queue_init(&s->q_free); | 122 | cx18_queue_init(&s->q_free); |
123 | spin_lock_init(&s->q_busy.lock); | ||
123 | cx18_queue_init(&s->q_busy); | 124 | cx18_queue_init(&s->q_busy); |
125 | spin_lock_init(&s->q_full.lock); | ||
124 | cx18_queue_init(&s->q_full); | 126 | cx18_queue_init(&s->q_full); |
127 | |||
128 | INIT_WORK(&s->out_work_order, cx18_out_work_handler); | ||
125 | } | 129 | } |
126 | 130 | ||
127 | static int cx18_prep_dev(struct cx18 *cx, int type) | 131 | static int cx18_prep_dev(struct cx18 *cx, int type) |
@@ -367,9 +371,14 @@ static void cx18_vbi_setup(struct cx18_stream *s) | |||
367 | * Tell the encoder to capture 21-4+1=18 lines per field, | 371 | * Tell the encoder to capture 21-4+1=18 lines per field, |
368 | * since we want lines 10 through 21. | 372 | * since we want lines 10 through 21. |
369 | * | 373 | * |
370 | * FIXME - revisit for 625/50 systems | 374 | * For 625/50 systems, according to the VIP 2 & BT.656 std: |
375 | * The EAV RP code's Field bit toggles on line 1, a few lines | ||
376 | * after the Vertcal Blank bit has already toggled. | ||
377 | * (We've actually set the digitizer so that the Field bit | ||
378 | * toggles on line 2.) Tell the encoder to capture 23-2+1=22 | ||
379 | * lines per field, since we want lines 6 through 23. | ||
371 | */ | 380 | */ |
372 | lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38; | 381 | lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 2 + 1) * 2; |
373 | } | 382 | } |
374 | 383 | ||
375 | data[0] = s->handle; | 384 | data[0] = s->handle; |
@@ -431,14 +440,16 @@ static void cx18_vbi_setup(struct cx18_stream *s) | |||
431 | cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); | 440 | cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); |
432 | } | 441 | } |
433 | 442 | ||
434 | struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, | 443 | static |
435 | struct cx18_buffer *buf) | 444 | struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s, |
445 | struct cx18_buffer *buf) | ||
436 | { | 446 | { |
437 | struct cx18 *cx = s->cx; | 447 | struct cx18 *cx = s->cx; |
438 | struct cx18_queue *q; | 448 | struct cx18_queue *q; |
439 | 449 | ||
440 | /* Don't give it to the firmware, if we're not running a capture */ | 450 | /* Don't give it to the firmware, if we're not running a capture */ |
441 | if (s->handle == CX18_INVALID_TASK_HANDLE || | 451 | if (s->handle == CX18_INVALID_TASK_HANDLE || |
452 | test_bit(CX18_F_S_STOPPING, &s->s_flags) || | ||
442 | !test_bit(CX18_F_S_STREAMING, &s->s_flags)) | 453 | !test_bit(CX18_F_S_STREAMING, &s->s_flags)) |
443 | return cx18_enqueue(s, buf, &s->q_free); | 454 | return cx18_enqueue(s, buf, &s->q_free); |
444 | 455 | ||
@@ -453,7 +464,8 @@ struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, | |||
453 | return q; | 464 | return q; |
454 | } | 465 | } |
455 | 466 | ||
456 | void cx18_stream_load_fw_queue(struct cx18_stream *s) | 467 | static |
468 | void _cx18_stream_load_fw_queue(struct cx18_stream *s) | ||
457 | { | 469 | { |
458 | struct cx18_queue *q; | 470 | struct cx18_queue *q; |
459 | struct cx18_buffer *buf; | 471 | struct cx18_buffer *buf; |
@@ -467,11 +479,19 @@ void cx18_stream_load_fw_queue(struct cx18_stream *s) | |||
467 | buf = cx18_dequeue(s, &s->q_free); | 479 | buf = cx18_dequeue(s, &s->q_free); |
468 | if (buf == NULL) | 480 | if (buf == NULL) |
469 | break; | 481 | break; |
470 | q = cx18_stream_put_buf_fw(s, buf); | 482 | q = _cx18_stream_put_buf_fw(s, buf); |
471 | } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM | 483 | } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM |
472 | && q == &s->q_busy); | 484 | && q == &s->q_busy); |
473 | } | 485 | } |
474 | 486 | ||
487 | void cx18_out_work_handler(struct work_struct *work) | ||
488 | { | ||
489 | struct cx18_stream *s = | ||
490 | container_of(work, struct cx18_stream, out_work_order); | ||
491 | |||
492 | _cx18_stream_load_fw_queue(s); | ||
493 | } | ||
494 | |||
475 | int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | 495 | int cx18_start_v4l2_encode_stream(struct cx18_stream *s) |
476 | { | 496 | { |
477 | u32 data[MAX_MB_ARGUMENTS]; | 497 | u32 data[MAX_MB_ARGUMENTS]; |
@@ -600,19 +620,20 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | |||
600 | 620 | ||
601 | /* Init all the cpu_mdls for this stream */ | 621 | /* Init all the cpu_mdls for this stream */ |
602 | cx18_flush_queues(s); | 622 | cx18_flush_queues(s); |
603 | mutex_lock(&s->qlock); | 623 | spin_lock(&s->q_free.lock); |
604 | list_for_each_entry(buf, &s->q_free.list, list) { | 624 | list_for_each_entry(buf, &s->q_free.list, list) { |
605 | cx18_writel(cx, buf->dma_handle, | 625 | cx18_writel(cx, buf->dma_handle, |
606 | &cx->scb->cpu_mdl[buf->id].paddr); | 626 | &cx->scb->cpu_mdl[buf->id].paddr); |
607 | cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length); | 627 | cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length); |
608 | } | 628 | } |
609 | mutex_unlock(&s->qlock); | 629 | spin_unlock(&s->q_free.lock); |
610 | cx18_stream_load_fw_queue(s); | 630 | _cx18_stream_load_fw_queue(s); |
611 | 631 | ||
612 | /* begin_capture */ | 632 | /* begin_capture */ |
613 | if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { | 633 | if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { |
614 | CX18_DEBUG_WARN("Error starting capture!\n"); | 634 | CX18_DEBUG_WARN("Error starting capture!\n"); |
615 | /* Ensure we're really not capturing before releasing MDLs */ | 635 | /* Ensure we're really not capturing before releasing MDLs */ |
636 | set_bit(CX18_F_S_STOPPING, &s->s_flags); | ||
616 | if (s->type == CX18_ENC_STREAM_TYPE_MPG) | 637 | if (s->type == CX18_ENC_STREAM_TYPE_MPG) |
617 | cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); | 638 | cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); |
618 | else | 639 | else |
@@ -622,6 +643,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | |||
622 | cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); | 643 | cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); |
623 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); | 644 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); |
624 | s->handle = CX18_INVALID_TASK_HANDLE; | 645 | s->handle = CX18_INVALID_TASK_HANDLE; |
646 | clear_bit(CX18_F_S_STOPPING, &s->s_flags); | ||
625 | if (atomic_read(&cx->tot_capturing) == 0) { | 647 | if (atomic_read(&cx->tot_capturing) == 0) { |
626 | set_bit(CX18_F_I_EOS, &cx->i_flags); | 648 | set_bit(CX18_F_I_EOS, &cx->i_flags); |
627 | cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); | 649 | cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); |
@@ -666,6 +688,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) | |||
666 | if (atomic_read(&cx->tot_capturing) == 0) | 688 | if (atomic_read(&cx->tot_capturing) == 0) |
667 | return 0; | 689 | return 0; |
668 | 690 | ||
691 | set_bit(CX18_F_S_STOPPING, &s->s_flags); | ||
669 | if (s->type == CX18_ENC_STREAM_TYPE_MPG) | 692 | if (s->type == CX18_ENC_STREAM_TYPE_MPG) |
670 | cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end); | 693 | cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end); |
671 | else | 694 | else |
@@ -689,6 +712,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) | |||
689 | 712 | ||
690 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); | 713 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); |
691 | s->handle = CX18_INVALID_TASK_HANDLE; | 714 | s->handle = CX18_INVALID_TASK_HANDLE; |
715 | clear_bit(CX18_F_S_STOPPING, &s->s_flags); | ||
692 | 716 | ||
693 | if (atomic_read(&cx->tot_capturing) > 0) | 717 | if (atomic_read(&cx->tot_capturing) > 0) |
694 | return 0; | 718 | return 0; |
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h index 420e0a172945..1afc3fd9d822 100644 --- a/drivers/media/video/cx18/cx18-streams.h +++ b/drivers/media/video/cx18/cx18-streams.h | |||
@@ -28,10 +28,24 @@ int cx18_streams_setup(struct cx18 *cx); | |||
28 | int cx18_streams_register(struct cx18 *cx); | 28 | int cx18_streams_register(struct cx18 *cx); |
29 | void cx18_streams_cleanup(struct cx18 *cx, int unregister); | 29 | void cx18_streams_cleanup(struct cx18 *cx, int unregister); |
30 | 30 | ||
31 | /* Related to submission of buffers to firmware */ | ||
32 | static inline void cx18_stream_load_fw_queue(struct cx18_stream *s) | ||
33 | { | ||
34 | struct cx18 *cx = s->cx; | ||
35 | queue_work(cx->out_work_queue, &s->out_work_order); | ||
36 | } | ||
37 | |||
38 | static inline void cx18_stream_put_buf_fw(struct cx18_stream *s, | ||
39 | struct cx18_buffer *buf) | ||
40 | { | ||
41 | /* Put buf on q_free; the out work handler will move buf(s) to q_busy */ | ||
42 | cx18_enqueue(s, buf, &s->q_free); | ||
43 | cx18_stream_load_fw_queue(s); | ||
44 | } | ||
45 | |||
46 | void cx18_out_work_handler(struct work_struct *work); | ||
47 | |||
31 | /* Capture related */ | 48 | /* Capture related */ |
32 | void cx18_stream_load_fw_queue(struct cx18_stream *s); | ||
33 | struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, | ||
34 | struct cx18_buffer *buf); | ||
35 | int cx18_start_v4l2_encode_stream(struct cx18_stream *s); | 49 | int cx18_start_v4l2_encode_stream(struct cx18_stream *s); |
36 | int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end); | 50 | int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end); |
37 | 51 | ||
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h index bd9bd44da791..45494b094e7f 100644 --- a/drivers/media/video/cx18/cx18-version.h +++ b/drivers/media/video/cx18/cx18-version.h | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #define CX18_DRIVER_NAME "cx18" | 25 | #define CX18_DRIVER_NAME "cx18" |
26 | #define CX18_DRIVER_VERSION_MAJOR 1 | 26 | #define CX18_DRIVER_VERSION_MAJOR 1 |
27 | #define CX18_DRIVER_VERSION_MINOR 1 | 27 | #define CX18_DRIVER_VERSION_MINOR 2 |
28 | #define CX18_DRIVER_VERSION_PATCHLEVEL 0 | 28 | #define CX18_DRIVER_VERSION_PATCHLEVEL 0 |
29 | 29 | ||
30 | #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) | 30 | #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) |
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c index 1be3881be991..6a9464079b4c 100644 --- a/drivers/media/video/cx231xx/cx231xx-avcore.c +++ b/drivers/media/video/cx231xx/cx231xx-avcore.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/bitmap.h> | 29 | #include <linux/bitmap.h> |
30 | #include <linux/usb.h> | 30 | #include <linux/usb.h> |
31 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
32 | #include <linux/version.h> | ||
33 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
34 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
35 | 34 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index c8a32b1b5381..63d2239fd324 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c | |||
@@ -281,12 +281,12 @@ static void cx231xx_config_tuner(struct cx231xx *dev) | |||
281 | } | 281 | } |
282 | 282 | ||
283 | /* ----------------------------------------------------------------------- */ | 283 | /* ----------------------------------------------------------------------- */ |
284 | void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir) | 284 | void cx231xx_register_i2c_ir(struct cx231xx *dev) |
285 | { | 285 | { |
286 | if (disable_ir) { | 286 | if (disable_ir) |
287 | ir->get_key = NULL; | ||
288 | return; | 287 | return; |
289 | } | 288 | |
289 | /* REVISIT: instantiate IR device */ | ||
290 | 290 | ||
291 | /* detect & configure */ | 291 | /* detect & configure */ |
292 | switch (dev->model) { | 292 | switch (dev->model) { |
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c index b4a03d813e00..33219dc4d649 100644 --- a/drivers/media/video/cx231xx/cx231xx-i2c.c +++ b/drivers/media/video/cx231xx/cx231xx-i2c.c | |||
@@ -424,34 +424,6 @@ static u32 functionality(struct i2c_adapter *adap) | |||
424 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; | 424 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; |
425 | } | 425 | } |
426 | 426 | ||
427 | /* | ||
428 | * attach_inform() | ||
429 | * gets called when a device attaches to the i2c bus | ||
430 | * does some basic configuration | ||
431 | */ | ||
432 | static int attach_inform(struct i2c_client *client) | ||
433 | { | ||
434 | struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter); | ||
435 | struct cx231xx *dev = bus->dev; | ||
436 | |||
437 | switch (client->addr << 1) { | ||
438 | case 0x8e: | ||
439 | { | ||
440 | struct IR_i2c *ir = i2c_get_clientdata(client); | ||
441 | dprintk1(1, "attach_inform: IR detected (%s).\n", | ||
442 | ir->phys); | ||
443 | cx231xx_set_ir(dev, ir); | ||
444 | break; | ||
445 | } | ||
446 | break; | ||
447 | |||
448 | default: | ||
449 | break; | ||
450 | } | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static struct i2c_algorithm cx231xx_algo = { | 427 | static struct i2c_algorithm cx231xx_algo = { |
456 | .master_xfer = cx231xx_i2c_xfer, | 428 | .master_xfer = cx231xx_i2c_xfer, |
457 | .functionality = functionality, | 429 | .functionality = functionality, |
@@ -462,7 +434,6 @@ static struct i2c_adapter cx231xx_adap_template = { | |||
462 | .name = "cx231xx", | 434 | .name = "cx231xx", |
463 | .id = I2C_HW_B_CX231XX, | 435 | .id = I2C_HW_B_CX231XX, |
464 | .algo = &cx231xx_algo, | 436 | .algo = &cx231xx_algo, |
465 | .client_register = attach_inform, | ||
466 | }; | 437 | }; |
467 | 438 | ||
468 | static struct i2c_client cx231xx_client_template = { | 439 | static struct i2c_client cx231xx_client_template = { |
@@ -537,6 +508,9 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) | |||
537 | if (0 == bus->i2c_rc) { | 508 | if (0 == bus->i2c_rc) { |
538 | if (i2c_scan) | 509 | if (i2c_scan) |
539 | cx231xx_do_i2c_scan(dev, &bus->i2c_client); | 510 | cx231xx_do_i2c_scan(dev, &bus->i2c_client); |
511 | |||
512 | /* Instantiate the IR receiver device, if present */ | ||
513 | cx231xx_register_i2c_ir(dev); | ||
540 | } else | 514 | } else |
541 | cx231xx_warn("%s: i2c bus %d register FAILED\n", | 515 | cx231xx_warn("%s: i2c bus %d register FAILED\n", |
542 | dev->name, bus->nr); | 516 | dev->name, bus->nr); |
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c index 97e304c3c799..48f22fa38e6c 100644 --- a/drivers/media/video/cx231xx/cx231xx-input.c +++ b/drivers/media/video/cx231xx/cx231xx-input.c | |||
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | |||
36 | 36 | ||
37 | #define i2cdprintk(fmt, arg...) \ | 37 | #define i2cdprintk(fmt, arg...) \ |
38 | if (ir_debug) { \ | 38 | if (ir_debug) { \ |
39 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ | 39 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ |
40 | } | 40 | } |
41 | 41 | ||
42 | #define dprintk(fmt, arg...) \ | 42 | #define dprintk(fmt, arg...) \ |
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c index 94180526909c..e97b8023a655 100644 --- a/drivers/media/video/cx231xx/cx231xx-vbi.c +++ b/drivers/media/video/cx231xx/cx231xx-vbi.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/bitmap.h> | 26 | #include <linux/bitmap.h> |
27 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/version.h> | ||
30 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
31 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
32 | 31 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h index aa4a23ef491a..e38eb2d425f7 100644 --- a/drivers/media/video/cx231xx/cx231xx.h +++ b/drivers/media/video/cx231xx/cx231xx.h | |||
@@ -738,7 +738,7 @@ extern void cx231xx_card_setup(struct cx231xx *dev); | |||
738 | extern struct cx231xx_board cx231xx_boards[]; | 738 | extern struct cx231xx_board cx231xx_boards[]; |
739 | extern struct usb_device_id cx231xx_id_table[]; | 739 | extern struct usb_device_id cx231xx_id_table[]; |
740 | extern const unsigned int cx231xx_bcount; | 740 | extern const unsigned int cx231xx_bcount; |
741 | void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir); | 741 | void cx231xx_register_i2c_ir(struct cx231xx *dev); |
742 | int cx231xx_tuner_callback(void *ptr, int component, int command, int arg); | 742 | int cx231xx_tuner_callback(void *ptr, int component, int command, int arg); |
743 | 743 | ||
744 | /* Provided by cx231xx-input.c */ | 744 | /* Provided by cx231xx-input.c */ |
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c index 9a6536998d90..08582e58bdbf 100644 --- a/drivers/media/video/cx23885/cimax2.c +++ b/drivers/media/video/cx23885/cimax2.c | |||
@@ -312,7 +312,7 @@ static void netup_read_ci_status(struct work_struct *work) | |||
312 | "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0], | 312 | "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0], |
313 | buf[32]); | 313 | buf[32]); |
314 | 314 | ||
315 | if (buf[0] && 1) | 315 | if (buf[0] & 1) |
316 | state->status = DVB_CA_EN50221_POLL_CAM_PRESENT | | 316 | state->status = DVB_CA_EN50221_POLL_CAM_PRESENT | |
317 | DVB_CA_EN50221_POLL_CAM_READY; | 317 | DVB_CA_EN50221_POLL_CAM_READY; |
318 | else | 318 | else |
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 6f5df90af93e..2943bfd32a94 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c | |||
@@ -1742,7 +1742,6 @@ static struct video_device *cx23885_video_dev_alloc( | |||
1742 | if (NULL == vfd) | 1742 | if (NULL == vfd) |
1743 | return NULL; | 1743 | return NULL; |
1744 | *vfd = *template; | 1744 | *vfd = *template; |
1745 | vfd->minor = -1; | ||
1746 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, | 1745 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, |
1747 | type, cx23885_boards[tsport->dev->board].name); | 1746 | type, cx23885_boards[tsport->dev->board].name); |
1748 | vfd->parent = &pci->dev; | 1747 | vfd->parent = &pci->dev; |
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 6d6293f7d428..ce29b5e34a11 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c | |||
@@ -181,6 +181,26 @@ struct cx23885_board cx23885_boards[] = { | |||
181 | .portb = CX23885_MPEG_DVB, | 181 | .portb = CX23885_MPEG_DVB, |
182 | .portc = CX23885_MPEG_DVB, | 182 | .portc = CX23885_MPEG_DVB, |
183 | }, | 183 | }, |
184 | [CX23885_BOARD_HAUPPAUGE_HVR1270] = { | ||
185 | .name = "Hauppauge WinTV-HVR1270", | ||
186 | .portc = CX23885_MPEG_DVB, | ||
187 | }, | ||
188 | [CX23885_BOARD_HAUPPAUGE_HVR1275] = { | ||
189 | .name = "Hauppauge WinTV-HVR1275", | ||
190 | .portc = CX23885_MPEG_DVB, | ||
191 | }, | ||
192 | [CX23885_BOARD_HAUPPAUGE_HVR1255] = { | ||
193 | .name = "Hauppauge WinTV-HVR1255", | ||
194 | .portc = CX23885_MPEG_DVB, | ||
195 | }, | ||
196 | [CX23885_BOARD_HAUPPAUGE_HVR1210] = { | ||
197 | .name = "Hauppauge WinTV-HVR1210", | ||
198 | .portc = CX23885_MPEG_DVB, | ||
199 | }, | ||
200 | [CX23885_BOARD_MYGICA_X8506] = { | ||
201 | .name = "Mygica X8506 DMB-TH", | ||
202 | .portb = CX23885_MPEG_DVB, | ||
203 | }, | ||
184 | }; | 204 | }; |
185 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); | 205 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); |
186 | 206 | ||
@@ -280,6 +300,30 @@ struct cx23885_subid cx23885_subids[] = { | |||
280 | .subvendor = 0x1b55, | 300 | .subvendor = 0x1b55, |
281 | .subdevice = 0x2a2c, | 301 | .subdevice = 0x2a2c, |
282 | .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI, | 302 | .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI, |
303 | }, { | ||
304 | .subvendor = 0x0070, | ||
305 | .subdevice = 0x2211, | ||
306 | .card = CX23885_BOARD_HAUPPAUGE_HVR1270, | ||
307 | }, { | ||
308 | .subvendor = 0x0070, | ||
309 | .subdevice = 0x2215, | ||
310 | .card = CX23885_BOARD_HAUPPAUGE_HVR1275, | ||
311 | }, { | ||
312 | .subvendor = 0x0070, | ||
313 | .subdevice = 0x2251, | ||
314 | .card = CX23885_BOARD_HAUPPAUGE_HVR1255, | ||
315 | }, { | ||
316 | .subvendor = 0x0070, | ||
317 | .subdevice = 0x2291, | ||
318 | .card = CX23885_BOARD_HAUPPAUGE_HVR1210, | ||
319 | }, { | ||
320 | .subvendor = 0x0070, | ||
321 | .subdevice = 0x2295, | ||
322 | .card = CX23885_BOARD_HAUPPAUGE_HVR1210, | ||
323 | }, { | ||
324 | .subvendor = 0x14f1, | ||
325 | .subdevice = 0x8651, | ||
326 | .card = CX23885_BOARD_MYGICA_X8506, | ||
283 | }, | 327 | }, |
284 | }; | 328 | }; |
285 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); | 329 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); |
@@ -321,6 +365,42 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) | |||
321 | 365 | ||
322 | /* Make sure we support the board model */ | 366 | /* Make sure we support the board model */ |
323 | switch (tv.model) { | 367 | switch (tv.model) { |
368 | case 22001: | ||
369 | /* WinTV-HVR1270 (PCIe, Retail, half height) | ||
370 | * ATSC/QAM and basic analog, IR Blast */ | ||
371 | case 22009: | ||
372 | /* WinTV-HVR1210 (PCIe, Retail, half height) | ||
373 | * DVB-T and basic analog, IR Blast */ | ||
374 | case 22011: | ||
375 | /* WinTV-HVR1270 (PCIe, Retail, half height) | ||
376 | * ATSC/QAM and basic analog, IR Recv */ | ||
377 | case 22019: | ||
378 | /* WinTV-HVR1210 (PCIe, Retail, half height) | ||
379 | * DVB-T and basic analog, IR Recv */ | ||
380 | case 22021: | ||
381 | /* WinTV-HVR1275 (PCIe, Retail, half height) | ||
382 | * ATSC/QAM and basic analog, IR Recv */ | ||
383 | case 22029: | ||
384 | /* WinTV-HVR1210 (PCIe, Retail, half height) | ||
385 | * DVB-T and basic analog, IR Recv */ | ||
386 | case 22101: | ||
387 | /* WinTV-HVR1270 (PCIe, Retail, full height) | ||
388 | * ATSC/QAM and basic analog, IR Blast */ | ||
389 | case 22109: | ||
390 | /* WinTV-HVR1210 (PCIe, Retail, full height) | ||
391 | * DVB-T and basic analog, IR Blast */ | ||
392 | case 22111: | ||
393 | /* WinTV-HVR1270 (PCIe, Retail, full height) | ||
394 | * ATSC/QAM and basic analog, IR Recv */ | ||
395 | case 22119: | ||
396 | /* WinTV-HVR1210 (PCIe, Retail, full height) | ||
397 | * DVB-T and basic analog, IR Recv */ | ||
398 | case 22121: | ||
399 | /* WinTV-HVR1275 (PCIe, Retail, full height) | ||
400 | * ATSC/QAM and basic analog, IR Recv */ | ||
401 | case 22129: | ||
402 | /* WinTV-HVR1210 (PCIe, Retail, full height) | ||
403 | * DVB-T and basic analog, IR Recv */ | ||
324 | case 71009: | 404 | case 71009: |
325 | /* WinTV-HVR1200 (PCIe, Retail, full height) | 405 | /* WinTV-HVR1200 (PCIe, Retail, full height) |
326 | * DVB-T and basic analog */ | 406 | * DVB-T and basic analog */ |
@@ -619,6 +699,30 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
619 | /* enable irq */ | 699 | /* enable irq */ |
620 | cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ | 700 | cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ |
621 | break; | 701 | break; |
702 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | ||
703 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
704 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | ||
705 | case CX23885_BOARD_HAUPPAUGE_HVR1210: | ||
706 | /* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */ | ||
707 | /* GPIO-6 I2C Gate which can isolate the demod from the bus */ | ||
708 | /* GPIO-9 Demod reset */ | ||
709 | |||
710 | /* Put the parts into reset and back */ | ||
711 | cx23885_gpio_enable(dev, GPIO_9 | GPIO_6 | GPIO_5, 1); | ||
712 | cx23885_gpio_set(dev, GPIO_9 | GPIO_6 | GPIO_5); | ||
713 | cx23885_gpio_clear(dev, GPIO_9); | ||
714 | mdelay(20); | ||
715 | cx23885_gpio_set(dev, GPIO_9); | ||
716 | break; | ||
717 | case CX23885_BOARD_MYGICA_X8506: | ||
718 | /* GPIO-1 reset XC5000 */ | ||
719 | /* GPIO-2 reset LGS8GL5 */ | ||
720 | cx_set(GP0_IO, 0x00060000); | ||
721 | cx_clear(GP0_IO, 0x00000006); | ||
722 | mdelay(100); | ||
723 | cx_set(GP0_IO, 0x00060006); | ||
724 | mdelay(100); | ||
725 | break; | ||
622 | } | 726 | } |
623 | } | 727 | } |
624 | 728 | ||
@@ -631,6 +735,10 @@ int cx23885_ir_init(struct cx23885_dev *dev) | |||
631 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 735 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
632 | case CX23885_BOARD_HAUPPAUGE_HVR1200: | 736 | case CX23885_BOARD_HAUPPAUGE_HVR1200: |
633 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | 737 | case CX23885_BOARD_HAUPPAUGE_HVR1400: |
738 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | ||
739 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
740 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | ||
741 | case CX23885_BOARD_HAUPPAUGE_HVR1210: | ||
634 | /* FIXME: Implement me */ | 742 | /* FIXME: Implement me */ |
635 | break; | 743 | break; |
636 | case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: | 744 | case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: |
@@ -666,6 +774,10 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
666 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: | 774 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: |
667 | case CX23885_BOARD_HAUPPAUGE_HVR1200: | 775 | case CX23885_BOARD_HAUPPAUGE_HVR1200: |
668 | case CX23885_BOARD_HAUPPAUGE_HVR1700: | 776 | case CX23885_BOARD_HAUPPAUGE_HVR1700: |
777 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | ||
778 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
779 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | ||
780 | case CX23885_BOARD_HAUPPAUGE_HVR1210: | ||
669 | if (dev->i2c_bus[0].i2c_rc == 0) | 781 | if (dev->i2c_bus[0].i2c_rc == 0) |
670 | hauppauge_eeprom(dev, eeprom+0xc0); | 782 | hauppauge_eeprom(dev, eeprom+0xc0); |
671 | break; | 783 | break; |
@@ -714,6 +826,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
714 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 826 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
715 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 827 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
716 | break; | 828 | break; |
829 | case CX23885_BOARD_MYGICA_X8506: | ||
830 | ts1->gen_ctrl_val = 0x5; /* Parallel */ | ||
831 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | ||
832 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | ||
833 | break; | ||
717 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 834 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
718 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 835 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
719 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 836 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
@@ -723,6 +840,10 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
723 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | 840 | case CX23885_BOARD_HAUPPAUGE_HVR1400: |
724 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: | 841 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: |
725 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: | 842 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: |
843 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | ||
844 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
845 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | ||
846 | case CX23885_BOARD_HAUPPAUGE_HVR1210: | ||
726 | default: | 847 | default: |
727 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | 848 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ |
728 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 849 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index beda42925ce7..bf7bb1c412fb 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c | |||
@@ -1700,9 +1700,13 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) | |||
1700 | } | 1700 | } |
1701 | 1701 | ||
1702 | if (cx23885_boards[dev->board].cimax > 0 && | 1702 | if (cx23885_boards[dev->board].cimax > 0 && |
1703 | ((pci_status & PCI_MSK_GPIO0) || (pci_status & PCI_MSK_GPIO1))) | 1703 | ((pci_status & PCI_MSK_GPIO0) || |
1704 | /* handled += cx23885_irq_gpio(dev, pci_status); */ | 1704 | (pci_status & PCI_MSK_GPIO1))) { |
1705 | handled += netup_ci_slot_status(dev, pci_status); | 1705 | |
1706 | if (cx23885_boards[dev->board].cimax > 0) | ||
1707 | handled += netup_ci_slot_status(dev, pci_status); | ||
1708 | |||
1709 | } | ||
1706 | 1710 | ||
1707 | if (ts1_status) { | 1711 | if (ts1_status) { |
1708 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) | 1712 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) |
@@ -1729,6 +1733,88 @@ out: | |||
1729 | return IRQ_RETVAL(handled); | 1733 | return IRQ_RETVAL(handled); |
1730 | } | 1734 | } |
1731 | 1735 | ||
1736 | static inline int encoder_on_portb(struct cx23885_dev *dev) | ||
1737 | { | ||
1738 | return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER; | ||
1739 | } | ||
1740 | |||
1741 | static inline int encoder_on_portc(struct cx23885_dev *dev) | ||
1742 | { | ||
1743 | return cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER; | ||
1744 | } | ||
1745 | |||
1746 | /* Mask represents 32 different GPIOs, GPIO's are split into multiple | ||
1747 | * registers depending on the board configuration (and whether the | ||
1748 | * 417 encoder (wi it's own GPIO's) are present. Each GPIO bit will | ||
1749 | * be pushed into the correct hardware register, regardless of the | ||
1750 | * physical location. Certain registers are shared so we sanity check | ||
1751 | * and report errors if we think we're tampering with a GPIo that might | ||
1752 | * be assigned to the encoder (and used for the host bus). | ||
1753 | * | ||
1754 | * GPIO 2 thru 0 - On the cx23885 bridge | ||
1755 | * GPIO 18 thru 3 - On the cx23417 host bus interface | ||
1756 | * GPIO 23 thru 19 - On the cx25840 a/v core | ||
1757 | */ | ||
1758 | void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask) | ||
1759 | { | ||
1760 | if (mask & 0x7) | ||
1761 | cx_set(GP0_IO, mask & 0x7); | ||
1762 | |||
1763 | if (mask & 0x0007fff8) { | ||
1764 | if (encoder_on_portb(dev) || encoder_on_portc(dev)) | ||
1765 | printk(KERN_ERR | ||
1766 | "%s: Setting GPIO on encoder ports\n", | ||
1767 | dev->name); | ||
1768 | cx_set(MC417_RWD, (mask & 0x0007fff8) >> 3); | ||
1769 | } | ||
1770 | |||
1771 | /* TODO: 23-19 */ | ||
1772 | if (mask & 0x00f80000) | ||
1773 | printk(KERN_INFO "%s: Unsupported\n", dev->name); | ||
1774 | } | ||
1775 | |||
1776 | void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask) | ||
1777 | { | ||
1778 | if (mask & 0x00000007) | ||
1779 | cx_clear(GP0_IO, mask & 0x7); | ||
1780 | |||
1781 | if (mask & 0x0007fff8) { | ||
1782 | if (encoder_on_portb(dev) || encoder_on_portc(dev)) | ||
1783 | printk(KERN_ERR | ||
1784 | "%s: Clearing GPIO moving on encoder ports\n", | ||
1785 | dev->name); | ||
1786 | cx_clear(MC417_RWD, (mask & 0x7fff8) >> 3); | ||
1787 | } | ||
1788 | |||
1789 | /* TODO: 23-19 */ | ||
1790 | if (mask & 0x00f80000) | ||
1791 | printk(KERN_INFO "%s: Unsupported\n", dev->name); | ||
1792 | } | ||
1793 | |||
1794 | void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput) | ||
1795 | { | ||
1796 | if ((mask & 0x00000007) && asoutput) | ||
1797 | cx_set(GP0_IO, (mask & 0x7) << 16); | ||
1798 | else if ((mask & 0x00000007) && !asoutput) | ||
1799 | cx_clear(GP0_IO, (mask & 0x7) << 16); | ||
1800 | |||
1801 | if (mask & 0x0007fff8) { | ||
1802 | if (encoder_on_portb(dev) || encoder_on_portc(dev)) | ||
1803 | printk(KERN_ERR | ||
1804 | "%s: Enabling GPIO on encoder ports\n", | ||
1805 | dev->name); | ||
1806 | } | ||
1807 | |||
1808 | /* MC417_OEN is active low for output, write 1 for an input */ | ||
1809 | if ((mask & 0x0007fff8) && asoutput) | ||
1810 | cx_clear(MC417_OEN, (mask & 0x7fff8) >> 3); | ||
1811 | |||
1812 | else if ((mask & 0x0007fff8) && !asoutput) | ||
1813 | cx_set(MC417_OEN, (mask & 0x7fff8) >> 3); | ||
1814 | |||
1815 | /* TODO: 23-19 */ | ||
1816 | } | ||
1817 | |||
1732 | static int __devinit cx23885_initdev(struct pci_dev *pci_dev, | 1818 | static int __devinit cx23885_initdev(struct pci_dev *pci_dev, |
1733 | const struct pci_device_id *pci_id) | 1819 | const struct pci_device_id *pci_id) |
1734 | { | 1820 | { |
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 1dc070da8652..e236df23370e 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c | |||
@@ -49,8 +49,10 @@ | |||
49 | #include "lnbh24.h" | 49 | #include "lnbh24.h" |
50 | #include "cx24116.h" | 50 | #include "cx24116.h" |
51 | #include "cimax2.h" | 51 | #include "cimax2.h" |
52 | #include "lgs8gxx.h" | ||
52 | #include "netup-eeprom.h" | 53 | #include "netup-eeprom.h" |
53 | #include "netup-init.h" | 54 | #include "netup-init.h" |
55 | #include "lgdt3305.h" | ||
54 | 56 | ||
55 | static unsigned int debug; | 57 | static unsigned int debug; |
56 | 58 | ||
@@ -122,7 +124,22 @@ static struct tda10048_config hauppauge_hvr1200_config = { | |||
122 | .demod_address = 0x10 >> 1, | 124 | .demod_address = 0x10 >> 1, |
123 | .output_mode = TDA10048_SERIAL_OUTPUT, | 125 | .output_mode = TDA10048_SERIAL_OUTPUT, |
124 | .fwbulkwritelen = TDA10048_BULKWRITE_200, | 126 | .fwbulkwritelen = TDA10048_BULKWRITE_200, |
125 | .inversion = TDA10048_INVERSION_ON | 127 | .inversion = TDA10048_INVERSION_ON, |
128 | .dtv6_if_freq_khz = TDA10048_IF_3300, | ||
129 | .dtv7_if_freq_khz = TDA10048_IF_3800, | ||
130 | .dtv8_if_freq_khz = TDA10048_IF_4300, | ||
131 | .clk_freq_khz = TDA10048_CLK_16000, | ||
132 | }; | ||
133 | |||
134 | static struct tda10048_config hauppauge_hvr1210_config = { | ||
135 | .demod_address = 0x10 >> 1, | ||
136 | .output_mode = TDA10048_SERIAL_OUTPUT, | ||
137 | .fwbulkwritelen = TDA10048_BULKWRITE_200, | ||
138 | .inversion = TDA10048_INVERSION_ON, | ||
139 | .dtv6_if_freq_khz = TDA10048_IF_3300, | ||
140 | .dtv7_if_freq_khz = TDA10048_IF_3500, | ||
141 | .dtv8_if_freq_khz = TDA10048_IF_4000, | ||
142 | .clk_freq_khz = TDA10048_CLK_16000, | ||
126 | }; | 143 | }; |
127 | 144 | ||
128 | static struct s5h1409_config hauppauge_ezqam_config = { | 145 | static struct s5h1409_config hauppauge_ezqam_config = { |
@@ -194,6 +211,16 @@ static struct s5h1411_config dvico_s5h1411_config = { | |||
194 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 211 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, |
195 | }; | 212 | }; |
196 | 213 | ||
214 | static struct s5h1411_config hcw_s5h1411_config = { | ||
215 | .output_mode = S5H1411_SERIAL_OUTPUT, | ||
216 | .gpio = S5H1411_GPIO_OFF, | ||
217 | .vsb_if = S5H1411_IF_44000, | ||
218 | .qam_if = S5H1411_IF_4000, | ||
219 | .inversion = S5H1411_INVERSION_ON, | ||
220 | .status_mode = S5H1411_DEMODLOCKING, | ||
221 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | ||
222 | }; | ||
223 | |||
197 | static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { | 224 | static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { |
198 | .i2c_address = 0x61, | 225 | .i2c_address = 0x61, |
199 | .if_khz = 5380, | 226 | .if_khz = 5380, |
@@ -224,6 +251,32 @@ static struct tda18271_config hauppauge_hvr1200_tuner_config = { | |||
224 | .gate = TDA18271_GATE_ANALOG, | 251 | .gate = TDA18271_GATE_ANALOG, |
225 | }; | 252 | }; |
226 | 253 | ||
254 | static struct tda18271_config hauppauge_hvr1210_tuner_config = { | ||
255 | .gate = TDA18271_GATE_DIGITAL, | ||
256 | }; | ||
257 | |||
258 | static struct tda18271_std_map hauppauge_hvr127x_std_map = { | ||
259 | .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, | ||
260 | .if_lvl = 1, .rfagc_top = 0x58 }, | ||
261 | .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5, | ||
262 | .if_lvl = 1, .rfagc_top = 0x58 }, | ||
263 | }; | ||
264 | |||
265 | static struct tda18271_config hauppauge_hvr127x_config = { | ||
266 | .std_map = &hauppauge_hvr127x_std_map, | ||
267 | }; | ||
268 | |||
269 | static struct lgdt3305_config hauppauge_lgdt3305_config = { | ||
270 | .i2c_addr = 0x0e, | ||
271 | .mpeg_mode = LGDT3305_MPEG_SERIAL, | ||
272 | .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE, | ||
273 | .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, | ||
274 | .deny_i2c_rptr = 1, | ||
275 | .spectral_inversion = 1, | ||
276 | .qam_if_khz = 4000, | ||
277 | .vsb_if_khz = 3250, | ||
278 | }; | ||
279 | |||
227 | static struct dibx000_agc_config xc3028_agc_config = { | 280 | static struct dibx000_agc_config xc3028_agc_config = { |
228 | BAND_VHF | BAND_UHF, /* band_caps */ | 281 | BAND_VHF | BAND_UHF, /* band_caps */ |
229 | 282 | ||
@@ -368,10 +421,29 @@ static struct cx24116_config dvbworld_cx24116_config = { | |||
368 | .demod_address = 0x05, | 421 | .demod_address = 0x05, |
369 | }; | 422 | }; |
370 | 423 | ||
424 | static struct lgs8gxx_config mygica_x8506_lgs8gl5_config = { | ||
425 | .prod = LGS8GXX_PROD_LGS8GL5, | ||
426 | .demod_address = 0x19, | ||
427 | .serial_ts = 0, | ||
428 | .ts_clk_pol = 1, | ||
429 | .ts_clk_gated = 1, | ||
430 | .if_clk_freq = 30400, /* 30.4 MHz */ | ||
431 | .if_freq = 5380, /* 5.38 MHz */ | ||
432 | .if_neg_center = 1, | ||
433 | .ext_adc = 0, | ||
434 | .adc_signed = 0, | ||
435 | .if_neg_edge = 0, | ||
436 | }; | ||
437 | |||
438 | static struct xc5000_config mygica_x8506_xc5000_config = { | ||
439 | .i2c_address = 0x61, | ||
440 | .if_khz = 5380, | ||
441 | }; | ||
442 | |||
371 | static int dvb_register(struct cx23885_tsport *port) | 443 | static int dvb_register(struct cx23885_tsport *port) |
372 | { | 444 | { |
373 | struct cx23885_dev *dev = port->dev; | 445 | struct cx23885_dev *dev = port->dev; |
374 | struct cx23885_i2c *i2c_bus = NULL; | 446 | struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; |
375 | struct videobuf_dvb_frontend *fe0; | 447 | struct videobuf_dvb_frontend *fe0; |
376 | int ret; | 448 | int ret; |
377 | 449 | ||
@@ -396,6 +468,29 @@ static int dvb_register(struct cx23885_tsport *port) | |||
396 | &hauppauge_generic_tunerconfig, 0); | 468 | &hauppauge_generic_tunerconfig, 0); |
397 | } | 469 | } |
398 | break; | 470 | break; |
471 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | ||
472 | case CX23885_BOARD_HAUPPAUGE_HVR1275: | ||
473 | i2c_bus = &dev->i2c_bus[0]; | ||
474 | fe0->dvb.frontend = dvb_attach(lgdt3305_attach, | ||
475 | &hauppauge_lgdt3305_config, | ||
476 | &i2c_bus->i2c_adap); | ||
477 | if (fe0->dvb.frontend != NULL) { | ||
478 | dvb_attach(tda18271_attach, fe0->dvb.frontend, | ||
479 | 0x60, &dev->i2c_bus[1].i2c_adap, | ||
480 | &hauppauge_hvr127x_config); | ||
481 | } | ||
482 | break; | ||
483 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | ||
484 | i2c_bus = &dev->i2c_bus[0]; | ||
485 | fe0->dvb.frontend = dvb_attach(s5h1411_attach, | ||
486 | &hcw_s5h1411_config, | ||
487 | &i2c_bus->i2c_adap); | ||
488 | if (fe0->dvb.frontend != NULL) { | ||
489 | dvb_attach(tda18271_attach, fe0->dvb.frontend, | ||
490 | 0x60, &dev->i2c_bus[1].i2c_adap, | ||
491 | &hauppauge_tda18271_config); | ||
492 | } | ||
493 | break; | ||
399 | case CX23885_BOARD_HAUPPAUGE_HVR1800: | 494 | case CX23885_BOARD_HAUPPAUGE_HVR1800: |
400 | i2c_bus = &dev->i2c_bus[0]; | 495 | i2c_bus = &dev->i2c_bus[0]; |
401 | switch (alt_tuner) { | 496 | switch (alt_tuner) { |
@@ -496,6 +591,17 @@ static int dvb_register(struct cx23885_tsport *port) | |||
496 | &hauppauge_hvr1200_tuner_config); | 591 | &hauppauge_hvr1200_tuner_config); |
497 | } | 592 | } |
498 | break; | 593 | break; |
594 | case CX23885_BOARD_HAUPPAUGE_HVR1210: | ||
595 | i2c_bus = &dev->i2c_bus[0]; | ||
596 | fe0->dvb.frontend = dvb_attach(tda10048_attach, | ||
597 | &hauppauge_hvr1210_config, | ||
598 | &i2c_bus->i2c_adap); | ||
599 | if (fe0->dvb.frontend != NULL) { | ||
600 | dvb_attach(tda18271_attach, fe0->dvb.frontend, | ||
601 | 0x60, &dev->i2c_bus[1].i2c_adap, | ||
602 | &hauppauge_hvr1210_tuner_config); | ||
603 | } | ||
604 | break; | ||
499 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | 605 | case CX23885_BOARD_HAUPPAUGE_HVR1400: |
500 | i2c_bus = &dev->i2c_bus[0]; | 606 | i2c_bus = &dev->i2c_bus[0]; |
501 | fe0->dvb.frontend = dvb_attach(dib7000p_attach, | 607 | fe0->dvb.frontend = dvb_attach(dib7000p_attach, |
@@ -659,6 +765,19 @@ static int dvb_register(struct cx23885_tsport *port) | |||
659 | break; | 765 | break; |
660 | } | 766 | } |
661 | break; | 767 | break; |
768 | case CX23885_BOARD_MYGICA_X8506: | ||
769 | i2c_bus = &dev->i2c_bus[0]; | ||
770 | i2c_bus2 = &dev->i2c_bus[1]; | ||
771 | fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, | ||
772 | &mygica_x8506_lgs8gl5_config, | ||
773 | &i2c_bus->i2c_adap); | ||
774 | if (fe0->dvb.frontend != NULL) { | ||
775 | dvb_attach(xc5000_attach, | ||
776 | fe0->dvb.frontend, | ||
777 | &i2c_bus2->i2c_adap, | ||
778 | &mygica_x8506_xc5000_config); | ||
779 | } | ||
780 | break; | ||
662 | default: | 781 | default: |
663 | printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " | 782 | printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " |
664 | " isn't supported yet\n", | 783 | " isn't supported yet\n", |
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index 3421bd12056a..384dec34134f 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c | |||
@@ -357,6 +357,18 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) | |||
357 | printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", | 357 | printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", |
358 | dev->name, bus->nr); | 358 | dev->name, bus->nr); |
359 | 359 | ||
360 | /* Instantiate the IR receiver device, if present */ | ||
361 | if (0 == bus->i2c_rc) { | ||
362 | struct i2c_board_info info; | ||
363 | const unsigned short addr_list[] = { | ||
364 | 0x6b, I2C_CLIENT_END | ||
365 | }; | ||
366 | |||
367 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
368 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
369 | i2c_new_probed_device(&bus->i2c_adap, &info, addr_list); | ||
370 | } | ||
371 | |||
360 | return bus->i2c_rc; | 372 | return bus->i2c_rc; |
361 | } | 373 | } |
362 | 374 | ||
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 68068c6d0987..66bbd2e71105 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -796,6 +796,7 @@ static unsigned int video_poll(struct file *file, | |||
796 | { | 796 | { |
797 | struct cx23885_fh *fh = file->private_data; | 797 | struct cx23885_fh *fh = file->private_data; |
798 | struct cx23885_buffer *buf; | 798 | struct cx23885_buffer *buf; |
799 | unsigned int rc = POLLERR; | ||
799 | 800 | ||
800 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { | 801 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { |
801 | if (!res_get(fh->dev, fh, RESOURCE_VBI)) | 802 | if (!res_get(fh->dev, fh, RESOURCE_VBI)) |
@@ -803,23 +804,28 @@ static unsigned int video_poll(struct file *file, | |||
803 | return videobuf_poll_stream(file, &fh->vbiq, wait); | 804 | return videobuf_poll_stream(file, &fh->vbiq, wait); |
804 | } | 805 | } |
805 | 806 | ||
807 | mutex_lock(&fh->vidq.vb_lock); | ||
806 | if (res_check(fh, RESOURCE_VIDEO)) { | 808 | if (res_check(fh, RESOURCE_VIDEO)) { |
807 | /* streaming capture */ | 809 | /* streaming capture */ |
808 | if (list_empty(&fh->vidq.stream)) | 810 | if (list_empty(&fh->vidq.stream)) |
809 | return POLLERR; | 811 | goto done; |
810 | buf = list_entry(fh->vidq.stream.next, | 812 | buf = list_entry(fh->vidq.stream.next, |
811 | struct cx23885_buffer, vb.stream); | 813 | struct cx23885_buffer, vb.stream); |
812 | } else { | 814 | } else { |
813 | /* read() capture */ | 815 | /* read() capture */ |
814 | buf = (struct cx23885_buffer *)fh->vidq.read_buf; | 816 | buf = (struct cx23885_buffer *)fh->vidq.read_buf; |
815 | if (NULL == buf) | 817 | if (NULL == buf) |
816 | return POLLERR; | 818 | goto done; |
817 | } | 819 | } |
818 | poll_wait(file, &buf->vb.done, wait); | 820 | poll_wait(file, &buf->vb.done, wait); |
819 | if (buf->vb.state == VIDEOBUF_DONE || | 821 | if (buf->vb.state == VIDEOBUF_DONE || |
820 | buf->vb.state == VIDEOBUF_ERROR) | 822 | buf->vb.state == VIDEOBUF_ERROR) |
821 | return POLLIN|POLLRDNORM; | 823 | rc = POLLIN|POLLRDNORM; |
822 | return 0; | 824 | else |
825 | rc = 0; | ||
826 | done: | ||
827 | mutex_unlock(&fh->vidq.vb_lock); | ||
828 | return rc; | ||
823 | } | 829 | } |
824 | 830 | ||
825 | static int video_release(struct file *file) | 831 | static int video_release(struct file *file) |
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 85642831ea8e..1a2ac518a3f1 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h | |||
@@ -71,6 +71,22 @@ | |||
71 | #define CX23885_BOARD_TEVII_S470 15 | 71 | #define CX23885_BOARD_TEVII_S470 15 |
72 | #define CX23885_BOARD_DVBWORLD_2005 16 | 72 | #define CX23885_BOARD_DVBWORLD_2005 16 |
73 | #define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17 | 73 | #define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17 |
74 | #define CX23885_BOARD_HAUPPAUGE_HVR1270 18 | ||
75 | #define CX23885_BOARD_HAUPPAUGE_HVR1275 19 | ||
76 | #define CX23885_BOARD_HAUPPAUGE_HVR1255 20 | ||
77 | #define CX23885_BOARD_HAUPPAUGE_HVR1210 21 | ||
78 | #define CX23885_BOARD_MYGICA_X8506 22 | ||
79 | |||
80 | #define GPIO_0 0x00000001 | ||
81 | #define GPIO_1 0x00000002 | ||
82 | #define GPIO_2 0x00000004 | ||
83 | #define GPIO_3 0x00000008 | ||
84 | #define GPIO_4 0x00000010 | ||
85 | #define GPIO_5 0x00000020 | ||
86 | #define GPIO_6 0x00000040 | ||
87 | #define GPIO_7 0x00000080 | ||
88 | #define GPIO_8 0x00000100 | ||
89 | #define GPIO_9 0x00000200 | ||
74 | 90 | ||
75 | /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ | 91 | /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ |
76 | #define CX23885_NORMS (\ | 92 | #define CX23885_NORMS (\ |
@@ -422,6 +438,11 @@ extern int cx23885_restart_queue(struct cx23885_tsport *port, | |||
422 | extern void cx23885_wakeup(struct cx23885_tsport *port, | 438 | extern void cx23885_wakeup(struct cx23885_tsport *port, |
423 | struct cx23885_dmaqueue *q, u32 count); | 439 | struct cx23885_dmaqueue *q, u32 count); |
424 | 440 | ||
441 | extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask); | ||
442 | extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask); | ||
443 | extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, | ||
444 | int asoutput); | ||
445 | |||
425 | 446 | ||
426 | /* ----------------------------------------------------------- */ | 447 | /* ----------------------------------------------------------- */ |
427 | /* cx23885-cards.c */ | 448 | /* cx23885-cards.c */ |
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index b06b1275a9ec..5b7e26761f0a 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \ | 1 | cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \ |
2 | cx88-input.o | 2 | cx88-dsp.o cx88-input.o |
3 | cx8800-objs := cx88-video.o cx88-vbi.o | 3 | cx8800-objs := cx88-video.o cx88-vbi.o |
4 | cx8802-objs := cx88-mpeg.o | 4 | cx8802-objs := cx88-mpeg.o |
5 | 5 | ||
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 0ccdf36626e3..5a67445dd6ed 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -871,7 +871,7 @@ static struct pci_driver cx88_audio_pci_driver = { | |||
871 | .name = "cx88_audio", | 871 | .name = "cx88_audio", |
872 | .id_table = cx88_audio_pci_tbl, | 872 | .id_table = cx88_audio_pci_tbl, |
873 | .probe = cx88_audio_initdev, | 873 | .probe = cx88_audio_initdev, |
874 | .remove = cx88_audio_finidev, | 874 | .remove = __devexit_p(cx88_audio_finidev), |
875 | }; | 875 | }; |
876 | 876 | ||
877 | /**************************************************************************** | 877 | /**************************************************************************** |
@@ -881,7 +881,7 @@ static struct pci_driver cx88_audio_pci_driver = { | |||
881 | /* | 881 | /* |
882 | * module init | 882 | * module init |
883 | */ | 883 | */ |
884 | static int cx88_audio_init(void) | 884 | static int __init cx88_audio_init(void) |
885 | { | 885 | { |
886 | printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n", | 886 | printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n", |
887 | (CX88_VERSION_CODE >> 16) & 0xff, | 887 | (CX88_VERSION_CODE >> 16) & 0xff, |
@@ -897,9 +897,8 @@ static int cx88_audio_init(void) | |||
897 | /* | 897 | /* |
898 | * module remove | 898 | * module remove |
899 | */ | 899 | */ |
900 | static void cx88_audio_fini(void) | 900 | static void __exit cx88_audio_fini(void) |
901 | { | 901 | { |
902 | |||
903 | pci_unregister_driver(&cx88_audio_pci_driver); | 902 | pci_unregister_driver(&cx88_audio_pci_driver); |
904 | } | 903 | } |
905 | 904 | ||
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 6bbbfc66bb4b..94b7a52629d0 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1969,6 +1969,54 @@ static const struct cx88_board cx88_boards[] = { | |||
1969 | }, | 1969 | }, |
1970 | .mpeg = CX88_MPEG_DVB, | 1970 | .mpeg = CX88_MPEG_DVB, |
1971 | }, | 1971 | }, |
1972 | [CX88_BOARD_HAUPPAUGE_IRONLY] = { | ||
1973 | .name = "Hauppauge WinTV-IR Only", | ||
1974 | .tuner_type = UNSET, | ||
1975 | .radio_type = UNSET, | ||
1976 | .tuner_addr = ADDR_UNSET, | ||
1977 | .radio_addr = ADDR_UNSET, | ||
1978 | }, | ||
1979 | [CX88_BOARD_WINFAST_DTV1800H] = { | ||
1980 | .name = "Leadtek WinFast DTV1800 Hybrid", | ||
1981 | .tuner_type = TUNER_XC2028, | ||
1982 | .radio_type = TUNER_XC2028, | ||
1983 | .tuner_addr = 0x61, | ||
1984 | .radio_addr = 0x61, | ||
1985 | /* | ||
1986 | * GPIO setting | ||
1987 | * | ||
1988 | * 2: mute (0=off,1=on) | ||
1989 | * 12: tuner reset pin | ||
1990 | * 13: audio source (0=tuner audio,1=line in) | ||
1991 | * 14: FM (0=on,1=off ???) | ||
1992 | */ | ||
1993 | .input = {{ | ||
1994 | .type = CX88_VMUX_TELEVISION, | ||
1995 | .vmux = 0, | ||
1996 | .gpio0 = 0x0400, /* pin 2 = 0 */ | ||
1997 | .gpio1 = 0x6040, /* pin 13 = 0, pin 14 = 1 */ | ||
1998 | .gpio2 = 0x0000, | ||
1999 | }, { | ||
2000 | .type = CX88_VMUX_COMPOSITE1, | ||
2001 | .vmux = 1, | ||
2002 | .gpio0 = 0x0400, /* pin 2 = 0 */ | ||
2003 | .gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */ | ||
2004 | .gpio2 = 0x0000, | ||
2005 | }, { | ||
2006 | .type = CX88_VMUX_SVIDEO, | ||
2007 | .vmux = 2, | ||
2008 | .gpio0 = 0x0400, /* pin 2 = 0 */ | ||
2009 | .gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */ | ||
2010 | .gpio2 = 0x0000, | ||
2011 | } }, | ||
2012 | .radio = { | ||
2013 | .type = CX88_RADIO, | ||
2014 | .gpio0 = 0x0400, /* pin 2 = 0 */ | ||
2015 | .gpio1 = 0x6000, /* pin 13 = 0, pin 14 = 0 */ | ||
2016 | .gpio2 = 0x0000, | ||
2017 | }, | ||
2018 | .mpeg = CX88_MPEG_DVB, | ||
2019 | }, | ||
1972 | }; | 2020 | }; |
1973 | 2021 | ||
1974 | /* ------------------------------------------------------------------ */ | 2022 | /* ------------------------------------------------------------------ */ |
@@ -2382,6 +2430,14 @@ static const struct cx88_subid cx88_subids[] = { | |||
2382 | .subvendor = 0x153b, | 2430 | .subvendor = 0x153b, |
2383 | .subdevice = 0x1177, | 2431 | .subdevice = 0x1177, |
2384 | .card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII, | 2432 | .card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII, |
2433 | }, { | ||
2434 | .subvendor = 0x0070, | ||
2435 | .subdevice = 0x9290, | ||
2436 | .card = CX88_BOARD_HAUPPAUGE_IRONLY, | ||
2437 | }, { | ||
2438 | .subvendor = 0x107d, | ||
2439 | .subdevice = 0x6654, | ||
2440 | .card = CX88_BOARD_WINFAST_DTV1800H, | ||
2385 | }, | 2441 | }, |
2386 | }; | 2442 | }; |
2387 | 2443 | ||
@@ -2448,6 +2504,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
2448 | case 90500: /* Nova-T-PCI (oem) */ | 2504 | case 90500: /* Nova-T-PCI (oem) */ |
2449 | case 90501: /* Nova-T-PCI (oem/IR) */ | 2505 | case 90501: /* Nova-T-PCI (oem/IR) */ |
2450 | case 92000: /* Nova-SE2 (OEM, No Video or IR) */ | 2506 | case 92000: /* Nova-SE2 (OEM, No Video or IR) */ |
2507 | case 92900: /* WinTV-IROnly (No analog or digital Video inputs) */ | ||
2451 | case 94009: /* WinTV-HVR1100 (Video and IR Retail) */ | 2508 | case 94009: /* WinTV-HVR1100 (Video and IR Retail) */ |
2452 | case 94501: /* WinTV-HVR1100 (Video and IR OEM) */ | 2509 | case 94501: /* WinTV-HVR1100 (Video and IR OEM) */ |
2453 | case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */ | 2510 | case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */ |
@@ -2579,6 +2636,23 @@ static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core, | |||
2579 | return -EINVAL; | 2636 | return -EINVAL; |
2580 | } | 2637 | } |
2581 | 2638 | ||
2639 | static int cx88_xc3028_winfast1800h_callback(struct cx88_core *core, | ||
2640 | int command, int arg) | ||
2641 | { | ||
2642 | switch (command) { | ||
2643 | case XC2028_TUNER_RESET: | ||
2644 | /* GPIO 12 (xc3028 tuner reset) */ | ||
2645 | cx_set(MO_GP1_IO, 0x1010); | ||
2646 | mdelay(50); | ||
2647 | cx_clear(MO_GP1_IO, 0x10); | ||
2648 | mdelay(50); | ||
2649 | cx_set(MO_GP1_IO, 0x10); | ||
2650 | mdelay(50); | ||
2651 | return 0; | ||
2652 | } | ||
2653 | return -EINVAL; | ||
2654 | } | ||
2655 | |||
2582 | /* ------------------------------------------------------------------- */ | 2656 | /* ------------------------------------------------------------------- */ |
2583 | /* some Divco specific stuff */ | 2657 | /* some Divco specific stuff */ |
2584 | static int cx88_pv_8000gt_callback(struct cx88_core *core, | 2658 | static int cx88_pv_8000gt_callback(struct cx88_core *core, |
@@ -2651,6 +2725,8 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core, | |||
2651 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: | 2725 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: |
2652 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: | 2726 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: |
2653 | return cx88_dvico_xc2028_callback(core, command, arg); | 2727 | return cx88_dvico_xc2028_callback(core, command, arg); |
2728 | case CX88_BOARD_WINFAST_DTV1800H: | ||
2729 | return cx88_xc3028_winfast1800h_callback(core, command, arg); | ||
2654 | } | 2730 | } |
2655 | 2731 | ||
2656 | switch (command) { | 2732 | switch (command) { |
@@ -2690,10 +2766,22 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core, | |||
2690 | switch (core->boardnr) { | 2766 | switch (core->boardnr) { |
2691 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: | 2767 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: |
2692 | if (command == 0) { /* This is the reset command from xc5000 */ | 2768 | if (command == 0) { /* This is the reset command from xc5000 */ |
2693 | /* Reset XC5000 tuner via SYS_RSTO_pin */ | 2769 | |
2694 | cx_write(MO_SRST_IO, 0); | 2770 | /* djh - According to the engineer at PCTV Systems, |
2695 | msleep(10); | 2771 | the xc5000 reset pin is supposed to be on GPIO12. |
2696 | cx_write(MO_SRST_IO, 1); | 2772 | However, despite three nights of effort, pulling |
2773 | that GPIO low didn't reset the xc5000. While | ||
2774 | pulling MO_SRST_IO low does reset the xc5000, this | ||
2775 | also resets in the s5h1409 being reset as well. | ||
2776 | This causes tuning to always fail since the internal | ||
2777 | state of the s5h1409 does not match the driver's | ||
2778 | state. Given that the only two conditions in which | ||
2779 | the driver performs a reset is during firmware load | ||
2780 | and powering down the chip, I am taking out the | ||
2781 | reset. We know that the chip is being reset | ||
2782 | when the cx88 comes online, and not being able to | ||
2783 | do power management for this board is worse than | ||
2784 | not having any tuning at all. */ | ||
2697 | return 0; | 2785 | return 0; |
2698 | } else { | 2786 | } else { |
2699 | err_printk(core, "xc5000: unknown tuner " | 2787 | err_printk(core, "xc5000: unknown tuner " |
@@ -2825,6 +2913,16 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) | |||
2825 | cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ | 2913 | cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ |
2826 | udelay(1000); | 2914 | udelay(1000); |
2827 | break; | 2915 | break; |
2916 | |||
2917 | case CX88_BOARD_WINFAST_DTV1800H: | ||
2918 | /* GPIO 12 (xc3028 tuner reset) */ | ||
2919 | cx_set(MO_GP1_IO, 0x1010); | ||
2920 | mdelay(50); | ||
2921 | cx_clear(MO_GP1_IO, 0x10); | ||
2922 | mdelay(50); | ||
2923 | cx_set(MO_GP1_IO, 0x10); | ||
2924 | mdelay(50); | ||
2925 | break; | ||
2828 | } | 2926 | } |
2829 | } | 2927 | } |
2830 | 2928 | ||
@@ -2845,6 +2943,7 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl) | |||
2845 | core->i2c_algo.udelay = 16; | 2943 | core->i2c_algo.udelay = 16; |
2846 | break; | 2944 | break; |
2847 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: | 2945 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: |
2946 | case CX88_BOARD_WINFAST_DTV1800H: | ||
2848 | ctl->demod = XC3028_FE_ZARLINK456; | 2947 | ctl->demod = XC3028_FE_ZARLINK456; |
2849 | break; | 2948 | break; |
2850 | case CX88_BOARD_KWORLD_ATSC_120: | 2949 | case CX88_BOARD_KWORLD_ATSC_120: |
@@ -2907,6 +3006,7 @@ static void cx88_card_setup(struct cx88_core *core) | |||
2907 | case CX88_BOARD_HAUPPAUGE_HVR1300: | 3006 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
2908 | case CX88_BOARD_HAUPPAUGE_HVR4000: | 3007 | case CX88_BOARD_HAUPPAUGE_HVR4000: |
2909 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: | 3008 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: |
3009 | case CX88_BOARD_HAUPPAUGE_IRONLY: | ||
2910 | if (0 == core->i2c_rc) | 3010 | if (0 == core->i2c_rc) |
2911 | hauppauge_eeprom(core, eeprom); | 3011 | hauppauge_eeprom(core, eeprom); |
2912 | break; | 3012 | break; |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 0e149b22bd19..cf634606ba9a 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -231,7 +231,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) | |||
231 | * can use the whole SDRAM for the DMA fifos. To simplify things, we | 231 | * can use the whole SDRAM for the DMA fifos. To simplify things, we |
232 | * use a static memory layout. That surely will waste memory in case | 232 | * use a static memory layout. That surely will waste memory in case |
233 | * we don't use all DMA channels at the same time (which will be the | 233 | * we don't use all DMA channels at the same time (which will be the |
234 | * case most of the time). But that still gives us enougth FIFO space | 234 | * case most of the time). But that still gives us enough FIFO space |
235 | * to be able to deal with insane long pci latencies ... | 235 | * to be able to deal with insane long pci latencies ... |
236 | * | 236 | * |
237 | * FIFO space allocations: | 237 | * FIFO space allocations: |
@@ -241,6 +241,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) | |||
241 | * channel 24 (vbi) - 4.0k | 241 | * channel 24 (vbi) - 4.0k |
242 | * channels 25+26 (audio) - 4.0k | 242 | * channels 25+26 (audio) - 4.0k |
243 | * channel 28 (mpeg) - 4.0k | 243 | * channel 28 (mpeg) - 4.0k |
244 | * channel 27 (audio rds)- 3.0k | ||
244 | * TOTAL = 29.0k | 245 | * TOTAL = 29.0k |
245 | * | 246 | * |
246 | * Every channel has 160 bytes control data (64 bytes instruction | 247 | * Every channel has 160 bytes control data (64 bytes instruction |
@@ -337,6 +338,18 @@ struct sram_channel cx88_sram_channels[] = { | |||
337 | .cnt1_reg = MO_DMA28_CNT1, | 338 | .cnt1_reg = MO_DMA28_CNT1, |
338 | .cnt2_reg = MO_DMA28_CNT2, | 339 | .cnt2_reg = MO_DMA28_CNT2, |
339 | }, | 340 | }, |
341 | [SRAM_CH27] = { | ||
342 | .name = "audio rds", | ||
343 | .cmds_start = 0x1801C0, | ||
344 | .ctrl_start = 0x180860, | ||
345 | .cdt = 0x180860 + 64, | ||
346 | .fifo_start = 0x187400, | ||
347 | .fifo_size = 0x000C00, | ||
348 | .ptr1_reg = MO_DMA27_PTR1, | ||
349 | .ptr2_reg = MO_DMA27_PTR2, | ||
350 | .cnt1_reg = MO_DMA27_CNT1, | ||
351 | .cnt2_reg = MO_DMA27_CNT2, | ||
352 | }, | ||
340 | }; | 353 | }; |
341 | 354 | ||
342 | int cx88_sram_channel_setup(struct cx88_core *core, | 355 | int cx88_sram_channel_setup(struct cx88_core *core, |
@@ -598,6 +611,7 @@ int cx88_reset(struct cx88_core *core) | |||
598 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0); | 611 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0); |
599 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0); | 612 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0); |
600 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0); | 613 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0); |
614 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0); | ||
601 | 615 | ||
602 | /* misc init ... */ | 616 | /* misc init ... */ |
603 | cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable | 617 | cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable |
@@ -796,6 +810,8 @@ int cx88_start_audio_dma(struct cx88_core *core) | |||
796 | /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */ | 810 | /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */ |
797 | int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4; | 811 | int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4; |
798 | 812 | ||
813 | int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size/AUD_RDS_LINES; | ||
814 | |||
799 | /* If downstream RISC is enabled, bail out; ALSA is managing DMA */ | 815 | /* If downstream RISC is enabled, bail out; ALSA is managing DMA */ |
800 | if (cx_read(MO_AUD_DMACNTRL) & 0x10) | 816 | if (cx_read(MO_AUD_DMACNTRL) & 0x10) |
801 | return 0; | 817 | return 0; |
@@ -803,12 +819,14 @@ int cx88_start_audio_dma(struct cx88_core *core) | |||
803 | /* setup fifo + format */ | 819 | /* setup fifo + format */ |
804 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0); | 820 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0); |
805 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0); | 821 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0); |
822 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], | ||
823 | rds_bpl, 0); | ||
806 | 824 | ||
807 | cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */ | 825 | cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */ |
808 | cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */ | 826 | cx_write(MO_AUDR_LNGTH, rds_bpl); /* fifo bpl size */ |
809 | 827 | ||
810 | /* start dma */ | 828 | /* enable Up, Down and Audio RDS fifo */ |
811 | cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ | 829 | cx_write(MO_AUD_DMACNTRL, 0x0007); |
812 | 830 | ||
813 | return 0; | 831 | return 0; |
814 | } | 832 | } |
@@ -1010,7 +1028,6 @@ struct video_device *cx88_vdev_init(struct cx88_core *core, | |||
1010 | if (NULL == vfd) | 1028 | if (NULL == vfd) |
1011 | return NULL; | 1029 | return NULL; |
1012 | *vfd = *template; | 1030 | *vfd = *template; |
1013 | vfd->minor = -1; | ||
1014 | vfd->v4l2_dev = &core->v4l2_dev; | 1031 | vfd->v4l2_dev = &core->v4l2_dev; |
1015 | vfd->parent = &pci->dev; | 1032 | vfd->parent = &pci->dev; |
1016 | vfd->release = video_device_release; | 1033 | vfd->release = video_device_release; |
diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c new file mode 100644 index 000000000000..3e5eaf3fe2a6 --- /dev/null +++ b/drivers/media/video/cx88/cx88-dsp.c | |||
@@ -0,0 +1,312 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Stereo and SAP detection for cx88 | ||
4 | * | ||
5 | * Copyright (c) 2009 Marton Balint <cus@fazekas.hu> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (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 General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/jiffies.h> | ||
25 | #include <asm/div64.h> | ||
26 | |||
27 | #include "cx88.h" | ||
28 | #include "cx88-reg.h" | ||
29 | |||
30 | #define INT_PI ((s32)(3.141592653589 * 32768.0)) | ||
31 | |||
32 | #define compat_remainder(a, b) \ | ||
33 | ((float)(((s32)((a)*100))%((s32)((b)*100)))/100.0) | ||
34 | |||
35 | #define baseband_freq(carrier, srate, tone) ((s32)( \ | ||
36 | (compat_remainder(carrier + tone, srate)) / srate * 2 * INT_PI)) | ||
37 | |||
38 | /* We calculate the baseband frequencies of the carrier and the pilot tones | ||
39 | * based on the the sampling rate of the audio rds fifo. */ | ||
40 | |||
41 | #define FREQ_A2_CARRIER baseband_freq(54687.5, 2689.36, 0.0) | ||
42 | #define FREQ_A2_DUAL baseband_freq(54687.5, 2689.36, 274.1) | ||
43 | #define FREQ_A2_STEREO baseband_freq(54687.5, 2689.36, 117.5) | ||
44 | |||
45 | /* The frequencies below are from the reference driver. They probably need | ||
46 | * further adjustments, because they are not tested at all. You may even need | ||
47 | * to play a bit with the registers of the chip to select the proper signal | ||
48 | * for the input of the audio rds fifo, and measure it's sampling rate to | ||
49 | * calculate the proper baseband frequencies... */ | ||
50 | |||
51 | #define FREQ_A2M_CARRIER ((s32)(2.114516 * 32768.0)) | ||
52 | #define FREQ_A2M_DUAL ((s32)(2.754916 * 32768.0)) | ||
53 | #define FREQ_A2M_STEREO ((s32)(2.462326 * 32768.0)) | ||
54 | |||
55 | #define FREQ_EIAJ_CARRIER ((s32)(1.963495 * 32768.0)) /* 5pi/8 */ | ||
56 | #define FREQ_EIAJ_DUAL ((s32)(2.562118 * 32768.0)) | ||
57 | #define FREQ_EIAJ_STEREO ((s32)(2.601053 * 32768.0)) | ||
58 | |||
59 | #define FREQ_BTSC_DUAL ((s32)(1.963495 * 32768.0)) /* 5pi/8 */ | ||
60 | #define FREQ_BTSC_DUAL_REF ((s32)(1.374446 * 32768.0)) /* 7pi/16 */ | ||
61 | |||
62 | #define FREQ_BTSC_SAP ((s32)(2.471532 * 32768.0)) | ||
63 | #define FREQ_BTSC_SAP_REF ((s32)(1.730072 * 32768.0)) | ||
64 | |||
65 | /* The spectrum of the signal should be empty between these frequencies. */ | ||
66 | #define FREQ_NOISE_START ((s32)(0.100000 * 32768.0)) | ||
67 | #define FREQ_NOISE_END ((s32)(1.200000 * 32768.0)) | ||
68 | |||
69 | static unsigned int dsp_debug; | ||
70 | module_param(dsp_debug, int, 0644); | ||
71 | MODULE_PARM_DESC(dsp_debug, "enable audio dsp debug messages"); | ||
72 | |||
73 | #define dprintk(level, fmt, arg...) if (dsp_debug >= level) \ | ||
74 | printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) | ||
75 | |||
76 | static s32 int_cos(u32 x) | ||
77 | { | ||
78 | u32 t2, t4, t6, t8; | ||
79 | s32 ret; | ||
80 | u16 period = x / INT_PI; | ||
81 | if (period % 2) | ||
82 | return -int_cos(x - INT_PI); | ||
83 | x = x % INT_PI; | ||
84 | if (x > INT_PI/2) | ||
85 | return -int_cos(INT_PI/2 - (x % (INT_PI/2))); | ||
86 | /* Now x is between 0 and INT_PI/2. | ||
87 | * To calculate cos(x) we use it's Taylor polinom. */ | ||
88 | t2 = x*x/32768/2; | ||
89 | t4 = t2*x/32768*x/32768/3/4; | ||
90 | t6 = t4*x/32768*x/32768/5/6; | ||
91 | t8 = t6*x/32768*x/32768/7/8; | ||
92 | ret = 32768-t2+t4-t6+t8; | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | static u32 int_goertzel(s16 x[], u32 N, u32 freq) | ||
97 | { | ||
98 | /* We use the Goertzel algorithm to determine the power of the | ||
99 | * given frequency in the signal */ | ||
100 | s32 s_prev = 0; | ||
101 | s32 s_prev2 = 0; | ||
102 | s32 coeff = 2*int_cos(freq); | ||
103 | u32 i; | ||
104 | |||
105 | u64 tmp; | ||
106 | u32 divisor; | ||
107 | |||
108 | for (i = 0; i < N; i++) { | ||
109 | s32 s = x[i] + ((s64)coeff*s_prev/32768) - s_prev2; | ||
110 | s_prev2 = s_prev; | ||
111 | s_prev = s; | ||
112 | } | ||
113 | |||
114 | tmp = (s64)s_prev2 * s_prev2 + (s64)s_prev * s_prev - | ||
115 | (s64)coeff * s_prev2 * s_prev / 32768; | ||
116 | |||
117 | /* XXX: N must be low enough so that N*N fits in s32. | ||
118 | * Else we need two divisions. */ | ||
119 | divisor = N * N; | ||
120 | do_div(tmp, divisor); | ||
121 | |||
122 | return (u32) tmp; | ||
123 | } | ||
124 | |||
125 | static u32 freq_magnitude(s16 x[], u32 N, u32 freq) | ||
126 | { | ||
127 | u32 sum = int_goertzel(x, N, freq); | ||
128 | return (u32)int_sqrt(sum); | ||
129 | } | ||
130 | |||
131 | static u32 noise_magnitude(s16 x[], u32 N, u32 freq_start, u32 freq_end) | ||
132 | { | ||
133 | int i; | ||
134 | u32 sum = 0; | ||
135 | u32 freq_step; | ||
136 | int samples = 5; | ||
137 | |||
138 | if (N > 192) { | ||
139 | /* The last 192 samples are enough for noise detection */ | ||
140 | x += (N-192); | ||
141 | N = 192; | ||
142 | } | ||
143 | |||
144 | freq_step = (freq_end - freq_start) / (samples - 1); | ||
145 | |||
146 | for (i = 0; i < samples; i++) { | ||
147 | sum += int_goertzel(x, N, freq_start); | ||
148 | freq_start += freq_step; | ||
149 | } | ||
150 | |||
151 | return (u32)int_sqrt(sum / samples); | ||
152 | } | ||
153 | |||
154 | static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N) | ||
155 | { | ||
156 | s32 carrier, stereo, dual, noise; | ||
157 | s32 carrier_freq, stereo_freq, dual_freq; | ||
158 | s32 ret; | ||
159 | |||
160 | switch (core->tvaudio) { | ||
161 | case WW_BG: | ||
162 | case WW_DK: | ||
163 | carrier_freq = FREQ_A2_CARRIER; | ||
164 | stereo_freq = FREQ_A2_STEREO; | ||
165 | dual_freq = FREQ_A2_DUAL; | ||
166 | break; | ||
167 | case WW_M: | ||
168 | carrier_freq = FREQ_A2M_CARRIER; | ||
169 | stereo_freq = FREQ_A2M_STEREO; | ||
170 | dual_freq = FREQ_A2M_DUAL; | ||
171 | break; | ||
172 | case WW_EIAJ: | ||
173 | carrier_freq = FREQ_EIAJ_CARRIER; | ||
174 | stereo_freq = FREQ_EIAJ_STEREO; | ||
175 | dual_freq = FREQ_EIAJ_DUAL; | ||
176 | break; | ||
177 | default: | ||
178 | printk(KERN_WARNING "%s/0: unsupported audio mode %d for %s\n", | ||
179 | core->name, core->tvaudio, __func__); | ||
180 | return UNSET; | ||
181 | } | ||
182 | |||
183 | carrier = freq_magnitude(x, N, carrier_freq); | ||
184 | stereo = freq_magnitude(x, N, stereo_freq); | ||
185 | dual = freq_magnitude(x, N, dual_freq); | ||
186 | noise = noise_magnitude(x, N, FREQ_NOISE_START, FREQ_NOISE_END); | ||
187 | |||
188 | dprintk(1, "detect a2/a2m/eiaj: carrier=%d, stereo=%d, dual=%d, " | ||
189 | "noise=%d\n", carrier, stereo, dual, noise); | ||
190 | |||
191 | if (stereo > dual) | ||
192 | ret = V4L2_TUNER_SUB_STEREO; | ||
193 | else | ||
194 | ret = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | ||
195 | |||
196 | if (core->tvaudio == WW_EIAJ) { | ||
197 | /* EIAJ checks may need adjustments */ | ||
198 | if ((carrier > max(stereo, dual)*2) && | ||
199 | (carrier < max(stereo, dual)*6) && | ||
200 | (carrier > 20 && carrier < 200) && | ||
201 | (max(stereo, dual) > min(stereo, dual))) { | ||
202 | /* For EIAJ the carrier is always present, | ||
203 | so we probably don't need noise detection */ | ||
204 | return ret; | ||
205 | } | ||
206 | } else { | ||
207 | if ((carrier > max(stereo, dual)*2) && | ||
208 | (carrier < max(stereo, dual)*8) && | ||
209 | (carrier > 20 && carrier < 200) && | ||
210 | (noise < 10) && | ||
211 | (max(stereo, dual) > min(stereo, dual)*2)) { | ||
212 | return ret; | ||
213 | } | ||
214 | } | ||
215 | return V4L2_TUNER_SUB_MONO; | ||
216 | } | ||
217 | |||
218 | static s32 detect_btsc(struct cx88_core *core, s16 x[], u32 N) | ||
219 | { | ||
220 | s32 sap_ref = freq_magnitude(x, N, FREQ_BTSC_SAP_REF); | ||
221 | s32 sap = freq_magnitude(x, N, FREQ_BTSC_SAP); | ||
222 | s32 dual_ref = freq_magnitude(x, N, FREQ_BTSC_DUAL_REF); | ||
223 | s32 dual = freq_magnitude(x, N, FREQ_BTSC_DUAL); | ||
224 | dprintk(1, "detect btsc: dual_ref=%d, dual=%d, sap_ref=%d, sap=%d" | ||
225 | "\n", dual_ref, dual, sap_ref, sap); | ||
226 | /* FIXME: Currently not supported */ | ||
227 | return UNSET; | ||
228 | } | ||
229 | |||
230 | static s16 *read_rds_samples(struct cx88_core *core, u32 *N) | ||
231 | { | ||
232 | struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27]; | ||
233 | s16 *samples; | ||
234 | |||
235 | unsigned int i; | ||
236 | unsigned int bpl = srch->fifo_size/AUD_RDS_LINES; | ||
237 | unsigned int spl = bpl/4; | ||
238 | unsigned int sample_count = spl*(AUD_RDS_LINES-1); | ||
239 | |||
240 | u32 current_address = cx_read(srch->ptr1_reg); | ||
241 | u32 offset = (current_address - srch->fifo_start + bpl); | ||
242 | |||
243 | dprintk(1, "read RDS samples: current_address=%08x (offset=%08x), " | ||
244 | "sample_count=%d, aud_intstat=%08x\n", current_address, | ||
245 | current_address - srch->fifo_start, sample_count, | ||
246 | cx_read(MO_AUD_INTSTAT)); | ||
247 | |||
248 | samples = kmalloc(sizeof(s16)*sample_count, GFP_KERNEL); | ||
249 | if (!samples) | ||
250 | return NULL; | ||
251 | |||
252 | *N = sample_count; | ||
253 | |||
254 | for (i = 0; i < sample_count; i++) { | ||
255 | offset = offset % (AUD_RDS_LINES*bpl); | ||
256 | samples[i] = cx_read(srch->fifo_start + offset); | ||
257 | offset += 4; | ||
258 | } | ||
259 | |||
260 | if (dsp_debug >= 2) { | ||
261 | dprintk(2, "RDS samples dump: "); | ||
262 | for (i = 0; i < sample_count; i++) | ||
263 | printk("%hd ", samples[i]); | ||
264 | printk(".\n"); | ||
265 | } | ||
266 | |||
267 | return samples; | ||
268 | } | ||
269 | |||
270 | s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core) | ||
271 | { | ||
272 | s16 *samples; | ||
273 | u32 N = 0; | ||
274 | s32 ret = UNSET; | ||
275 | |||
276 | /* If audio RDS fifo is disabled, we can't read the samples */ | ||
277 | if (!(cx_read(MO_AUD_DMACNTRL) & 0x04)) | ||
278 | return ret; | ||
279 | if (!(cx_read(AUD_CTL) & EN_FMRADIO_EN_RDS)) | ||
280 | return ret; | ||
281 | |||
282 | /* Wait at least 500 ms after an audio standard change */ | ||
283 | if (time_before(jiffies, core->last_change + msecs_to_jiffies(500))) | ||
284 | return ret; | ||
285 | |||
286 | samples = read_rds_samples(core, &N); | ||
287 | |||
288 | if (!samples) | ||
289 | return ret; | ||
290 | |||
291 | switch (core->tvaudio) { | ||
292 | case WW_BG: | ||
293 | case WW_DK: | ||
294 | ret = detect_a2_a2m_eiaj(core, samples, N); | ||
295 | break; | ||
296 | case WW_BTSC: | ||
297 | ret = detect_btsc(core, samples, N); | ||
298 | break; | ||
299 | } | ||
300 | |||
301 | kfree(samples); | ||
302 | |||
303 | if (UNSET != ret) | ||
304 | dprintk(1, "stereo/sap detection result:%s%s%s\n", | ||
305 | (ret & V4L2_TUNER_SUB_MONO) ? " mono" : "", | ||
306 | (ret & V4L2_TUNER_SUB_STEREO) ? " stereo" : "", | ||
307 | (ret & V4L2_TUNER_SUB_LANG2) ? " dual" : ""); | ||
308 | |||
309 | return ret; | ||
310 | } | ||
311 | EXPORT_SYMBOL(cx88_dsp_detect_stereo_sap); | ||
312 | |||
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 9389cf290c1b..c44e87600219 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -1014,6 +1014,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
1014 | } | 1014 | } |
1015 | break; | 1015 | break; |
1016 | case CX88_BOARD_PINNACLE_HYBRID_PCTV: | 1016 | case CX88_BOARD_PINNACLE_HYBRID_PCTV: |
1017 | case CX88_BOARD_WINFAST_DTV1800H: | ||
1017 | fe0->dvb.frontend = dvb_attach(zl10353_attach, | 1018 | fe0->dvb.frontend = dvb_attach(zl10353_attach, |
1018 | &cx88_pinnacle_hybrid_pctv, | 1019 | &cx88_pinnacle_hybrid_pctv, |
1019 | &core->i2c_adap); | 1020 | &core->i2c_adap); |
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 996b4ed5a4fc..ee1ca39db06a 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -180,6 +180,19 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) | |||
180 | do_i2c_scan(core->name,&core->i2c_client); | 180 | do_i2c_scan(core->name,&core->i2c_client); |
181 | } else | 181 | } else |
182 | printk("%s: i2c register FAILED\n", core->name); | 182 | printk("%s: i2c register FAILED\n", core->name); |
183 | |||
184 | /* Instantiate the IR receiver device, if present */ | ||
185 | if (0 == core->i2c_rc) { | ||
186 | struct i2c_board_info info; | ||
187 | const unsigned short addr_list[] = { | ||
188 | 0x18, 0x6b, 0x71, | ||
189 | I2C_CLIENT_END | ||
190 | }; | ||
191 | |||
192 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
193 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
194 | i2c_new_probed_device(&core->i2c_adap, &info, addr_list); | ||
195 | } | ||
183 | return core->i2c_rc; | 196 | return core->i2c_rc; |
184 | } | 197 | } |
185 | 198 | ||
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index ec05312a9b62..d91f5c51206d 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -91,6 +91,8 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) | |||
91 | gpio=(gpio & 0x7fd) + (auxgpio & 0xef); | 91 | gpio=(gpio & 0x7fd) + (auxgpio & 0xef); |
92 | break; | 92 | break; |
93 | case CX88_BOARD_WINFAST_DTV1000: | 93 | case CX88_BOARD_WINFAST_DTV1000: |
94 | case CX88_BOARD_WINFAST_DTV1800H: | ||
95 | case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: | ||
94 | gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900); | 96 | gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900); |
95 | auxgpio = gpio; | 97 | auxgpio = gpio; |
96 | break; | 98 | break; |
@@ -217,11 +219,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
217 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: | 219 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: |
218 | case CX88_BOARD_PCHDTV_HD3000: | 220 | case CX88_BOARD_PCHDTV_HD3000: |
219 | case CX88_BOARD_PCHDTV_HD5500: | 221 | case CX88_BOARD_PCHDTV_HD5500: |
222 | case CX88_BOARD_HAUPPAUGE_IRONLY: | ||
220 | ir_codes = ir_codes_hauppauge_new; | 223 | ir_codes = ir_codes_hauppauge_new; |
221 | ir_type = IR_TYPE_RC5; | 224 | ir_type = IR_TYPE_RC5; |
222 | ir->sampling = 1; | 225 | ir->sampling = 1; |
223 | break; | 226 | break; |
224 | case CX88_BOARD_WINFAST_DTV2000H: | 227 | case CX88_BOARD_WINFAST_DTV2000H: |
228 | case CX88_BOARD_WINFAST_DTV1800H: | ||
225 | ir_codes = ir_codes_winfast; | 229 | ir_codes = ir_codes_winfast; |
226 | ir->gpio_addr = MO_GP0_IO; | 230 | ir->gpio_addr = MO_GP0_IO; |
227 | ir->mask_keycode = 0x8f8; | 231 | ir->mask_keycode = 0x8f8; |
@@ -230,6 +234,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
230 | break; | 234 | break; |
231 | case CX88_BOARD_WINFAST2000XP_EXPERT: | 235 | case CX88_BOARD_WINFAST2000XP_EXPERT: |
232 | case CX88_BOARD_WINFAST_DTV1000: | 236 | case CX88_BOARD_WINFAST_DTV1000: |
237 | case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: | ||
233 | ir_codes = ir_codes_winfast; | 238 | ir_codes = ir_codes_winfast; |
234 | ir->gpio_addr = MO_GP0_IO; | 239 | ir->gpio_addr = MO_GP0_IO; |
235 | ir->mask_keycode = 0x8f8; | 240 | ir->mask_keycode = 0x8f8; |
@@ -459,6 +464,7 @@ void cx88_ir_irq(struct cx88_core *core) | |||
459 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: | 464 | case CX88_BOARD_HAUPPAUGE_HVR4000LITE: |
460 | case CX88_BOARD_PCHDTV_HD3000: | 465 | case CX88_BOARD_PCHDTV_HD3000: |
461 | case CX88_BOARD_PCHDTV_HD5500: | 466 | case CX88_BOARD_PCHDTV_HD5500: |
467 | case CX88_BOARD_HAUPPAUGE_IRONLY: | ||
462 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); | 468 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); |
463 | ir_dprintk("biphase decoded: %x\n", ircode); | 469 | ir_dprintk("biphase decoded: %x\n", ircode); |
464 | /* | 470 | /* |
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 7dd506b987fe..e8316cf7f32f 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c | |||
@@ -163,6 +163,8 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) | |||
163 | /* unmute */ | 163 | /* unmute */ |
164 | volume = cx_sread(SHADOW_AUD_VOL_CTL); | 164 | volume = cx_sread(SHADOW_AUD_VOL_CTL); |
165 | cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume); | 165 | cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume); |
166 | |||
167 | core->last_change = jiffies; | ||
166 | } | 168 | } |
167 | 169 | ||
168 | /* ----------------------------------------------------------- */ | 170 | /* ----------------------------------------------------------- */ |
@@ -745,6 +747,7 @@ void cx88_set_tvaudio(struct cx88_core *core) | |||
745 | break; | 747 | break; |
746 | case WW_BG: | 748 | case WW_BG: |
747 | case WW_DK: | 749 | case WW_DK: |
750 | case WW_M: | ||
748 | case WW_I: | 751 | case WW_I: |
749 | case WW_L: | 752 | case WW_L: |
750 | /* prepare all dsp registers */ | 753 | /* prepare all dsp registers */ |
@@ -756,6 +759,7 @@ void cx88_set_tvaudio(struct cx88_core *core) | |||
756 | if (0 == cx88_detect_nicam(core)) { | 759 | if (0 == cx88_detect_nicam(core)) { |
757 | /* fall back to fm / am mono */ | 760 | /* fall back to fm / am mono */ |
758 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); | 761 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); |
762 | core->audiomode_current = V4L2_TUNER_MODE_MONO; | ||
759 | core->use_nicam = 0; | 763 | core->use_nicam = 0; |
760 | } else { | 764 | } else { |
761 | core->use_nicam = 1; | 765 | core->use_nicam = 1; |
@@ -787,6 +791,7 @@ void cx88_set_tvaudio(struct cx88_core *core) | |||
787 | void cx88_newstation(struct cx88_core *core) | 791 | void cx88_newstation(struct cx88_core *core) |
788 | { | 792 | { |
789 | core->audiomode_manual = UNSET; | 793 | core->audiomode_manual = UNSET; |
794 | core->last_change = jiffies; | ||
790 | } | 795 | } |
791 | 796 | ||
792 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | 797 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) |
@@ -805,12 +810,50 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | |||
805 | aud_ctl_names[cx_read(AUD_CTL) & 63]); | 810 | aud_ctl_names[cx_read(AUD_CTL) & 63]); |
806 | core->astat = reg; | 811 | core->astat = reg; |
807 | 812 | ||
808 | /* TODO | 813 | t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | |
809 | Reading from AUD_STATUS is not enough | 814 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; |
810 | for auto-detecting sap/dual-fm/nicam. | 815 | t->rxsubchans = UNSET; |
811 | Add some code here later. | 816 | t->audmode = V4L2_TUNER_MODE_MONO; |
812 | */ | 817 | |
818 | switch (mode) { | ||
819 | case 0: | ||
820 | t->audmode = V4L2_TUNER_MODE_STEREO; | ||
821 | break; | ||
822 | case 1: | ||
823 | t->audmode = V4L2_TUNER_MODE_LANG2; | ||
824 | break; | ||
825 | case 2: | ||
826 | t->audmode = V4L2_TUNER_MODE_MONO; | ||
827 | break; | ||
828 | case 3: | ||
829 | t->audmode = V4L2_TUNER_MODE_SAP; | ||
830 | break; | ||
831 | } | ||
813 | 832 | ||
833 | switch (core->tvaudio) { | ||
834 | case WW_BTSC: | ||
835 | case WW_BG: | ||
836 | case WW_DK: | ||
837 | case WW_M: | ||
838 | case WW_EIAJ: | ||
839 | if (!core->use_nicam) { | ||
840 | t->rxsubchans = cx88_dsp_detect_stereo_sap(core); | ||
841 | break; | ||
842 | } | ||
843 | break; | ||
844 | default: | ||
845 | /* nothing */ | ||
846 | break; | ||
847 | } | ||
848 | |||
849 | /* If software stereo detection is not supported... */ | ||
850 | if (UNSET == t->rxsubchans) { | ||
851 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
852 | /* If the hardware itself detected stereo, also return | ||
853 | stereo as an available subchannel */ | ||
854 | if (V4L2_TUNER_MODE_STEREO == t->audmode) | ||
855 | t->rxsubchans |= V4L2_TUNER_SUB_STEREO; | ||
856 | } | ||
814 | return; | 857 | return; |
815 | } | 858 | } |
816 | 859 | ||
@@ -847,6 +890,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) | |||
847 | break; | 890 | break; |
848 | case WW_BG: | 891 | case WW_BG: |
849 | case WW_DK: | 892 | case WW_DK: |
893 | case WW_M: | ||
850 | case WW_I: | 894 | case WW_I: |
851 | case WW_L: | 895 | case WW_L: |
852 | if (1 == core->use_nicam) { | 896 | if (1 == core->use_nicam) { |
@@ -872,20 +916,18 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) | |||
872 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); | 916 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); |
873 | } else { | 917 | } else { |
874 | /* TODO: Add A2 autodection */ | 918 | /* TODO: Add A2 autodection */ |
919 | mask = 0x3f; | ||
875 | switch (mode) { | 920 | switch (mode) { |
876 | case V4L2_TUNER_MODE_MONO: | 921 | case V4L2_TUNER_MODE_MONO: |
877 | case V4L2_TUNER_MODE_LANG1: | 922 | case V4L2_TUNER_MODE_LANG1: |
878 | set_audio_standard_A2(core, | 923 | ctl = EN_A2_FORCE_MONO1; |
879 | EN_A2_FORCE_MONO1); | ||
880 | break; | 924 | break; |
881 | case V4L2_TUNER_MODE_LANG2: | 925 | case V4L2_TUNER_MODE_LANG2: |
882 | set_audio_standard_A2(core, | 926 | ctl = EN_A2_FORCE_MONO2; |
883 | EN_A2_FORCE_MONO2); | ||
884 | break; | 927 | break; |
885 | case V4L2_TUNER_MODE_STEREO: | 928 | case V4L2_TUNER_MODE_STEREO: |
886 | case V4L2_TUNER_MODE_LANG1_LANG2: | 929 | case V4L2_TUNER_MODE_LANG1_LANG2: |
887 | set_audio_standard_A2(core, | 930 | ctl = EN_A2_FORCE_STEREO; |
888 | EN_A2_FORCE_STEREO); | ||
889 | break; | 931 | break; |
890 | } | 932 | } |
891 | } | 933 | } |
@@ -932,24 +974,39 @@ int cx88_audio_thread(void *data) | |||
932 | break; | 974 | break; |
933 | try_to_freeze(); | 975 | try_to_freeze(); |
934 | 976 | ||
935 | /* just monitor the audio status for now ... */ | 977 | switch (core->tvaudio) { |
936 | memset(&t, 0, sizeof(t)); | 978 | case WW_BG: |
937 | cx88_get_stereo(core, &t); | 979 | case WW_DK: |
938 | 980 | case WW_M: | |
939 | if (UNSET != core->audiomode_manual) | 981 | case WW_I: |
940 | /* manually set, don't do anything. */ | 982 | case WW_L: |
941 | continue; | 983 | if (core->use_nicam) |
942 | 984 | goto hw_autodetect; | |
943 | /* monitor signal */ | 985 | |
944 | if (t.rxsubchans & V4L2_TUNER_SUB_STEREO) | 986 | /* just monitor the audio status for now ... */ |
945 | mode = V4L2_TUNER_MODE_STEREO; | 987 | memset(&t, 0, sizeof(t)); |
946 | else | 988 | cx88_get_stereo(core, &t); |
947 | mode = V4L2_TUNER_MODE_MONO; | 989 | |
948 | if (mode == core->audiomode_current) | 990 | if (UNSET != core->audiomode_manual) |
949 | continue; | 991 | /* manually set, don't do anything. */ |
950 | 992 | continue; | |
951 | /* automatically switch to best available mode */ | 993 | |
952 | cx88_set_stereo(core, mode, 0); | 994 | /* monitor signal and set stereo if available */ |
995 | if (t.rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
996 | mode = V4L2_TUNER_MODE_STEREO; | ||
997 | else | ||
998 | mode = V4L2_TUNER_MODE_MONO; | ||
999 | if (mode == core->audiomode_current) | ||
1000 | continue; | ||
1001 | /* automatically switch to best available mode */ | ||
1002 | cx88_set_stereo(core, mode, 0); | ||
1003 | break; | ||
1004 | default: | ||
1005 | hw_autodetect: | ||
1006 | /* stereo autodetection is supported by hardware so | ||
1007 | we don't need to do it manually. Do nothing. */ | ||
1008 | break; | ||
1009 | } | ||
953 | } | 1010 | } |
954 | 1011 | ||
955 | dprintk("cx88: tvaudio thread exiting\n"); | 1012 | dprintk("cx88: tvaudio thread exiting\n"); |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index b993d42fe73c..0ccac702bea4 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -869,6 +869,7 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
869 | { | 869 | { |
870 | struct cx8800_fh *fh = file->private_data; | 870 | struct cx8800_fh *fh = file->private_data; |
871 | struct cx88_buffer *buf; | 871 | struct cx88_buffer *buf; |
872 | unsigned int rc = POLLERR; | ||
872 | 873 | ||
873 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { | 874 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { |
874 | if (!res_get(fh->dev,fh,RESOURCE_VBI)) | 875 | if (!res_get(fh->dev,fh,RESOURCE_VBI)) |
@@ -876,22 +877,27 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
876 | return videobuf_poll_stream(file, &fh->vbiq, wait); | 877 | return videobuf_poll_stream(file, &fh->vbiq, wait); |
877 | } | 878 | } |
878 | 879 | ||
880 | mutex_lock(&fh->vidq.vb_lock); | ||
879 | if (res_check(fh,RESOURCE_VIDEO)) { | 881 | if (res_check(fh,RESOURCE_VIDEO)) { |
880 | /* streaming capture */ | 882 | /* streaming capture */ |
881 | if (list_empty(&fh->vidq.stream)) | 883 | if (list_empty(&fh->vidq.stream)) |
882 | return POLLERR; | 884 | goto done; |
883 | buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream); | 885 | buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream); |
884 | } else { | 886 | } else { |
885 | /* read() capture */ | 887 | /* read() capture */ |
886 | buf = (struct cx88_buffer*)fh->vidq.read_buf; | 888 | buf = (struct cx88_buffer*)fh->vidq.read_buf; |
887 | if (NULL == buf) | 889 | if (NULL == buf) |
888 | return POLLERR; | 890 | goto done; |
889 | } | 891 | } |
890 | poll_wait(file, &buf->vb.done, wait); | 892 | poll_wait(file, &buf->vb.done, wait); |
891 | if (buf->vb.state == VIDEOBUF_DONE || | 893 | if (buf->vb.state == VIDEOBUF_DONE || |
892 | buf->vb.state == VIDEOBUF_ERROR) | 894 | buf->vb.state == VIDEOBUF_ERROR) |
893 | return POLLIN|POLLRDNORM; | 895 | rc = POLLIN|POLLRDNORM; |
894 | return 0; | 896 | else |
897 | rc = 0; | ||
898 | done: | ||
899 | mutex_unlock(&fh->vidq.vb_lock); | ||
900 | return rc; | ||
895 | } | 901 | } |
896 | 902 | ||
897 | static int video_release(struct file *file) | 903 | static int video_release(struct file *file) |
@@ -926,8 +932,10 @@ static int video_release(struct file *file) | |||
926 | file->private_data = NULL; | 932 | file->private_data = NULL; |
927 | kfree(fh); | 933 | kfree(fh); |
928 | 934 | ||
935 | mutex_lock(&dev->core->lock); | ||
929 | if(atomic_dec_and_test(&dev->core->users)) | 936 | if(atomic_dec_and_test(&dev->core->users)) |
930 | call_all(dev->core, tuner, s_standby); | 937 | call_all(dev->core, tuner, s_standby); |
938 | mutex_unlock(&dev->core->lock); | ||
931 | 939 | ||
932 | return 0; | 940 | return 0; |
933 | } | 941 | } |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 7724d168fc04..9d83762163f5 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -65,6 +65,8 @@ | |||
65 | #define VBI_LINE_COUNT 17 | 65 | #define VBI_LINE_COUNT 17 |
66 | #define VBI_LINE_LENGTH 2048 | 66 | #define VBI_LINE_LENGTH 2048 |
67 | 67 | ||
68 | #define AUD_RDS_LINES 4 | ||
69 | |||
68 | /* need "shadow" registers for some write-only ones ... */ | 70 | /* need "shadow" registers for some write-only ones ... */ |
69 | #define SHADOW_AUD_VOL_CTL 1 | 71 | #define SHADOW_AUD_VOL_CTL 1 |
70 | #define SHADOW_AUD_BAL_CTL 2 | 72 | #define SHADOW_AUD_BAL_CTL 2 |
@@ -132,6 +134,7 @@ struct cx88_ctrl { | |||
132 | #define SRAM_CH25 4 /* audio */ | 134 | #define SRAM_CH25 4 /* audio */ |
133 | #define SRAM_CH26 5 | 135 | #define SRAM_CH26 5 |
134 | #define SRAM_CH28 6 /* mpeg */ | 136 | #define SRAM_CH28 6 /* mpeg */ |
137 | #define SRAM_CH27 7 /* audio rds */ | ||
135 | /* more */ | 138 | /* more */ |
136 | 139 | ||
137 | struct sram_channel { | 140 | struct sram_channel { |
@@ -232,6 +235,8 @@ extern struct sram_channel cx88_sram_channels[]; | |||
232 | #define CX88_BOARD_TBS_8910 77 | 235 | #define CX88_BOARD_TBS_8910 77 |
233 | #define CX88_BOARD_PROF_6200 78 | 236 | #define CX88_BOARD_PROF_6200 78 |
234 | #define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79 | 237 | #define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79 |
238 | #define CX88_BOARD_HAUPPAUGE_IRONLY 80 | ||
239 | #define CX88_BOARD_WINFAST_DTV1800H 81 | ||
235 | 240 | ||
236 | enum cx88_itype { | 241 | enum cx88_itype { |
237 | CX88_VMUX_COMPOSITE1 = 1, | 242 | CX88_VMUX_COMPOSITE1 = 1, |
@@ -350,6 +355,7 @@ struct cx88_core { | |||
350 | u32 input; | 355 | u32 input; |
351 | u32 astat; | 356 | u32 astat; |
352 | u32 use_nicam; | 357 | u32 use_nicam; |
358 | unsigned long last_change; | ||
353 | 359 | ||
354 | /* IR remote control state */ | 360 | /* IR remote control state */ |
355 | struct cx88_IR *ir; | 361 | struct cx88_IR *ir; |
@@ -652,6 +658,7 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl); | |||
652 | #define WW_I2SPT 8 | 658 | #define WW_I2SPT 8 |
653 | #define WW_FM 9 | 659 | #define WW_FM 9 |
654 | #define WW_I2SADC 10 | 660 | #define WW_I2SADC 10 |
661 | #define WW_M 11 | ||
655 | 662 | ||
656 | void cx88_set_tvaudio(struct cx88_core *core); | 663 | void cx88_set_tvaudio(struct cx88_core *core); |
657 | void cx88_newstation(struct cx88_core *core); | 664 | void cx88_newstation(struct cx88_core *core); |
@@ -665,6 +672,11 @@ struct cx8802_dev *cx8802_get_device(int minor); | |||
665 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); | 672 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); |
666 | 673 | ||
667 | /* ----------------------------------------------------------- */ | 674 | /* ----------------------------------------------------------- */ |
675 | /* cx88-dsp.c */ | ||
676 | |||
677 | s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core); | ||
678 | |||
679 | /* ----------------------------------------------------------- */ | ||
668 | /* cx88-input.c */ | 680 | /* cx88-input.c */ |
669 | 681 | ||
670 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci); | 682 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci); |
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 0131322475bf..7bd8a70f0a0b 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
@@ -339,6 +339,11 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) | |||
339 | mutex_lock(&dev->lock); | 339 | mutex_lock(&dev->lock); |
340 | dev->adev.users--; | 340 | dev->adev.users--; |
341 | em28xx_audio_analog_set(dev); | 341 | em28xx_audio_analog_set(dev); |
342 | if (substream->runtime->dma_area) { | ||
343 | dprintk("freeing\n"); | ||
344 | vfree(substream->runtime->dma_area); | ||
345 | substream->runtime->dma_area = NULL; | ||
346 | } | ||
342 | mutex_unlock(&dev->lock); | 347 | mutex_unlock(&dev->lock); |
343 | 348 | ||
344 | return 0; | 349 | return 0; |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 7c70738479dd..00cc791a9e44 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -49,6 +49,11 @@ static unsigned int disable_ir; | |||
49 | module_param(disable_ir, int, 0444); | 49 | module_param(disable_ir, int, 0444); |
50 | MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); | 50 | MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); |
51 | 51 | ||
52 | static unsigned int disable_usb_speed_check; | ||
53 | module_param(disable_usb_speed_check, int, 0444); | ||
54 | MODULE_PARM_DESC(disable_usb_speed_check, | ||
55 | "override min bandwidth requirement of 480M bps"); | ||
56 | |||
52 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 57 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
53 | module_param_array(card, int, NULL, 0444); | 58 | module_param_array(card, int, NULL, 0444); |
54 | MODULE_PARM_DESC(card, "card type"); | 59 | MODULE_PARM_DESC(card, "card type"); |
@@ -104,6 +109,24 @@ static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { | |||
104 | /* Board - EM2870 Kworld 355u | 109 | /* Board - EM2870 Kworld 355u |
105 | Analog - No input analog */ | 110 | Analog - No input analog */ |
106 | 111 | ||
112 | /* Board - EM2882 Kworld 315U digital */ | ||
113 | static struct em28xx_reg_seq em2882_kworld_315u_digital[] = { | ||
114 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
115 | {EM28XX_R08_GPIO, 0xfe, 0xff, 10}, | ||
116 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | ||
117 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
118 | {EM28XX_R08_GPIO, 0x7e, 0xff, 10}, | ||
119 | { -1, -1, -1, -1}, | ||
120 | }; | ||
121 | |||
122 | static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { | ||
123 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
124 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
125 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
126 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
127 | { -1, -1, -1, -1}, | ||
128 | }; | ||
129 | |||
107 | static struct em28xx_reg_seq kworld_330u_analog[] = { | 130 | static struct em28xx_reg_seq kworld_330u_analog[] = { |
108 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | 131 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, |
109 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | 132 | {EM2880_R04_GPO, 0x00, 0xff, 10}, |
@@ -140,6 +163,16 @@ static struct em28xx_reg_seq compro_mute_gpio[] = { | |||
140 | { -1, -1, -1, -1}, | 163 | { -1, -1, -1, -1}, |
141 | }; | 164 | }; |
142 | 165 | ||
166 | /* Terratec AV350 */ | ||
167 | static struct em28xx_reg_seq terratec_av350_mute_gpio[] = { | ||
168 | {EM28XX_R08_GPIO, 0xff, 0x7f, 10}, | ||
169 | { -1, -1, -1, -1}, | ||
170 | }; | ||
171 | |||
172 | static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = { | ||
173 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
174 | { -1, -1, -1, -1}, | ||
175 | }; | ||
143 | /* | 176 | /* |
144 | * Board definitions | 177 | * Board definitions |
145 | */ | 178 | */ |
@@ -992,16 +1025,17 @@ struct em28xx_board em28xx_boards[] = { | |||
992 | .amux = EM28XX_AMUX_LINE_IN, | 1025 | .amux = EM28XX_AMUX_LINE_IN, |
993 | } }, | 1026 | } }, |
994 | }, | 1027 | }, |
995 | [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { | 1028 | [EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = { |
996 | .name = "PointNix Intra-Oral Camera", | 1029 | .name = "EM2860/SAA711X Reference Design", |
997 | .has_snapshot_button = 1, | 1030 | .has_snapshot_button = 1, |
998 | .tda9887_conf = TDA9887_PRESENT, | ||
999 | .tuner_type = TUNER_ABSENT, | 1031 | .tuner_type = TUNER_ABSENT, |
1000 | .decoder = EM28XX_SAA711X, | 1032 | .decoder = EM28XX_SAA711X, |
1001 | .input = { { | 1033 | .input = { { |
1002 | .type = EM28XX_VMUX_SVIDEO, | 1034 | .type = EM28XX_VMUX_SVIDEO, |
1003 | .vmux = SAA7115_SVIDEO3, | 1035 | .vmux = SAA7115_SVIDEO3, |
1004 | .amux = EM28XX_AMUX_VIDEO, | 1036 | }, { |
1037 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1038 | .vmux = SAA7115_COMPOSITE0, | ||
1005 | } }, | 1039 | } }, |
1006 | }, | 1040 | }, |
1007 | [EM2880_BOARD_MSI_DIGIVOX_AD] = { | 1041 | [EM2880_BOARD_MSI_DIGIVOX_AD] = { |
@@ -1095,6 +1129,63 @@ struct em28xx_board em28xx_boards[] = { | |||
1095 | .gpio = default_analog, | 1129 | .gpio = default_analog, |
1096 | } }, | 1130 | } }, |
1097 | }, | 1131 | }, |
1132 | [EM2882_BOARD_KWORLD_ATSC_315U] = { | ||
1133 | .name = "KWorld ATSC 315U HDTV TV Box", | ||
1134 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1135 | .tuner_type = TUNER_THOMSON_DTT761X, | ||
1136 | .tuner_gpio = em2882_kworld_315u_tuner_gpio, | ||
1137 | .tda9887_conf = TDA9887_PRESENT, | ||
1138 | .decoder = EM28XX_SAA711X, | ||
1139 | .has_dvb = 1, | ||
1140 | .dvb_gpio = em2882_kworld_315u_digital, | ||
1141 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1142 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, | ||
1143 | /* Analog mode - still not ready */ | ||
1144 | /*.input = { { | ||
1145 | .type = EM28XX_VMUX_TELEVISION, | ||
1146 | .vmux = SAA7115_COMPOSITE2, | ||
1147 | .amux = EM28XX_AMUX_VIDEO, | ||
1148 | .gpio = em2882_kworld_315u_analog, | ||
1149 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1150 | }, { | ||
1151 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1152 | .vmux = SAA7115_COMPOSITE0, | ||
1153 | .amux = EM28XX_AMUX_LINE_IN, | ||
1154 | .gpio = em2882_kworld_315u_analog1, | ||
1155 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1156 | }, { | ||
1157 | .type = EM28XX_VMUX_SVIDEO, | ||
1158 | .vmux = SAA7115_SVIDEO3, | ||
1159 | .amux = EM28XX_AMUX_LINE_IN, | ||
1160 | .gpio = em2882_kworld_315u_analog1, | ||
1161 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1162 | } }, */ | ||
1163 | }, | ||
1164 | [EM2880_BOARD_EMPIRE_DUAL_TV] = { | ||
1165 | .name = "Empire dual TV", | ||
1166 | .tuner_type = TUNER_XC2028, | ||
1167 | .tuner_gpio = default_tuner_gpio, | ||
1168 | .has_dvb = 1, | ||
1169 | .dvb_gpio = default_digital, | ||
1170 | .mts_firmware = 1, | ||
1171 | .decoder = EM28XX_TVP5150, | ||
1172 | .input = { { | ||
1173 | .type = EM28XX_VMUX_TELEVISION, | ||
1174 | .vmux = TVP5150_COMPOSITE0, | ||
1175 | .amux = EM28XX_AMUX_VIDEO, | ||
1176 | .gpio = default_analog, | ||
1177 | }, { | ||
1178 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1179 | .vmux = TVP5150_COMPOSITE1, | ||
1180 | .amux = EM28XX_AMUX_LINE_IN, | ||
1181 | .gpio = default_analog, | ||
1182 | }, { | ||
1183 | .type = EM28XX_VMUX_SVIDEO, | ||
1184 | .vmux = TVP5150_SVIDEO, | ||
1185 | .amux = EM28XX_AMUX_LINE_IN, | ||
1186 | .gpio = default_analog, | ||
1187 | } }, | ||
1188 | }, | ||
1098 | [EM2881_BOARD_DNT_DA2_HYBRID] = { | 1189 | [EM2881_BOARD_DNT_DA2_HYBRID] = { |
1099 | .name = "DNT DA2 Hybrid", | 1190 | .name = "DNT DA2 Hybrid", |
1100 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1191 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
@@ -1322,6 +1413,42 @@ struct em28xx_board em28xx_boards[] = { | |||
1322 | .amux = EM28XX_AMUX_VIDEO, | 1413 | .amux = EM28XX_AMUX_VIDEO, |
1323 | } }, | 1414 | } }, |
1324 | }, | 1415 | }, |
1416 | [EM2860_BOARD_TERRATEC_GRABBY] = { | ||
1417 | .name = "Terratec Grabby", | ||
1418 | .vchannels = 2, | ||
1419 | .tuner_type = TUNER_ABSENT, | ||
1420 | .decoder = EM28XX_SAA711X, | ||
1421 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1422 | .input = { { | ||
1423 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1424 | .vmux = SAA7115_COMPOSITE0, | ||
1425 | .amux = EM28XX_AMUX_VIDEO2, | ||
1426 | }, { | ||
1427 | .type = EM28XX_VMUX_SVIDEO, | ||
1428 | .vmux = SAA7115_SVIDEO3, | ||
1429 | .amux = EM28XX_AMUX_VIDEO2, | ||
1430 | } }, | ||
1431 | }, | ||
1432 | [EM2860_BOARD_TERRATEC_AV350] = { | ||
1433 | .name = "Terratec AV350", | ||
1434 | .vchannels = 2, | ||
1435 | .tuner_type = TUNER_ABSENT, | ||
1436 | .decoder = EM28XX_TVP5150, | ||
1437 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1438 | .mute_gpio = terratec_av350_mute_gpio, | ||
1439 | .input = { { | ||
1440 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1441 | .vmux = TVP5150_COMPOSITE1, | ||
1442 | .amux = EM28XX_AUDIO_SRC_LINE, | ||
1443 | .gpio = terratec_av350_unmute_gpio, | ||
1444 | |||
1445 | }, { | ||
1446 | .type = EM28XX_VMUX_SVIDEO, | ||
1447 | .vmux = TVP5150_SVIDEO, | ||
1448 | .amux = EM28XX_AUDIO_SRC_LINE, | ||
1449 | .gpio = terratec_av350_unmute_gpio, | ||
1450 | } }, | ||
1451 | }, | ||
1325 | }; | 1452 | }; |
1326 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); | 1453 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); |
1327 | 1454 | ||
@@ -1355,6 +1482,8 @@ struct usb_device_id em28xx_id_table[] = { | |||
1355 | .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, | 1482 | .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, |
1356 | { USB_DEVICE(0xeb1a, 0xe310), | 1483 | { USB_DEVICE(0xeb1a, 0xe310), |
1357 | .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, | 1484 | .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, |
1485 | { USB_DEVICE(0xeb1a, 0xa313), | ||
1486 | .driver_info = EM2882_BOARD_KWORLD_ATSC_315U }, | ||
1358 | { USB_DEVICE(0xeb1a, 0xa316), | 1487 | { USB_DEVICE(0xeb1a, 0xa316), |
1359 | .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U }, | 1488 | .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U }, |
1360 | { USB_DEVICE(0xeb1a, 0xe320), | 1489 | { USB_DEVICE(0xeb1a, 0xe320), |
@@ -1385,6 +1514,10 @@ struct usb_device_id em28xx_id_table[] = { | |||
1385 | .driver_info = EM2870_BOARD_TERRATEC_XS }, | 1514 | .driver_info = EM2870_BOARD_TERRATEC_XS }, |
1386 | { USB_DEVICE(0x0ccd, 0x0047), | 1515 | { USB_DEVICE(0x0ccd, 0x0047), |
1387 | .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, | 1516 | .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, |
1517 | { USB_DEVICE(0x0ccd, 0x0084), | ||
1518 | .driver_info = EM2860_BOARD_TERRATEC_AV350 }, | ||
1519 | { USB_DEVICE(0x0ccd, 0x0096), | ||
1520 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, | ||
1388 | { USB_DEVICE(0x185b, 0x2870), | 1521 | { USB_DEVICE(0x185b, 0x2870), |
1389 | .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, | 1522 | .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, |
1390 | { USB_DEVICE(0x185b, 0x2041), | 1523 | { USB_DEVICE(0x185b, 0x2041), |
@@ -1437,13 +1570,14 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = { | |||
1437 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, | 1570 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, |
1438 | {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, | 1571 | {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, |
1439 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, | 1572 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, |
1573 | {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, | ||
1440 | }; | 1574 | }; |
1441 | 1575 | ||
1442 | /* I2C devicelist hash table for devices with generic USB IDs */ | 1576 | /* I2C devicelist hash table for devices with generic USB IDs */ |
1443 | static struct em28xx_hash_table em28xx_i2c_hash[] = { | 1577 | static struct em28xx_hash_table em28xx_i2c_hash[] = { |
1444 | {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, | 1578 | {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, |
1445 | {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, | 1579 | {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, |
1446 | {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT}, | 1580 | {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT}, |
1447 | {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, | 1581 | {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, |
1448 | }; | 1582 | }; |
1449 | 1583 | ||
@@ -1619,6 +1753,17 @@ void em28xx_pre_card_setup(struct em28xx *dev) | |||
1619 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | 1753 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); |
1620 | break; | 1754 | break; |
1621 | 1755 | ||
1756 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
1757 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); | ||
1758 | msleep(10); | ||
1759 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
1760 | msleep(10); | ||
1761 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); | ||
1762 | msleep(10); | ||
1763 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x08); | ||
1764 | msleep(10); | ||
1765 | break; | ||
1766 | |||
1622 | case EM2860_BOARD_KAIOMY_TVNPC_U2: | 1767 | case EM2860_BOARD_KAIOMY_TVNPC_U2: |
1623 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); | 1768 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); |
1624 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | 1769 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); |
@@ -1664,6 +1809,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | |||
1664 | ctl->mts = em28xx_boards[dev->model].mts_firmware; | 1809 | ctl->mts = em28xx_boards[dev->model].mts_firmware; |
1665 | 1810 | ||
1666 | switch (dev->model) { | 1811 | switch (dev->model) { |
1812 | case EM2880_BOARD_EMPIRE_DUAL_TV: | ||
1667 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | 1813 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: |
1668 | ctl->demod = XC3028_FE_ZARLINK456; | 1814 | ctl->demod = XC3028_FE_ZARLINK456; |
1669 | break; | 1815 | break; |
@@ -1835,12 +1981,20 @@ static int em28xx_hint_board(struct em28xx *dev) | |||
1835 | } | 1981 | } |
1836 | 1982 | ||
1837 | /* ----------------------------------------------------------------------- */ | 1983 | /* ----------------------------------------------------------------------- */ |
1838 | void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) | 1984 | void em28xx_register_i2c_ir(struct em28xx *dev) |
1839 | { | 1985 | { |
1840 | if (disable_ir) { | 1986 | struct i2c_board_info info; |
1841 | ir->get_key = NULL; | 1987 | struct IR_i2c_init_data init_data; |
1842 | return ; | 1988 | const unsigned short addr_list[] = { |
1843 | } | 1989 | 0x30, 0x47, I2C_CLIENT_END |
1990 | }; | ||
1991 | |||
1992 | if (disable_ir) | ||
1993 | return; | ||
1994 | |||
1995 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1996 | memset(&init_data, 0, sizeof(struct IR_i2c_init_data)); | ||
1997 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
1844 | 1998 | ||
1845 | /* detect & configure */ | 1999 | /* detect & configure */ |
1846 | switch (dev->model) { | 2000 | switch (dev->model) { |
@@ -1850,22 +2004,19 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) | |||
1850 | break; | 2004 | break; |
1851 | case (EM2800_BOARD_TERRATEC_CINERGY_200): | 2005 | case (EM2800_BOARD_TERRATEC_CINERGY_200): |
1852 | case (EM2820_BOARD_TERRATEC_CINERGY_250): | 2006 | case (EM2820_BOARD_TERRATEC_CINERGY_250): |
1853 | ir->ir_codes = ir_codes_em_terratec; | 2007 | init_data.ir_codes = ir_codes_em_terratec; |
1854 | ir->get_key = em28xx_get_key_terratec; | 2008 | init_data.get_key = em28xx_get_key_terratec; |
1855 | snprintf(ir->c.name, sizeof(ir->c.name), | 2009 | init_data.name = "i2c IR (EM28XX Terratec)"; |
1856 | "i2c IR (EM28XX Terratec)"); | ||
1857 | break; | 2010 | break; |
1858 | case (EM2820_BOARD_PINNACLE_USB_2): | 2011 | case (EM2820_BOARD_PINNACLE_USB_2): |
1859 | ir->ir_codes = ir_codes_pinnacle_grey; | 2012 | init_data.ir_codes = ir_codes_pinnacle_grey; |
1860 | ir->get_key = em28xx_get_key_pinnacle_usb_grey; | 2013 | init_data.get_key = em28xx_get_key_pinnacle_usb_grey; |
1861 | snprintf(ir->c.name, sizeof(ir->c.name), | 2014 | init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; |
1862 | "i2c IR (EM28XX Pinnacle PCTV)"); | ||
1863 | break; | 2015 | break; |
1864 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): | 2016 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): |
1865 | ir->ir_codes = ir_codes_hauppauge_new; | 2017 | init_data.ir_codes = ir_codes_hauppauge_new; |
1866 | ir->get_key = em28xx_get_key_em_haup; | 2018 | init_data.get_key = em28xx_get_key_em_haup; |
1867 | snprintf(ir->c.name, sizeof(ir->c.name), | 2019 | init_data.name = "i2c IR (EM2840 Hauppauge)"; |
1868 | "i2c IR (EM2840 Hauppauge)"); | ||
1869 | break; | 2020 | break; |
1870 | case (EM2820_BOARD_MSI_VOX_USB_2): | 2021 | case (EM2820_BOARD_MSI_VOX_USB_2): |
1871 | break; | 2022 | break; |
@@ -1876,6 +2027,10 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) | |||
1876 | case (EM2800_BOARD_GRABBEEX_USB2800): | 2027 | case (EM2800_BOARD_GRABBEEX_USB2800): |
1877 | break; | 2028 | break; |
1878 | } | 2029 | } |
2030 | |||
2031 | if (init_data.name) | ||
2032 | info.platform_data = &init_data; | ||
2033 | i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); | ||
1879 | } | 2034 | } |
1880 | 2035 | ||
1881 | void em28xx_card_setup(struct em28xx *dev) | 2036 | void em28xx_card_setup(struct em28xx *dev) |
@@ -1886,6 +2041,9 @@ void em28xx_card_setup(struct em28xx *dev) | |||
1886 | if (em28xx_boards[dev->model].tuner_addr) | 2041 | if (em28xx_boards[dev->model].tuner_addr) |
1887 | dev->tuner_addr = em28xx_boards[dev->model].tuner_addr; | 2042 | dev->tuner_addr = em28xx_boards[dev->model].tuner_addr; |
1888 | 2043 | ||
2044 | if (em28xx_boards[dev->model].tda9887_conf) | ||
2045 | dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; | ||
2046 | |||
1889 | /* request some modules */ | 2047 | /* request some modules */ |
1890 | switch (dev->model) { | 2048 | switch (dev->model) { |
1891 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: | 2049 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: |
@@ -1915,6 +2073,12 @@ void em28xx_card_setup(struct em28xx *dev) | |||
1915 | #endif | 2073 | #endif |
1916 | break; | 2074 | break; |
1917 | } | 2075 | } |
2076 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
2077 | em28xx_write_reg(dev, 0x0d, 0x42); | ||
2078 | msleep(10); | ||
2079 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | ||
2080 | msleep(10); | ||
2081 | break; | ||
1918 | case EM2820_BOARD_KWORLD_PVRTV2800RF: | 2082 | case EM2820_BOARD_KWORLD_PVRTV2800RF: |
1919 | /* GPIO enables sound on KWORLD PVR TV 2800RF */ | 2083 | /* GPIO enables sound on KWORLD PVR TV 2800RF */ |
1920 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9); | 2084 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9); |
@@ -2279,6 +2443,20 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
2279 | ifnum, | 2443 | ifnum, |
2280 | interface->altsetting->desc.bInterfaceNumber); | 2444 | interface->altsetting->desc.bInterfaceNumber); |
2281 | 2445 | ||
2446 | /* | ||
2447 | * Make sure we have 480 Mbps of bandwidth, otherwise things like | ||
2448 | * video stream wouldn't likely work, since 12 Mbps is generally | ||
2449 | * not enough even for most Digital TV streams. | ||
2450 | */ | ||
2451 | if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { | ||
2452 | printk(DRIVER_NAME ": Device initialization failed.\n"); | ||
2453 | printk(DRIVER_NAME ": Device must be connected to a high-speed" | ||
2454 | " USB 2.0 port.\n"); | ||
2455 | em28xx_devused &= ~(1<<nr); | ||
2456 | retval = -ENODEV; | ||
2457 | goto err; | ||
2458 | } | ||
2459 | |||
2282 | if (nr >= EM28XX_MAXBOARDS) { | 2460 | if (nr >= EM28XX_MAXBOARDS) { |
2283 | printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", | 2461 | printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", |
2284 | EM28XX_MAXBOARDS); | 2462 | EM28XX_MAXBOARDS); |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 192b76cdd5d7..c8d7ce8fbd36 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -500,18 +500,21 @@ int em28xx_audio_setup(struct em28xx *dev) | |||
500 | 500 | ||
501 | /* See how this device is configured */ | 501 | /* See how this device is configured */ |
502 | cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); | 502 | cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); |
503 | if (cfg < 0) | 503 | em28xx_info("Config register raw data: 0x%02x\n", cfg); |
504 | if (cfg < 0) { | ||
505 | /* Register read error? */ | ||
504 | cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */ | 506 | cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */ |
505 | else | 507 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 0x00) { |
506 | em28xx_info("Config register raw data: 0x%02x\n", cfg); | 508 | /* The device doesn't have vendor audio at all */ |
507 | 509 | dev->has_alsa_audio = 0; | |
508 | if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == | 510 | dev->audio_mode.has_audio = 0; |
509 | EM28XX_CHIPCFG_I2S_3_SAMPRATES) { | 511 | return 0; |
512 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == | ||
513 | EM28XX_CHIPCFG_I2S_3_SAMPRATES) { | ||
510 | em28xx_info("I2S Audio (3 sample rates)\n"); | 514 | em28xx_info("I2S Audio (3 sample rates)\n"); |
511 | dev->audio_mode.i2s_3rates = 1; | 515 | dev->audio_mode.i2s_3rates = 1; |
512 | } | 516 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == |
513 | if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == | 517 | EM28XX_CHIPCFG_I2S_5_SAMPRATES) { |
514 | EM28XX_CHIPCFG_I2S_5_SAMPRATES) { | ||
515 | em28xx_info("I2S Audio (5 sample rates)\n"); | 518 | em28xx_info("I2S Audio (5 sample rates)\n"); |
516 | dev->audio_mode.i2s_5rates = 1; | 519 | dev->audio_mode.i2s_5rates = 1; |
517 | } | 520 | } |
@@ -938,7 +941,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
938 | dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, | 941 | dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, |
939 | GFP_KERNEL); | 942 | GFP_KERNEL); |
940 | if (!dev->isoc_ctl.transfer_buffer) { | 943 | if (!dev->isoc_ctl.transfer_buffer) { |
941 | em28xx_errdev("cannot allocate memory for usbtransfer\n"); | 944 | em28xx_errdev("cannot allocate memory for usb transfer\n"); |
942 | kfree(dev->isoc_ctl.urb); | 945 | kfree(dev->isoc_ctl.urb); |
943 | return -ENOMEM; | 946 | return -ENOMEM; |
944 | } | 947 | } |
@@ -1012,6 +1015,41 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
1012 | } | 1015 | } |
1013 | EXPORT_SYMBOL_GPL(em28xx_init_isoc); | 1016 | EXPORT_SYMBOL_GPL(em28xx_init_isoc); |
1014 | 1017 | ||
1018 | /* Determine the packet size for the DVB stream for the given device | ||
1019 | (underlying value programmed into the eeprom) */ | ||
1020 | int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev) | ||
1021 | { | ||
1022 | unsigned int chip_cfg2; | ||
1023 | unsigned int packet_size = 564; | ||
1024 | |||
1025 | if (dev->chip_id == CHIP_ID_EM2874) { | ||
1026 | /* FIXME - for now assume 564 like it was before, but the | ||
1027 | em2874 code should be added to return the proper value... */ | ||
1028 | packet_size = 564; | ||
1029 | } else { | ||
1030 | /* TS max packet size stored in bits 1-0 of R01 */ | ||
1031 | chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2); | ||
1032 | switch (chip_cfg2 & EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK) { | ||
1033 | case EM28XX_CHIPCFG2_TS_PACKETSIZE_188: | ||
1034 | packet_size = 188; | ||
1035 | break; | ||
1036 | case EM28XX_CHIPCFG2_TS_PACKETSIZE_376: | ||
1037 | packet_size = 376; | ||
1038 | break; | ||
1039 | case EM28XX_CHIPCFG2_TS_PACKETSIZE_564: | ||
1040 | packet_size = 564; | ||
1041 | break; | ||
1042 | case EM28XX_CHIPCFG2_TS_PACKETSIZE_752: | ||
1043 | packet_size = 752; | ||
1044 | break; | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1048 | em28xx_coredbg("dvb max packet size=%d\n", packet_size); | ||
1049 | return packet_size; | ||
1050 | } | ||
1051 | EXPORT_SYMBOL_GPL(em28xx_isoc_dvb_max_packetsize); | ||
1052 | |||
1015 | /* | 1053 | /* |
1016 | * em28xx_wake_i2c() | 1054 | * em28xx_wake_i2c() |
1017 | * configure i2c attached devices | 1055 | * configure i2c attached devices |
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index fcd25511209b..563dd2b1c8e9 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include "em28xx.h" | 25 | #include "em28xx.h" |
26 | #include <media/v4l2-common.h> | 26 | #include <media/v4l2-common.h> |
27 | #include <media/videobuf-vmalloc.h> | 27 | #include <media/videobuf-vmalloc.h> |
28 | #include <media/tuner.h> | ||
29 | #include "tuner-simple.h" | ||
28 | 30 | ||
29 | #include "lgdt330x.h" | 31 | #include "lgdt330x.h" |
30 | #include "zl10353.h" | 32 | #include "zl10353.h" |
@@ -46,7 +48,6 @@ if (debug >= level) \ | |||
46 | } while (0) | 48 | } while (0) |
47 | 49 | ||
48 | #define EM28XX_DVB_NUM_BUFS 5 | 50 | #define EM28XX_DVB_NUM_BUFS 5 |
49 | #define EM28XX_DVB_MAX_PACKETSIZE 564 | ||
50 | #define EM28XX_DVB_MAX_PACKETS 64 | 51 | #define EM28XX_DVB_MAX_PACKETS 64 |
51 | 52 | ||
52 | struct em28xx_dvb { | 53 | struct em28xx_dvb { |
@@ -142,14 +143,17 @@ static int start_streaming(struct em28xx_dvb *dvb) | |||
142 | { | 143 | { |
143 | int rc; | 144 | int rc; |
144 | struct em28xx *dev = dvb->adapter.priv; | 145 | struct em28xx *dev = dvb->adapter.priv; |
146 | int max_dvb_packet_size; | ||
145 | 147 | ||
146 | usb_set_interface(dev->udev, 0, 1); | 148 | usb_set_interface(dev->udev, 0, 1); |
147 | rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | 149 | rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); |
148 | if (rc < 0) | 150 | if (rc < 0) |
149 | return rc; | 151 | return rc; |
150 | 152 | ||
153 | max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev); | ||
154 | |||
151 | return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, | 155 | return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, |
152 | EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE, | 156 | EM28XX_DVB_NUM_BUFS, max_dvb_packet_size, |
153 | dvb_isoc_copy); | 157 | dvb_isoc_copy); |
154 | } | 158 | } |
155 | 159 | ||
@@ -431,6 +435,7 @@ static int dvb_init(struct em28xx *dev) | |||
431 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | 435 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: |
432 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | 436 | case EM2880_BOARD_TERRATEC_HYBRID_XS: |
433 | case EM2880_BOARD_KWORLD_DVB_310U: | 437 | case EM2880_BOARD_KWORLD_DVB_310U: |
438 | case EM2880_BOARD_EMPIRE_DUAL_TV: | ||
434 | dvb->frontend = dvb_attach(zl10353_attach, | 439 | dvb->frontend = dvb_attach(zl10353_attach, |
435 | &em28xx_zl10353_with_xc3028, | 440 | &em28xx_zl10353_with_xc3028, |
436 | &dev->i2c_adap); | 441 | &dev->i2c_adap); |
@@ -448,6 +453,18 @@ static int dvb_init(struct em28xx *dev) | |||
448 | goto out_free; | 453 | goto out_free; |
449 | } | 454 | } |
450 | break; | 455 | break; |
456 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
457 | dvb->frontend = dvb_attach(lgdt330x_attach, | ||
458 | &em2880_lgdt3303_dev, | ||
459 | &dev->i2c_adap); | ||
460 | if (dvb->frontend != NULL) { | ||
461 | if (!dvb_attach(simple_tuner_attach, dvb->frontend, | ||
462 | &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) { | ||
463 | result = -EINVAL; | ||
464 | goto out_free; | ||
465 | } | ||
466 | } | ||
467 | break; | ||
451 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | 468 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: |
452 | #ifdef EM28XX_DRX397XD_SUPPORT | 469 | #ifdef EM28XX_DRX397XD_SUPPORT |
453 | /* We don't have the config structure properly populated, so | 470 | /* We don't have the config structure properly populated, so |
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index f0bf1d960c75..2c86fcf089f5 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -451,27 +451,6 @@ static u32 functionality(struct i2c_adapter *adap) | |||
451 | return I2C_FUNC_SMBUS_EMUL; | 451 | return I2C_FUNC_SMBUS_EMUL; |
452 | } | 452 | } |
453 | 453 | ||
454 | /* | ||
455 | * attach_inform() | ||
456 | * gets called when a device attaches to the i2c bus | ||
457 | * does some basic configuration | ||
458 | */ | ||
459 | static int attach_inform(struct i2c_client *client) | ||
460 | { | ||
461 | struct em28xx *dev = client->adapter->algo_data; | ||
462 | struct IR_i2c *ir = i2c_get_clientdata(client); | ||
463 | |||
464 | switch (client->addr << 1) { | ||
465 | case 0x60: | ||
466 | case 0x8e: | ||
467 | dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys); | ||
468 | em28xx_set_ir(dev, ir); | ||
469 | break; | ||
470 | } | ||
471 | |||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | static struct i2c_algorithm em28xx_algo = { | 454 | static struct i2c_algorithm em28xx_algo = { |
476 | .master_xfer = em28xx_i2c_xfer, | 455 | .master_xfer = em28xx_i2c_xfer, |
477 | .functionality = functionality, | 456 | .functionality = functionality, |
@@ -482,7 +461,6 @@ static struct i2c_adapter em28xx_adap_template = { | |||
482 | .name = "em28xx", | 461 | .name = "em28xx", |
483 | .id = I2C_HW_B_EM28XX, | 462 | .id = I2C_HW_B_EM28XX, |
484 | .algo = &em28xx_algo, | 463 | .algo = &em28xx_algo, |
485 | .client_register = attach_inform, | ||
486 | }; | 464 | }; |
487 | 465 | ||
488 | static struct i2c_client em28xx_client_template = { | 466 | static struct i2c_client em28xx_client_template = { |
@@ -575,6 +553,9 @@ int em28xx_i2c_register(struct em28xx *dev) | |||
575 | if (i2c_scan) | 553 | if (i2c_scan) |
576 | em28xx_do_i2c_scan(dev); | 554 | em28xx_do_i2c_scan(dev); |
577 | 555 | ||
556 | /* Instantiate the IR receiver device, if present */ | ||
557 | em28xx_register_i2c_ir(dev); | ||
558 | |||
578 | return 0; | 559 | return 0; |
579 | } | 560 | } |
580 | 561 | ||
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index a5abfd7a19f5..7a0fe3816e3d 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | |||
40 | 40 | ||
41 | #define i2cdprintk(fmt, arg...) \ | 41 | #define i2cdprintk(fmt, arg...) \ |
42 | if (ir_debug) { \ | 42 | if (ir_debug) { \ |
43 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ | 43 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ |
44 | } | 44 | } |
45 | 45 | ||
46 | #define dprintk(fmt, arg...) \ | 46 | #define dprintk(fmt, arg...) \ |
@@ -85,7 +85,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
85 | unsigned char b; | 85 | unsigned char b; |
86 | 86 | ||
87 | /* poll IR chip */ | 87 | /* poll IR chip */ |
88 | if (1 != i2c_master_recv(&ir->c, &b, 1)) { | 88 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
89 | i2cdprintk("read error\n"); | 89 | i2cdprintk("read error\n"); |
90 | return -EIO; | 90 | return -EIO; |
91 | } | 91 | } |
@@ -114,7 +114,7 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
114 | unsigned char code; | 114 | unsigned char code; |
115 | 115 | ||
116 | /* poll IR chip */ | 116 | /* poll IR chip */ |
117 | if (2 != i2c_master_recv(&ir->c, buf, 2)) | 117 | if (2 != i2c_master_recv(ir->c, buf, 2)) |
118 | return -EIO; | 118 | return -EIO; |
119 | 119 | ||
120 | /* Does eliminate repeated parity code */ | 120 | /* Does eliminate repeated parity code */ |
@@ -147,7 +147,7 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | |||
147 | 147 | ||
148 | /* poll IR chip */ | 148 | /* poll IR chip */ |
149 | 149 | ||
150 | if (3 != i2c_master_recv(&ir->c, buf, 3)) { | 150 | if (3 != i2c_master_recv(ir->c, buf, 3)) { |
151 | i2cdprintk("read error\n"); | 151 | i2cdprintk("read error\n"); |
152 | return -EIO; | 152 | return -EIO; |
153 | } | 153 | } |
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h index 24e39c56811e..a2676d63cfd0 100644 --- a/drivers/media/video/em28xx/em28xx-reg.h +++ b/drivers/media/video/em28xx/em28xx-reg.h | |||
@@ -27,6 +27,22 @@ | |||
27 | #define EM28XX_CHIPCFG_AC97 0x10 | 27 | #define EM28XX_CHIPCFG_AC97 0x10 |
28 | #define EM28XX_CHIPCFG_AUDIOMASK 0x30 | 28 | #define EM28XX_CHIPCFG_AUDIOMASK 0x30 |
29 | 29 | ||
30 | #define EM28XX_R01_CHIPCFG2 0x01 | ||
31 | |||
32 | /* em28xx Chip Configuration 2 0x01 */ | ||
33 | #define EM28XX_CHIPCFG2_TS_PRESENT 0x10 | ||
34 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_MASK 0x0c /* bits 3-2 */ | ||
35 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_1MF 0x00 | ||
36 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_2MF 0x04 | ||
37 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_4MF 0x08 | ||
38 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_8MF 0x0c | ||
39 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK 0x03 /* bits 0-1 */ | ||
40 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_188 0x00 | ||
41 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_376 0x01 | ||
42 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_564 0x02 | ||
43 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_752 0x03 | ||
44 | |||
45 | |||
30 | /* GPIO/GPO registers */ | 46 | /* GPIO/GPO registers */ |
31 | #define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ | 47 | #define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ |
32 | #define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ | 48 | #define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 4c4e58004f54..8bf81be1da61 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -58,7 +58,7 @@ | |||
58 | #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16 | 58 | #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16 |
59 | #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 | 59 | #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 |
60 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 | 60 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 |
61 | #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 | 61 | #define EM2860_BOARD_SAA711X_REFERENCE_DESIGN 19 |
62 | #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 | 62 | #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 |
63 | #define EM2800_BOARD_GRABBEEX_USB2800 21 | 63 | #define EM2800_BOARD_GRABBEEX_USB2800 21 |
64 | #define EM2750_BOARD_UNKNOWN 22 | 64 | #define EM2750_BOARD_UNKNOWN 22 |
@@ -102,6 +102,10 @@ | |||
102 | #define EM2860_BOARD_KAIOMY_TVNPC_U2 63 | 102 | #define EM2860_BOARD_KAIOMY_TVNPC_U2 63 |
103 | #define EM2860_BOARD_EASYCAP 64 | 103 | #define EM2860_BOARD_EASYCAP 64 |
104 | #define EM2820_BOARD_IODATA_GVMVP_SZ 65 | 104 | #define EM2820_BOARD_IODATA_GVMVP_SZ 65 |
105 | #define EM2880_BOARD_EMPIRE_DUAL_TV 66 | ||
106 | #define EM2860_BOARD_TERRATEC_GRABBY 67 | ||
107 | #define EM2860_BOARD_TERRATEC_AV350 68 | ||
108 | #define EM2882_BOARD_KWORLD_ATSC_315U 69 | ||
105 | 109 | ||
106 | /* Limits minimum and default number of buffers */ | 110 | /* Limits minimum and default number of buffers */ |
107 | #define EM28XX_MIN_BUF 4 | 111 | #define EM28XX_MIN_BUF 4 |
@@ -615,6 +619,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
615 | int num_bufs, int max_pkt_size, | 619 | int num_bufs, int max_pkt_size, |
616 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); | 620 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); |
617 | void em28xx_uninit_isoc(struct em28xx *dev); | 621 | void em28xx_uninit_isoc(struct em28xx *dev); |
622 | int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev); | ||
618 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); | 623 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); |
619 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); | 624 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); |
620 | void em28xx_wake_i2c(struct em28xx *dev); | 625 | void em28xx_wake_i2c(struct em28xx *dev); |
@@ -639,7 +644,7 @@ extern void em28xx_card_setup(struct em28xx *dev); | |||
639 | extern struct em28xx_board em28xx_boards[]; | 644 | extern struct em28xx_board em28xx_boards[]; |
640 | extern struct usb_device_id em28xx_id_table[]; | 645 | extern struct usb_device_id em28xx_id_table[]; |
641 | extern const unsigned int em28xx_bcount; | 646 | extern const unsigned int em28xx_bcount; |
642 | void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); | 647 | void em28xx_register_i2c_ir(struct em28xx *dev); |
643 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); | 648 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); |
644 | void em28xx_release_resources(struct em28xx *dev); | 649 | void em28xx_release_resources(struct em28xx *dev); |
645 | 650 | ||
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c index 00e6863ed666..480ec5c87d0e 100644 --- a/drivers/media/video/gspca/finepix.c +++ b/drivers/media/video/gspca/finepix.c | |||
@@ -168,6 +168,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
168 | 168 | ||
169 | cam->cam_mode = fpix_mode; | 169 | cam->cam_mode = fpix_mode; |
170 | cam->nmodes = 1; | 170 | cam->nmodes = 1; |
171 | cam->bulk = 1; | ||
171 | cam->bulk_size = FPIX_MAX_TRANSFER; | 172 | cam->bulk_size = FPIX_MAX_TRANSFER; |
172 | 173 | ||
173 | INIT_WORK(&dev->work_struct, dostream); | 174 | INIT_WORK(&dev->work_struct, dostream); |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index a2741d7dccfe..f7e0355ad644 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Main USB camera driver | 2 | * Main USB camera driver |
3 | * | 3 | * |
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | 4 | * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr) |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | |||
47 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | 47 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); |
48 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
49 | 49 | ||
50 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0) | 50 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 6, 0) |
51 | 51 | ||
52 | #ifdef GSPCA_DEBUG | 52 | #ifdef GSPCA_DEBUG |
53 | int gspca_debug = D_ERR | D_PROBE; | 53 | int gspca_debug = D_ERR | D_PROBE; |
@@ -441,7 +441,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) | |||
441 | * look for an input transfer endpoint in an alternate setting | 441 | * look for an input transfer endpoint in an alternate setting |
442 | */ | 442 | */ |
443 | static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, | 443 | static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, |
444 | __u8 xfer) | 444 | int xfer) |
445 | { | 445 | { |
446 | struct usb_host_endpoint *ep; | 446 | struct usb_host_endpoint *ep; |
447 | int i, attr; | 447 | int i, attr; |
@@ -449,7 +449,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, | |||
449 | for (i = 0; i < alt->desc.bNumEndpoints; i++) { | 449 | for (i = 0; i < alt->desc.bNumEndpoints; i++) { |
450 | ep = &alt->endpoint[i]; | 450 | ep = &alt->endpoint[i]; |
451 | attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | 451 | attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; |
452 | if (attr == xfer) | 452 | if (attr == xfer |
453 | && ep->desc.wMaxPacketSize != 0) | ||
453 | return ep; | 454 | return ep; |
454 | } | 455 | } |
455 | return NULL; | 456 | return NULL; |
@@ -467,37 +468,28 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) | |||
467 | { | 468 | { |
468 | struct usb_interface *intf; | 469 | struct usb_interface *intf; |
469 | struct usb_host_endpoint *ep; | 470 | struct usb_host_endpoint *ep; |
470 | int i, ret; | 471 | int xfer, i, ret; |
471 | 472 | ||
472 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); | 473 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); |
473 | ep = NULL; | 474 | ep = NULL; |
475 | xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK | ||
476 | : USB_ENDPOINT_XFER_ISOC; | ||
474 | i = gspca_dev->alt; /* previous alt setting */ | 477 | i = gspca_dev->alt; /* previous alt setting */ |
475 | |||
476 | /* try isoc */ | ||
477 | while (--i >= 0) { | 478 | while (--i >= 0) { |
478 | ep = alt_xfer(&intf->altsetting[i], | 479 | ep = alt_xfer(&intf->altsetting[i], xfer); |
479 | USB_ENDPOINT_XFER_ISOC); | ||
480 | if (ep) | 480 | if (ep) |
481 | break; | 481 | break; |
482 | } | 482 | } |
483 | |||
484 | /* if no isoc, try bulk (alt 0 only) */ | ||
485 | if (ep == NULL) { | 483 | if (ep == NULL) { |
486 | ep = alt_xfer(&intf->altsetting[0], | 484 | err("no transfer endpoint found"); |
487 | USB_ENDPOINT_XFER_BULK); | 485 | return NULL; |
488 | if (ep == NULL) { | ||
489 | err("no transfer endpoint found"); | ||
490 | return NULL; | ||
491 | } | ||
492 | i = 0; | ||
493 | gspca_dev->bulk = 1; | ||
494 | } | 486 | } |
495 | PDEBUG(D_STREAM, "use alt %d ep 0x%02x", | 487 | PDEBUG(D_STREAM, "use alt %d ep 0x%02x", |
496 | i, ep->desc.bEndpointAddress); | 488 | i, ep->desc.bEndpointAddress); |
497 | if (i > 0) { | 489 | if (gspca_dev->nbalt > 1) { |
498 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); | 490 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); |
499 | if (ret < 0) { | 491 | if (ret < 0) { |
500 | err("set interface err %d", ret); | 492 | err("set alt %d err %d", i, ret); |
501 | return NULL; | 493 | return NULL; |
502 | } | 494 | } |
503 | } | 495 | } |
@@ -517,13 +509,13 @@ static int create_urbs(struct gspca_dev *gspca_dev, | |||
517 | /* calculate the packet size and the number of packets */ | 509 | /* calculate the packet size and the number of packets */ |
518 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); | 510 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); |
519 | 511 | ||
520 | if (!gspca_dev->bulk) { /* isoc */ | 512 | if (!gspca_dev->cam.bulk) { /* isoc */ |
521 | 513 | ||
522 | /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ | 514 | /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ |
523 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | 515 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); |
524 | npkt = ISO_MAX_SIZE / psize; | 516 | npkt = gspca_dev->cam.npkt; |
525 | if (npkt > ISO_MAX_PKT) | 517 | if (npkt == 0) |
526 | npkt = ISO_MAX_PKT; | 518 | npkt = 32; /* default value */ |
527 | bsize = psize * npkt; | 519 | bsize = psize * npkt; |
528 | PDEBUG(D_STREAM, | 520 | PDEBUG(D_STREAM, |
529 | "isoc %d pkts size %d = bsize:%d", | 521 | "isoc %d pkts size %d = bsize:%d", |
@@ -617,7 +609,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
617 | goto out; | 609 | goto out; |
618 | 610 | ||
619 | /* clear the bulk endpoint */ | 611 | /* clear the bulk endpoint */ |
620 | if (gspca_dev->bulk) | 612 | if (gspca_dev->cam.bulk) |
621 | usb_clear_halt(gspca_dev->dev, | 613 | usb_clear_halt(gspca_dev->dev, |
622 | gspca_dev->urb[0]->pipe); | 614 | gspca_dev->urb[0]->pipe); |
623 | 615 | ||
@@ -630,7 +622,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
630 | gspca_dev->streaming = 1; | 622 | gspca_dev->streaming = 1; |
631 | 623 | ||
632 | /* some bulk transfers are started by the subdriver */ | 624 | /* some bulk transfers are started by the subdriver */ |
633 | if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0) | 625 | if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0) |
634 | break; | 626 | break; |
635 | 627 | ||
636 | /* submit the URBs */ | 628 | /* submit the URBs */ |
@@ -661,6 +653,8 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) | |||
661 | { | 653 | { |
662 | int ret; | 654 | int ret; |
663 | 655 | ||
656 | if (gspca_dev->alt == 0) | ||
657 | return 0; | ||
664 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); | 658 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); |
665 | if (ret < 0) | 659 | if (ret < 0) |
666 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); | 660 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); |
@@ -869,6 +863,32 @@ out: | |||
869 | return ret; | 863 | return ret; |
870 | } | 864 | } |
871 | 865 | ||
866 | static int vidioc_enum_framesizes(struct file *file, void *priv, | ||
867 | struct v4l2_frmsizeenum *fsize) | ||
868 | { | ||
869 | struct gspca_dev *gspca_dev = priv; | ||
870 | int i; | ||
871 | __u32 index = 0; | ||
872 | |||
873 | for (i = 0; i < gspca_dev->cam.nmodes; i++) { | ||
874 | if (fsize->pixel_format != | ||
875 | gspca_dev->cam.cam_mode[i].pixelformat) | ||
876 | continue; | ||
877 | |||
878 | if (fsize->index == index) { | ||
879 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
880 | fsize->discrete.width = | ||
881 | gspca_dev->cam.cam_mode[i].width; | ||
882 | fsize->discrete.height = | ||
883 | gspca_dev->cam.cam_mode[i].height; | ||
884 | return 0; | ||
885 | } | ||
886 | index++; | ||
887 | } | ||
888 | |||
889 | return -EINVAL; | ||
890 | } | ||
891 | |||
872 | static void gspca_release(struct video_device *vfd) | 892 | static void gspca_release(struct video_device *vfd) |
873 | { | 893 | { |
874 | struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); | 894 | struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); |
@@ -989,43 +1009,54 @@ out: | |||
989 | return ret; | 1009 | return ret; |
990 | } | 1010 | } |
991 | 1011 | ||
1012 | static const struct ctrl *get_ctrl(struct gspca_dev *gspca_dev, | ||
1013 | int id) | ||
1014 | { | ||
1015 | const struct ctrl *ctrls; | ||
1016 | int i; | ||
1017 | |||
1018 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | ||
1019 | i < gspca_dev->sd_desc->nctrls; | ||
1020 | i++, ctrls++) { | ||
1021 | if (gspca_dev->ctrl_dis & (1 << i)) | ||
1022 | continue; | ||
1023 | if (id == ctrls->qctrl.id) | ||
1024 | return ctrls; | ||
1025 | } | ||
1026 | return NULL; | ||
1027 | } | ||
1028 | |||
992 | static int vidioc_queryctrl(struct file *file, void *priv, | 1029 | static int vidioc_queryctrl(struct file *file, void *priv, |
993 | struct v4l2_queryctrl *q_ctrl) | 1030 | struct v4l2_queryctrl *q_ctrl) |
994 | { | 1031 | { |
995 | struct gspca_dev *gspca_dev = priv; | 1032 | struct gspca_dev *gspca_dev = priv; |
996 | int i, ix; | 1033 | const struct ctrl *ctrls; |
1034 | int i; | ||
997 | u32 id; | 1035 | u32 id; |
998 | 1036 | ||
999 | ix = -1; | 1037 | ctrls = NULL; |
1000 | id = q_ctrl->id; | 1038 | id = q_ctrl->id; |
1001 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { | 1039 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { |
1002 | id &= V4L2_CTRL_ID_MASK; | 1040 | id &= V4L2_CTRL_ID_MASK; |
1003 | id++; | 1041 | id++; |
1004 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | 1042 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { |
1005 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id) | 1043 | if (gspca_dev->ctrl_dis & (1 << i)) |
1006 | continue; | 1044 | continue; |
1007 | if (ix < 0) { | 1045 | if (ctrls->qctrl.id < id) |
1008 | ix = i; | ||
1009 | continue; | 1046 | continue; |
1047 | if (ctrls != NULL) { | ||
1048 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id | ||
1049 | > ctrls->qctrl.id) | ||
1050 | continue; | ||
1010 | } | 1051 | } |
1011 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id | 1052 | ctrls = &gspca_dev->sd_desc->ctrls[i]; |
1012 | > gspca_dev->sd_desc->ctrls[ix].qctrl.id) | ||
1013 | continue; | ||
1014 | ix = i; | ||
1015 | } | ||
1016 | } | ||
1017 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | ||
1018 | if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { | ||
1019 | ix = i; | ||
1020 | break; | ||
1021 | } | 1053 | } |
1054 | } else { | ||
1055 | ctrls = get_ctrl(gspca_dev, id); | ||
1022 | } | 1056 | } |
1023 | if (ix < 0) | 1057 | if (ctrls == NULL) |
1024 | return -EINVAL; | 1058 | return -EINVAL; |
1025 | memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl, | 1059 | memcpy(q_ctrl, ctrls, sizeof *q_ctrl); |
1026 | sizeof *q_ctrl); | ||
1027 | if (gspca_dev->ctrl_dis & (1 << ix)) | ||
1028 | q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
1029 | return 0; | 1060 | return 0; |
1030 | } | 1061 | } |
1031 | 1062 | ||
@@ -1034,56 +1065,45 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1034 | { | 1065 | { |
1035 | struct gspca_dev *gspca_dev = priv; | 1066 | struct gspca_dev *gspca_dev = priv; |
1036 | const struct ctrl *ctrls; | 1067 | const struct ctrl *ctrls; |
1037 | int i, ret; | 1068 | int ret; |
1038 | 1069 | ||
1039 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | 1070 | ctrls = get_ctrl(gspca_dev, ctrl->id); |
1040 | i < gspca_dev->sd_desc->nctrls; | 1071 | if (ctrls == NULL) |
1041 | i++, ctrls++) { | 1072 | return -EINVAL; |
1042 | if (ctrl->id != ctrls->qctrl.id) | 1073 | |
1043 | continue; | 1074 | if (ctrl->value < ctrls->qctrl.minimum |
1044 | if (gspca_dev->ctrl_dis & (1 << i)) | 1075 | || ctrl->value > ctrls->qctrl.maximum) |
1045 | return -EINVAL; | 1076 | return -ERANGE; |
1046 | if (ctrl->value < ctrls->qctrl.minimum | 1077 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); |
1047 | || ctrl->value > ctrls->qctrl.maximum) | 1078 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1048 | return -ERANGE; | 1079 | return -ERESTARTSYS; |
1049 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); | 1080 | if (gspca_dev->present) |
1050 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1081 | ret = ctrls->set(gspca_dev, ctrl->value); |
1051 | return -ERESTARTSYS; | 1082 | else |
1052 | if (gspca_dev->present) | 1083 | ret = -ENODEV; |
1053 | ret = ctrls->set(gspca_dev, ctrl->value); | 1084 | mutex_unlock(&gspca_dev->usb_lock); |
1054 | else | 1085 | return ret; |
1055 | ret = -ENODEV; | ||
1056 | mutex_unlock(&gspca_dev->usb_lock); | ||
1057 | return ret; | ||
1058 | } | ||
1059 | return -EINVAL; | ||
1060 | } | 1086 | } |
1061 | 1087 | ||
1062 | static int vidioc_g_ctrl(struct file *file, void *priv, | 1088 | static int vidioc_g_ctrl(struct file *file, void *priv, |
1063 | struct v4l2_control *ctrl) | 1089 | struct v4l2_control *ctrl) |
1064 | { | 1090 | { |
1065 | struct gspca_dev *gspca_dev = priv; | 1091 | struct gspca_dev *gspca_dev = priv; |
1066 | |||
1067 | const struct ctrl *ctrls; | 1092 | const struct ctrl *ctrls; |
1068 | int i, ret; | 1093 | int ret; |
1069 | 1094 | ||
1070 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | 1095 | ctrls = get_ctrl(gspca_dev, ctrl->id); |
1071 | i < gspca_dev->sd_desc->nctrls; | 1096 | if (ctrls == NULL) |
1072 | i++, ctrls++) { | 1097 | return -EINVAL; |
1073 | if (ctrl->id != ctrls->qctrl.id) | 1098 | |
1074 | continue; | 1099 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1075 | if (gspca_dev->ctrl_dis & (1 << i)) | 1100 | return -ERESTARTSYS; |
1076 | return -EINVAL; | 1101 | if (gspca_dev->present) |
1077 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1102 | ret = ctrls->get(gspca_dev, &ctrl->value); |
1078 | return -ERESTARTSYS; | 1103 | else |
1079 | if (gspca_dev->present) | 1104 | ret = -ENODEV; |
1080 | ret = ctrls->get(gspca_dev, &ctrl->value); | 1105 | mutex_unlock(&gspca_dev->usb_lock); |
1081 | else | 1106 | return ret; |
1082 | ret = -ENODEV; | ||
1083 | mutex_unlock(&gspca_dev->usb_lock); | ||
1084 | return ret; | ||
1085 | } | ||
1086 | return -EINVAL; | ||
1087 | } | 1107 | } |
1088 | 1108 | ||
1089 | /*fixme: have an audio flag in gspca_dev?*/ | 1109 | /*fixme: have an audio flag in gspca_dev?*/ |
@@ -1864,6 +1884,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { | |||
1864 | .vidioc_g_parm = vidioc_g_parm, | 1884 | .vidioc_g_parm = vidioc_g_parm, |
1865 | .vidioc_s_parm = vidioc_s_parm, | 1885 | .vidioc_s_parm = vidioc_s_parm, |
1866 | .vidioc_s_std = vidioc_s_std, | 1886 | .vidioc_s_std = vidioc_s_std, |
1887 | .vidioc_enum_framesizes = vidioc_enum_framesizes, | ||
1867 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1888 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1868 | .vidiocgmbuf = vidiocgmbuf, | 1889 | .vidiocgmbuf = vidiocgmbuf, |
1869 | #endif | 1890 | #endif |
@@ -1943,7 +1964,7 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
1943 | 1964 | ||
1944 | /* init video stuff */ | 1965 | /* init video stuff */ |
1945 | memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); | 1966 | memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); |
1946 | gspca_dev->vdev.parent = &dev->dev; | 1967 | gspca_dev->vdev.parent = &intf->dev; |
1947 | gspca_dev->module = module; | 1968 | gspca_dev->module = module; |
1948 | gspca_dev->present = 1; | 1969 | gspca_dev->present = 1; |
1949 | ret = video_register_device(&gspca_dev->vdev, | 1970 | ret = video_register_device(&gspca_dev->vdev, |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 58e8ff02136a..bd1faff88644 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -44,8 +44,6 @@ extern int gspca_debug; | |||
44 | #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ | 44 | #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ |
45 | /* image transfers */ | 45 | /* image transfers */ |
46 | #define MAX_NURBS 4 /* max number of URBs */ | 46 | #define MAX_NURBS 4 /* max number of URBs */ |
47 | #define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ | ||
48 | #define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ | ||
49 | 47 | ||
50 | /* device information - set at probe time */ | 48 | /* device information - set at probe time */ |
51 | struct cam { | 49 | struct cam { |
@@ -56,6 +54,9 @@ struct cam { | |||
56 | * - cannot be > MAX_NURBS | 54 | * - cannot be > MAX_NURBS |
57 | * - when 0 and bulk_size != 0 means | 55 | * - when 0 and bulk_size != 0 means |
58 | * 1 URB and submit done by subdriver */ | 56 | * 1 URB and submit done by subdriver */ |
57 | u8 bulk; /* image transfer by 0:isoc / 1:bulk */ | ||
58 | u8 npkt; /* number of packets in an ISOC message | ||
59 | * 0 is the default value: 32 packets */ | ||
59 | u32 input_flags; /* value for ENUM_INPUT status flags */ | 60 | u32 input_flags; /* value for ENUM_INPUT status flags */ |
60 | }; | 61 | }; |
61 | 62 | ||
@@ -168,7 +169,6 @@ struct gspca_dev { | |||
168 | __u8 iface; /* USB interface number */ | 169 | __u8 iface; /* USB interface number */ |
169 | __u8 alt; /* USB alternate setting */ | 170 | __u8 alt; /* USB alternate setting */ |
170 | __u8 nbalt; /* number of USB alternate settings */ | 171 | __u8 nbalt; /* number of USB alternate settings */ |
171 | u8 bulk; /* image transfer by 0:isoc / 1:bulk */ | ||
172 | }; | 172 | }; |
173 | 173 | ||
174 | int gspca_dev_probe(struct usb_interface *intf, | 174 | int gspca_dev_probe(struct usb_interface *intf, |
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile index 9fa3644f4869..bf7a19a1e6d1 100644 --- a/drivers/media/video/gspca/m5602/Makefile +++ b/drivers/media/video/gspca/m5602/Makefile | |||
@@ -2,9 +2,10 @@ obj-$(CONFIG_USB_M5602) += gspca_m5602.o | |||
2 | 2 | ||
3 | gspca_m5602-objs := m5602_core.o \ | 3 | gspca_m5602-objs := m5602_core.o \ |
4 | m5602_ov9650.o \ | 4 | m5602_ov9650.o \ |
5 | m5602_ov7660.o \ | ||
5 | m5602_mt9m111.o \ | 6 | m5602_mt9m111.o \ |
6 | m5602_po1030.o \ | 7 | m5602_po1030.o \ |
7 | m5602_s5k83a.o \ | 8 | m5602_s5k83a.o \ |
8 | m5602_s5k4aa.o | 9 | m5602_s5k4aa.o |
9 | 10 | ||
10 | EXTRA_CFLAGS += -Idrivers/media/video/gspca \ No newline at end of file | 11 | EXTRA_CFLAGS += -Idrivers/media/video/gspca |
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h index 8f1cea6fd3bf..1127a405c9b2 100644 --- a/drivers/media/video/gspca/m5602/m5602_bridge.h +++ b/drivers/media/video/gspca/m5602/m5602_bridge.h | |||
@@ -45,6 +45,15 @@ | |||
45 | #define M5602_XB_SEN_CLK_DIV 0x15 | 45 | #define M5602_XB_SEN_CLK_DIV 0x15 |
46 | #define M5602_XB_AUD_CLK_CTRL 0x16 | 46 | #define M5602_XB_AUD_CLK_CTRL 0x16 |
47 | #define M5602_XB_AUD_CLK_DIV 0x17 | 47 | #define M5602_XB_AUD_CLK_DIV 0x17 |
48 | #define M5602_OB_AC_LINK_STATE 0x22 | ||
49 | #define M5602_OB_PCM_SLOT_INDEX 0x24 | ||
50 | #define M5602_OB_GPIO_SLOT_INDEX 0x25 | ||
51 | #define M5602_OB_ACRX_STATUS_ADDRESS_H 0x28 | ||
52 | #define M5602_OB_ACRX_STATUS_DATA_L 0x29 | ||
53 | #define M5602_OB_ACRX_STATUS_DATA_H 0x2a | ||
54 | #define M5602_OB_ACTX_COMMAND_ADDRESS 0x31 | ||
55 | #define M5602_OB_ACRX_COMMAND_DATA_L 0x32 | ||
56 | #define M5602_OB_ACTX_COMMAND_DATA_H 0X33 | ||
48 | #define M5602_XB_DEVCTR1 0x41 | 57 | #define M5602_XB_DEVCTR1 0x41 |
49 | #define M5602_XB_EPSETR0 0x42 | 58 | #define M5602_XB_EPSETR0 0x42 |
50 | #define M5602_XB_EPAFCTR 0x47 | 59 | #define M5602_XB_EPAFCTR 0x47 |
@@ -77,7 +86,18 @@ | |||
77 | #define M5602_XB_GPIO_EN_L 0x75 | 86 | #define M5602_XB_GPIO_EN_L 0x75 |
78 | #define M5602_XB_GPIO_DAT 0x76 | 87 | #define M5602_XB_GPIO_DAT 0x76 |
79 | #define M5602_XB_GPIO_DIR 0x77 | 88 | #define M5602_XB_GPIO_DIR 0x77 |
80 | #define M5602_XB_MISC_CTL 0x70 | 89 | #define M5602_XB_SEN_CLK_CONTROL 0x80 |
90 | #define M5602_XB_SEN_CLK_DIVISION 0x81 | ||
91 | #define M5602_XB_CPR_CLK_CONTROL 0x82 | ||
92 | #define M5602_XB_CPR_CLK_DIVISION 0x83 | ||
93 | #define M5602_XB_MCU_CLK_CONTROL 0x84 | ||
94 | #define M5602_XB_MCU_CLK_DIVISION 0x85 | ||
95 | #define M5602_XB_DCT_CLK_CONTROL 0x86 | ||
96 | #define M5602_XB_DCT_CLK_DIVISION 0x87 | ||
97 | #define M5602_XB_EC_CLK_CONTROL 0x88 | ||
98 | #define M5602_XB_EC_CLK_DIVISION 0x89 | ||
99 | #define M5602_XB_LBUF_CLK_CONTROL 0x8a | ||
100 | #define M5602_XB_LBUF_CLK_DIVISION 0x8b | ||
81 | 101 | ||
82 | #define I2C_BUSY 0x80 | 102 | #define I2C_BUSY 0x80 |
83 | 103 | ||
@@ -128,10 +148,10 @@ struct sd { | |||
128 | }; | 148 | }; |
129 | 149 | ||
130 | int m5602_read_bridge( | 150 | int m5602_read_bridge( |
131 | struct sd *sd, u8 address, u8 *i2c_data); | 151 | struct sd *sd, const u8 address, u8 *i2c_data); |
132 | 152 | ||
133 | int m5602_write_bridge( | 153 | int m5602_write_bridge( |
134 | struct sd *sd, u8 address, u8 i2c_data); | 154 | struct sd *sd, const u8 address, const u8 i2c_data); |
135 | 155 | ||
136 | int m5602_write_sensor(struct sd *sd, const u8 address, | 156 | int m5602_write_sensor(struct sd *sd, const u8 address, |
137 | u8 *i2c_data, const u8 len); | 157 | u8 *i2c_data, const u8 len); |
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index 1aac2985fee6..8a5bba16ff32 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "m5602_ov9650.h" | 19 | #include "m5602_ov9650.h" |
20 | #include "m5602_ov7660.h" | ||
20 | #include "m5602_mt9m111.h" | 21 | #include "m5602_mt9m111.h" |
21 | #include "m5602_po1030.h" | 22 | #include "m5602_po1030.h" |
22 | #include "m5602_s5k83a.h" | 23 | #include "m5602_s5k83a.h" |
@@ -35,7 +36,7 @@ static const __devinitdata struct usb_device_id m5602_table[] = { | |||
35 | MODULE_DEVICE_TABLE(usb, m5602_table); | 36 | MODULE_DEVICE_TABLE(usb, m5602_table); |
36 | 37 | ||
37 | /* Reads a byte from the m5602 */ | 38 | /* Reads a byte from the m5602 */ |
38 | int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) | 39 | int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data) |
39 | { | 40 | { |
40 | int err; | 41 | int err; |
41 | struct usb_device *udev = sd->gspca_dev.dev; | 42 | struct usb_device *udev = sd->gspca_dev.dev; |
@@ -56,7 +57,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) | |||
56 | } | 57 | } |
57 | 58 | ||
58 | /* Writes a byte to to the m5602 */ | 59 | /* Writes a byte to to the m5602 */ |
59 | int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) | 60 | int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data) |
60 | { | 61 | { |
61 | int err; | 62 | int err; |
62 | struct usb_device *udev = sd->gspca_dev.dev; | 63 | struct usb_device *udev = sd->gspca_dev.dev; |
@@ -80,6 +81,17 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) | |||
80 | return (err < 0) ? err : 0; | 81 | return (err < 0) ? err : 0; |
81 | } | 82 | } |
82 | 83 | ||
84 | int m5602_wait_for_i2c(struct sd *sd) | ||
85 | { | ||
86 | int err; | ||
87 | u8 data; | ||
88 | |||
89 | do { | ||
90 | err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data); | ||
91 | } while ((data & I2C_BUSY) && !err); | ||
92 | return err; | ||
93 | } | ||
94 | |||
83 | int m5602_read_sensor(struct sd *sd, const u8 address, | 95 | int m5602_read_sensor(struct sd *sd, const u8 address, |
84 | u8 *i2c_data, const u8 len) | 96 | u8 *i2c_data, const u8 len) |
85 | { | 97 | { |
@@ -88,9 +100,7 @@ int m5602_read_sensor(struct sd *sd, const u8 address, | |||
88 | if (!len || len > sd->sensor->i2c_regW) | 100 | if (!len || len > sd->sensor->i2c_regW) |
89 | return -EINVAL; | 101 | return -EINVAL; |
90 | 102 | ||
91 | do { | 103 | err = m5602_wait_for_i2c(sd); |
92 | err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); | ||
93 | } while ((*i2c_data & I2C_BUSY) && !err); | ||
94 | if (err < 0) | 104 | if (err < 0) |
95 | return err; | 105 | return err; |
96 | 106 | ||
@@ -103,21 +113,25 @@ int m5602_read_sensor(struct sd *sd, const u8 address, | |||
103 | if (err < 0) | 113 | if (err < 0) |
104 | return err; | 114 | return err; |
105 | 115 | ||
116 | /* Sensors with registers that are of only | ||
117 | one byte width are differently read */ | ||
118 | |||
119 | /* FIXME: This works with the ov9650, but has issues with the po1030 */ | ||
106 | if (sd->sensor->i2c_regW == 1) { | 120 | if (sd->sensor->i2c_regW == 1) { |
107 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len); | 121 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1); |
108 | if (err < 0) | 122 | if (err < 0) |
109 | return err; | 123 | return err; |
110 | 124 | ||
111 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); | 125 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); |
112 | if (err < 0) | ||
113 | return err; | ||
114 | } else { | 126 | } else { |
115 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); | 127 | err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); |
116 | if (err < 0) | ||
117 | return err; | ||
118 | } | 128 | } |
119 | 129 | ||
120 | for (i = 0; (i < len) && !err; i++) { | 130 | for (i = 0; (i < len) && !err; i++) { |
131 | err = m5602_wait_for_i2c(sd); | ||
132 | if (err < 0) | ||
133 | return err; | ||
134 | |||
121 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); | 135 | err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); |
122 | 136 | ||
123 | PDEBUG(D_CONF, "Reading sensor register " | 137 | PDEBUG(D_CONF, "Reading sensor register " |
@@ -206,6 +220,11 @@ static int m5602_probe_sensor(struct sd *sd) | |||
206 | if (!sd->sensor->probe(sd)) | 220 | if (!sd->sensor->probe(sd)) |
207 | return 0; | 221 | return 0; |
208 | 222 | ||
223 | /* Try the ov7660 */ | ||
224 | sd->sensor = &ov7660; | ||
225 | if (!sd->sensor->probe(sd)) | ||
226 | return 0; | ||
227 | |||
209 | /* Try the s5k83a */ | 228 | /* Try the s5k83a */ |
210 | sd->sensor = &s5k83a; | 229 | sd->sensor = &s5k83a; |
211 | if (!sd->sensor->probe(sd)) | 230 | if (!sd->sensor->probe(sd)) |
@@ -409,8 +428,9 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
409 | MODULE_LICENSE("GPL"); | 428 | MODULE_LICENSE("GPL"); |
410 | module_param(force_sensor, int, S_IRUGO | S_IWUSR); | 429 | module_param(force_sensor, int, S_IRUGO | S_IWUSR); |
411 | MODULE_PARM_DESC(force_sensor, | 430 | MODULE_PARM_DESC(force_sensor, |
412 | "force detection of sensor, " | 431 | "forces detection of a sensor, " |
413 | "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, 4 = MT9M111, 5 = PO1030"); | 432 | "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, " |
433 | "4 = MT9M111, 5 = PO1030, 6 = OV7660"); | ||
414 | 434 | ||
415 | module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); | 435 | module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); |
416 | MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); | 436 | MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); |
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 7d3f9e348ef4..8d071dff6944 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c | |||
@@ -18,6 +18,23 @@ | |||
18 | 18 | ||
19 | #include "m5602_mt9m111.h" | 19 | #include "m5602_mt9m111.h" |
20 | 20 | ||
21 | static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
22 | static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
23 | static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, | ||
28 | __s32 val); | ||
29 | static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, | ||
30 | __s32 *val); | ||
31 | static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
34 | static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
35 | static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
36 | static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
37 | |||
21 | static struct v4l2_pix_format mt9m111_modes[] = { | 38 | static struct v4l2_pix_format mt9m111_modes[] = { |
22 | { | 39 | { |
23 | 640, | 40 | 640, |
@@ -32,6 +49,7 @@ static struct v4l2_pix_format mt9m111_modes[] = { | |||
32 | }; | 49 | }; |
33 | 50 | ||
34 | const static struct ctrl mt9m111_ctrls[] = { | 51 | const static struct ctrl mt9m111_ctrls[] = { |
52 | #define VFLIP_IDX 0 | ||
35 | { | 53 | { |
36 | { | 54 | { |
37 | .id = V4L2_CID_VFLIP, | 55 | .id = V4L2_CID_VFLIP, |
@@ -44,7 +62,9 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
44 | }, | 62 | }, |
45 | .set = mt9m111_set_vflip, | 63 | .set = mt9m111_set_vflip, |
46 | .get = mt9m111_get_vflip | 64 | .get = mt9m111_get_vflip |
47 | }, { | 65 | }, |
66 | #define HFLIP_IDX 1 | ||
67 | { | ||
48 | { | 68 | { |
49 | .id = V4L2_CID_HFLIP, | 69 | .id = V4L2_CID_HFLIP, |
50 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 70 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -56,7 +76,9 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
56 | }, | 76 | }, |
57 | .set = mt9m111_set_hflip, | 77 | .set = mt9m111_set_hflip, |
58 | .get = mt9m111_get_hflip | 78 | .get = mt9m111_get_hflip |
59 | }, { | 79 | }, |
80 | #define GAIN_IDX 2 | ||
81 | { | ||
60 | { | 82 | { |
61 | .id = V4L2_CID_GAIN, | 83 | .id = V4L2_CID_GAIN, |
62 | .type = V4L2_CTRL_TYPE_INTEGER, | 84 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -64,21 +86,80 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
64 | .minimum = 0, | 86 | .minimum = 0, |
65 | .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, | 87 | .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, |
66 | .step = 1, | 88 | .step = 1, |
67 | .default_value = DEFAULT_GAIN, | 89 | .default_value = MT9M111_DEFAULT_GAIN, |
68 | .flags = V4L2_CTRL_FLAG_SLIDER | 90 | .flags = V4L2_CTRL_FLAG_SLIDER |
69 | }, | 91 | }, |
70 | .set = mt9m111_set_gain, | 92 | .set = mt9m111_set_gain, |
71 | .get = mt9m111_get_gain | 93 | .get = mt9m111_get_gain |
72 | } | 94 | }, |
95 | #define AUTO_WHITE_BALANCE_IDX 3 | ||
96 | { | ||
97 | { | ||
98 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
99 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
100 | .name = "auto white balance", | ||
101 | .minimum = 0, | ||
102 | .maximum = 1, | ||
103 | .step = 1, | ||
104 | .default_value = 0, | ||
105 | }, | ||
106 | .set = mt9m111_set_auto_white_balance, | ||
107 | .get = mt9m111_get_auto_white_balance | ||
108 | }, | ||
109 | #define GREEN_BALANCE_IDX 4 | ||
110 | { | ||
111 | { | ||
112 | .id = M5602_V4L2_CID_GREEN_BALANCE, | ||
113 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
114 | .name = "green balance", | ||
115 | .minimum = 0x00, | ||
116 | .maximum = 0x7ff, | ||
117 | .step = 0x1, | ||
118 | .default_value = MT9M111_GREEN_GAIN_DEFAULT, | ||
119 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
120 | }, | ||
121 | .set = mt9m111_set_green_balance, | ||
122 | .get = mt9m111_get_green_balance | ||
123 | }, | ||
124 | #define BLUE_BALANCE_IDX 5 | ||
125 | { | ||
126 | { | ||
127 | .id = V4L2_CID_BLUE_BALANCE, | ||
128 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
129 | .name = "blue balance", | ||
130 | .minimum = 0x00, | ||
131 | .maximum = 0x7ff, | ||
132 | .step = 0x1, | ||
133 | .default_value = MT9M111_BLUE_GAIN_DEFAULT, | ||
134 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
135 | }, | ||
136 | .set = mt9m111_set_blue_balance, | ||
137 | .get = mt9m111_get_blue_balance | ||
138 | }, | ||
139 | #define RED_BALANCE_IDX 5 | ||
140 | { | ||
141 | { | ||
142 | .id = V4L2_CID_RED_BALANCE, | ||
143 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
144 | .name = "red balance", | ||
145 | .minimum = 0x00, | ||
146 | .maximum = 0x7ff, | ||
147 | .step = 0x1, | ||
148 | .default_value = MT9M111_RED_GAIN_DEFAULT, | ||
149 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
150 | }, | ||
151 | .set = mt9m111_set_red_balance, | ||
152 | .get = mt9m111_get_red_balance | ||
153 | }, | ||
73 | }; | 154 | }; |
74 | 155 | ||
75 | |||
76 | static void mt9m111_dump_registers(struct sd *sd); | 156 | static void mt9m111_dump_registers(struct sd *sd); |
77 | 157 | ||
78 | int mt9m111_probe(struct sd *sd) | 158 | int mt9m111_probe(struct sd *sd) |
79 | { | 159 | { |
80 | u8 data[2] = {0x00, 0x00}; | 160 | u8 data[2] = {0x00, 0x00}; |
81 | int i; | 161 | int i; |
162 | s32 *sensor_settings; | ||
82 | 163 | ||
83 | if (force_sensor) { | 164 | if (force_sensor) { |
84 | if (force_sensor == MT9M111_SENSOR) { | 165 | if (force_sensor == MT9M111_SENSOR) { |
@@ -117,16 +198,27 @@ int mt9m111_probe(struct sd *sd) | |||
117 | return -ENODEV; | 198 | return -ENODEV; |
118 | 199 | ||
119 | sensor_found: | 200 | sensor_found: |
201 | sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), | ||
202 | GFP_KERNEL); | ||
203 | if (!sensor_settings) | ||
204 | return -ENOMEM; | ||
205 | |||
120 | sd->gspca_dev.cam.cam_mode = mt9m111_modes; | 206 | sd->gspca_dev.cam.cam_mode = mt9m111_modes; |
121 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); | 207 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); |
122 | sd->desc->ctrls = mt9m111_ctrls; | 208 | sd->desc->ctrls = mt9m111_ctrls; |
123 | sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); | 209 | sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); |
210 | |||
211 | for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++) | ||
212 | sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value; | ||
213 | sd->sensor_priv = sensor_settings; | ||
214 | |||
124 | return 0; | 215 | return 0; |
125 | } | 216 | } |
126 | 217 | ||
127 | int mt9m111_init(struct sd *sd) | 218 | int mt9m111_init(struct sd *sd) |
128 | { | 219 | { |
129 | int i, err = 0; | 220 | int i, err = 0; |
221 | s32 *sensor_settings = sd->sensor_priv; | ||
130 | 222 | ||
131 | /* Init the sensor */ | 223 | /* Init the sensor */ |
132 | for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { | 224 | for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { |
@@ -147,36 +239,154 @@ int mt9m111_init(struct sd *sd) | |||
147 | if (dump_sensor) | 239 | if (dump_sensor) |
148 | mt9m111_dump_registers(sd); | 240 | mt9m111_dump_registers(sd); |
149 | 241 | ||
150 | return (err < 0) ? err : 0; | 242 | err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); |
243 | if (err < 0) | ||
244 | return err; | ||
245 | |||
246 | err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
247 | if (err < 0) | ||
248 | return err; | ||
249 | |||
250 | err = mt9m111_set_green_balance(&sd->gspca_dev, | ||
251 | sensor_settings[GREEN_BALANCE_IDX]); | ||
252 | if (err < 0) | ||
253 | return err; | ||
254 | |||
255 | err = mt9m111_set_blue_balance(&sd->gspca_dev, | ||
256 | sensor_settings[BLUE_BALANCE_IDX]); | ||
257 | if (err < 0) | ||
258 | return err; | ||
259 | |||
260 | err = mt9m111_set_red_balance(&sd->gspca_dev, | ||
261 | sensor_settings[RED_BALANCE_IDX]); | ||
262 | if (err < 0) | ||
263 | return err; | ||
264 | |||
265 | return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
151 | } | 266 | } |
152 | 267 | ||
153 | int mt9m111_power_down(struct sd *sd) | 268 | int mt9m111_start(struct sd *sd) |
154 | { | 269 | { |
155 | return 0; | 270 | int i, err = 0; |
271 | u8 data[2]; | ||
272 | struct cam *cam = &sd->gspca_dev.cam; | ||
273 | s32 *sensor_settings = sd->sensor_priv; | ||
274 | |||
275 | int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1; | ||
276 | int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; | ||
277 | |||
278 | for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) { | ||
279 | if (start_mt9m111[i][0] == BRIDGE) { | ||
280 | err = m5602_write_bridge(sd, | ||
281 | start_mt9m111[i][1], | ||
282 | start_mt9m111[i][2]); | ||
283 | } else { | ||
284 | data[0] = start_mt9m111[i][2]; | ||
285 | data[1] = start_mt9m111[i][3]; | ||
286 | err = m5602_write_sensor(sd, | ||
287 | start_mt9m111[i][1], data, 2); | ||
288 | } | ||
289 | } | ||
290 | if (err < 0) | ||
291 | return err; | ||
292 | |||
293 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); | ||
294 | if (err < 0) | ||
295 | return err; | ||
296 | |||
297 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); | ||
298 | if (err < 0) | ||
299 | return err; | ||
300 | |||
301 | for (i = 0; i < 2 && !err; i++) | ||
302 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); | ||
303 | if (err < 0) | ||
304 | return err; | ||
305 | |||
306 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
307 | if (err < 0) | ||
308 | return err; | ||
309 | |||
310 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); | ||
311 | if (err < 0) | ||
312 | return err; | ||
313 | |||
314 | for (i = 0; i < 2 && !err; i++) | ||
315 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0); | ||
316 | if (err < 0) | ||
317 | return err; | ||
318 | |||
319 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, | ||
320 | (width >> 8) & 0xff); | ||
321 | if (err < 0) | ||
322 | return err; | ||
323 | |||
324 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff); | ||
325 | if (err < 0) | ||
326 | return err; | ||
327 | |||
328 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
329 | if (err < 0) | ||
330 | return err; | ||
331 | |||
332 | switch (width) { | ||
333 | case 640: | ||
334 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); | ||
335 | data[0] = MT9M111_RMB_OVER_SIZED; | ||
336 | data[1] = MT9M111_RMB_ROW_SKIP_2X | | ||
337 | MT9M111_RMB_COLUMN_SKIP_2X | | ||
338 | (sensor_settings[VFLIP_IDX] << 0) | | ||
339 | (sensor_settings[HFLIP_IDX] << 1); | ||
340 | |||
341 | err = m5602_write_sensor(sd, | ||
342 | MT9M111_SC_R_MODE_CONTEXT_B, data, 2); | ||
343 | break; | ||
344 | |||
345 | case 320: | ||
346 | PDEBUG(D_V4L2, "Configuring camera for QVGA mode"); | ||
347 | data[0] = MT9M111_RMB_OVER_SIZED; | ||
348 | data[1] = MT9M111_RMB_ROW_SKIP_4X | | ||
349 | MT9M111_RMB_COLUMN_SKIP_4X | | ||
350 | (sensor_settings[VFLIP_IDX] << 0) | | ||
351 | (sensor_settings[HFLIP_IDX] << 1); | ||
352 | err = m5602_write_sensor(sd, | ||
353 | MT9M111_SC_R_MODE_CONTEXT_B, data, 2); | ||
354 | break; | ||
355 | } | ||
356 | return err; | ||
156 | } | 357 | } |
157 | 358 | ||
158 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 359 | void mt9m111_disconnect(struct sd *sd) |
360 | { | ||
361 | sd->sensor = NULL; | ||
362 | kfree(sd->sensor_priv); | ||
363 | } | ||
364 | |||
365 | static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
159 | { | 366 | { |
160 | int err; | ||
161 | u8 data[2] = {0x00, 0x00}; | ||
162 | struct sd *sd = (struct sd *) gspca_dev; | 367 | struct sd *sd = (struct sd *) gspca_dev; |
368 | s32 *sensor_settings = sd->sensor_priv; | ||
163 | 369 | ||
164 | err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 370 | *val = sensor_settings[VFLIP_IDX]; |
165 | data, 2); | ||
166 | *val = data[0] & MT9M111_RMB_MIRROR_ROWS; | ||
167 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 371 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
168 | 372 | ||
169 | return err; | 373 | return 0; |
170 | } | 374 | } |
171 | 375 | ||
172 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 376 | static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
173 | { | 377 | { |
174 | int err; | 378 | int err; |
175 | u8 data[2] = {0x00, 0x00}; | 379 | u8 data[2] = {0x00, 0x00}; |
176 | struct sd *sd = (struct sd *) gspca_dev; | 380 | struct sd *sd = (struct sd *) gspca_dev; |
381 | s32 *sensor_settings = sd->sensor_priv; | ||
177 | 382 | ||
178 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 383 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
179 | 384 | ||
385 | sensor_settings[VFLIP_IDX] = val; | ||
386 | |||
387 | /* The mt9m111 is flipped by default */ | ||
388 | val = !val; | ||
389 | |||
180 | /* Set the correct page map */ | 390 | /* Set the correct page map */ |
181 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 391 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
182 | if (err < 0) | 392 | if (err < 0) |
@@ -186,34 +396,37 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
186 | if (err < 0) | 396 | if (err < 0) |
187 | return err; | 397 | return err; |
188 | 398 | ||
189 | data[0] = (data[0] & 0xfe) | val; | 399 | data[1] = (data[1] & 0xfe) | val; |
190 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 400 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, |
191 | data, 2); | 401 | data, 2); |
192 | return err; | 402 | return err; |
193 | } | 403 | } |
194 | 404 | ||
195 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 405 | static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
196 | { | 406 | { |
197 | int err; | ||
198 | u8 data[2] = {0x00, 0x00}; | ||
199 | struct sd *sd = (struct sd *) gspca_dev; | 407 | struct sd *sd = (struct sd *) gspca_dev; |
408 | s32 *sensor_settings = sd->sensor_priv; | ||
200 | 409 | ||
201 | err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 410 | *val = sensor_settings[HFLIP_IDX]; |
202 | data, 2); | ||
203 | *val = data[0] & MT9M111_RMB_MIRROR_COLS; | ||
204 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 411 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
205 | 412 | ||
206 | return err; | 413 | return 0; |
207 | } | 414 | } |
208 | 415 | ||
209 | int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 416 | static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
210 | { | 417 | { |
211 | int err; | 418 | int err; |
212 | u8 data[2] = {0x00, 0x00}; | 419 | u8 data[2] = {0x00, 0x00}; |
213 | struct sd *sd = (struct sd *) gspca_dev; | 420 | struct sd *sd = (struct sd *) gspca_dev; |
421 | s32 *sensor_settings = sd->sensor_priv; | ||
214 | 422 | ||
215 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | 423 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); |
216 | 424 | ||
425 | sensor_settings[HFLIP_IDX] = val; | ||
426 | |||
427 | /* The mt9m111 is flipped by default */ | ||
428 | val = !val; | ||
429 | |||
217 | /* Set the correct page map */ | 430 | /* Set the correct page map */ |
218 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 431 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
219 | if (err < 0) | 432 | if (err < 0) |
@@ -223,36 +436,62 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
223 | if (err < 0) | 436 | if (err < 0) |
224 | return err; | 437 | return err; |
225 | 438 | ||
226 | data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02); | 439 | data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02); |
227 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 440 | err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, |
228 | data, 2); | 441 | data, 2); |
229 | return err; | 442 | return err; |
230 | } | 443 | } |
231 | 444 | ||
232 | int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 445 | static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
233 | { | 446 | { |
234 | int err, tmp; | ||
235 | u8 data[2] = {0x00, 0x00}; | ||
236 | struct sd *sd = (struct sd *) gspca_dev; | 447 | struct sd *sd = (struct sd *) gspca_dev; |
448 | s32 *sensor_settings = sd->sensor_priv; | ||
237 | 449 | ||
238 | err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); | 450 | *val = sensor_settings[GAIN_IDX]; |
239 | tmp = ((data[1] << 8) | data[0]); | 451 | PDEBUG(D_V4L2, "Read gain %d", *val); |
240 | 452 | ||
241 | *val = ((tmp & (1 << 10)) * 2) | | 453 | return 0; |
242 | ((tmp & (1 << 9)) * 2) | | 454 | } |
243 | ((tmp & (1 << 8)) * 2) | | ||
244 | (tmp & 0x7f); | ||
245 | 455 | ||
246 | PDEBUG(D_V4L2, "Read gain %d", *val); | 456 | static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, |
457 | __s32 val) | ||
458 | { | ||
459 | struct sd *sd = (struct sd *) gspca_dev; | ||
460 | s32 *sensor_settings = sd->sensor_priv; | ||
461 | int err; | ||
462 | u8 data[2]; | ||
463 | |||
464 | err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); | ||
465 | if (err < 0) | ||
466 | return err; | ||
467 | |||
468 | sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01; | ||
469 | data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1)); | ||
247 | 470 | ||
471 | err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); | ||
472 | |||
473 | PDEBUG(D_V4L2, "Set auto white balance %d", val); | ||
248 | return err; | 474 | return err; |
249 | } | 475 | } |
250 | 476 | ||
251 | int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 477 | static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, |
478 | __s32 *val) { | ||
479 | struct sd *sd = (struct sd *) gspca_dev; | ||
480 | s32 *sensor_settings = sd->sensor_priv; | ||
481 | |||
482 | *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; | ||
483 | PDEBUG(D_V4L2, "Read auto white balance %d", *val); | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
252 | { | 488 | { |
253 | int err, tmp; | 489 | int err, tmp; |
254 | u8 data[2] = {0x00, 0x00}; | 490 | u8 data[2] = {0x00, 0x00}; |
255 | struct sd *sd = (struct sd *) gspca_dev; | 491 | struct sd *sd = (struct sd *) gspca_dev; |
492 | s32 *sensor_settings = sd->sensor_priv; | ||
493 | |||
494 | sensor_settings[GAIN_IDX] = val; | ||
256 | 495 | ||
257 | /* Set the correct page map */ | 496 | /* Set the correct page map */ |
258 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 497 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
@@ -275,8 +514,8 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
275 | else | 514 | else |
276 | tmp = val; | 515 | tmp = val; |
277 | 516 | ||
278 | data[1] = (tmp & 0xff00) >> 8; | 517 | data[1] = (tmp & 0xff); |
279 | data[0] = (tmp & 0xff); | 518 | data[0] = (tmp & 0xff00) >> 8; |
280 | PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, | 519 | PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, |
281 | data[1], data[0]); | 520 | data[1], data[0]); |
282 | 521 | ||
@@ -286,6 +525,89 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
286 | return err; | 525 | return err; |
287 | } | 526 | } |
288 | 527 | ||
528 | static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
529 | { | ||
530 | int err; | ||
531 | u8 data[2]; | ||
532 | struct sd *sd = (struct sd *) gspca_dev; | ||
533 | s32 *sensor_settings = sd->sensor_priv; | ||
534 | |||
535 | sensor_settings[GREEN_BALANCE_IDX] = val; | ||
536 | data[1] = (val & 0xff); | ||
537 | data[0] = (val & 0xff00) >> 8; | ||
538 | |||
539 | PDEBUG(D_V4L2, "Set green balance %d", val); | ||
540 | err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN, | ||
541 | data, 2); | ||
542 | if (err < 0) | ||
543 | return err; | ||
544 | |||
545 | return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN, | ||
546 | data, 2); | ||
547 | } | ||
548 | |||
549 | static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
550 | { | ||
551 | struct sd *sd = (struct sd *) gspca_dev; | ||
552 | s32 *sensor_settings = sd->sensor_priv; | ||
553 | |||
554 | *val = sensor_settings[GREEN_BALANCE_IDX]; | ||
555 | PDEBUG(D_V4L2, "Read green balance %d", *val); | ||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
560 | { | ||
561 | u8 data[2]; | ||
562 | struct sd *sd = (struct sd *) gspca_dev; | ||
563 | s32 *sensor_settings = sd->sensor_priv; | ||
564 | |||
565 | sensor_settings[BLUE_BALANCE_IDX] = val; | ||
566 | data[1] = (val & 0xff); | ||
567 | data[0] = (val & 0xff00) >> 8; | ||
568 | |||
569 | PDEBUG(D_V4L2, "Set blue balance %d", val); | ||
570 | |||
571 | return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN, | ||
572 | data, 2); | ||
573 | } | ||
574 | |||
575 | static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
576 | { | ||
577 | struct sd *sd = (struct sd *) gspca_dev; | ||
578 | s32 *sensor_settings = sd->sensor_priv; | ||
579 | |||
580 | *val = sensor_settings[BLUE_BALANCE_IDX]; | ||
581 | PDEBUG(D_V4L2, "Read blue balance %d", *val); | ||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
586 | { | ||
587 | u8 data[2]; | ||
588 | struct sd *sd = (struct sd *) gspca_dev; | ||
589 | s32 *sensor_settings = sd->sensor_priv; | ||
590 | |||
591 | sensor_settings[RED_BALANCE_IDX] = val; | ||
592 | data[1] = (val & 0xff); | ||
593 | data[0] = (val & 0xff00) >> 8; | ||
594 | |||
595 | PDEBUG(D_V4L2, "Set red balance %d", val); | ||
596 | |||
597 | return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN, | ||
598 | data, 2); | ||
599 | } | ||
600 | |||
601 | static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
602 | { | ||
603 | struct sd *sd = (struct sd *) gspca_dev; | ||
604 | s32 *sensor_settings = sd->sensor_priv; | ||
605 | |||
606 | *val = sensor_settings[RED_BALANCE_IDX]; | ||
607 | PDEBUG(D_V4L2, "Read red balance %d", *val); | ||
608 | return 0; | ||
609 | } | ||
610 | |||
289 | static void mt9m111_dump_registers(struct sd *sd) | 611 | static void mt9m111_dump_registers(struct sd *sd) |
290 | { | 612 | { |
291 | u8 address, value[2] = {0x00, 0x00}; | 613 | u8 address, value[2] = {0x00, 0x00}; |
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h index 00c6db02bdb7..b3de77823091 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h | |||
@@ -37,7 +37,6 @@ | |||
37 | #define MT9M111_SC_VBLANK_CONTEXT_A 0x08 | 37 | #define MT9M111_SC_VBLANK_CONTEXT_A 0x08 |
38 | #define MT9M111_SC_SHUTTER_WIDTH 0x09 | 38 | #define MT9M111_SC_SHUTTER_WIDTH 0x09 |
39 | #define MT9M111_SC_ROW_SPEED 0x0a | 39 | #define MT9M111_SC_ROW_SPEED 0x0a |
40 | |||
41 | #define MT9M111_SC_EXTRA_DELAY 0x0b | 40 | #define MT9M111_SC_EXTRA_DELAY 0x0b |
42 | #define MT9M111_SC_SHUTTER_DELAY 0x0c | 41 | #define MT9M111_SC_SHUTTER_DELAY 0x0c |
43 | #define MT9M111_SC_RESET 0x0d | 42 | #define MT9M111_SC_RESET 0x0d |
@@ -50,9 +49,6 @@ | |||
50 | #define MT9M111_SC_GREEN_2_GAIN 0x2e | 49 | #define MT9M111_SC_GREEN_2_GAIN 0x2e |
51 | #define MT9M111_SC_GLOBAL_GAIN 0x2f | 50 | #define MT9M111_SC_GLOBAL_GAIN 0x2f |
52 | 51 | ||
53 | #define MT9M111_RMB_MIRROR_ROWS (1 << 0) | ||
54 | #define MT9M111_RMB_MIRROR_COLS (1 << 1) | ||
55 | |||
56 | #define MT9M111_CONTEXT_CONTROL 0xc8 | 52 | #define MT9M111_CONTEXT_CONTROL 0xc8 |
57 | #define MT9M111_PAGE_MAP 0xf0 | 53 | #define MT9M111_PAGE_MAP 0xf0 |
58 | #define MT9M111_BYTEWISE_ADDRESS 0xf1 | 54 | #define MT9M111_BYTEWISE_ADDRESS 0xf1 |
@@ -74,8 +70,37 @@ | |||
74 | #define MT9M111_COLORPIPE 0x01 | 70 | #define MT9M111_COLORPIPE 0x01 |
75 | #define MT9M111_CAMERA_CONTROL 0x02 | 71 | #define MT9M111_CAMERA_CONTROL 0x02 |
76 | 72 | ||
73 | #define MT9M111_RESET (1 << 0) | ||
74 | #define MT9M111_RESTART (1 << 1) | ||
75 | #define MT9M111_ANALOG_STANDBY (1 << 2) | ||
76 | #define MT9M111_CHIP_ENABLE (1 << 3) | ||
77 | #define MT9M111_CHIP_DISABLE (0 << 3) | ||
78 | #define MT9M111_OUTPUT_DISABLE (1 << 4) | ||
79 | #define MT9M111_SHOW_BAD_FRAMES (1 << 0) | ||
80 | #define MT9M111_RESTART_BAD_FRAMES (1 << 1) | ||
81 | #define MT9M111_SYNCHRONIZE_CHANGES (1 << 7) | ||
82 | |||
83 | #define MT9M111_RMB_OVER_SIZED (1 << 0) | ||
84 | #define MT9M111_RMB_MIRROR_ROWS (1 << 0) | ||
85 | #define MT9M111_RMB_MIRROR_COLS (1 << 1) | ||
86 | #define MT9M111_RMB_ROW_SKIP_2X (1 << 2) | ||
87 | #define MT9M111_RMB_COLUMN_SKIP_2X (1 << 3) | ||
88 | #define MT9M111_RMB_ROW_SKIP_4X (1 << 4) | ||
89 | #define MT9M111_RMB_COLUMN_SKIP_4X (1 << 5) | ||
90 | |||
91 | #define MT9M111_COLOR_MATRIX_BYPASS (1 << 4) | ||
92 | #define MT9M111_SEL_CONTEXT_B (1 << 3) | ||
93 | |||
94 | #define MT9M111_TRISTATE_PIN_IN_STANDBY (1 << 1) | ||
95 | #define MT9M111_SOC_SOFT_STANDBY (1 << 0) | ||
96 | |||
97 | #define MT9M111_2D_DEFECT_CORRECTION_ENABLE (1 << 0) | ||
98 | |||
77 | #define INITIAL_MAX_GAIN 64 | 99 | #define INITIAL_MAX_GAIN 64 |
78 | #define DEFAULT_GAIN 283 | 100 | #define MT9M111_DEFAULT_GAIN 283 |
101 | #define MT9M111_GREEN_GAIN_DEFAULT 0x20 | ||
102 | #define MT9M111_BLUE_GAIN_DEFAULT 0x20 | ||
103 | #define MT9M111_RED_GAIN_DEFAULT 0x20 | ||
79 | 104 | ||
80 | /*****************************************************************************/ | 105 | /*****************************************************************************/ |
81 | 106 | ||
@@ -85,16 +110,10 @@ extern int dump_sensor; | |||
85 | 110 | ||
86 | int mt9m111_probe(struct sd *sd); | 111 | int mt9m111_probe(struct sd *sd); |
87 | int mt9m111_init(struct sd *sd); | 112 | int mt9m111_init(struct sd *sd); |
88 | int mt9m111_power_down(struct sd *sd); | 113 | int mt9m111_start(struct sd *sd); |
114 | void mt9m111_disconnect(struct sd *sd); | ||
89 | 115 | ||
90 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | 116 | static const struct m5602_sensor mt9m111 = { |
91 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
92 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
93 | int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
94 | int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
95 | int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
96 | |||
97 | const static struct m5602_sensor mt9m111 = { | ||
98 | .name = "MT9M111", | 117 | .name = "MT9M111", |
99 | 118 | ||
100 | .i2c_slave_id = 0xba, | 119 | .i2c_slave_id = 0xba, |
@@ -102,7 +121,8 @@ const static struct m5602_sensor mt9m111 = { | |||
102 | 121 | ||
103 | .probe = mt9m111_probe, | 122 | .probe = mt9m111_probe, |
104 | .init = mt9m111_init, | 123 | .init = mt9m111_init, |
105 | .power_down = mt9m111_power_down | 124 | .disconnect = mt9m111_disconnect, |
125 | .start = mt9m111_start, | ||
106 | }; | 126 | }; |
107 | 127 | ||
108 | static const unsigned char preinit_mt9m111[][4] = | 128 | static const unsigned char preinit_mt9m111[][4] = |
@@ -117,7 +137,14 @@ static const unsigned char preinit_mt9m111[][4] = | |||
117 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | 137 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, |
118 | 138 | ||
119 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | 139 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, |
120 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7}, | 140 | {SENSOR, MT9M111_SC_RESET, |
141 | MT9M111_RESET | | ||
142 | MT9M111_RESTART | | ||
143 | MT9M111_ANALOG_STANDBY | | ||
144 | MT9M111_CHIP_DISABLE, | ||
145 | MT9M111_SHOW_BAD_FRAMES | | ||
146 | MT9M111_RESTART_BAD_FRAMES | | ||
147 | MT9M111_SYNCHRONIZE_CHANGES}, | ||
121 | 148 | ||
122 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | 149 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, |
123 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | 150 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, |
@@ -145,731 +172,42 @@ static const unsigned char init_mt9m111[][4] = | |||
145 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 172 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
146 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 173 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
147 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 174 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
148 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00}, | ||
149 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00}, | ||
150 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
151 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | 175 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, |
152 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
153 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
154 | |||
155 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
156 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, | ||
157 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, | ||
158 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xde}, | ||
159 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xff}, | ||
160 | {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7}, | ||
161 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
162 | 176 | ||
163 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
164 | |||
165 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0xff, 0xff}, | ||
166 | |||
167 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
168 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
169 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
170 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
171 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
172 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
173 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
174 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
175 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
176 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
177 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
178 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
179 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
180 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
181 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
182 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
183 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
184 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
185 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | 177 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, |
186 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | 178 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, |
187 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
188 | |||
189 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
190 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
191 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
192 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
193 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
194 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
195 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
196 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
197 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
198 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
199 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
200 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
201 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
202 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
203 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
204 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
205 | |||
206 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
207 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
208 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
209 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
210 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
211 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
212 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
213 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
214 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
215 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
216 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
217 | {SENSOR, 0x33, 0x03, 0x49}, | ||
218 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
219 | |||
220 | {SENSOR, 0x33, 0x03, 0x49}, | ||
221 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
222 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
223 | {SENSOR, 0x40, 0x20, 0x20}, | ||
224 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
225 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
226 | {SENSOR, 0x71, 0xff, 0x00}, | ||
227 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
228 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
229 | {SENSOR, 0x74, 0x57, 0x32}, | ||
230 | {SENSOR, 0x75, 0x56, 0x34}, | ||
231 | {SENSOR, 0x76, 0x73, 0x35}, | ||
232 | {SENSOR, 0x77, 0x30, 0x12}, | ||
233 | {SENSOR, 0x78, 0x79, 0x02}, | ||
234 | {SENSOR, 0x79, 0x75, 0x06}, | ||
235 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
236 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
237 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
238 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
239 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
240 | {SENSOR, 0x80, 0x59, 0x04}, | ||
241 | {SENSOR, 0x81, 0x59, 0x04}, | ||
242 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
243 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
244 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
245 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
246 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
247 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
248 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
249 | {SENSOR, 0x60, 0x00, 0x80}, | ||
250 | {SENSOR, 0x61, 0x00, 0x00}, | ||
251 | {SENSOR, 0x62, 0x00, 0x00}, | ||
252 | {SENSOR, 0x63, 0x00, 0x00}, | ||
253 | {SENSOR, 0x64, 0x00, 0x00}, | ||
254 | |||
255 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
256 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, | ||
257 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, | ||
258 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, | ||
259 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, | ||
260 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
261 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, | ||
262 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
263 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, | ||
264 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, | ||
265 | {SENSOR, 0x30, 0x04, 0x00}, | ||
266 | |||
267 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
268 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
269 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
270 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
271 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
272 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
273 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
274 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
275 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
276 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
277 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
278 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
279 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
280 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
281 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
282 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
283 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
284 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
285 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
286 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
287 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
288 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
289 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
290 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, | ||
291 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
292 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, | ||
293 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, | ||
294 | |||
295 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
296 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
297 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
298 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
299 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
300 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
301 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
302 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
303 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
304 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
305 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
306 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
307 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
308 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
309 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
310 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
311 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
312 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
313 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
314 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
315 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
316 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
317 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
318 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
319 | |||
320 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
321 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
322 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
323 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
324 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
325 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
326 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
327 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
328 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
329 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
330 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | 179 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, |
331 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
332 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | 180 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, |
333 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
334 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
335 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | 181 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, |
336 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
337 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
338 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
339 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
340 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
341 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
342 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
343 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
344 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
345 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
346 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
347 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
348 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
349 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
350 | |||
351 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
352 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
353 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
354 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
355 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
356 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
357 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
358 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
359 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
360 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
361 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
362 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
363 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
364 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
365 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
366 | |||
367 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
368 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
369 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
370 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
371 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
372 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
373 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
374 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
375 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
376 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
377 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
378 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
379 | {SENSOR, 0x33, 0x03, 0x49}, | ||
380 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
381 | |||
382 | {SENSOR, 0x33, 0x03, 0x49}, | ||
383 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
384 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
385 | {SENSOR, 0x40, 0x20, 0x20}, | ||
386 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
387 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
388 | {SENSOR, 0x71, 0xff, 0x00}, | ||
389 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
390 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
391 | {SENSOR, 0x74, 0x57, 0x32}, | ||
392 | {SENSOR, 0x75, 0x56, 0x34}, | ||
393 | {SENSOR, 0x76, 0x73, 0x35}, | ||
394 | {SENSOR, 0x77, 0x30, 0x12}, | ||
395 | {SENSOR, 0x78, 0x79, 0x02}, | ||
396 | {SENSOR, 0x79, 0x75, 0x06}, | ||
397 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
398 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
399 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
400 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
401 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
402 | {SENSOR, 0x80, 0x59, 0x04}, | ||
403 | {SENSOR, 0x81, 0x59, 0x04}, | ||
404 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
405 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
406 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
407 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
408 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
409 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
410 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
411 | {SENSOR, 0x60, 0x00, 0x80}, | ||
412 | {SENSOR, 0x61, 0x00, 0x00}, | ||
413 | {SENSOR, 0x62, 0x00, 0x00}, | ||
414 | {SENSOR, 0x63, 0x00, 0x00}, | ||
415 | {SENSOR, 0x64, 0x00, 0x00}, | ||
416 | |||
417 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
418 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, | ||
419 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, | ||
420 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, | ||
421 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, | ||
422 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
423 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, | ||
424 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
425 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, | ||
426 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, | ||
427 | {SENSOR, 0x30, 0x04, 0x00}, | ||
428 | |||
429 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
430 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
431 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
432 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
433 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
434 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
435 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
436 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
437 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
438 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
439 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
440 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
441 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
442 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
443 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
444 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
445 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
446 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
447 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
448 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
449 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
450 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
451 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
452 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, | ||
453 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
454 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, | ||
455 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, | ||
456 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
457 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
458 | |||
459 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
460 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
461 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
462 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
463 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
464 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
465 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
466 | |||
467 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
468 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
469 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
470 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
471 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
472 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
473 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | 182 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, |
474 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
475 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
476 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | 183 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, |
477 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
478 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
479 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
480 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
481 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
482 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
483 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
484 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
485 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | 184 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, |
486 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | 185 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, |
487 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
488 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
489 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | 186 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, |
490 | 187 | ||
491 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
492 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
493 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
494 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | 188 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, |
495 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | 189 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, |
496 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | 190 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, |
497 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | 191 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, |
498 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | 192 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, |
193 | MT9M111_CP_OPERATING_MODE_CTL}, | ||
499 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | 194 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, |
500 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | 195 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, |
501 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | 196 | MT9M111_2D_DEFECT_CORRECTION_ENABLE}, |
197 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, | ||
198 | MT9M111_2D_DEFECT_CORRECTION_ENABLE}, | ||
502 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | 199 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, |
503 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | 200 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, |
504 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | 201 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, |
505 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | 202 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, |
506 | |||
507 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
508 | {SENSOR, 0xcd, 0x00, 0x0e}, | 203 | {SENSOR, 0xcd, 0x00, 0x0e}, |
509 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
510 | {SENSOR, 0xd0, 0x00, 0x40}, | 204 | {SENSOR, 0xd0, 0x00, 0x40}, |
511 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
512 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
513 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
514 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
515 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
516 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
517 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
518 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
519 | {SENSOR, 0x33, 0x03, 0x49}, | ||
520 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
521 | |||
522 | {SENSOR, 0x33, 0x03, 0x49}, | ||
523 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
524 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
525 | {SENSOR, 0x40, 0x20, 0x20}, | ||
526 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
527 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
528 | {SENSOR, 0x71, 0xff, 0x00}, | ||
529 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
530 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
531 | {SENSOR, 0x74, 0x57, 0x32}, | ||
532 | {SENSOR, 0x75, 0x56, 0x34}, | ||
533 | {SENSOR, 0x76, 0x73, 0x35}, | ||
534 | {SENSOR, 0x77, 0x30, 0x12}, | ||
535 | {SENSOR, 0x78, 0x79, 0x02}, | ||
536 | {SENSOR, 0x79, 0x75, 0x06}, | ||
537 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
538 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
539 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
540 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
541 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
542 | {SENSOR, 0x80, 0x59, 0x04}, | ||
543 | {SENSOR, 0x81, 0x59, 0x04}, | ||
544 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
545 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
546 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
547 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
548 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
549 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
550 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
551 | {SENSOR, 0x60, 0x00, 0x80}, | ||
552 | {SENSOR, 0x61, 0x00, 0x00}, | ||
553 | {SENSOR, 0x62, 0x00, 0x00}, | ||
554 | {SENSOR, 0x63, 0x00, 0x00}, | ||
555 | {SENSOR, 0x64, 0x00, 0x00}, | ||
556 | 205 | ||
557 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
558 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18}, | ||
559 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04}, | ||
560 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08}, | ||
561 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38}, | ||
562 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
563 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38}, | ||
564 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
565 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03}, | ||
566 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03}, | ||
567 | {SENSOR, 0x30, 0x04, 0x00}, | ||
568 | |||
569 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
570 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
571 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
572 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
573 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
574 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
575 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
576 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
577 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
578 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
579 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
580 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
581 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, | ||
582 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
583 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
584 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
585 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
586 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, | ||
587 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00}, | ||
588 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
589 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
590 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, | ||
591 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
592 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4}, | ||
593 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea}, | ||
594 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
595 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
596 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
597 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
598 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
599 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
600 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
601 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
602 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
603 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
604 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
605 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
606 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
607 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
608 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
609 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
610 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
611 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
612 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
613 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
614 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
615 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
616 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
617 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
618 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
619 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
620 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
621 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
622 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
623 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
624 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
625 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
626 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
627 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
628 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
629 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
630 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
631 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
632 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
633 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
634 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
635 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
636 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
637 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
638 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
639 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
640 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
641 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
642 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
643 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
644 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
645 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
646 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
647 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
648 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
649 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
650 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
651 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
652 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
653 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
654 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
655 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
656 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
657 | |||
658 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
659 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
660 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
661 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
662 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
663 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
664 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
665 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
666 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
667 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
668 | |||
669 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
670 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
671 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
672 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
673 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
674 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
675 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
676 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
677 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | 206 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, |
678 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | 207 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, |
679 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
680 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
681 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
682 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
683 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
684 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
685 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
686 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | 208 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, |
687 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
688 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
689 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
690 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
691 | {SENSOR, 0x33, 0x03, 0x49}, | ||
692 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
693 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
694 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
695 | |||
696 | {SENSOR, 0x33, 0x03, 0x49}, | ||
697 | {SENSOR, 0x34, 0xc0, 0x19}, | ||
698 | {SENSOR, 0x3f, 0x20, 0x20}, | ||
699 | {SENSOR, 0x40, 0x20, 0x20}, | ||
700 | {SENSOR, 0x5a, 0xc0, 0x0a}, | ||
701 | {SENSOR, 0x70, 0x7b, 0x0a}, | ||
702 | {SENSOR, 0x71, 0xff, 0x00}, | ||
703 | {SENSOR, 0x72, 0x19, 0x0e}, | ||
704 | {SENSOR, 0x73, 0x18, 0x0f}, | ||
705 | {SENSOR, 0x74, 0x57, 0x32}, | ||
706 | {SENSOR, 0x75, 0x56, 0x34}, | ||
707 | {SENSOR, 0x76, 0x73, 0x35}, | ||
708 | {SENSOR, 0x77, 0x30, 0x12}, | ||
709 | {SENSOR, 0x78, 0x79, 0x02}, | ||
710 | {SENSOR, 0x79, 0x75, 0x06}, | ||
711 | {SENSOR, 0x7a, 0x77, 0x0a}, | ||
712 | {SENSOR, 0x7b, 0x78, 0x09}, | ||
713 | {SENSOR, 0x7c, 0x7d, 0x06}, | ||
714 | {SENSOR, 0x7d, 0x31, 0x10}, | ||
715 | {SENSOR, 0x7e, 0x00, 0x7e}, | ||
716 | {SENSOR, 0x80, 0x59, 0x04}, | ||
717 | {SENSOR, 0x81, 0x59, 0x04}, | ||
718 | {SENSOR, 0x82, 0x57, 0x0a}, | ||
719 | {SENSOR, 0x83, 0x58, 0x0b}, | ||
720 | {SENSOR, 0x84, 0x47, 0x0c}, | ||
721 | {SENSOR, 0x85, 0x48, 0x0e}, | ||
722 | {SENSOR, 0x86, 0x5b, 0x02}, | ||
723 | {SENSOR, 0x87, 0x00, 0x5c}, | ||
724 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | ||
725 | {SENSOR, 0x60, 0x00, 0x80}, | ||
726 | {SENSOR, 0x61, 0x00, 0x00}, | ||
727 | {SENSOR, 0x62, 0x00, 0x00}, | ||
728 | {SENSOR, 0x63, 0x00, 0x00}, | ||
729 | {SENSOR, 0x64, 0x00, 0x00}, | ||
730 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | ||
731 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, | ||
732 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, | ||
733 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, | ||
734 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, | ||
735 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | ||
736 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, | ||
737 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | ||
738 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, | ||
739 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, | ||
740 | {SENSOR, 0x30, 0x04, 0x00}, | ||
741 | |||
742 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
743 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
744 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
745 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
746 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
747 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
748 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
749 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
750 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
751 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
752 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
753 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
754 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe3, 0x00}, | ||
755 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
756 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
757 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
758 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
759 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
760 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
761 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
762 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, | ||
763 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
764 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
765 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
766 | |||
767 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
768 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, | ||
769 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xe6}, | ||
770 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
771 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
772 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
773 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
774 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
775 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
776 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x09}, | ||
777 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
778 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
779 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
780 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
781 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
782 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
783 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
784 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
785 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
786 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
787 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
788 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c}, | ||
789 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
790 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
791 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
792 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x04}, | ||
793 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
794 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
795 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00}, | ||
796 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
797 | {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03}, | ||
798 | 209 | ||
799 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, | ||
800 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, | ||
801 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00}, | ||
802 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, | ||
803 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, | ||
804 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
805 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
806 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
807 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00}, | ||
808 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
809 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
810 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
811 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
812 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
813 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
814 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
815 | {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, | ||
816 | {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, | ||
817 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
818 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
819 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, | ||
820 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
821 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
822 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
823 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
824 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x05}, | ||
825 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | 210 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, |
826 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
827 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
828 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
829 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, | ||
830 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
831 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
832 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00}, | ||
833 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
834 | {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, | ||
835 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, | ||
836 | {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, | ||
837 | {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, | ||
838 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, | ||
839 | {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, | ||
840 | {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, | ||
841 | {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, | ||
842 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, | ||
843 | {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, | ||
844 | |||
845 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
846 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00}, | ||
847 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
848 | {SENSOR, 0xcd, 0x00, 0x0e}, | ||
849 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
850 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00}, | ||
851 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
852 | {SENSOR, 0xd0, 0x00, 0x40}, | ||
853 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, | ||
854 | {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, | ||
855 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
856 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
857 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
858 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07}, | ||
859 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
860 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00}, | ||
861 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
862 | {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, | ||
863 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
864 | |||
865 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
866 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
867 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
868 | {SENSOR, 0x33, 0x03, 0x49}, | ||
869 | {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00}, | ||
870 | {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00}, | ||
871 | {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00}, | ||
872 | |||
873 | {SENSOR, 0x33, 0x03, 0x49}, | 211 | {SENSOR, 0x33, 0x03, 0x49}, |
874 | {SENSOR, 0x34, 0xc0, 0x19}, | 212 | {SENSOR, 0x34, 0xc0, 0x19}, |
875 | {SENSOR, 0x3f, 0x20, 0x20}, | 213 | {SENSOR, 0x3f, 0x20, 0x20}, |
@@ -898,25 +236,29 @@ static const unsigned char init_mt9m111[][4] = | |||
898 | {SENSOR, 0x85, 0x48, 0x0e}, | 236 | {SENSOR, 0x85, 0x48, 0x0e}, |
899 | {SENSOR, 0x86, 0x5b, 0x02}, | 237 | {SENSOR, 0x86, 0x5b, 0x02}, |
900 | {SENSOR, 0x87, 0x00, 0x5c}, | 238 | {SENSOR, 0x87, 0x00, 0x5c}, |
901 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, | 239 | {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B}, |
902 | {SENSOR, 0x60, 0x00, 0x80}, | 240 | {SENSOR, 0x60, 0x00, 0x80}, |
903 | {SENSOR, 0x61, 0x00, 0x00}, | 241 | {SENSOR, 0x61, 0x00, 0x00}, |
904 | {SENSOR, 0x62, 0x00, 0x00}, | 242 | {SENSOR, 0x62, 0x00, 0x00}, |
905 | {SENSOR, 0x63, 0x00, 0x00}, | 243 | {SENSOR, 0x63, 0x00, 0x00}, |
906 | {SENSOR, 0x64, 0x00, 0x00}, | 244 | {SENSOR, 0x64, 0x00, 0x00}, |
907 | 245 | ||
908 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, | 246 | {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */ |
909 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, | 247 | {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */ |
910 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, | 248 | {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */ |
911 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, | 249 | {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */ |
912 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, | 250 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */ |
913 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, | 251 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */ |
914 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, | 252 | {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */ |
915 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, | 253 | {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */ |
916 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, | 254 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */ |
917 | {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, | ||
918 | {SENSOR, 0x30, 0x04, 0x00}, | 255 | {SENSOR, 0x30, 0x04, 0x00}, |
256 | /* Set number of blank rows chosen to 400 */ | ||
257 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, | ||
258 | }; | ||
919 | 259 | ||
260 | static const unsigned char start_mt9m111[][4] = | ||
261 | { | ||
920 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 262 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
921 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 263 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
922 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 264 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -928,25 +270,6 @@ static const unsigned char init_mt9m111[][4] = | |||
928 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 270 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
929 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 271 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
930 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 272 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
931 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
932 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, | ||
933 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
934 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
935 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
936 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
937 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
938 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
939 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, /* 639*/ | ||
940 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, | ||
941 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
942 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
943 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
944 | |||
945 | {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, | ||
946 | /* Set number of blank rows chosen to 400 */ | ||
947 | {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90}, | ||
948 | /* Set the global gain to 283 (of 512) */ | ||
949 | {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x03, 0x63} | ||
950 | }; | 273 | }; |
951 | 274 | ||
952 | #endif | 275 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c new file mode 100644 index 000000000000..7aafeb7cfa07 --- /dev/null +++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | * Driver for the ov7660 sensor | ||
3 | * | ||
4 | * Copyright (C) 2009 Erik Andrén | ||
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | ||
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | ||
7 | * | ||
8 | * Portions of code to USB interface and ALi driver software, | ||
9 | * Copyright (c) 2006 Willem Duinker | ||
10 | * v4l2 interface modeled after the V4L2 driver | ||
11 | * for SN9C10x PC Camera Controllers | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License as | ||
15 | * published by the Free Software Foundation, version 2. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include "m5602_ov7660.h" | ||
20 | |||
21 | static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
22 | static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | |||
24 | const static struct ctrl ov7660_ctrls[] = { | ||
25 | #define GAIN_IDX 1 | ||
26 | { | ||
27 | { | ||
28 | .id = V4L2_CID_GAIN, | ||
29 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
30 | .name = "gain", | ||
31 | .minimum = 0x00, | ||
32 | .maximum = 0xff, | ||
33 | .step = 0x1, | ||
34 | .default_value = OV7660_DEFAULT_GAIN, | ||
35 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
36 | }, | ||
37 | .set = ov7660_set_gain, | ||
38 | .get = ov7660_get_gain | ||
39 | }, | ||
40 | }; | ||
41 | |||
42 | static struct v4l2_pix_format ov7660_modes[] = { | ||
43 | { | ||
44 | 640, | ||
45 | 480, | ||
46 | V4L2_PIX_FMT_SBGGR8, | ||
47 | V4L2_FIELD_NONE, | ||
48 | .sizeimage = | ||
49 | 640 * 480, | ||
50 | .bytesperline = 640, | ||
51 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
52 | .priv = 0 | ||
53 | } | ||
54 | }; | ||
55 | |||
56 | static void ov7660_dump_registers(struct sd *sd); | ||
57 | |||
58 | int ov7660_probe(struct sd *sd) | ||
59 | { | ||
60 | int err = 0, i; | ||
61 | u8 prod_id = 0, ver_id = 0; | ||
62 | |||
63 | s32 *sensor_settings; | ||
64 | |||
65 | if (force_sensor) { | ||
66 | if (force_sensor == OV7660_SENSOR) { | ||
67 | info("Forcing an %s sensor", ov7660.name); | ||
68 | goto sensor_found; | ||
69 | } | ||
70 | /* If we want to force another sensor, | ||
71 | don't try to probe this one */ | ||
72 | return -ENODEV; | ||
73 | } | ||
74 | |||
75 | /* Do the preinit */ | ||
76 | for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) { | ||
77 | u8 data[2]; | ||
78 | |||
79 | if (preinit_ov7660[i][0] == BRIDGE) { | ||
80 | err = m5602_write_bridge(sd, | ||
81 | preinit_ov7660[i][1], | ||
82 | preinit_ov7660[i][2]); | ||
83 | } else { | ||
84 | data[0] = preinit_ov7660[i][2]; | ||
85 | err = m5602_write_sensor(sd, | ||
86 | preinit_ov7660[i][1], data, 1); | ||
87 | } | ||
88 | } | ||
89 | if (err < 0) | ||
90 | return err; | ||
91 | |||
92 | if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1)) | ||
93 | return -ENODEV; | ||
94 | |||
95 | if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1)) | ||
96 | return -ENODEV; | ||
97 | |||
98 | info("Sensor reported 0x%x%x", prod_id, ver_id); | ||
99 | |||
100 | if ((prod_id == 0x76) && (ver_id == 0x60)) { | ||
101 | info("Detected a ov7660 sensor"); | ||
102 | goto sensor_found; | ||
103 | } | ||
104 | return -ENODEV; | ||
105 | |||
106 | sensor_found: | ||
107 | sensor_settings = kmalloc( | ||
108 | ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL); | ||
109 | if (!sensor_settings) | ||
110 | return -ENOMEM; | ||
111 | |||
112 | sd->gspca_dev.cam.cam_mode = ov7660_modes; | ||
113 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes); | ||
114 | sd->desc->ctrls = ov7660_ctrls; | ||
115 | sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls); | ||
116 | |||
117 | for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++) | ||
118 | sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value; | ||
119 | sd->sensor_priv = sensor_settings; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | int ov7660_init(struct sd *sd) | ||
125 | { | ||
126 | int i, err = 0; | ||
127 | s32 *sensor_settings = sd->sensor_priv; | ||
128 | |||
129 | /* Init the sensor */ | ||
130 | for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) { | ||
131 | u8 data[2]; | ||
132 | |||
133 | if (init_ov7660[i][0] == BRIDGE) { | ||
134 | err = m5602_write_bridge(sd, | ||
135 | init_ov7660[i][1], | ||
136 | init_ov7660[i][2]); | ||
137 | } else { | ||
138 | data[0] = init_ov7660[i][2]; | ||
139 | err = m5602_write_sensor(sd, | ||
140 | init_ov7660[i][1], data, 1); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | if (dump_sensor) | ||
145 | ov7660_dump_registers(sd); | ||
146 | |||
147 | err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
148 | if (err < 0) | ||
149 | return err; | ||
150 | |||
151 | return err; | ||
152 | } | ||
153 | |||
154 | int ov7660_start(struct sd *sd) | ||
155 | { | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | int ov7660_stop(struct sd *sd) | ||
160 | { | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | void ov7660_disconnect(struct sd *sd) | ||
165 | { | ||
166 | ov7660_stop(sd); | ||
167 | |||
168 | sd->sensor = NULL; | ||
169 | kfree(sd->sensor_priv); | ||
170 | } | ||
171 | |||
172 | static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | ||
173 | { | ||
174 | struct sd *sd = (struct sd *) gspca_dev; | ||
175 | s32 *sensor_settings = sd->sensor_priv; | ||
176 | |||
177 | *val = sensor_settings[GAIN_IDX]; | ||
178 | PDEBUG(D_V4L2, "Read gain %d", *val); | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
183 | { | ||
184 | int err; | ||
185 | u8 i2c_data; | ||
186 | struct sd *sd = (struct sd *) gspca_dev; | ||
187 | s32 *sensor_settings = sd->sensor_priv; | ||
188 | |||
189 | PDEBUG(D_V4L2, "Setting gain to %d", val); | ||
190 | |||
191 | sensor_settings[GAIN_IDX] = val; | ||
192 | |||
193 | err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1); | ||
194 | return err; | ||
195 | } | ||
196 | |||
197 | static void ov7660_dump_registers(struct sd *sd) | ||
198 | { | ||
199 | int address; | ||
200 | info("Dumping the ov7660 register state"); | ||
201 | for (address = 0; address < 0xa9; address++) { | ||
202 | u8 value; | ||
203 | m5602_read_sensor(sd, address, &value, 1); | ||
204 | info("register 0x%x contains 0x%x", | ||
205 | address, value); | ||
206 | } | ||
207 | |||
208 | info("ov7660 register state dump complete"); | ||
209 | |||
210 | info("Probing for which registers that are read/write"); | ||
211 | for (address = 0; address < 0xff; address++) { | ||
212 | u8 old_value, ctrl_value; | ||
213 | u8 test_value[2] = {0xff, 0xff}; | ||
214 | |||
215 | m5602_read_sensor(sd, address, &old_value, 1); | ||
216 | m5602_write_sensor(sd, address, test_value, 1); | ||
217 | m5602_read_sensor(sd, address, &ctrl_value, 1); | ||
218 | |||
219 | if (ctrl_value == test_value[0]) | ||
220 | info("register 0x%x is writeable", address); | ||
221 | else | ||
222 | info("register 0x%x is read only", address); | ||
223 | |||
224 | /* Restore original value */ | ||
225 | m5602_write_sensor(sd, address, &old_value, 1); | ||
226 | } | ||
227 | } | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h new file mode 100644 index 000000000000..3f2c169a93ea --- /dev/null +++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h | |||
@@ -0,0 +1,279 @@ | |||
1 | /* | ||
2 | * Driver for the ov7660 sensor | ||
3 | * | ||
4 | * Copyright (C) 2009 Erik Andrén | ||
5 | * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. | ||
6 | * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> | ||
7 | * | ||
8 | * Portions of code to USB interface and ALi driver software, | ||
9 | * Copyright (c) 2006 Willem Duinker | ||
10 | * v4l2 interface modeled after the V4L2 driver | ||
11 | * for SN9C10x PC Camera Controllers | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License as | ||
15 | * published by the Free Software Foundation, version 2. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #ifndef M5602_OV7660_H_ | ||
20 | #define M5602_OV7660_H_ | ||
21 | |||
22 | #include "m5602_sensor.h" | ||
23 | |||
24 | #define OV7660_GAIN 0x00 | ||
25 | #define OV7660_BLUE_GAIN 0x01 | ||
26 | #define OV7660_RED_GAIN 0x02 | ||
27 | #define OV7660_VREF 0x03 | ||
28 | #define OV7660_COM1 0x04 | ||
29 | #define OV7660_BAVE 0x05 | ||
30 | #define OV7660_GEAVE 0x06 | ||
31 | #define OV7660_AECHH 0x07 | ||
32 | #define OV7660_RAVE 0x08 | ||
33 | #define OV7660_COM2 0x09 | ||
34 | #define OV7660_PID 0x0a | ||
35 | #define OV7660_VER 0x0b | ||
36 | #define OV7660_COM3 0x0c | ||
37 | #define OV7660_COM4 0x0d | ||
38 | #define OV7660_COM5 0x0e | ||
39 | #define OV7660_COM6 0x0f | ||
40 | #define OV7660_AECH 0x10 | ||
41 | #define OV7660_CLKRC 0x11 | ||
42 | #define OV7660_COM7 0x12 | ||
43 | #define OV7660_COM8 0x13 | ||
44 | #define OV7660_COM9 0x14 | ||
45 | #define OV7660_COM10 0x15 | ||
46 | #define OV7660_RSVD16 0x16 | ||
47 | #define OV7660_HSTART 0x17 | ||
48 | #define OV7660_HSTOP 0x18 | ||
49 | #define OV7660_VSTART 0x19 | ||
50 | #define OV7660_VSTOP 0x1a | ||
51 | #define OV7660_PSHFT 0x1b | ||
52 | #define OV7660_MIDH 0x1c | ||
53 | #define OV7660_MIDL 0x1d | ||
54 | #define OV7660_MVFP 0x1e | ||
55 | #define OV7660_LAEC 0x1f | ||
56 | #define OV7660_BOS 0x20 | ||
57 | #define OV7660_GBOS 0x21 | ||
58 | #define OV7660_GROS 0x22 | ||
59 | #define OV7660_ROS 0x23 | ||
60 | #define OV7660_AEW 0x24 | ||
61 | #define OV7660_AEB 0x25 | ||
62 | #define OV7660_VPT 0x26 | ||
63 | #define OV7660_BBIAS 0x27 | ||
64 | #define OV7660_GbBIAS 0x28 | ||
65 | #define OV7660_RSVD29 0x29 | ||
66 | #define OV7660_RBIAS 0x2c | ||
67 | #define OV7660_HREF 0x32 | ||
68 | #define OV7660_ADC 0x37 | ||
69 | #define OV7660_OFON 0x39 | ||
70 | #define OV7660_TSLB 0x3a | ||
71 | #define OV7660_COM12 0x3c | ||
72 | #define OV7660_COM13 0x3d | ||
73 | #define OV7660_LCC1 0x62 | ||
74 | #define OV7660_LCC2 0x63 | ||
75 | #define OV7660_LCC3 0x64 | ||
76 | #define OV7660_LCC4 0x65 | ||
77 | #define OV7660_LCC5 0x66 | ||
78 | #define OV7660_HV 0x69 | ||
79 | #define OV7660_RSVDA1 0xa1 | ||
80 | |||
81 | #define OV7660_DEFAULT_GAIN 0x0e | ||
82 | #define OV7660_DEFAULT_RED_GAIN 0x80 | ||
83 | #define OV7660_DEFAULT_BLUE_GAIN 0x80 | ||
84 | #define OV7660_DEFAULT_SATURATION 0x00 | ||
85 | #define OV7660_DEFAULT_EXPOSURE 0x20 | ||
86 | |||
87 | /* Kernel module parameters */ | ||
88 | extern int force_sensor; | ||
89 | extern int dump_sensor; | ||
90 | |||
91 | int ov7660_probe(struct sd *sd); | ||
92 | int ov7660_init(struct sd *sd); | ||
93 | int ov7660_start(struct sd *sd); | ||
94 | int ov7660_stop(struct sd *sd); | ||
95 | void ov7660_disconnect(struct sd *sd); | ||
96 | |||
97 | const static struct m5602_sensor ov7660 = { | ||
98 | .name = "ov7660", | ||
99 | .i2c_slave_id = 0x42, | ||
100 | .i2c_regW = 1, | ||
101 | .probe = ov7660_probe, | ||
102 | .init = ov7660_init, | ||
103 | .start = ov7660_start, | ||
104 | .stop = ov7660_stop, | ||
105 | .disconnect = ov7660_disconnect, | ||
106 | }; | ||
107 | |||
108 | static const unsigned char preinit_ov7660[][4] = | ||
109 | { | ||
110 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | ||
111 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | ||
112 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
113 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
114 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
115 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
116 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | ||
117 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
118 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
119 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
120 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
121 | |||
122 | {SENSOR, OV7660_OFON, 0x0c}, | ||
123 | {SENSOR, OV7660_COM2, 0x11}, | ||
124 | {SENSOR, OV7660_COM7, 0x05}, | ||
125 | |||
126 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
127 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
128 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
129 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
130 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
131 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
132 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
133 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
134 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
135 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
136 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
137 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
138 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | ||
139 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
140 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00} | ||
141 | }; | ||
142 | |||
143 | static const unsigned char init_ov7660[][4] = | ||
144 | { | ||
145 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | ||
146 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | ||
147 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
148 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
149 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
150 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
151 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | ||
152 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
153 | {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, | ||
154 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
155 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
156 | |||
157 | {SENSOR, OV7660_OFON, 0x0c}, | ||
158 | {SENSOR, OV7660_COM2, 0x11}, | ||
159 | {SENSOR, OV7660_COM7, 0x05}, | ||
160 | |||
161 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
162 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
163 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
164 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
165 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
166 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
167 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
168 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
169 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
170 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
171 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
172 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
173 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | ||
174 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
175 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
176 | |||
177 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02}, | ||
178 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
179 | |||
180 | {SENSOR, OV7660_AECH, OV7660_DEFAULT_EXPOSURE}, | ||
181 | {SENSOR, OV7660_COM1, 0x00}, | ||
182 | |||
183 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
184 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
185 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
186 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
187 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
188 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
189 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
190 | |||
191 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
192 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
193 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
194 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
195 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
196 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | ||
197 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
198 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
199 | |||
200 | {SENSOR, OV7660_COM7, 0x80}, | ||
201 | {SENSOR, OV7660_CLKRC, 0x80}, | ||
202 | {SENSOR, OV7660_BLUE_GAIN, 0x80}, | ||
203 | {SENSOR, OV7660_RED_GAIN, 0x80}, | ||
204 | {SENSOR, OV7660_COM9, 0x4c}, | ||
205 | {SENSOR, OV7660_OFON, 0x43}, | ||
206 | {SENSOR, OV7660_COM12, 0x28}, | ||
207 | {SENSOR, OV7660_COM8, 0x00}, | ||
208 | {SENSOR, OV7660_COM10, 0x40}, | ||
209 | {SENSOR, OV7660_HSTART, 0x0c}, | ||
210 | {SENSOR, OV7660_HSTOP, 0x61}, | ||
211 | {SENSOR, OV7660_HREF, 0xa4}, | ||
212 | {SENSOR, OV7660_PSHFT, 0x0b}, | ||
213 | {SENSOR, OV7660_VSTART, 0x01}, | ||
214 | {SENSOR, OV7660_VSTOP, 0x7a}, | ||
215 | {SENSOR, OV7660_VREF, 0x00}, | ||
216 | {SENSOR, OV7660_COM7, 0x05}, | ||
217 | {SENSOR, OV7660_COM6, 0x4b}, | ||
218 | {SENSOR, OV7660_BBIAS, 0x98}, | ||
219 | {SENSOR, OV7660_GbBIAS, 0x98}, | ||
220 | {SENSOR, OV7660_RSVD29, 0x98}, | ||
221 | {SENSOR, OV7660_RBIAS, 0x98}, | ||
222 | {SENSOR, OV7660_COM1, 0x00}, | ||
223 | {SENSOR, OV7660_AECH, 0x00}, | ||
224 | {SENSOR, OV7660_AECHH, 0x00}, | ||
225 | {SENSOR, OV7660_ADC, 0x04}, | ||
226 | {SENSOR, OV7660_COM13, 0x00}, | ||
227 | {SENSOR, OV7660_RSVDA1, 0x23}, | ||
228 | {SENSOR, OV7660_TSLB, 0x0d}, | ||
229 | {SENSOR, OV7660_HV, 0x80}, | ||
230 | {SENSOR, OV7660_LCC1, 0x00}, | ||
231 | {SENSOR, OV7660_LCC2, 0x00}, | ||
232 | {SENSOR, OV7660_LCC3, 0x10}, | ||
233 | {SENSOR, OV7660_LCC4, 0x40}, | ||
234 | {SENSOR, OV7660_LCC5, 0x01}, | ||
235 | |||
236 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
237 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
238 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
239 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
240 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
241 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
242 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
243 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
244 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x08}, | ||
245 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
246 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
247 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
248 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */ | ||
249 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
250 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
251 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
252 | {BRIDGE, M5602_XB_SIG_INI, 0x02}, | ||
253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */ | ||
255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
256 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */ | ||
257 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
258 | |||
259 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
260 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
261 | |||
262 | {SENSOR, OV7660_AECH, 0x20}, | ||
263 | {SENSOR, OV7660_COM1, 0x00}, | ||
264 | {SENSOR, OV7660_OFON, 0x0c}, | ||
265 | {SENSOR, OV7660_COM2, 0x11}, | ||
266 | {SENSOR, OV7660_COM7, 0x05}, | ||
267 | {SENSOR, OV7660_BLUE_GAIN, 0x80}, | ||
268 | {SENSOR, OV7660_RED_GAIN, 0x80}, | ||
269 | |||
270 | {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, | ||
271 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
272 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
273 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
274 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, | ||
275 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, | ||
276 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0} | ||
277 | }; | ||
278 | |||
279 | #endif | ||
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index fc4548fd441d..c2739d6605a1 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -18,44 +18,87 @@ | |||
18 | 18 | ||
19 | #include "m5602_ov9650.h" | 19 | #include "m5602_ov9650.h" |
20 | 20 | ||
21 | static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
22 | static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
23 | static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
29 | static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
30 | static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
31 | static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, | ||
34 | __s32 *val); | ||
35 | static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, | ||
36 | __s32 val); | ||
37 | static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
38 | static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
39 | static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
40 | static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
41 | |||
21 | /* Vertically and horizontally flips the image if matched, needed for machines | 42 | /* Vertically and horizontally flips the image if matched, needed for machines |
22 | where the sensor is mounted upside down */ | 43 | where the sensor is mounted upside down */ |
23 | static | 44 | static |
24 | const | 45 | const |
25 | struct dmi_system_id ov9650_flip_dmi_table[] = { | 46 | struct dmi_system_id ov9650_flip_dmi_table[] = { |
26 | { | 47 | { |
27 | .ident = "ASUS A6VC", | 48 | .ident = "ASUS A6Ja", |
28 | .matches = { | 49 | .matches = { |
29 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 50 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
30 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") | 51 | DMI_MATCH(DMI_PRODUCT_NAME, "A6J") |
31 | } | 52 | } |
32 | }, | 53 | }, |
33 | { | 54 | { |
34 | .ident = "ASUS A6VM", | 55 | .ident = "ASUS A6JC", |
35 | .matches = { | 56 | .matches = { |
36 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 57 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
37 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") | 58 | DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") |
38 | } | 59 | } |
39 | }, | 60 | }, |
40 | { | 61 | { |
41 | .ident = "ASUS A6JC", | 62 | .ident = "ASUS A6K", |
42 | .matches = { | 63 | .matches = { |
43 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 64 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
44 | DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") | 65 | DMI_MATCH(DMI_PRODUCT_NAME, "A6K") |
45 | } | 66 | } |
46 | }, | 67 | }, |
47 | { | 68 | { |
48 | .ident = "ASUS A6Ja", | 69 | .ident = "ASUS A6Kt", |
49 | .matches = { | 70 | .matches = { |
50 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 71 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
51 | DMI_MATCH(DMI_PRODUCT_NAME, "A6J") | 72 | DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") |
52 | } | 73 | } |
53 | }, | 74 | }, |
54 | { | 75 | { |
55 | .ident = "ASUS A6Kt", | 76 | .ident = "ASUS A6VA", |
56 | .matches = { | 77 | .matches = { |
57 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 78 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
58 | DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") | 79 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VA") |
80 | } | ||
81 | }, | ||
82 | { | ||
83 | |||
84 | .ident = "ASUS A6VC", | ||
85 | .matches = { | ||
86 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
87 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") | ||
88 | } | ||
89 | }, | ||
90 | { | ||
91 | .ident = "ASUS A6VM", | ||
92 | .matches = { | ||
93 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
94 | DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") | ||
95 | } | ||
96 | }, | ||
97 | { | ||
98 | .ident = "ASUS A7V", | ||
99 | .matches = { | ||
100 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
101 | DMI_MATCH(DMI_PRODUCT_NAME, "A7V") | ||
59 | } | 102 | } |
60 | }, | 103 | }, |
61 | { | 104 | { |
@@ -68,7 +111,7 @@ static | |||
68 | {} | 111 | {} |
69 | }; | 112 | }; |
70 | 113 | ||
71 | const static struct ctrl ov9650_ctrls[] = { | 114 | static const struct ctrl ov9650_ctrls[] = { |
72 | #define EXPOSURE_IDX 0 | 115 | #define EXPOSURE_IDX 0 |
73 | { | 116 | { |
74 | { | 117 | { |
@@ -102,6 +145,7 @@ const static struct ctrl ov9650_ctrls[] = { | |||
102 | #define RED_BALANCE_IDX 2 | 145 | #define RED_BALANCE_IDX 2 |
103 | { | 146 | { |
104 | { | 147 | { |
148 | .id = V4L2_CID_RED_BALANCE, | ||
105 | .type = V4L2_CTRL_TYPE_INTEGER, | 149 | .type = V4L2_CTRL_TYPE_INTEGER, |
106 | .name = "red balance", | 150 | .name = "red balance", |
107 | .minimum = 0x00, | 151 | .minimum = 0x00, |
@@ -116,6 +160,7 @@ const static struct ctrl ov9650_ctrls[] = { | |||
116 | #define BLUE_BALANCE_IDX 3 | 160 | #define BLUE_BALANCE_IDX 3 |
117 | { | 161 | { |
118 | { | 162 | { |
163 | .id = V4L2_CID_BLUE_BALANCE, | ||
119 | .type = V4L2_CTRL_TYPE_INTEGER, | 164 | .type = V4L2_CTRL_TYPE_INTEGER, |
120 | .name = "blue balance", | 165 | .name = "blue balance", |
121 | .minimum = 0x00, | 166 | .minimum = 0x00, |
@@ -182,7 +227,22 @@ const static struct ctrl ov9650_ctrls[] = { | |||
182 | }, | 227 | }, |
183 | .set = ov9650_set_auto_gain, | 228 | .set = ov9650_set_auto_gain, |
184 | .get = ov9650_get_auto_gain | 229 | .get = ov9650_get_auto_gain |
230 | }, | ||
231 | #define AUTO_EXPOSURE_IDX 8 | ||
232 | { | ||
233 | { | ||
234 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
235 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
236 | .name = "auto exposure", | ||
237 | .minimum = 0, | ||
238 | .maximum = 1, | ||
239 | .step = 1, | ||
240 | .default_value = 1 | ||
241 | }, | ||
242 | .set = ov9650_set_auto_exposure, | ||
243 | .get = ov9650_get_auto_exposure | ||
185 | } | 244 | } |
245 | |||
186 | }; | 246 | }; |
187 | 247 | ||
188 | static struct v4l2_pix_format ov9650_modes[] = { | 248 | static struct v4l2_pix_format ov9650_modes[] = { |
@@ -289,12 +349,6 @@ sensor_found: | |||
289 | for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) | 349 | for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) |
290 | sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; | 350 | sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; |
291 | sd->sensor_priv = sensor_settings; | 351 | sd->sensor_priv = sensor_settings; |
292 | |||
293 | if (dmi_check_system(ov9650_flip_dmi_table) && !err) { | ||
294 | info("vflip quirk active"); | ||
295 | sensor_settings[VFLIP_IDX] = 1; | ||
296 | } | ||
297 | |||
298 | return 0; | 352 | return 0; |
299 | } | 353 | } |
300 | 354 | ||
@@ -316,7 +370,8 @@ int ov9650_init(struct sd *sd) | |||
316 | err = m5602_write_bridge(sd, init_ov9650[i][1], data); | 370 | err = m5602_write_bridge(sd, init_ov9650[i][1], data); |
317 | } | 371 | } |
318 | 372 | ||
319 | err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]); | 373 | err = ov9650_set_exposure(&sd->gspca_dev, |
374 | sensor_settings[EXPOSURE_IDX]); | ||
320 | if (err < 0) | 375 | if (err < 0) |
321 | return err; | 376 | return err; |
322 | 377 | ||
@@ -324,11 +379,13 @@ int ov9650_init(struct sd *sd) | |||
324 | if (err < 0) | 379 | if (err < 0) |
325 | return err; | 380 | return err; |
326 | 381 | ||
327 | err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]); | 382 | err = ov9650_set_red_balance(&sd->gspca_dev, |
383 | sensor_settings[RED_BALANCE_IDX]); | ||
328 | if (err < 0) | 384 | if (err < 0) |
329 | return err; | 385 | return err; |
330 | 386 | ||
331 | err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]); | 387 | err = ov9650_set_blue_balance(&sd->gspca_dev, |
388 | sensor_settings[BLUE_BALANCE_IDX]); | ||
332 | if (err < 0) | 389 | if (err < 0) |
333 | return err; | 390 | return err; |
334 | 391 | ||
@@ -340,11 +397,18 @@ int ov9650_init(struct sd *sd) | |||
340 | if (err < 0) | 397 | if (err < 0) |
341 | return err; | 398 | return err; |
342 | 399 | ||
343 | err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]); | 400 | err = ov9650_set_auto_exposure(&sd->gspca_dev, |
401 | sensor_settings[AUTO_EXPOSURE_IDX]); | ||
402 | if (err < 0) | ||
403 | return err; | ||
404 | |||
405 | err = ov9650_set_auto_white_balance(&sd->gspca_dev, | ||
406 | sensor_settings[AUTO_WHITE_BALANCE_IDX]); | ||
344 | if (err < 0) | 407 | if (err < 0) |
345 | return err; | 408 | return err; |
346 | 409 | ||
347 | err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]); | 410 | err = ov9650_set_auto_gain(&sd->gspca_dev, |
411 | sensor_settings[AUTO_GAIN_CTRL_IDX]); | ||
348 | return err; | 412 | return err; |
349 | } | 413 | } |
350 | 414 | ||
@@ -360,7 +424,10 @@ int ov9650_start(struct sd *sd) | |||
360 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; | 424 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; |
361 | int hor_offs = OV9650_LEFT_OFFSET; | 425 | int hor_offs = OV9650_LEFT_OFFSET; |
362 | 426 | ||
363 | if (sensor_settings[VFLIP_IDX]) | 427 | if ((!dmi_check_system(ov9650_flip_dmi_table) && |
428 | sensor_settings[VFLIP_IDX]) || | ||
429 | (dmi_check_system(ov9650_flip_dmi_table) && | ||
430 | !sensor_settings[VFLIP_IDX])) | ||
364 | ver_offs--; | 431 | ver_offs--; |
365 | 432 | ||
366 | if (width <= 320) | 433 | if (width <= 320) |
@@ -406,6 +473,14 @@ int ov9650_start(struct sd *sd) | |||
406 | if (err < 0) | 473 | if (err < 0) |
407 | return err; | 474 | return err; |
408 | 475 | ||
476 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
477 | if (err < 0) | ||
478 | return err; | ||
479 | |||
480 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); | ||
481 | if (err < 0) | ||
482 | return err; | ||
483 | |||
409 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, | 484 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, |
410 | (hor_offs >> 8) & 0xff); | 485 | (hor_offs >> 8) & 0xff); |
411 | if (err < 0) | 486 | if (err < 0) |
@@ -425,6 +500,10 @@ int ov9650_start(struct sd *sd) | |||
425 | if (err < 0) | 500 | if (err < 0) |
426 | return err; | 501 | return err; |
427 | 502 | ||
503 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
504 | if (err < 0) | ||
505 | return err; | ||
506 | |||
428 | switch (width) { | 507 | switch (width) { |
429 | case 640: | 508 | case 640: |
430 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); | 509 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); |
@@ -467,32 +546,15 @@ int ov9650_stop(struct sd *sd) | |||
467 | return m5602_write_sensor(sd, OV9650_COM2, &data, 1); | 546 | return m5602_write_sensor(sd, OV9650_COM2, &data, 1); |
468 | } | 547 | } |
469 | 548 | ||
470 | int ov9650_power_down(struct sd *sd) | ||
471 | { | ||
472 | int i, err = 0; | ||
473 | for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) { | ||
474 | u8 data = power_down_ov9650[i][2]; | ||
475 | if (power_down_ov9650[i][0] == SENSOR) | ||
476 | err = m5602_write_sensor(sd, | ||
477 | power_down_ov9650[i][1], &data, 1); | ||
478 | else | ||
479 | err = m5602_write_bridge(sd, power_down_ov9650[i][1], | ||
480 | data); | ||
481 | } | ||
482 | |||
483 | return err; | ||
484 | } | ||
485 | |||
486 | void ov9650_disconnect(struct sd *sd) | 549 | void ov9650_disconnect(struct sd *sd) |
487 | { | 550 | { |
488 | ov9650_stop(sd); | 551 | ov9650_stop(sd); |
489 | ov9650_power_down(sd); | ||
490 | 552 | ||
491 | sd->sensor = NULL; | 553 | sd->sensor = NULL; |
492 | kfree(sd->sensor_priv); | 554 | kfree(sd->sensor_priv); |
493 | } | 555 | } |
494 | 556 | ||
495 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 557 | static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
496 | { | 558 | { |
497 | struct sd *sd = (struct sd *) gspca_dev; | 559 | struct sd *sd = (struct sd *) gspca_dev; |
498 | s32 *sensor_settings = sd->sensor_priv; | 560 | s32 *sensor_settings = sd->sensor_priv; |
@@ -502,7 +564,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | |||
502 | return 0; | 564 | return 0; |
503 | } | 565 | } |
504 | 566 | ||
505 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 567 | static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
506 | { | 568 | { |
507 | struct sd *sd = (struct sd *) gspca_dev; | 569 | struct sd *sd = (struct sd *) gspca_dev; |
508 | s32 *sensor_settings = sd->sensor_priv; | 570 | s32 *sensor_settings = sd->sensor_priv; |
@@ -532,7 +594,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
532 | return err; | 594 | return err; |
533 | } | 595 | } |
534 | 596 | ||
535 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 597 | static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
536 | { | 598 | { |
537 | struct sd *sd = (struct sd *) gspca_dev; | 599 | struct sd *sd = (struct sd *) gspca_dev; |
538 | s32 *sensor_settings = sd->sensor_priv; | 600 | s32 *sensor_settings = sd->sensor_priv; |
@@ -542,7 +604,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
542 | return 0; | 604 | return 0; |
543 | } | 605 | } |
544 | 606 | ||
545 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 607 | static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
546 | { | 608 | { |
547 | int err; | 609 | int err; |
548 | u8 i2c_data; | 610 | u8 i2c_data; |
@@ -573,7 +635,7 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
573 | return err; | 635 | return err; |
574 | } | 636 | } |
575 | 637 | ||
576 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 638 | static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) |
577 | { | 639 | { |
578 | struct sd *sd = (struct sd *) gspca_dev; | 640 | struct sd *sd = (struct sd *) gspca_dev; |
579 | s32 *sensor_settings = sd->sensor_priv; | 641 | s32 *sensor_settings = sd->sensor_priv; |
@@ -583,7 +645,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
583 | return 0; | 645 | return 0; |
584 | } | 646 | } |
585 | 647 | ||
586 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 648 | static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) |
587 | { | 649 | { |
588 | int err; | 650 | int err; |
589 | u8 i2c_data; | 651 | u8 i2c_data; |
@@ -599,7 +661,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
599 | return err; | 661 | return err; |
600 | } | 662 | } |
601 | 663 | ||
602 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 664 | static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) |
603 | { | 665 | { |
604 | struct sd *sd = (struct sd *) gspca_dev; | 666 | struct sd *sd = (struct sd *) gspca_dev; |
605 | s32 *sensor_settings = sd->sensor_priv; | 667 | s32 *sensor_settings = sd->sensor_priv; |
@@ -610,7 +672,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
610 | return 0; | 672 | return 0; |
611 | } | 673 | } |
612 | 674 | ||
613 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 675 | static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) |
614 | { | 676 | { |
615 | int err; | 677 | int err; |
616 | u8 i2c_data; | 678 | u8 i2c_data; |
@@ -626,7 +688,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
626 | return err; | 688 | return err; |
627 | } | 689 | } |
628 | 690 | ||
629 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 691 | static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
630 | { | 692 | { |
631 | struct sd *sd = (struct sd *) gspca_dev; | 693 | struct sd *sd = (struct sd *) gspca_dev; |
632 | s32 *sensor_settings = sd->sensor_priv; | 694 | s32 *sensor_settings = sd->sensor_priv; |
@@ -636,7 +698,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
636 | return 0; | 698 | return 0; |
637 | } | 699 | } |
638 | 700 | ||
639 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 701 | static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
640 | { | 702 | { |
641 | int err; | 703 | int err; |
642 | u8 i2c_data; | 704 | u8 i2c_data; |
@@ -646,13 +708,20 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
646 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | 708 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); |
647 | 709 | ||
648 | sensor_settings[HFLIP_IDX] = val; | 710 | sensor_settings[HFLIP_IDX] = val; |
649 | i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4); | 711 | |
712 | if (!dmi_check_system(ov9650_flip_dmi_table)) | ||
713 | i2c_data = ((val & 0x01) << 5) | | ||
714 | (sensor_settings[VFLIP_IDX] << 4); | ||
715 | else | ||
716 | i2c_data = ((val & 0x01) << 5) | | ||
717 | (!sensor_settings[VFLIP_IDX] << 4); | ||
718 | |||
650 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 719 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
651 | 720 | ||
652 | return err; | 721 | return err; |
653 | } | 722 | } |
654 | 723 | ||
655 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 724 | static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
656 | { | 725 | { |
657 | struct sd *sd = (struct sd *) gspca_dev; | 726 | struct sd *sd = (struct sd *) gspca_dev; |
658 | s32 *sensor_settings = sd->sensor_priv; | 727 | s32 *sensor_settings = sd->sensor_priv; |
@@ -663,7 +732,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | |||
663 | return 0; | 732 | return 0; |
664 | } | 733 | } |
665 | 734 | ||
666 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 735 | static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
667 | { | 736 | { |
668 | int err; | 737 | int err; |
669 | u8 i2c_data; | 738 | u8 i2c_data; |
@@ -673,6 +742,9 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
673 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 742 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
674 | sensor_settings[VFLIP_IDX] = val; | 743 | sensor_settings[VFLIP_IDX] = val; |
675 | 744 | ||
745 | if (dmi_check_system(ov9650_flip_dmi_table)) | ||
746 | val = !val; | ||
747 | |||
676 | i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); | 748 | i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); |
677 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); | 749 | err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); |
678 | if (err < 0) | 750 | if (err < 0) |
@@ -685,48 +757,38 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
685 | return err; | 757 | return err; |
686 | } | 758 | } |
687 | 759 | ||
688 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 760 | static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
689 | { | 761 | { |
690 | struct sd *sd = (struct sd *) gspca_dev; | 762 | struct sd *sd = (struct sd *) gspca_dev; |
691 | s32 *sensor_settings = sd->sensor_priv; | 763 | s32 *sensor_settings = sd->sensor_priv; |
692 | 764 | ||
693 | *val = sensor_settings[GAIN_IDX]; | 765 | *val = sensor_settings[AUTO_EXPOSURE_IDX]; |
694 | PDEBUG(D_V4L2, "Read gain %d", *val); | 766 | PDEBUG(D_V4L2, "Read auto exposure control %d", *val); |
695 | |||
696 | return 0; | 767 | return 0; |
697 | } | 768 | } |
698 | 769 | ||
699 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 770 | static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, |
771 | __s32 val) | ||
700 | { | 772 | { |
701 | int err; | 773 | int err; |
702 | u8 i2c_data; | 774 | u8 i2c_data; |
703 | struct sd *sd = (struct sd *) gspca_dev; | 775 | struct sd *sd = (struct sd *) gspca_dev; |
704 | s32 *sensor_settings = sd->sensor_priv; | 776 | s32 *sensor_settings = sd->sensor_priv; |
705 | 777 | ||
706 | PDEBUG(D_V4L2, "Set gain to %d", val); | 778 | PDEBUG(D_V4L2, "Set auto exposure control to %d", val); |
707 | |||
708 | sensor_settings[GAIN_IDX] = val; | ||
709 | 779 | ||
710 | /* Read the OV9650_VREF register first to avoid | 780 | sensor_settings[AUTO_EXPOSURE_IDX] = val; |
711 | corrupting the VREF high and low bits */ | 781 | err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); |
712 | err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1); | ||
713 | if (err < 0) | ||
714 | return err; | ||
715 | |||
716 | /* Mask away all uninteresting bits */ | ||
717 | i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F); | ||
718 | err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1); | ||
719 | if (err < 0) | 782 | if (err < 0) |
720 | return err; | 783 | return err; |
721 | 784 | ||
722 | /* The 8 LSBs */ | 785 | i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); |
723 | i2c_data = val & 0xff; | ||
724 | err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); | ||
725 | 786 | ||
726 | return err; | 787 | return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); |
727 | } | 788 | } |
728 | 789 | ||
729 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | 790 | static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, |
791 | __s32 *val) | ||
730 | { | 792 | { |
731 | struct sd *sd = (struct sd *) gspca_dev; | 793 | struct sd *sd = (struct sd *) gspca_dev; |
732 | s32 *sensor_settings = sd->sensor_priv; | 794 | s32 *sensor_settings = sd->sensor_priv; |
@@ -735,7 +797,8 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | |||
735 | return 0; | 797 | return 0; |
736 | } | 798 | } |
737 | 799 | ||
738 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | 800 | static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, |
801 | __s32 val) | ||
739 | { | 802 | { |
740 | int err; | 803 | int err; |
741 | u8 i2c_data; | 804 | u8 i2c_data; |
@@ -755,7 +818,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
755 | return err; | 818 | return err; |
756 | } | 819 | } |
757 | 820 | ||
758 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | 821 | static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) |
759 | { | 822 | { |
760 | struct sd *sd = (struct sd *) gspca_dev; | 823 | struct sd *sd = (struct sd *) gspca_dev; |
761 | s32 *sensor_settings = sd->sensor_priv; | 824 | s32 *sensor_settings = sd->sensor_priv; |
@@ -765,7 +828,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | |||
765 | return 0; | 828 | return 0; |
766 | } | 829 | } |
767 | 830 | ||
768 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | 831 | static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) |
769 | { | 832 | { |
770 | int err; | 833 | int err; |
771 | u8 i2c_data; | 834 | u8 i2c_data; |
@@ -780,9 +843,8 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
780 | return err; | 843 | return err; |
781 | 844 | ||
782 | i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); | 845 | i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); |
783 | err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); | ||
784 | 846 | ||
785 | return err; | 847 | return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); |
786 | } | 848 | } |
787 | 849 | ||
788 | static void ov9650_dump_registers(struct sd *sd) | 850 | static void ov9650_dump_registers(struct sd *sd) |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h index fcc54e4c0f4f..c98c40d69e05 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h | |||
@@ -120,6 +120,10 @@ | |||
120 | #define OV9650_SOFT_SLEEP (1 << 4) | 120 | #define OV9650_SOFT_SLEEP (1 << 4) |
121 | #define OV9650_OUTPUT_DRIVE_2X (1 << 0) | 121 | #define OV9650_OUTPUT_DRIVE_2X (1 << 0) |
122 | 122 | ||
123 | #define OV9650_DENOISE_ENABLE (1 << 5) | ||
124 | #define OV9650_WHITE_PIXEL_ENABLE (1 << 1) | ||
125 | #define OV9650_WHITE_PIXEL_OPTION (1 << 0) | ||
126 | |||
123 | #define OV9650_LEFT_OFFSET 0x62 | 127 | #define OV9650_LEFT_OFFSET 0x62 |
124 | 128 | ||
125 | #define GAIN_DEFAULT 0x14 | 129 | #define GAIN_DEFAULT 0x14 |
@@ -137,29 +141,9 @@ int ov9650_probe(struct sd *sd); | |||
137 | int ov9650_init(struct sd *sd); | 141 | int ov9650_init(struct sd *sd); |
138 | int ov9650_start(struct sd *sd); | 142 | int ov9650_start(struct sd *sd); |
139 | int ov9650_stop(struct sd *sd); | 143 | int ov9650_stop(struct sd *sd); |
140 | int ov9650_power_down(struct sd *sd); | ||
141 | void ov9650_disconnect(struct sd *sd); | 144 | void ov9650_disconnect(struct sd *sd); |
142 | 145 | ||
143 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | 146 | static const struct m5602_sensor ov9650 = { |
144 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
145 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
146 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
147 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
148 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
149 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
150 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
151 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
152 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
153 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
154 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
155 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
156 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
157 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
158 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
159 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
160 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
161 | |||
162 | const static struct m5602_sensor ov9650 = { | ||
163 | .name = "OV9650", | 147 | .name = "OV9650", |
164 | .i2c_slave_id = 0x60, | 148 | .i2c_slave_id = 0x60, |
165 | .i2c_regW = 1, | 149 | .i2c_regW = 1, |
@@ -167,7 +151,6 @@ const static struct m5602_sensor ov9650 = { | |||
167 | .init = ov9650_init, | 151 | .init = ov9650_init, |
168 | .start = ov9650_start, | 152 | .start = ov9650_start, |
169 | .stop = ov9650_stop, | 153 | .stop = ov9650_stop, |
170 | .power_down = ov9650_power_down, | ||
171 | .disconnect = ov9650_disconnect, | 154 | .disconnect = ov9650_disconnect, |
172 | }; | 155 | }; |
173 | 156 | ||
@@ -219,7 +202,7 @@ static const unsigned char init_ov9650[][3] = | |||
219 | /* Reset chip */ | 202 | /* Reset chip */ |
220 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, | 203 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, |
221 | /* One extra reset is needed in order to make the sensor behave | 204 | /* One extra reset is needed in order to make the sensor behave |
222 | properly when resuming from ram */ | 205 | properly when resuming from ram, could be a timing issue */ |
223 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, | 206 | {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, |
224 | 207 | ||
225 | /* Enable double clock */ | 208 | /* Enable double clock */ |
@@ -229,8 +212,7 @@ static const unsigned char init_ov9650[][3] = | |||
229 | 212 | ||
230 | /* Set fast AGC/AEC algorithm with unlimited step size */ | 213 | /* Set fast AGC/AEC algorithm with unlimited step size */ |
231 | {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | | 214 | {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | |
232 | OV9650_AEC_UNLIM_STEP_SIZE | | 215 | OV9650_AEC_UNLIM_STEP_SIZE}, |
233 | OV9650_AWB_EN | OV9650_AGC_EN}, | ||
234 | 216 | ||
235 | {SENSOR, OV9650_CHLF, 0x10}, | 217 | {SENSOR, OV9650_CHLF, 0x10}, |
236 | {SENSOR, OV9650_ARBLM, 0xbf}, | 218 | {SENSOR, OV9650_ARBLM, 0xbf}, |
@@ -301,8 +283,11 @@ static const unsigned char init_ov9650[][3] = | |||
301 | {SENSOR, OV9650_VREF, 0x10}, | 283 | {SENSOR, OV9650_VREF, 0x10}, |
302 | {SENSOR, OV9650_ADC, 0x04}, | 284 | {SENSOR, OV9650_ADC, 0x04}, |
303 | {SENSOR, OV9650_HV, 0x40}, | 285 | {SENSOR, OV9650_HV, 0x40}, |
286 | |||
304 | /* Enable denoise, and white-pixel erase */ | 287 | /* Enable denoise, and white-pixel erase */ |
305 | {SENSOR, OV9650_COM22, 0x23}, | 288 | {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE | |
289 | OV9650_WHITE_PIXEL_ENABLE | | ||
290 | OV9650_WHITE_PIXEL_OPTION}, | ||
306 | 291 | ||
307 | /* Enable VARIOPIXEL */ | 292 | /* Enable VARIOPIXEL */ |
308 | {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, | 293 | {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, |
@@ -312,26 +297,6 @@ static const unsigned char init_ov9650[][3] = | |||
312 | {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, | 297 | {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, |
313 | }; | 298 | }; |
314 | 299 | ||
315 | static const unsigned char power_down_ov9650[][3] = | ||
316 | { | ||
317 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
318 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
319 | {SENSOR, OV9650_COM7, 0x80}, | ||
320 | {SENSOR, OV9650_OFON, 0xf4}, | ||
321 | {SENSOR, OV9650_MVFP, 0x80}, | ||
322 | {SENSOR, OV9650_DBLV, 0x3f}, | ||
323 | {SENSOR, OV9650_RSVD36, 0x49}, | ||
324 | {SENSOR, OV9650_COM7, 0x05}, | ||
325 | |||
326 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
327 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
328 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
329 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x06}, | ||
330 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | ||
331 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
332 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
333 | }; | ||
334 | |||
335 | static const unsigned char res_init_ov9650[][3] = | 300 | static const unsigned char res_init_ov9650[][3] = |
336 | { | 301 | { |
337 | {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, | 302 | {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, |
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c index eaddf488bad1..8d74d8065b79 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.c +++ b/drivers/media/video/gspca/m5602/m5602_po1030.c | |||
@@ -18,6 +18,29 @@ | |||
18 | 18 | ||
19 | #include "m5602_po1030.h" | 19 | #include "m5602_po1030.h" |
20 | 20 | ||
21 | static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
22 | static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
29 | static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
30 | static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
31 | static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
34 | static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
35 | static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, | ||
36 | __s32 val); | ||
37 | static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, | ||
38 | __s32 *val); | ||
39 | static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, | ||
40 | __s32 val); | ||
41 | static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev, | ||
42 | __s32 *val); | ||
43 | |||
21 | static struct v4l2_pix_format po1030_modes[] = { | 44 | static struct v4l2_pix_format po1030_modes[] = { |
22 | { | 45 | { |
23 | 640, | 46 | 640, |
@@ -27,11 +50,12 @@ static struct v4l2_pix_format po1030_modes[] = { | |||
27 | .sizeimage = 640 * 480, | 50 | .sizeimage = 640 * 480, |
28 | .bytesperline = 640, | 51 | .bytesperline = 640, |
29 | .colorspace = V4L2_COLORSPACE_SRGB, | 52 | .colorspace = V4L2_COLORSPACE_SRGB, |
30 | .priv = 0 | 53 | .priv = 2 |
31 | } | 54 | } |
32 | }; | 55 | }; |
33 | 56 | ||
34 | const static struct ctrl po1030_ctrls[] = { | 57 | static const struct ctrl po1030_ctrls[] = { |
58 | #define GAIN_IDX 0 | ||
35 | { | 59 | { |
36 | { | 60 | { |
37 | .id = V4L2_CID_GAIN, | 61 | .id = V4L2_CID_GAIN, |
@@ -45,7 +69,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
45 | }, | 69 | }, |
46 | .set = po1030_set_gain, | 70 | .set = po1030_set_gain, |
47 | .get = po1030_get_gain | 71 | .get = po1030_get_gain |
48 | }, { | 72 | }, |
73 | #define EXPOSURE_IDX 1 | ||
74 | { | ||
49 | { | 75 | { |
50 | .id = V4L2_CID_EXPOSURE, | 76 | .id = V4L2_CID_EXPOSURE, |
51 | .type = V4L2_CTRL_TYPE_INTEGER, | 77 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -58,7 +84,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
58 | }, | 84 | }, |
59 | .set = po1030_set_exposure, | 85 | .set = po1030_set_exposure, |
60 | .get = po1030_get_exposure | 86 | .get = po1030_get_exposure |
61 | }, { | 87 | }, |
88 | #define RED_BALANCE_IDX 2 | ||
89 | { | ||
62 | { | 90 | { |
63 | .id = V4L2_CID_RED_BALANCE, | 91 | .id = V4L2_CID_RED_BALANCE, |
64 | .type = V4L2_CTRL_TYPE_INTEGER, | 92 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -71,7 +99,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
71 | }, | 99 | }, |
72 | .set = po1030_set_red_balance, | 100 | .set = po1030_set_red_balance, |
73 | .get = po1030_get_red_balance | 101 | .get = po1030_get_red_balance |
74 | }, { | 102 | }, |
103 | #define BLUE_BALANCE_IDX 3 | ||
104 | { | ||
75 | { | 105 | { |
76 | .id = V4L2_CID_BLUE_BALANCE, | 106 | .id = V4L2_CID_BLUE_BALANCE, |
77 | .type = V4L2_CTRL_TYPE_INTEGER, | 107 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -84,7 +114,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
84 | }, | 114 | }, |
85 | .set = po1030_set_blue_balance, | 115 | .set = po1030_set_blue_balance, |
86 | .get = po1030_get_blue_balance | 116 | .get = po1030_get_blue_balance |
87 | }, { | 117 | }, |
118 | #define HFLIP_IDX 4 | ||
119 | { | ||
88 | { | 120 | { |
89 | .id = V4L2_CID_HFLIP, | 121 | .id = V4L2_CID_HFLIP, |
90 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 122 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -96,7 +128,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
96 | }, | 128 | }, |
97 | .set = po1030_set_hflip, | 129 | .set = po1030_set_hflip, |
98 | .get = po1030_get_hflip | 130 | .get = po1030_get_hflip |
99 | }, { | 131 | }, |
132 | #define VFLIP_IDX 5 | ||
133 | { | ||
100 | { | 134 | { |
101 | .id = V4L2_CID_VFLIP, | 135 | .id = V4L2_CID_VFLIP, |
102 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 136 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -108,14 +142,58 @@ const static struct ctrl po1030_ctrls[] = { | |||
108 | }, | 142 | }, |
109 | .set = po1030_set_vflip, | 143 | .set = po1030_set_vflip, |
110 | .get = po1030_get_vflip | 144 | .get = po1030_get_vflip |
111 | } | 145 | }, |
146 | #define AUTO_WHITE_BALANCE_IDX 6 | ||
147 | { | ||
148 | { | ||
149 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
150 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
151 | .name = "auto white balance", | ||
152 | .minimum = 0, | ||
153 | .maximum = 1, | ||
154 | .step = 1, | ||
155 | .default_value = 0, | ||
156 | }, | ||
157 | .set = po1030_set_auto_white_balance, | ||
158 | .get = po1030_get_auto_white_balance | ||
159 | }, | ||
160 | #define AUTO_EXPOSURE_IDX 7 | ||
161 | { | ||
162 | { | ||
163 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
164 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
165 | .name = "auto exposure", | ||
166 | .minimum = 0, | ||
167 | .maximum = 1, | ||
168 | .step = 1, | ||
169 | .default_value = 0, | ||
170 | }, | ||
171 | .set = po1030_set_auto_exposure, | ||
172 | .get = po1030_get_auto_exposure | ||
173 | }, | ||
174 | #define GREEN_BALANCE_IDX 8 | ||
175 | { | ||
176 | { | ||
177 | .id = M5602_V4L2_CID_GREEN_BALANCE, | ||
178 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
179 | .name = "green balance", | ||
180 | .minimum = 0x00, | ||
181 | .maximum = 0xff, | ||
182 | .step = 0x1, | ||
183 | .default_value = PO1030_GREEN_GAIN_DEFAULT, | ||
184 | .flags = V4L2_CTRL_FLAG_SLIDER | ||
185 | }, | ||
186 | .set = po1030_set_green_balance, | ||
187 | .get = po1030_get_green_balance | ||
188 | }, | ||
112 | }; | 189 | }; |
113 | 190 | ||
114 | static void po1030_dump_registers(struct sd *sd); | 191 | static void po1030_dump_registers(struct sd *sd); |
115 | 192 | ||
116 | int po1030_probe(struct sd *sd) | 193 | int po1030_probe(struct sd *sd) |
117 | { | 194 | { |
118 | u8 prod_id = 0, ver_id = 0, i; | 195 | u8 dev_id_h = 0, i; |
196 | s32 *sensor_settings; | ||
119 | 197 | ||
120 | if (force_sensor) { | 198 | if (force_sensor) { |
121 | if (force_sensor == PO1030_SENSOR) { | 199 | if (force_sensor == PO1030_SENSOR) { |
@@ -139,28 +217,36 @@ int po1030_probe(struct sd *sd) | |||
139 | m5602_write_bridge(sd, preinit_po1030[i][1], data); | 217 | m5602_write_bridge(sd, preinit_po1030[i][1], data); |
140 | } | 218 | } |
141 | 219 | ||
142 | if (m5602_read_sensor(sd, 0x3, &prod_id, 1)) | 220 | if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1)) |
143 | return -ENODEV; | 221 | return -ENODEV; |
144 | 222 | ||
145 | if (m5602_read_sensor(sd, 0x4, &ver_id, 1)) | 223 | if (dev_id_h == 0x30) { |
146 | return -ENODEV; | ||
147 | |||
148 | if ((prod_id == 0x02) && (ver_id == 0xef)) { | ||
149 | info("Detected a po1030 sensor"); | 224 | info("Detected a po1030 sensor"); |
150 | goto sensor_found; | 225 | goto sensor_found; |
151 | } | 226 | } |
152 | return -ENODEV; | 227 | return -ENODEV; |
153 | 228 | ||
154 | sensor_found: | 229 | sensor_found: |
230 | sensor_settings = kmalloc( | ||
231 | ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL); | ||
232 | if (!sensor_settings) | ||
233 | return -ENOMEM; | ||
234 | |||
155 | sd->gspca_dev.cam.cam_mode = po1030_modes; | 235 | sd->gspca_dev.cam.cam_mode = po1030_modes; |
156 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); | 236 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); |
157 | sd->desc->ctrls = po1030_ctrls; | 237 | sd->desc->ctrls = po1030_ctrls; |
158 | sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); | 238 | sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); |
239 | |||
240 | for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++) | ||
241 | sensor_settings[i] = po1030_ctrls[i].qctrl.default_value; | ||
242 | sd->sensor_priv = sensor_settings; | ||
243 | |||
159 | return 0; | 244 | return 0; |
160 | } | 245 | } |
161 | 246 | ||
162 | int po1030_init(struct sd *sd) | 247 | int po1030_init(struct sd *sd) |
163 | { | 248 | { |
249 | s32 *sensor_settings = sd->sensor_priv; | ||
164 | int i, err = 0; | 250 | int i, err = 0; |
165 | 251 | ||
166 | /* Init the sensor */ | 252 | /* Init the sensor */ |
@@ -185,47 +271,206 @@ int po1030_init(struct sd *sd) | |||
185 | return -EINVAL; | 271 | return -EINVAL; |
186 | } | 272 | } |
187 | } | 273 | } |
274 | if (err < 0) | ||
275 | return err; | ||
188 | 276 | ||
189 | if (dump_sensor) | 277 | if (dump_sensor) |
190 | po1030_dump_registers(sd); | 278 | po1030_dump_registers(sd); |
191 | 279 | ||
280 | err = po1030_set_exposure(&sd->gspca_dev, | ||
281 | sensor_settings[EXPOSURE_IDX]); | ||
282 | if (err < 0) | ||
283 | return err; | ||
284 | |||
285 | err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
286 | if (err < 0) | ||
287 | return err; | ||
288 | |||
289 | err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
290 | if (err < 0) | ||
291 | return err; | ||
292 | |||
293 | err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); | ||
294 | if (err < 0) | ||
295 | return err; | ||
296 | |||
297 | err = po1030_set_red_balance(&sd->gspca_dev, | ||
298 | sensor_settings[RED_BALANCE_IDX]); | ||
299 | if (err < 0) | ||
300 | return err; | ||
301 | |||
302 | err = po1030_set_blue_balance(&sd->gspca_dev, | ||
303 | sensor_settings[BLUE_BALANCE_IDX]); | ||
304 | if (err < 0) | ||
305 | return err; | ||
306 | |||
307 | err = po1030_set_green_balance(&sd->gspca_dev, | ||
308 | sensor_settings[GREEN_BALANCE_IDX]); | ||
309 | if (err < 0) | ||
310 | return err; | ||
311 | |||
312 | err = po1030_set_auto_white_balance(&sd->gspca_dev, | ||
313 | sensor_settings[AUTO_WHITE_BALANCE_IDX]); | ||
314 | if (err < 0) | ||
315 | return err; | ||
316 | |||
317 | err = po1030_set_auto_exposure(&sd->gspca_dev, | ||
318 | sensor_settings[AUTO_EXPOSURE_IDX]); | ||
192 | return err; | 319 | return err; |
193 | } | 320 | } |
194 | 321 | ||
195 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 322 | int po1030_start(struct sd *sd) |
196 | { | 323 | { |
197 | struct sd *sd = (struct sd *) gspca_dev; | 324 | struct cam *cam = &sd->gspca_dev.cam; |
198 | u8 i2c_data; | 325 | int i, err = 0; |
199 | int err; | 326 | int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; |
327 | int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; | ||
328 | int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; | ||
329 | u8 data; | ||
330 | |||
331 | switch (width) { | ||
332 | case 320: | ||
333 | data = PO1030_SUBSAMPLING; | ||
334 | err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1); | ||
335 | if (err < 0) | ||
336 | return err; | ||
337 | |||
338 | data = ((width + 3) >> 8) & 0xff; | ||
339 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1); | ||
340 | if (err < 0) | ||
341 | return err; | ||
342 | |||
343 | data = (width + 3) & 0xff; | ||
344 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1); | ||
345 | if (err < 0) | ||
346 | return err; | ||
347 | |||
348 | data = ((height + 1) >> 8) & 0xff; | ||
349 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1); | ||
350 | if (err < 0) | ||
351 | return err; | ||
352 | |||
353 | data = (height + 1) & 0xff; | ||
354 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1); | ||
355 | |||
356 | height += 6; | ||
357 | width -= 1; | ||
358 | break; | ||
359 | |||
360 | case 640: | ||
361 | data = 0; | ||
362 | err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1); | ||
363 | if (err < 0) | ||
364 | return err; | ||
365 | |||
366 | data = ((width + 7) >> 8) & 0xff; | ||
367 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1); | ||
368 | if (err < 0) | ||
369 | return err; | ||
370 | |||
371 | data = (width + 7) & 0xff; | ||
372 | err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1); | ||
373 | if (err < 0) | ||
374 | return err; | ||
375 | |||
376 | data = ((height + 3) >> 8) & 0xff; | ||
377 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1); | ||
378 | if (err < 0) | ||
379 | return err; | ||
380 | |||
381 | data = (height + 3) & 0xff; | ||
382 | err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1); | ||
383 | |||
384 | height += 12; | ||
385 | width -= 2; | ||
386 | break; | ||
387 | } | ||
388 | err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c); | ||
389 | if (err < 0) | ||
390 | return err; | ||
200 | 391 | ||
201 | err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H, | 392 | err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81); |
202 | &i2c_data, 1); | ||
203 | if (err < 0) | 393 | if (err < 0) |
204 | return err; | 394 | return err; |
205 | *val = (i2c_data << 8); | ||
206 | 395 | ||
207 | err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M, | 396 | err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82); |
208 | &i2c_data, 1); | 397 | if (err < 0) |
209 | *val |= i2c_data; | 398 | return err; |
210 | 399 | ||
211 | PDEBUG(D_V4L2, "Exposure read as %d", *val); | 400 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01); |
401 | if (err < 0) | ||
402 | return err; | ||
403 | |||
404 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, | ||
405 | ((ver_offs >> 8) & 0xff)); | ||
406 | if (err < 0) | ||
407 | return err; | ||
408 | |||
409 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff)); | ||
410 | if (err < 0) | ||
411 | return err; | ||
412 | |||
413 | for (i = 0; i < 2 && !err; i++) | ||
414 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); | ||
415 | if (err < 0) | ||
416 | return err; | ||
417 | |||
418 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); | ||
419 | if (err < 0) | ||
420 | return err; | ||
421 | |||
422 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); | ||
423 | if (err < 0) | ||
424 | return err; | ||
425 | |||
426 | for (i = 0; i < 2 && !err; i++) | ||
427 | err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); | ||
428 | |||
429 | for (i = 0; i < 2 && !err; i++) | ||
430 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
431 | |||
432 | for (i = 0; i < 2 && !err; i++) | ||
433 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0); | ||
434 | if (err < 0) | ||
435 | return err; | ||
436 | |||
437 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff); | ||
438 | if (err < 0) | ||
439 | return err; | ||
212 | 440 | ||
441 | err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff)); | ||
442 | if (err < 0) | ||
443 | return err; | ||
444 | |||
445 | err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); | ||
213 | return err; | 446 | return err; |
214 | } | 447 | } |
215 | 448 | ||
216 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 449 | static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
217 | { | 450 | { |
218 | struct sd *sd = (struct sd *) gspca_dev; | 451 | struct sd *sd = (struct sd *) gspca_dev; |
452 | s32 *sensor_settings = sd->sensor_priv; | ||
453 | |||
454 | *val = sensor_settings[EXPOSURE_IDX]; | ||
455 | PDEBUG(D_V4L2, "Exposure read as %d", *val); | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | ||
460 | { | ||
461 | struct sd *sd = (struct sd *) gspca_dev; | ||
462 | s32 *sensor_settings = sd->sensor_priv; | ||
219 | u8 i2c_data; | 463 | u8 i2c_data; |
220 | int err; | 464 | int err; |
221 | 465 | ||
466 | sensor_settings[EXPOSURE_IDX] = val; | ||
222 | PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); | 467 | PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); |
223 | 468 | ||
224 | i2c_data = ((val & 0xff00) >> 8); | 469 | i2c_data = ((val & 0xff00) >> 8); |
225 | PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", | 470 | PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", |
226 | i2c_data); | 471 | i2c_data); |
227 | 472 | ||
228 | err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H, | 473 | err = m5602_write_sensor(sd, PO1030_INTEGLINES_H, |
229 | &i2c_data, 1); | 474 | &i2c_data, 1); |
230 | if (err < 0) | 475 | if (err < 0) |
231 | return err; | 476 | return err; |
@@ -233,167 +478,256 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
233 | i2c_data = (val & 0xff); | 478 | i2c_data = (val & 0xff); |
234 | PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", | 479 | PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", |
235 | i2c_data); | 480 | i2c_data); |
236 | err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M, | 481 | err = m5602_write_sensor(sd, PO1030_INTEGLINES_M, |
237 | &i2c_data, 1); | 482 | &i2c_data, 1); |
238 | 483 | ||
239 | return err; | 484 | return err; |
240 | } | 485 | } |
241 | 486 | ||
242 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 487 | static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
243 | { | 488 | { |
244 | struct sd *sd = (struct sd *) gspca_dev; | 489 | struct sd *sd = (struct sd *) gspca_dev; |
245 | u8 i2c_data; | 490 | s32 *sensor_settings = sd->sensor_priv; |
246 | int err; | ||
247 | 491 | ||
248 | err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN, | 492 | *val = sensor_settings[GAIN_IDX]; |
249 | &i2c_data, 1); | ||
250 | *val = i2c_data; | ||
251 | PDEBUG(D_V4L2, "Read global gain %d", *val); | 493 | PDEBUG(D_V4L2, "Read global gain %d", *val); |
252 | 494 | return 0; | |
253 | return err; | ||
254 | } | 495 | } |
255 | 496 | ||
256 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 497 | static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
257 | { | 498 | { |
258 | struct sd *sd = (struct sd *) gspca_dev; | 499 | struct sd *sd = (struct sd *) gspca_dev; |
500 | s32 *sensor_settings = sd->sensor_priv; | ||
259 | u8 i2c_data; | 501 | u8 i2c_data; |
260 | int err; | 502 | int err; |
261 | 503 | ||
262 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, | 504 | sensor_settings[GAIN_IDX] = val; |
505 | |||
506 | i2c_data = val & 0xff; | ||
507 | PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); | ||
508 | err = m5602_write_sensor(sd, PO1030_GLOBALGAIN, | ||
263 | &i2c_data, 1); | 509 | &i2c_data, 1); |
510 | return err; | ||
511 | } | ||
264 | 512 | ||
265 | *val = (i2c_data >> 7) & 0x01 ; | 513 | static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
514 | { | ||
515 | struct sd *sd = (struct sd *) gspca_dev; | ||
516 | s32 *sensor_settings = sd->sensor_priv; | ||
266 | 517 | ||
518 | *val = sensor_settings[HFLIP_IDX]; | ||
267 | PDEBUG(D_V4L2, "Read hflip %d", *val); | 519 | PDEBUG(D_V4L2, "Read hflip %d", *val); |
268 | 520 | ||
269 | return err; | 521 | return 0; |
270 | } | 522 | } |
271 | 523 | ||
272 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 524 | static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
273 | { | 525 | { |
274 | struct sd *sd = (struct sd *) gspca_dev; | 526 | struct sd *sd = (struct sd *) gspca_dev; |
527 | s32 *sensor_settings = sd->sensor_priv; | ||
275 | u8 i2c_data; | 528 | u8 i2c_data; |
276 | int err; | 529 | int err; |
277 | 530 | ||
531 | sensor_settings[HFLIP_IDX] = val; | ||
532 | |||
278 | PDEBUG(D_V4L2, "Set hflip %d", val); | 533 | PDEBUG(D_V4L2, "Set hflip %d", val); |
279 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); | 534 | err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); |
280 | if (err < 0) | 535 | if (err < 0) |
281 | return err; | 536 | return err; |
282 | 537 | ||
283 | i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7); | 538 | i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7); |
284 | 539 | ||
285 | err = m5602_write_sensor(sd, PO1030_REG_CONTROL2, | 540 | err = m5602_write_sensor(sd, PO1030_CONTROL2, |
286 | &i2c_data, 1); | 541 | &i2c_data, 1); |
287 | 542 | ||
288 | return err; | 543 | return err; |
289 | } | 544 | } |
290 | 545 | ||
291 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 546 | static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
292 | { | 547 | { |
293 | struct sd *sd = (struct sd *) gspca_dev; | 548 | struct sd *sd = (struct sd *) gspca_dev; |
294 | u8 i2c_data; | 549 | s32 *sensor_settings = sd->sensor_priv; |
295 | int err; | ||
296 | |||
297 | err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN, | ||
298 | &i2c_data, 1); | ||
299 | |||
300 | *val = (i2c_data >> 6) & 0x01; | ||
301 | 550 | ||
551 | *val = sensor_settings[VFLIP_IDX]; | ||
302 | PDEBUG(D_V4L2, "Read vflip %d", *val); | 552 | PDEBUG(D_V4L2, "Read vflip %d", *val); |
303 | 553 | ||
304 | return err; | 554 | return 0; |
305 | } | 555 | } |
306 | 556 | ||
307 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 557 | static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
308 | { | 558 | { |
309 | struct sd *sd = (struct sd *) gspca_dev; | 559 | struct sd *sd = (struct sd *) gspca_dev; |
560 | s32 *sensor_settings = sd->sensor_priv; | ||
310 | u8 i2c_data; | 561 | u8 i2c_data; |
311 | int err; | 562 | int err; |
312 | 563 | ||
564 | sensor_settings[VFLIP_IDX] = val; | ||
565 | |||
313 | PDEBUG(D_V4L2, "Set vflip %d", val); | 566 | PDEBUG(D_V4L2, "Set vflip %d", val); |
314 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); | 567 | err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1); |
315 | if (err < 0) | 568 | if (err < 0) |
316 | return err; | 569 | return err; |
317 | 570 | ||
318 | i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6); | 571 | i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6); |
319 | 572 | ||
320 | err = m5602_write_sensor(sd, PO1030_REG_CONTROL2, | 573 | err = m5602_write_sensor(sd, PO1030_CONTROL2, |
321 | &i2c_data, 1); | 574 | &i2c_data, 1); |
322 | 575 | ||
323 | return err; | 576 | return err; |
324 | } | 577 | } |
325 | 578 | ||
326 | int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 579 | static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) |
580 | { | ||
581 | struct sd *sd = (struct sd *) gspca_dev; | ||
582 | s32 *sensor_settings = sd->sensor_priv; | ||
583 | |||
584 | *val = sensor_settings[RED_BALANCE_IDX]; | ||
585 | PDEBUG(D_V4L2, "Read red gain %d", *val); | ||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
327 | { | 590 | { |
328 | struct sd *sd = (struct sd *) gspca_dev; | 591 | struct sd *sd = (struct sd *) gspca_dev; |
592 | s32 *sensor_settings = sd->sensor_priv; | ||
329 | u8 i2c_data; | 593 | u8 i2c_data; |
330 | int err; | 594 | int err; |
331 | 595 | ||
596 | sensor_settings[RED_BALANCE_IDX] = val; | ||
597 | |||
332 | i2c_data = val & 0xff; | 598 | i2c_data = val & 0xff; |
333 | PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); | 599 | PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); |
334 | err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN, | 600 | err = m5602_write_sensor(sd, PO1030_RED_GAIN, |
335 | &i2c_data, 1); | 601 | &i2c_data, 1); |
336 | return err; | 602 | return err; |
337 | } | 603 | } |
338 | 604 | ||
339 | int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 605 | static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) |
340 | { | 606 | { |
341 | struct sd *sd = (struct sd *) gspca_dev; | 607 | struct sd *sd = (struct sd *) gspca_dev; |
342 | u8 i2c_data; | 608 | s32 *sensor_settings = sd->sensor_priv; |
343 | int err; | ||
344 | 609 | ||
345 | err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN, | 610 | *val = sensor_settings[BLUE_BALANCE_IDX]; |
346 | &i2c_data, 1); | 611 | PDEBUG(D_V4L2, "Read blue gain %d", *val); |
347 | *val = i2c_data; | 612 | |
348 | PDEBUG(D_V4L2, "Read red gain %d", *val); | 613 | return 0; |
349 | return err; | ||
350 | } | 614 | } |
351 | 615 | ||
352 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 616 | static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) |
353 | { | 617 | { |
354 | struct sd *sd = (struct sd *) gspca_dev; | 618 | struct sd *sd = (struct sd *) gspca_dev; |
619 | s32 *sensor_settings = sd->sensor_priv; | ||
355 | u8 i2c_data; | 620 | u8 i2c_data; |
356 | int err; | 621 | int err; |
357 | 622 | ||
623 | sensor_settings[BLUE_BALANCE_IDX] = val; | ||
624 | |||
358 | i2c_data = val & 0xff; | 625 | i2c_data = val & 0xff; |
359 | PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); | 626 | PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); |
360 | err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN, | 627 | err = m5602_write_sensor(sd, PO1030_BLUE_GAIN, |
361 | &i2c_data, 1); | 628 | &i2c_data, 1); |
629 | |||
362 | return err; | 630 | return err; |
363 | } | 631 | } |
364 | 632 | ||
365 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 633 | static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val) |
366 | { | 634 | { |
367 | struct sd *sd = (struct sd *) gspca_dev; | 635 | struct sd *sd = (struct sd *) gspca_dev; |
636 | s32 *sensor_settings = sd->sensor_priv; | ||
637 | |||
638 | *val = sensor_settings[GREEN_BALANCE_IDX]; | ||
639 | PDEBUG(D_V4L2, "Read green gain %d", *val); | ||
640 | |||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
645 | { | ||
646 | struct sd *sd = (struct sd *) gspca_dev; | ||
647 | s32 *sensor_settings = sd->sensor_priv; | ||
368 | u8 i2c_data; | 648 | u8 i2c_data; |
369 | int err; | 649 | int err; |
370 | 650 | ||
371 | err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN, | 651 | sensor_settings[GREEN_BALANCE_IDX] = val; |
652 | i2c_data = val & 0xff; | ||
653 | PDEBUG(D_V4L2, "Set green gain to %d", i2c_data); | ||
654 | |||
655 | err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN, | ||
656 | &i2c_data, 1); | ||
657 | if (err < 0) | ||
658 | return err; | ||
659 | |||
660 | return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN, | ||
372 | &i2c_data, 1); | 661 | &i2c_data, 1); |
373 | *val = i2c_data; | 662 | } |
374 | PDEBUG(D_V4L2, "Read blue gain %d", *val); | ||
375 | 663 | ||
376 | return err; | 664 | static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev, |
665 | __s32 *val) | ||
666 | { | ||
667 | struct sd *sd = (struct sd *) gspca_dev; | ||
668 | s32 *sensor_settings = sd->sensor_priv; | ||
669 | |||
670 | *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; | ||
671 | PDEBUG(D_V4L2, "Auto white balancing is %d", *val); | ||
672 | |||
673 | return 0; | ||
377 | } | 674 | } |
378 | 675 | ||
379 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 676 | static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev, |
677 | __s32 val) | ||
380 | { | 678 | { |
381 | struct sd *sd = (struct sd *) gspca_dev; | 679 | struct sd *sd = (struct sd *) gspca_dev; |
680 | s32 *sensor_settings = sd->sensor_priv; | ||
382 | u8 i2c_data; | 681 | u8 i2c_data; |
383 | int err; | 682 | int err; |
384 | i2c_data = val & 0xff; | ||
385 | PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); | ||
386 | err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN, | ||
387 | &i2c_data, 1); | ||
388 | 683 | ||
684 | sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; | ||
685 | |||
686 | err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
687 | if (err < 0) | ||
688 | return err; | ||
689 | |||
690 | PDEBUG(D_V4L2, "Set auto white balance to %d", val); | ||
691 | i2c_data = (i2c_data & 0xfe) | (val & 0x01); | ||
692 | err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
389 | return err; | 693 | return err; |
390 | } | 694 | } |
391 | 695 | ||
392 | int po1030_power_down(struct sd *sd) | 696 | static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev, |
697 | __s32 *val) | ||
393 | { | 698 | { |
699 | struct sd *sd = (struct sd *) gspca_dev; | ||
700 | s32 *sensor_settings = sd->sensor_priv; | ||
701 | |||
702 | *val = sensor_settings[AUTO_EXPOSURE_IDX]; | ||
703 | PDEBUG(D_V4L2, "Auto exposure is %d", *val); | ||
394 | return 0; | 704 | return 0; |
395 | } | 705 | } |
396 | 706 | ||
707 | static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev, | ||
708 | __s32 val) | ||
709 | { | ||
710 | struct sd *sd = (struct sd *) gspca_dev; | ||
711 | s32 *sensor_settings = sd->sensor_priv; | ||
712 | u8 i2c_data; | ||
713 | int err; | ||
714 | |||
715 | sensor_settings[AUTO_EXPOSURE_IDX] = val; | ||
716 | err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
717 | if (err < 0) | ||
718 | return err; | ||
719 | |||
720 | PDEBUG(D_V4L2, "Set auto exposure to %d", val); | ||
721 | i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1); | ||
722 | return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1); | ||
723 | } | ||
724 | |||
725 | void po1030_disconnect(struct sd *sd) | ||
726 | { | ||
727 | sd->sensor = NULL; | ||
728 | kfree(sd->sensor_priv); | ||
729 | } | ||
730 | |||
397 | static void po1030_dump_registers(struct sd *sd) | 731 | static void po1030_dump_registers(struct sd *sd) |
398 | { | 732 | { |
399 | int address; | 733 | int address; |
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h index c10b12335818..1ea380b2bbe7 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.h +++ b/drivers/media/video/gspca/m5602/m5602_po1030.h | |||
@@ -25,98 +25,123 @@ | |||
25 | 25 | ||
26 | /*****************************************************************************/ | 26 | /*****************************************************************************/ |
27 | 27 | ||
28 | #define PO1030_REG_DEVID_H 0x00 | 28 | #define PO1030_DEVID_H 0x00 |
29 | #define PO1030_REG_DEVID_L 0x01 | 29 | #define PO1030_DEVID_L 0x01 |
30 | #define PO1030_REG_FRAMEWIDTH_H 0x04 | 30 | #define PO1030_FRAMEWIDTH_H 0x04 |
31 | #define PO1030_REG_FRAMEWIDTH_L 0x05 | 31 | #define PO1030_FRAMEWIDTH_L 0x05 |
32 | #define PO1030_REG_FRAMEHEIGHT_H 0x06 | 32 | #define PO1030_FRAMEHEIGHT_H 0x06 |
33 | #define PO1030_REG_FRAMEHEIGHT_L 0x07 | 33 | #define PO1030_FRAMEHEIGHT_L 0x07 |
34 | #define PO1030_REG_WINDOWX_H 0x08 | 34 | #define PO1030_WINDOWX_H 0x08 |
35 | #define PO1030_REG_WINDOWX_L 0x09 | 35 | #define PO1030_WINDOWX_L 0x09 |
36 | #define PO1030_REG_WINDOWY_H 0x0a | 36 | #define PO1030_WINDOWY_H 0x0a |
37 | #define PO1030_REG_WINDOWY_L 0x0b | 37 | #define PO1030_WINDOWY_L 0x0b |
38 | #define PO1030_REG_WINDOWWIDTH_H 0x0c | 38 | #define PO1030_WINDOWWIDTH_H 0x0c |
39 | #define PO1030_REG_WINDOWWIDTH_L 0x0d | 39 | #define PO1030_WINDOWWIDTH_L 0x0d |
40 | #define PO1030_REG_WINDOWHEIGHT_H 0x0e | 40 | #define PO1030_WINDOWHEIGHT_H 0x0e |
41 | #define PO1030_REG_WINDOWHEIGHT_L 0x0f | 41 | #define PO1030_WINDOWHEIGHT_L 0x0f |
42 | 42 | ||
43 | #define PO1030_REG_GLOBALIBIAS 0x12 | 43 | #define PO1030_GLOBALIBIAS 0x12 |
44 | #define PO1030_REG_PIXELIBIAS 0x13 | 44 | #define PO1030_PIXELIBIAS 0x13 |
45 | 45 | ||
46 | #define PO1030_REG_GLOBALGAIN 0x15 | 46 | #define PO1030_GLOBALGAIN 0x15 |
47 | #define PO1030_REG_RED_GAIN 0x16 | 47 | #define PO1030_RED_GAIN 0x16 |
48 | #define PO1030_REG_GREEN_1_GAIN 0x17 | 48 | #define PO1030_GREEN_1_GAIN 0x17 |
49 | #define PO1030_REG_BLUE_GAIN 0x18 | 49 | #define PO1030_BLUE_GAIN 0x18 |
50 | #define PO1030_REG_GREEN_2_GAIN 0x19 | 50 | #define PO1030_GREEN_2_GAIN 0x19 |
51 | 51 | ||
52 | #define PO1030_REG_INTEGLINES_H 0x1a | 52 | #define PO1030_INTEGLINES_H 0x1a |
53 | #define PO1030_REG_INTEGLINES_M 0x1b | 53 | #define PO1030_INTEGLINES_M 0x1b |
54 | #define PO1030_REG_INTEGLINES_L 0x1c | 54 | #define PO1030_INTEGLINES_L 0x1c |
55 | 55 | ||
56 | #define PO1030_REG_CONTROL1 0x1d | 56 | #define PO1030_CONTROL1 0x1d |
57 | #define PO1030_REG_CONTROL2 0x1e | 57 | #define PO1030_CONTROL2 0x1e |
58 | #define PO1030_REG_CONTROL3 0x1f | 58 | #define PO1030_CONTROL3 0x1f |
59 | #define PO1030_REG_CONTROL4 0x20 | 59 | #define PO1030_CONTROL4 0x20 |
60 | 60 | ||
61 | #define PO1030_REG_PERIOD50_H 0x23 | 61 | #define PO1030_PERIOD50_H 0x23 |
62 | #define PO1030_REG_PERIOD50_L 0x24 | 62 | #define PO1030_PERIOD50_L 0x24 |
63 | #define PO1030_REG_PERIOD60_H 0x25 | 63 | #define PO1030_PERIOD60_H 0x25 |
64 | #define PO1030_REG_PERIOD60_L 0x26 | 64 | #define PO1030_PERIOD60_L 0x26 |
65 | #define PO1030_REG_REGCLK167 0x27 | 65 | #define PO1030_REGCLK167 0x27 |
66 | #define PO1030_REG_DELTA50 0x28 | 66 | #define PO1030_FLICKER_DELTA50 0x28 |
67 | #define PO1030_REG_DELTA60 0x29 | 67 | #define PO1030_FLICKERDELTA60 0x29 |
68 | 68 | ||
69 | #define PO1030_REG_ADCOFFSET 0x2c | 69 | #define PO1030_ADCOFFSET 0x2c |
70 | 70 | ||
71 | /* Gamma Correction Coeffs */ | 71 | /* Gamma Correction Coeffs */ |
72 | #define PO1030_REG_GC0 0x2d | 72 | #define PO1030_GC0 0x2d |
73 | #define PO1030_REG_GC1 0x2e | 73 | #define PO1030_GC1 0x2e |
74 | #define PO1030_REG_GC2 0x2f | 74 | #define PO1030_GC2 0x2f |
75 | #define PO1030_REG_GC3 0x30 | 75 | #define PO1030_GC3 0x30 |
76 | #define PO1030_REG_GC4 0x31 | 76 | #define PO1030_GC4 0x31 |
77 | #define PO1030_REG_GC5 0x32 | 77 | #define PO1030_GC5 0x32 |
78 | #define PO1030_REG_GC6 0x33 | 78 | #define PO1030_GC6 0x33 |
79 | #define PO1030_REG_GC7 0x34 | 79 | #define PO1030_GC7 0x34 |
80 | 80 | ||
81 | /* Color Transform Matrix */ | 81 | /* Color Transform Matrix */ |
82 | #define PO1030_REG_CT0 0x35 | 82 | #define PO1030_CT0 0x35 |
83 | #define PO1030_REG_CT1 0x36 | 83 | #define PO1030_CT1 0x36 |
84 | #define PO1030_REG_CT2 0x37 | 84 | #define PO1030_CT2 0x37 |
85 | #define PO1030_REG_CT3 0x38 | 85 | #define PO1030_CT3 0x38 |
86 | #define PO1030_REG_CT4 0x39 | 86 | #define PO1030_CT4 0x39 |
87 | #define PO1030_REG_CT5 0x3a | 87 | #define PO1030_CT5 0x3a |
88 | #define PO1030_REG_CT6 0x3b | 88 | #define PO1030_CT6 0x3b |
89 | #define PO1030_REG_CT7 0x3c | 89 | #define PO1030_CT7 0x3c |
90 | #define PO1030_REG_CT8 0x3d | 90 | #define PO1030_CT8 0x3d |
91 | 91 | ||
92 | #define PO1030_REG_AUTOCTRL1 0x3e | 92 | #define PO1030_AUTOCTRL1 0x3e |
93 | #define PO1030_REG_AUTOCTRL2 0x3f | 93 | #define PO1030_AUTOCTRL2 0x3f |
94 | 94 | ||
95 | #define PO1030_REG_YTARGET 0x40 | 95 | #define PO1030_YTARGET 0x40 |
96 | #define PO1030_REG_GLOBALGAINMIN 0x41 | 96 | #define PO1030_GLOBALGAINMIN 0x41 |
97 | #define PO1030_REG_GLOBALGAINMAX 0x42 | 97 | #define PO1030_GLOBALGAINMAX 0x42 |
98 | |||
99 | #define PO1030_AWB_RED_TUNING 0x47 | ||
100 | #define PO1030_AWB_BLUE_TUNING 0x48 | ||
98 | 101 | ||
99 | /* Output format control */ | 102 | /* Output format control */ |
100 | #define PO1030_REG_OUTFORMCTRL1 0x5a | 103 | #define PO1030_OUTFORMCTRL1 0x5a |
101 | #define PO1030_REG_OUTFORMCTRL2 0x5b | 104 | #define PO1030_OUTFORMCTRL2 0x5b |
102 | #define PO1030_REG_OUTFORMCTRL3 0x5c | 105 | #define PO1030_OUTFORMCTRL3 0x5c |
103 | #define PO1030_REG_OUTFORMCTRL4 0x5d | 106 | #define PO1030_OUTFORMCTRL4 0x5d |
104 | #define PO1030_REG_OUTFORMCTRL5 0x5e | 107 | #define PO1030_OUTFORMCTRL5 0x5e |
105 | 108 | ||
106 | /* Imaging coefficients */ | 109 | #define PO1030_EDGE_ENH_OFF 0x5f |
107 | #define PO1030_REG_YBRIGHT 0x73 | 110 | #define PO1030_EGA 0x60 |
108 | #define PO1030_REG_YCONTRAST 0x74 | ||
109 | #define PO1030_REG_YSATURATION 0x75 | ||
110 | 111 | ||
111 | #define PO1030_HFLIP (1 << 7) | 112 | #define PO1030_Cb_U_GAIN 0x63 |
112 | #define PO1030_VFLIP (1 << 6) | 113 | #define PO1030_Cr_V_GAIN 0x64 |
114 | |||
115 | #define PO1030_YCONTRAST 0x74 | ||
116 | #define PO1030_YSATURATION 0x75 | ||
117 | |||
118 | #define PO1030_HFLIP (1 << 7) | ||
119 | #define PO1030_VFLIP (1 << 6) | ||
120 | |||
121 | #define PO1030_HREF_ENABLE (1 << 6) | ||
122 | |||
123 | #define PO1030_RAW_RGB_BAYER 0x4 | ||
124 | |||
125 | #define PO1030_FRAME_EQUAL (1 << 3) | ||
126 | #define PO1030_AUTO_SUBSAMPLING (1 << 4) | ||
127 | |||
128 | #define PO1030_WEIGHT_WIN_2X (1 << 3) | ||
129 | |||
130 | #define PO1030_SHUTTER_MODE (1 << 6) | ||
131 | #define PO1030_AUTO_SUBSAMPLING (1 << 4) | ||
132 | #define PO1030_FRAME_EQUAL (1 << 3) | ||
133 | |||
134 | #define PO1030_SENSOR_RESET (1 << 5) | ||
135 | |||
136 | #define PO1030_SUBSAMPLING (1 << 6) | ||
113 | 137 | ||
114 | /*****************************************************************************/ | 138 | /*****************************************************************************/ |
115 | 139 | ||
116 | #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 | 140 | #define PO1030_GLOBAL_GAIN_DEFAULT 0x12 |
117 | #define PO1030_EXPOSURE_DEFAULT 0x0085 | 141 | #define PO1030_EXPOSURE_DEFAULT 0x0085 |
118 | #define PO1030_BLUE_GAIN_DEFAULT 0x40 | 142 | #define PO1030_BLUE_GAIN_DEFAULT 0x36 |
119 | #define PO1030_RED_GAIN_DEFAULT 0x40 | 143 | #define PO1030_RED_GAIN_DEFAULT 0x36 |
144 | #define PO1030_GREEN_GAIN_DEFAULT 0x40 | ||
120 | 145 | ||
121 | /*****************************************************************************/ | 146 | /*****************************************************************************/ |
122 | 147 | ||
@@ -126,20 +151,8 @@ extern int dump_sensor; | |||
126 | 151 | ||
127 | int po1030_probe(struct sd *sd); | 152 | int po1030_probe(struct sd *sd); |
128 | int po1030_init(struct sd *sd); | 153 | int po1030_init(struct sd *sd); |
129 | int po1030_power_down(struct sd *sd); | 154 | int po1030_start(struct sd *sd); |
130 | 155 | void po1030_disconnect(struct sd *sd); | |
131 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
132 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
133 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
134 | int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
135 | int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
136 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
137 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
138 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
139 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
140 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
141 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
142 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
143 | 156 | ||
144 | static const struct m5602_sensor po1030 = { | 157 | static const struct m5602_sensor po1030 = { |
145 | .name = "PO1030", | 158 | .name = "PO1030", |
@@ -149,7 +162,8 @@ static const struct m5602_sensor po1030 = { | |||
149 | 162 | ||
150 | .probe = po1030_probe, | 163 | .probe = po1030_probe, |
151 | .init = po1030_init, | 164 | .init = po1030_init, |
152 | .power_down = po1030_power_down, | 165 | .start = po1030_start, |
166 | .disconnect = po1030_disconnect, | ||
153 | }; | 167 | }; |
154 | 168 | ||
155 | static const unsigned char preinit_po1030[][3] = | 169 | static const unsigned char preinit_po1030[][3] = |
@@ -159,248 +173,103 @@ static const unsigned char preinit_po1030[][3] = | |||
159 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 173 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
160 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 174 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
161 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | 175 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, |
162 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
163 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | 176 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, |
164 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
165 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | 177 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, |
166 | |||
167 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
168 | |||
169 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
170 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
171 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
172 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
173 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | ||
174 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
175 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
176 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
177 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
178 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | 178 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, |
179 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
180 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
181 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
182 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
183 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
184 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
185 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
186 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
187 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
188 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, | ||
189 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
190 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
191 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
192 | {BRIDGE, M5602_XB_SIG_INI, 0x02}, | ||
193 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
194 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
195 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, | ||
196 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87}, | ||
197 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
198 | |||
199 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
200 | |||
201 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 179 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
202 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | 180 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, |
203 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | 181 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, |
204 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | 182 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, |
205 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | 183 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, |
184 | |||
185 | {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)}, | ||
186 | |||
206 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | 187 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, |
207 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 188 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
208 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 189 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
209 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 190 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
210 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
211 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | 191 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, |
212 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 192 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
213 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00} | 193 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00} |
214 | }; | 194 | }; |
215 | 195 | ||
216 | static const unsigned char init_po1030[][4] = | 196 | static const unsigned char init_po1030[][3] = |
217 | { | 197 | { |
218 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, | 198 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, |
219 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, | 199 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, |
220 | /*sequence 1*/ | ||
221 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 200 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
222 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 201 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
223 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | 202 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, |
224 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, | ||
225 | |||
226 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, | 203 | {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, |
227 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
228 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | 204 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, |
229 | /*end of sequence 1*/ | ||
230 | |||
231 | /*sequence 2 (same as stop sequence)*/ | ||
232 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
233 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | ||
234 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | ||
235 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
236 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | ||
237 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | ||
238 | |||
239 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | ||
240 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
241 | /*end of sequence 2*/ | ||
242 | 205 | ||
243 | /*sequence 5*/ | 206 | {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)}, |
244 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
245 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
246 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
247 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
248 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
249 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
250 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
251 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
252 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
256 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, | ||
257 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
258 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
259 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
260 | {BRIDGE, M5602_XB_SIG_INI, 0x02}, | ||
261 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
262 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
263 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, | ||
264 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87}, | ||
265 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
266 | /*end of sequence 5*/ | ||
267 | |||
268 | /*sequence 2 stop */ | ||
269 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x24}, | ||
270 | 207 | ||
271 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 208 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
272 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, | 209 | {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, |
273 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | 210 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, |
211 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
274 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, | 212 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, |
275 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, | 213 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, |
276 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, | 214 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, |
277 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 215 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
278 | /*end of sequence 2 stop */ | ||
279 | |||
280 | /* --------------------------------- | ||
281 | * end of init - begin of start | ||
282 | * --------------------------------- */ | ||
283 | |||
284 | /*sequence 3*/ | ||
285 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | ||
286 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
287 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
288 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
289 | /*end of sequence 3*/ | ||
290 | /*sequence 4*/ | ||
291 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, | 216 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
292 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, | 217 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, |
293 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, | ||
294 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, | ||
295 | 218 | ||
296 | {SENSOR, PO1030_REG_AUTOCTRL2, 0x04}, | 219 | {SENSOR, PO1030_AUTOCTRL2, 0x04}, |
220 | |||
221 | {SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER}, | ||
222 | {SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X}, | ||
223 | |||
224 | {SENSOR, PO1030_CONTROL2, 0x03}, | ||
225 | {SENSOR, 0x21, 0x90}, | ||
226 | {SENSOR, PO1030_YTARGET, 0x60}, | ||
227 | {SENSOR, 0x59, 0x13}, | ||
228 | {SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE}, | ||
229 | {SENSOR, PO1030_EDGE_ENH_OFF, 0x00}, | ||
230 | {SENSOR, PO1030_EGA, 0x80}, | ||
231 | {SENSOR, 0x78, 0x14}, | ||
232 | {SENSOR, 0x6f, 0x01}, | ||
233 | {SENSOR, PO1030_GLOBALGAINMAX, 0x14}, | ||
234 | {SENSOR, PO1030_Cb_U_GAIN, 0x38}, | ||
235 | {SENSOR, PO1030_Cr_V_GAIN, 0x38}, | ||
236 | {SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE | | ||
237 | PO1030_AUTO_SUBSAMPLING | | ||
238 | PO1030_FRAME_EQUAL}, | ||
239 | {SENSOR, PO1030_GC0, 0x10}, | ||
240 | {SENSOR, PO1030_GC1, 0x20}, | ||
241 | {SENSOR, PO1030_GC2, 0x40}, | ||
242 | {SENSOR, PO1030_GC3, 0x60}, | ||
243 | {SENSOR, PO1030_GC4, 0x80}, | ||
244 | {SENSOR, PO1030_GC5, 0xa0}, | ||
245 | {SENSOR, PO1030_GC6, 0xc0}, | ||
246 | {SENSOR, PO1030_GC7, 0xff}, | ||
297 | 247 | ||
298 | /* Set the width to 751 */ | 248 | /* Set the width to 751 */ |
299 | {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02}, | 249 | {SENSOR, PO1030_FRAMEWIDTH_H, 0x02}, |
300 | {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}, | 250 | {SENSOR, PO1030_FRAMEWIDTH_L, 0xef}, |
301 | 251 | ||
302 | /* Set the height to 540 */ | 252 | /* Set the height to 540 */ |
303 | {SENSOR, PO1030_REG_FRAMEHEIGHT_H, 0x02}, | 253 | {SENSOR, PO1030_FRAMEHEIGHT_H, 0x02}, |
304 | {SENSOR, PO1030_REG_FRAMEHEIGHT_L, 0x1c}, | 254 | {SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c}, |
305 | 255 | ||
306 | /* Set the x window to 1 */ | 256 | /* Set the x window to 1 */ |
307 | {SENSOR, PO1030_REG_WINDOWX_H, 0x00}, | 257 | {SENSOR, PO1030_WINDOWX_H, 0x00}, |
308 | {SENSOR, PO1030_REG_WINDOWX_L, 0x01}, | 258 | {SENSOR, PO1030_WINDOWX_L, 0x01}, |
309 | 259 | ||
310 | /* Set the y window to 1 */ | 260 | /* Set the y window to 1 */ |
311 | {SENSOR, PO1030_REG_WINDOWY_H, 0x00}, | 261 | {SENSOR, PO1030_WINDOWY_H, 0x00}, |
312 | {SENSOR, PO1030_REG_WINDOWY_L, 0x01}, | 262 | {SENSOR, PO1030_WINDOWY_L, 0x01}, |
313 | |||
314 | {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02}, | ||
315 | {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87}, | ||
316 | {SENSOR, PO1030_REG_WINDOWHEIGHT_H, 0x01}, | ||
317 | {SENSOR, PO1030_REG_WINDOWHEIGHT_L, 0xe3}, | ||
318 | |||
319 | {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04}, | ||
320 | {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04}, | ||
321 | {SENSOR, PO1030_REG_AUTOCTRL1, 0x08}, | ||
322 | {SENSOR, PO1030_REG_CONTROL2, 0x03}, | ||
323 | {SENSOR, 0x21, 0x90}, | ||
324 | {SENSOR, PO1030_REG_YTARGET, 0x60}, | ||
325 | {SENSOR, 0x59, 0x13}, | ||
326 | {SENSOR, PO1030_REG_OUTFORMCTRL1, 0x40}, | ||
327 | {SENSOR, 0x5f, 0x00}, | ||
328 | {SENSOR, 0x60, 0x80}, | ||
329 | {SENSOR, 0x78, 0x14}, | ||
330 | {SENSOR, 0x6f, 0x01}, | ||
331 | {SENSOR, PO1030_REG_CONTROL1, 0x18}, | ||
332 | {SENSOR, PO1030_REG_GLOBALGAINMAX, 0x14}, | ||
333 | {SENSOR, 0x63, 0x38}, | ||
334 | {SENSOR, 0x64, 0x38}, | ||
335 | {SENSOR, PO1030_REG_CONTROL1, 0x58}, | ||
336 | {SENSOR, PO1030_REG_RED_GAIN, 0x30}, | ||
337 | {SENSOR, PO1030_REG_GREEN_1_GAIN, 0x30}, | ||
338 | {SENSOR, PO1030_REG_BLUE_GAIN, 0x30}, | ||
339 | {SENSOR, PO1030_REG_GREEN_2_GAIN, 0x30}, | ||
340 | {SENSOR, PO1030_REG_GC0, 0x10}, | ||
341 | {SENSOR, PO1030_REG_GC1, 0x20}, | ||
342 | {SENSOR, PO1030_REG_GC2, 0x40}, | ||
343 | {SENSOR, PO1030_REG_GC3, 0x60}, | ||
344 | {SENSOR, PO1030_REG_GC4, 0x80}, | ||
345 | {SENSOR, PO1030_REG_GC5, 0xa0}, | ||
346 | {SENSOR, PO1030_REG_GC6, 0xc0}, | ||
347 | {SENSOR, PO1030_REG_GC7, 0xff}, | ||
348 | /*end of sequence 4*/ | ||
349 | /*sequence 5*/ | ||
350 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, | ||
351 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | ||
352 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, | ||
353 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, | ||
354 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, | ||
355 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, | ||
356 | {BRIDGE, M5602_XB_SIG_INI, 0x01}, | ||
357 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
358 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, | ||
359 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
360 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
361 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, | ||
362 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, | ||
363 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
364 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, | ||
365 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
366 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
367 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
368 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, | ||
369 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, | ||
370 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7e}, | ||
371 | {BRIDGE, M5602_XB_SIG_INI, 0x00}, | ||
372 | /*end of sequence 5*/ | ||
373 | |||
374 | /*sequence 6*/ | ||
375 | /* Changing 40 in f0 the image becomes green in bayer mode and red in | ||
376 | * rgb mode */ | ||
377 | {SENSOR, PO1030_REG_RED_GAIN, PO1030_RED_GAIN_DEFAULT}, | ||
378 | /* in changing 40 in f0 the image becomes green in bayer mode and red in | ||
379 | * rgb mode */ | ||
380 | {SENSOR, PO1030_REG_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT}, | ||
381 | 263 | ||
382 | /* with a very low lighted environment increase the exposure but | 264 | /* with a very low lighted environment increase the exposure but |
383 | * decrease the FPS (Frame Per Second) */ | 265 | * decrease the FPS (Frame Per Second) */ |
384 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, | 266 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, |
385 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, | 267 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, |
386 | 268 | ||
387 | /* Controls high exposure more than SENSOR_LOW_EXPOSURE, use only in | 269 | {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, |
388 | * low lighted environment (f0 is more than ff ?)*/ | 270 | {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, |
389 | {SENSOR, PO1030_REG_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2) | 271 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, |
390 | & 0xff)}, | 272 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, |
391 | |||
392 | /* Controls middle exposure, use only in high lighted environment */ | ||
393 | {SENSOR, PO1030_REG_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff}, | ||
394 | |||
395 | /* Controls clarity (not sure) */ | ||
396 | {SENSOR, PO1030_REG_INTEGLINES_L, 0x00}, | ||
397 | /* Controls gain (the image is more lighted) */ | ||
398 | {SENSOR, PO1030_REG_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT}, | ||
399 | |||
400 | /* Sets the width */ | ||
401 | {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02}, | ||
402 | {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef} | ||
403 | /*end of sequence 6*/ | ||
404 | }; | 273 | }; |
405 | 274 | ||
406 | #endif | 275 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 4306d596056d..191bcd718979 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |||
@@ -18,6 +18,19 @@ | |||
18 | 18 | ||
19 | #include "m5602_s5k4aa.h" | 19 | #include "m5602_s5k4aa.h" |
20 | 20 | ||
21 | static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
22 | static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
29 | static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val); | ||
30 | static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val); | ||
31 | static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
32 | static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
33 | |||
21 | static | 34 | static |
22 | const | 35 | const |
23 | struct dmi_system_id s5k4aa_vflip_dmi_table[] = { | 36 | struct dmi_system_id s5k4aa_vflip_dmi_table[] = { |
@@ -46,6 +59,18 @@ static | |||
46 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), | 59 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), |
47 | DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700") | 60 | DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700") |
48 | } | 61 | } |
62 | }, { | ||
63 | .ident = "MSI L735", | ||
64 | .matches = { | ||
65 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), | ||
66 | DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X") | ||
67 | } | ||
68 | }, { | ||
69 | .ident = "Lenovo Y300", | ||
70 | .matches = { | ||
71 | DMI_MATCH(DMI_SYS_VENDOR, "L3000 Y300"), | ||
72 | DMI_MATCH(DMI_PRODUCT_NAME, "Y300") | ||
73 | } | ||
49 | }, | 74 | }, |
50 | { } | 75 | { } |
51 | }; | 76 | }; |
@@ -61,10 +86,22 @@ static struct v4l2_pix_format s5k4aa_modes[] = { | |||
61 | .bytesperline = 640, | 86 | .bytesperline = 640, |
62 | .colorspace = V4L2_COLORSPACE_SRGB, | 87 | .colorspace = V4L2_COLORSPACE_SRGB, |
63 | .priv = 0 | 88 | .priv = 0 |
89 | }, | ||
90 | { | ||
91 | 1280, | ||
92 | 1024, | ||
93 | V4L2_PIX_FMT_SBGGR8, | ||
94 | V4L2_FIELD_NONE, | ||
95 | .sizeimage = | ||
96 | 1280 * 1024, | ||
97 | .bytesperline = 1280, | ||
98 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
99 | .priv = 0 | ||
64 | } | 100 | } |
65 | }; | 101 | }; |
66 | 102 | ||
67 | const static struct ctrl s5k4aa_ctrls[] = { | 103 | static const struct ctrl s5k4aa_ctrls[] = { |
104 | #define VFLIP_IDX 0 | ||
68 | { | 105 | { |
69 | { | 106 | { |
70 | .id = V4L2_CID_VFLIP, | 107 | .id = V4L2_CID_VFLIP, |
@@ -77,8 +114,9 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
77 | }, | 114 | }, |
78 | .set = s5k4aa_set_vflip, | 115 | .set = s5k4aa_set_vflip, |
79 | .get = s5k4aa_get_vflip | 116 | .get = s5k4aa_get_vflip |
80 | 117 | }, | |
81 | }, { | 118 | #define HFLIP_IDX 1 |
119 | { | ||
82 | { | 120 | { |
83 | .id = V4L2_CID_HFLIP, | 121 | .id = V4L2_CID_HFLIP, |
84 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 122 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -90,8 +128,9 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
90 | }, | 128 | }, |
91 | .set = s5k4aa_set_hflip, | 129 | .set = s5k4aa_set_hflip, |
92 | .get = s5k4aa_get_hflip | 130 | .get = s5k4aa_get_hflip |
93 | 131 | }, | |
94 | }, { | 132 | #define GAIN_IDX 2 |
133 | { | ||
95 | { | 134 | { |
96 | .id = V4L2_CID_GAIN, | 135 | .id = V4L2_CID_GAIN, |
97 | .type = V4L2_CTRL_TYPE_INTEGER, | 136 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -99,12 +138,14 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
99 | .minimum = 0, | 138 | .minimum = 0, |
100 | .maximum = 127, | 139 | .maximum = 127, |
101 | .step = 1, | 140 | .step = 1, |
102 | .default_value = 0xa0, | 141 | .default_value = S5K4AA_DEFAULT_GAIN, |
103 | .flags = V4L2_CTRL_FLAG_SLIDER | 142 | .flags = V4L2_CTRL_FLAG_SLIDER |
104 | }, | 143 | }, |
105 | .set = s5k4aa_set_gain, | 144 | .set = s5k4aa_set_gain, |
106 | .get = s5k4aa_get_gain | 145 | .get = s5k4aa_get_gain |
107 | }, { | 146 | }, |
147 | #define EXPOSURE_IDX 3 | ||
148 | { | ||
108 | { | 149 | { |
109 | .id = V4L2_CID_EXPOSURE, | 150 | .id = V4L2_CID_EXPOSURE, |
110 | .type = V4L2_CTRL_TYPE_INTEGER, | 151 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -117,7 +158,36 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
117 | }, | 158 | }, |
118 | .set = s5k4aa_set_exposure, | 159 | .set = s5k4aa_set_exposure, |
119 | .get = s5k4aa_get_exposure | 160 | .get = s5k4aa_get_exposure |
120 | } | 161 | }, |
162 | #define NOISE_SUPP_IDX 4 | ||
163 | { | ||
164 | { | ||
165 | .id = V4L2_CID_PRIVATE_BASE, | ||
166 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
167 | .name = "Noise suppression (smoothing)", | ||
168 | .minimum = 0, | ||
169 | .maximum = 1, | ||
170 | .step = 1, | ||
171 | .default_value = 1, | ||
172 | }, | ||
173 | .set = s5k4aa_set_noise, | ||
174 | .get = s5k4aa_get_noise | ||
175 | }, | ||
176 | #define BRIGHTNESS_IDX 5 | ||
177 | { | ||
178 | { | ||
179 | .id = V4L2_CID_BRIGHTNESS, | ||
180 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
181 | .name = "Brightness", | ||
182 | .minimum = 0, | ||
183 | .maximum = 0x1f, | ||
184 | .step = 1, | ||
185 | .default_value = S5K4AA_DEFAULT_BRIGHTNESS, | ||
186 | }, | ||
187 | .set = s5k4aa_set_brightness, | ||
188 | .get = s5k4aa_get_brightness | ||
189 | }, | ||
190 | |||
121 | }; | 191 | }; |
122 | 192 | ||
123 | static void s5k4aa_dump_registers(struct sd *sd); | 193 | static void s5k4aa_dump_registers(struct sd *sd); |
@@ -127,6 +197,7 @@ int s5k4aa_probe(struct sd *sd) | |||
127 | u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | 197 | u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
128 | const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; | 198 | const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; |
129 | int i, err = 0; | 199 | int i, err = 0; |
200 | s32 *sensor_settings; | ||
130 | 201 | ||
131 | if (force_sensor) { | 202 | if (force_sensor) { |
132 | if (force_sensor == S5K4AA_SENSOR) { | 203 | if (force_sensor == S5K4AA_SENSOR) { |
@@ -185,10 +256,20 @@ int s5k4aa_probe(struct sd *sd) | |||
185 | info("Detected a s5k4aa sensor"); | 256 | info("Detected a s5k4aa sensor"); |
186 | 257 | ||
187 | sensor_found: | 258 | sensor_found: |
259 | sensor_settings = kmalloc( | ||
260 | ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL); | ||
261 | if (!sensor_settings) | ||
262 | return -ENOMEM; | ||
263 | |||
188 | sd->gspca_dev.cam.cam_mode = s5k4aa_modes; | 264 | sd->gspca_dev.cam.cam_mode = s5k4aa_modes; |
189 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); | 265 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); |
190 | sd->desc->ctrls = s5k4aa_ctrls; | 266 | sd->desc->ctrls = s5k4aa_ctrls; |
191 | sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); | 267 | sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); |
268 | |||
269 | for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++) | ||
270 | sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value; | ||
271 | sd->sensor_priv = sensor_settings; | ||
272 | |||
192 | return 0; | 273 | return 0; |
193 | } | 274 | } |
194 | 275 | ||
@@ -197,9 +278,45 @@ int s5k4aa_start(struct sd *sd) | |||
197 | int i, err = 0; | 278 | int i, err = 0; |
198 | u8 data[2]; | 279 | u8 data[2]; |
199 | struct cam *cam = &sd->gspca_dev.cam; | 280 | struct cam *cam = &sd->gspca_dev.cam; |
281 | s32 *sensor_settings = sd->sensor_priv; | ||
282 | |||
283 | switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) { | ||
284 | case 1280: | ||
285 | PDEBUG(D_V4L2, "Configuring camera for SXGA mode"); | ||
286 | |||
287 | for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) { | ||
288 | switch (SXGA_s5k4aa[i][0]) { | ||
289 | case BRIDGE: | ||
290 | err = m5602_write_bridge(sd, | ||
291 | SXGA_s5k4aa[i][1], | ||
292 | SXGA_s5k4aa[i][2]); | ||
293 | break; | ||
294 | |||
295 | case SENSOR: | ||
296 | data[0] = SXGA_s5k4aa[i][2]; | ||
297 | err = m5602_write_sensor(sd, | ||
298 | SXGA_s5k4aa[i][1], | ||
299 | data, 1); | ||
300 | break; | ||
301 | |||
302 | case SENSOR_LONG: | ||
303 | data[0] = SXGA_s5k4aa[i][2]; | ||
304 | data[1] = SXGA_s5k4aa[i][3]; | ||
305 | err = m5602_write_sensor(sd, | ||
306 | SXGA_s5k4aa[i][1], | ||
307 | data, 2); | ||
308 | break; | ||
309 | |||
310 | default: | ||
311 | err("Invalid stream command, exiting init"); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | } | ||
315 | err = s5k4aa_set_noise(&sd->gspca_dev, 0); | ||
316 | if (err < 0) | ||
317 | return err; | ||
318 | break; | ||
200 | 319 | ||
201 | switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) | ||
202 | { | ||
203 | case 640: | 320 | case 640: |
204 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); | 321 | PDEBUG(D_V4L2, "Configuring camera for VGA mode"); |
205 | 322 | ||
@@ -231,8 +348,37 @@ int s5k4aa_start(struct sd *sd) | |||
231 | return -EINVAL; | 348 | return -EINVAL; |
232 | } | 349 | } |
233 | } | 350 | } |
351 | err = s5k4aa_set_noise(&sd->gspca_dev, 1); | ||
352 | if (err < 0) | ||
353 | return err; | ||
354 | break; | ||
234 | } | 355 | } |
235 | return err; | 356 | if (err < 0) |
357 | return err; | ||
358 | |||
359 | err = s5k4aa_set_exposure(&sd->gspca_dev, | ||
360 | sensor_settings[EXPOSURE_IDX]); | ||
361 | if (err < 0) | ||
362 | return err; | ||
363 | |||
364 | err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); | ||
365 | if (err < 0) | ||
366 | return err; | ||
367 | |||
368 | err = s5k4aa_set_brightness(&sd->gspca_dev, | ||
369 | sensor_settings[BRIGHTNESS_IDX]); | ||
370 | if (err < 0) | ||
371 | return err; | ||
372 | |||
373 | err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]); | ||
374 | if (err < 0) | ||
375 | return err; | ||
376 | |||
377 | err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); | ||
378 | if (err < 0) | ||
379 | return err; | ||
380 | |||
381 | return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
236 | } | 382 | } |
237 | 383 | ||
238 | int s5k4aa_init(struct sd *sd) | 384 | int s5k4aa_init(struct sd *sd) |
@@ -270,62 +416,28 @@ int s5k4aa_init(struct sd *sd) | |||
270 | if (dump_sensor) | 416 | if (dump_sensor) |
271 | s5k4aa_dump_registers(sd); | 417 | s5k4aa_dump_registers(sd); |
272 | 418 | ||
273 | if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) { | 419 | return err; |
274 | u8 data = 0x02; | ||
275 | info("vertical flip quirk active"); | ||
276 | m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
277 | m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
278 | data |= S5K4AA_RM_V_FLIP; | ||
279 | data &= ~S5K4AA_RM_H_FLIP; | ||
280 | m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
281 | |||
282 | /* Decrement COLSTART to preserve color order (BGGR) */ | ||
283 | m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
284 | data--; | ||
285 | m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
286 | |||
287 | /* Increment ROWSTART to preserve color order (BGGR) */ | ||
288 | m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
289 | data++; | ||
290 | m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
291 | } | ||
292 | |||
293 | return (err < 0) ? err : 0; | ||
294 | } | ||
295 | |||
296 | int s5k4aa_power_down(struct sd *sd) | ||
297 | { | ||
298 | return 0; | ||
299 | } | 420 | } |
300 | 421 | ||
301 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 422 | static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
302 | { | 423 | { |
303 | struct sd *sd = (struct sd *) gspca_dev; | 424 | struct sd *sd = (struct sd *) gspca_dev; |
304 | u8 data = S5K4AA_PAGE_MAP_2; | 425 | s32 *sensor_settings = sd->sensor_priv; |
305 | int err; | ||
306 | |||
307 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
308 | if (err < 0) | ||
309 | return err; | ||
310 | 426 | ||
311 | err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); | 427 | *val = sensor_settings[EXPOSURE_IDX]; |
312 | if (err < 0) | ||
313 | return err; | ||
314 | |||
315 | *val = data << 8; | ||
316 | err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); | ||
317 | *val |= data; | ||
318 | PDEBUG(D_V4L2, "Read exposure %d", *val); | 428 | PDEBUG(D_V4L2, "Read exposure %d", *val); |
319 | 429 | ||
320 | return err; | 430 | return 0; |
321 | } | 431 | } |
322 | 432 | ||
323 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 433 | static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
324 | { | 434 | { |
325 | struct sd *sd = (struct sd *) gspca_dev; | 435 | struct sd *sd = (struct sd *) gspca_dev; |
436 | s32 *sensor_settings = sd->sensor_priv; | ||
326 | u8 data = S5K4AA_PAGE_MAP_2; | 437 | u8 data = S5K4AA_PAGE_MAP_2; |
327 | int err; | 438 | int err; |
328 | 439 | ||
440 | sensor_settings[EXPOSURE_IDX] = val; | ||
329 | PDEBUG(D_V4L2, "Set exposure to %d", val); | 441 | PDEBUG(D_V4L2, "Set exposure to %d", val); |
330 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 442 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
331 | if (err < 0) | 443 | if (err < 0) |
@@ -340,29 +452,26 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
340 | return err; | 452 | return err; |
341 | } | 453 | } |
342 | 454 | ||
343 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 455 | static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
344 | { | 456 | { |
345 | struct sd *sd = (struct sd *) gspca_dev; | 457 | struct sd *sd = (struct sd *) gspca_dev; |
346 | u8 data = S5K4AA_PAGE_MAP_2; | 458 | s32 *sensor_settings = sd->sensor_priv; |
347 | int err; | ||
348 | |||
349 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
350 | if (err < 0) | ||
351 | return err; | ||
352 | 459 | ||
353 | err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 460 | *val = sensor_settings[VFLIP_IDX]; |
354 | *val = (data & S5K4AA_RM_V_FLIP) >> 7; | ||
355 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 461 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
356 | 462 | ||
357 | return err; | 463 | return 0; |
358 | } | 464 | } |
359 | 465 | ||
360 | int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 466 | static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
361 | { | 467 | { |
362 | struct sd *sd = (struct sd *) gspca_dev; | 468 | struct sd *sd = (struct sd *) gspca_dev; |
469 | s32 *sensor_settings = sd->sensor_priv; | ||
363 | u8 data = S5K4AA_PAGE_MAP_2; | 470 | u8 data = S5K4AA_PAGE_MAP_2; |
364 | int err; | 471 | int err; |
365 | 472 | ||
473 | sensor_settings[VFLIP_IDX] = val; | ||
474 | |||
366 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 475 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
367 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 476 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
368 | if (err < 0) | 477 | if (err < 0) |
@@ -370,56 +479,48 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
370 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 479 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
371 | if (err < 0) | 480 | if (err < 0) |
372 | return err; | 481 | return err; |
373 | data = ((data & ~S5K4AA_RM_V_FLIP) | 482 | |
374 | | ((val & 0x01) << 7)); | 483 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
375 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
376 | if (err < 0) | 484 | if (err < 0) |
377 | return err; | 485 | return err; |
378 | 486 | ||
379 | if (val) { | 487 | if (dmi_check_system(s5k4aa_vflip_dmi_table)) |
380 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | 488 | val = !val; |
381 | if (err < 0) | ||
382 | return err; | ||
383 | |||
384 | data++; | ||
385 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
386 | } else { | ||
387 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
388 | if (err < 0) | ||
389 | return err; | ||
390 | 489 | ||
391 | data--; | 490 | data = ((data & ~S5K4AA_RM_V_FLIP) | ((val & 0x01) << 7)); |
392 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | 491 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
393 | } | 492 | if (err < 0) |
493 | return err; | ||
394 | 494 | ||
495 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
496 | if (err < 0) | ||
497 | return err; | ||
498 | data = (data & 0xfe) | !val; | ||
499 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | ||
395 | return err; | 500 | return err; |
396 | } | 501 | } |
397 | 502 | ||
398 | int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 503 | static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
399 | { | 504 | { |
400 | struct sd *sd = (struct sd *) gspca_dev; | 505 | struct sd *sd = (struct sd *) gspca_dev; |
401 | u8 data = S5K4AA_PAGE_MAP_2; | 506 | s32 *sensor_settings = sd->sensor_priv; |
402 | int err; | ||
403 | |||
404 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
405 | if (err < 0) | ||
406 | return err; | ||
407 | 507 | ||
408 | err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 508 | *val = sensor_settings[HFLIP_IDX]; |
409 | *val = (data & S5K4AA_RM_H_FLIP) >> 6; | ||
410 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 509 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
411 | 510 | ||
412 | return err; | 511 | return 0; |
413 | } | 512 | } |
414 | 513 | ||
415 | int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 514 | static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
416 | { | 515 | { |
417 | struct sd *sd = (struct sd *) gspca_dev; | 516 | struct sd *sd = (struct sd *) gspca_dev; |
517 | s32 *sensor_settings = sd->sensor_priv; | ||
418 | u8 data = S5K4AA_PAGE_MAP_2; | 518 | u8 data = S5K4AA_PAGE_MAP_2; |
419 | int err; | 519 | int err; |
420 | 520 | ||
421 | PDEBUG(D_V4L2, "Set horizontal flip to %d", | 521 | sensor_settings[HFLIP_IDX] = val; |
422 | val); | 522 | |
523 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | ||
423 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 524 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
424 | if (err < 0) | 525 | if (err < 0) |
425 | return err; | 526 | return err; |
@@ -427,62 +528,116 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
427 | if (err < 0) | 528 | if (err < 0) |
428 | return err; | 529 | return err; |
429 | 530 | ||
531 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
532 | if (err < 0) | ||
533 | return err; | ||
534 | |||
535 | if (dmi_check_system(s5k4aa_vflip_dmi_table)) | ||
536 | val = !val; | ||
537 | |||
430 | data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); | 538 | data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); |
431 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 539 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
432 | if (err < 0) | 540 | if (err < 0) |
433 | return err; | 541 | return err; |
434 | 542 | ||
435 | if (val) { | 543 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); |
436 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | 544 | if (err < 0) |
437 | if (err < 0) | 545 | return err; |
438 | return err; | 546 | data = (data & 0xfe) | !val; |
439 | data++; | 547 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); |
440 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
441 | if (err < 0) | ||
442 | return err; | ||
443 | } else { | ||
444 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
445 | if (err < 0) | ||
446 | return err; | ||
447 | data--; | ||
448 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | ||
449 | } | ||
450 | |||
451 | return err; | 548 | return err; |
452 | } | 549 | } |
453 | 550 | ||
454 | int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 551 | static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
552 | { | ||
553 | struct sd *sd = (struct sd *) gspca_dev; | ||
554 | s32 *sensor_settings = sd->sensor_priv; | ||
555 | |||
556 | *val = sensor_settings[GAIN_IDX]; | ||
557 | PDEBUG(D_V4L2, "Read gain %d", *val); | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
455 | { | 562 | { |
456 | struct sd *sd = (struct sd *) gspca_dev; | 563 | struct sd *sd = (struct sd *) gspca_dev; |
564 | s32 *sensor_settings = sd->sensor_priv; | ||
457 | u8 data = S5K4AA_PAGE_MAP_2; | 565 | u8 data = S5K4AA_PAGE_MAP_2; |
458 | int err; | 566 | int err; |
459 | 567 | ||
568 | sensor_settings[GAIN_IDX] = val; | ||
569 | |||
570 | PDEBUG(D_V4L2, "Set gain to %d", val); | ||
460 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 571 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
461 | if (err < 0) | 572 | if (err < 0) |
462 | return err; | 573 | return err; |
463 | 574 | ||
464 | err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); | 575 | data = val & 0xff; |
465 | *val = data; | 576 | err = m5602_write_sensor(sd, S5K4AA_GAIN, &data, 1); |
466 | PDEBUG(D_V4L2, "Read gain %d", *val); | ||
467 | 577 | ||
468 | return err; | 578 | return err; |
469 | } | 579 | } |
470 | 580 | ||
471 | int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 581 | static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) |
582 | { | ||
583 | struct sd *sd = (struct sd *) gspca_dev; | ||
584 | s32 *sensor_settings = sd->sensor_priv; | ||
585 | |||
586 | *val = sensor_settings[BRIGHTNESS_IDX]; | ||
587 | PDEBUG(D_V4L2, "Read brightness %d", *val); | ||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | ||
472 | { | 592 | { |
473 | struct sd *sd = (struct sd *) gspca_dev; | 593 | struct sd *sd = (struct sd *) gspca_dev; |
594 | s32 *sensor_settings = sd->sensor_priv; | ||
474 | u8 data = S5K4AA_PAGE_MAP_2; | 595 | u8 data = S5K4AA_PAGE_MAP_2; |
475 | int err; | 596 | int err; |
476 | 597 | ||
477 | PDEBUG(D_V4L2, "Set gain to %d", val); | 598 | sensor_settings[BRIGHTNESS_IDX] = val; |
599 | |||
600 | PDEBUG(D_V4L2, "Set brightness to %d", val); | ||
478 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 601 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
479 | if (err < 0) | 602 | if (err < 0) |
480 | return err; | 603 | return err; |
481 | 604 | ||
482 | data = val & 0xff; | 605 | data = val & 0xff; |
483 | err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1); | 606 | return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1); |
607 | } | ||
484 | 608 | ||
485 | return err; | 609 | static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val) |
610 | { | ||
611 | struct sd *sd = (struct sd *) gspca_dev; | ||
612 | s32 *sensor_settings = sd->sensor_priv; | ||
613 | |||
614 | *val = sensor_settings[NOISE_SUPP_IDX]; | ||
615 | PDEBUG(D_V4L2, "Read noise %d", *val); | ||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val) | ||
620 | { | ||
621 | struct sd *sd = (struct sd *) gspca_dev; | ||
622 | s32 *sensor_settings = sd->sensor_priv; | ||
623 | u8 data = S5K4AA_PAGE_MAP_2; | ||
624 | int err; | ||
625 | |||
626 | sensor_settings[NOISE_SUPP_IDX] = val; | ||
627 | |||
628 | PDEBUG(D_V4L2, "Set noise to %d", val); | ||
629 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
630 | if (err < 0) | ||
631 | return err; | ||
632 | |||
633 | data = val & 0x01; | ||
634 | return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1); | ||
635 | } | ||
636 | |||
637 | void s5k4aa_disconnect(struct sd *sd) | ||
638 | { | ||
639 | sd->sensor = NULL; | ||
640 | kfree(sd->sensor_priv); | ||
486 | } | 641 | } |
487 | 642 | ||
488 | static void s5k4aa_dump_registers(struct sd *sd) | 643 | static void s5k4aa_dump_registers(struct sd *sd) |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h index ca854d4f9475..4440da4e7f0f 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h | |||
@@ -47,8 +47,9 @@ | |||
47 | #define S5K4AA_H_BLANK_LO__ 0x1e | 47 | #define S5K4AA_H_BLANK_LO__ 0x1e |
48 | #define S5K4AA_EXPOSURE_HI 0x17 | 48 | #define S5K4AA_EXPOSURE_HI 0x17 |
49 | #define S5K4AA_EXPOSURE_LO 0x18 | 49 | #define S5K4AA_EXPOSURE_LO 0x18 |
50 | #define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */ | 50 | #define S5K4AA_BRIGHTNESS 0x1f /* (digital?) gain : 5 bits */ |
51 | #define S5K4AA_GAIN_2 0x20 /* (analogue?) gain : 7 bits */ | 51 | #define S5K4AA_GAIN 0x20 /* (analogue?) gain : 7 bits */ |
52 | #define S5K4AA_NOISE_SUPP 0x37 | ||
52 | 53 | ||
53 | #define S5K4AA_RM_ROW_SKIP_4X 0x08 | 54 | #define S5K4AA_RM_ROW_SKIP_4X 0x08 |
54 | #define S5K4AA_RM_ROW_SKIP_2X 0x04 | 55 | #define S5K4AA_RM_ROW_SKIP_2X 0x04 |
@@ -57,6 +58,9 @@ | |||
57 | #define S5K4AA_RM_H_FLIP 0x40 | 58 | #define S5K4AA_RM_H_FLIP 0x40 |
58 | #define S5K4AA_RM_V_FLIP 0x80 | 59 | #define S5K4AA_RM_V_FLIP 0x80 |
59 | 60 | ||
61 | #define S5K4AA_DEFAULT_GAIN 0x5f | ||
62 | #define S5K4AA_DEFAULT_BRIGHTNESS 0x10 | ||
63 | |||
60 | /*****************************************************************************/ | 64 | /*****************************************************************************/ |
61 | 65 | ||
62 | /* Kernel module parameters */ | 66 | /* Kernel module parameters */ |
@@ -66,25 +70,17 @@ extern int dump_sensor; | |||
66 | int s5k4aa_probe(struct sd *sd); | 70 | int s5k4aa_probe(struct sd *sd); |
67 | int s5k4aa_init(struct sd *sd); | 71 | int s5k4aa_init(struct sd *sd); |
68 | int s5k4aa_start(struct sd *sd); | 72 | int s5k4aa_start(struct sd *sd); |
69 | int s5k4aa_power_down(struct sd *sd); | 73 | void s5k4aa_disconnect(struct sd *sd); |
70 | |||
71 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
72 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
73 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
74 | int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
75 | int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
76 | int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
77 | int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
78 | int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
79 | 74 | ||
80 | static const struct m5602_sensor s5k4aa = { | 75 | static const struct m5602_sensor s5k4aa = { |
81 | .name = "S5K4AA", | 76 | .name = "S5K4AA", |
77 | .i2c_slave_id = 0x5a, | ||
78 | .i2c_regW = 2, | ||
79 | |||
82 | .probe = s5k4aa_probe, | 80 | .probe = s5k4aa_probe, |
83 | .init = s5k4aa_init, | 81 | .init = s5k4aa_init, |
84 | .start = s5k4aa_start, | 82 | .start = s5k4aa_start, |
85 | .power_down = s5k4aa_power_down, | 83 | .disconnect = s5k4aa_disconnect, |
86 | .i2c_slave_id = 0x5a, | ||
87 | .i2c_regW = 2, | ||
88 | }; | 84 | }; |
89 | 85 | ||
90 | static const unsigned char preinit_s5k4aa[][4] = | 86 | static const unsigned char preinit_s5k4aa[][4] = |
@@ -179,30 +175,12 @@ static const unsigned char init_s5k4aa[][4] = | |||
179 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 175 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
180 | {SENSOR, 0x0c, 0x05, 0x00}, | 176 | {SENSOR, 0x0c, 0x05, 0x00}, |
181 | {SENSOR, 0x02, 0x0e, 0x00}, | 177 | {SENSOR, 0x02, 0x0e, 0x00}, |
182 | {SENSOR, S5K4AA_GAIN_1, 0x0f, 0x00}, | ||
183 | {SENSOR, S5K4AA_GAIN_2, 0x00, 0x00}, | ||
184 | {SENSOR, S5K4AA_GLOBAL_GAIN__, 0x01, 0x00}, | ||
185 | {SENSOR, 0x11, 0x00, 0x00}, | ||
186 | {SENSOR, 0x12, 0x00, 0x00}, | ||
187 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | ||
188 | {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00}, | 178 | {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00}, |
189 | {SENSOR, 0x37, 0x00, 0x00}, | 179 | {SENSOR, 0x37, 0x00, 0x00}, |
190 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, | 180 | }; |
191 | {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, | ||
192 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, | ||
193 | {SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00}, | ||
194 | {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, | ||
195 | {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc4, 0x00}, | ||
196 | {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, | ||
197 | {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x08, 0x00}, | ||
198 | {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, | ||
199 | {SENSOR, S5K4AA_H_BLANK_LO__, 0x48, 0x00}, | ||
200 | {SENSOR, S5K4AA_EXPOSURE_HI, 0x00, 0x00}, | ||
201 | {SENSOR, S5K4AA_EXPOSURE_LO, 0x43, 0x00}, | ||
202 | {SENSOR, 0x11, 0x04, 0x00}, | ||
203 | {SENSOR, 0x12, 0xc3, 0x00}, | ||
204 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | ||
205 | 181 | ||
182 | static const unsigned char VGA_s5k4aa[][4] = | ||
183 | { | ||
206 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 184 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
207 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 185 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
208 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 186 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -238,7 +216,7 @@ static const unsigned char init_s5k4aa[][4] = | |||
238 | {SENSOR, 0x37, 0x01, 0x00}, | 216 | {SENSOR, 0x37, 0x01, 0x00}, |
239 | /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ | 217 | /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ |
240 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, | 218 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, |
241 | {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, | 219 | {SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00}, |
242 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, | 220 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, |
243 | {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, | 221 | {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, |
244 | /* window_height_hi, window_height_lo : 960 = 0x03c0 */ | 222 | /* window_height_hi, window_height_lo : 960 = 0x03c0 */ |
@@ -255,12 +233,9 @@ static const unsigned char init_s5k4aa[][4] = | |||
255 | {SENSOR, 0x12, 0xc3, 0x00}, | 233 | {SENSOR, 0x12, 0xc3, 0x00}, |
256 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 234 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
257 | {SENSOR, 0x02, 0x0e, 0x00}, | 235 | {SENSOR, 0x02, 0x0e, 0x00}, |
258 | {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00}, | ||
259 | {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00}, | ||
260 | {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00} | ||
261 | }; | 236 | }; |
262 | 237 | ||
263 | static const unsigned char VGA_s5k4aa[][4] = | 238 | static const unsigned char SXGA_s5k4aa[][4] = |
264 | { | 239 | { |
265 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 240 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
266 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 241 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
@@ -273,50 +248,42 @@ static const unsigned char VGA_s5k4aa[][4] = | |||
273 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 248 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
274 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 249 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
275 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 250 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
276 | /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */ | 251 | /* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */ |
277 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | 252 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00}, |
278 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, | 253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
279 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
280 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
281 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 256 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
282 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | 257 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, |
283 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 258 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
284 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 259 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
285 | /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */ | 260 | /* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */ |
286 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | 261 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00}, |
287 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00}, | 262 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
288 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 263 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
289 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 264 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
290 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ | 265 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ |
291 | 266 | ||
292 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 267 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
293 | {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X | 268 | {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00}, |
294 | | S5K4AA_RM_COL_SKIP_2X, 0x00}, | ||
295 | /* 0x37 : Fix image stability when light is too bright and improves | ||
296 | * image quality in 640x480, but worsens it in 1280x1024 */ | ||
297 | {SENSOR, 0x37, 0x01, 0x00}, | 269 | {SENSOR, 0x37, 0x01, 0x00}, |
298 | /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ | ||
299 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, | 270 | {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, |
300 | {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, | 271 | {SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00}, |
301 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, | 272 | {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, |
302 | {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, | 273 | {SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00}, |
303 | /* window_height_hi, window_height_lo : 960 = 0x03c0 */ | 274 | {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00}, |
304 | {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, | 275 | {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00}, |
305 | {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00}, | ||
306 | /* window_width_hi, window_width_lo : 1280 = 0x0500 */ | ||
307 | {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, | 276 | {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, |
308 | {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, | 277 | {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, |
309 | {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, | 278 | {SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00}, |
310 | {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */ | 279 | {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, |
311 | {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, | 280 | {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, |
312 | {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, | 281 | {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, |
313 | {SENSOR, 0x11, 0x04, 0x00}, | 282 | {SENSOR, 0x11, 0x04, 0x00}, |
314 | {SENSOR, 0x12, 0xc3, 0x00}, | 283 | {SENSOR, 0x12, 0xc3, 0x00}, |
315 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, | 284 | {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, |
316 | {SENSOR, 0x02, 0x0e, 0x00}, | 285 | {SENSOR, 0x02, 0x0e, 0x00}, |
317 | {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00}, | ||
318 | {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00}, | ||
319 | {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00} | ||
320 | }; | 286 | }; |
321 | 287 | ||
288 | |||
322 | #endif | 289 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c index 42c86aa4dc8d..7127321ace8c 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c | |||
@@ -16,8 +16,20 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/kthread.h> | ||
19 | #include "m5602_s5k83a.h" | 20 | #include "m5602_s5k83a.h" |
20 | 21 | ||
22 | static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
23 | static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
24 | static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
25 | static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
26 | static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
27 | static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
28 | static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
29 | static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
30 | static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
31 | static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
32 | |||
21 | static struct v4l2_pix_format s5k83a_modes[] = { | 33 | static struct v4l2_pix_format s5k83a_modes[] = { |
22 | { | 34 | { |
23 | 640, | 35 | 640, |
@@ -32,68 +44,77 @@ static struct v4l2_pix_format s5k83a_modes[] = { | |||
32 | } | 44 | } |
33 | }; | 45 | }; |
34 | 46 | ||
35 | const static struct ctrl s5k83a_ctrls[] = { | 47 | static const struct ctrl s5k83a_ctrls[] = { |
48 | #define GAIN_IDX 0 | ||
36 | { | 49 | { |
37 | { | 50 | { |
38 | .id = V4L2_CID_BRIGHTNESS, | 51 | .id = V4L2_CID_GAIN, |
39 | .type = V4L2_CTRL_TYPE_INTEGER, | 52 | .type = V4L2_CTRL_TYPE_INTEGER, |
40 | .name = "brightness", | 53 | .name = "gain", |
41 | .minimum = 0x00, | 54 | .minimum = 0x00, |
42 | .maximum = 0xff, | 55 | .maximum = 0xff, |
43 | .step = 0x01, | 56 | .step = 0x01, |
44 | .default_value = S5K83A_DEFAULT_BRIGHTNESS, | 57 | .default_value = S5K83A_DEFAULT_GAIN, |
45 | .flags = V4L2_CTRL_FLAG_SLIDER | 58 | .flags = V4L2_CTRL_FLAG_SLIDER |
46 | }, | 59 | }, |
47 | .set = s5k83a_set_brightness, | 60 | .set = s5k83a_set_gain, |
48 | .get = s5k83a_get_brightness | 61 | .get = s5k83a_get_gain |
49 | 62 | ||
50 | }, { | 63 | }, |
64 | #define BRIGHTNESS_IDX 1 | ||
65 | { | ||
51 | { | 66 | { |
52 | .id = V4L2_CID_WHITENESS, | 67 | .id = V4L2_CID_BRIGHTNESS, |
53 | .type = V4L2_CTRL_TYPE_INTEGER, | 68 | .type = V4L2_CTRL_TYPE_INTEGER, |
54 | .name = "whiteness", | 69 | .name = "brightness", |
55 | .minimum = 0x00, | 70 | .minimum = 0x00, |
56 | .maximum = 0xff, | 71 | .maximum = 0xff, |
57 | .step = 0x01, | 72 | .step = 0x01, |
58 | .default_value = S5K83A_DEFAULT_WHITENESS, | 73 | .default_value = S5K83A_DEFAULT_BRIGHTNESS, |
59 | .flags = V4L2_CTRL_FLAG_SLIDER | 74 | .flags = V4L2_CTRL_FLAG_SLIDER |
60 | }, | 75 | }, |
61 | .set = s5k83a_set_whiteness, | 76 | .set = s5k83a_set_brightness, |
62 | .get = s5k83a_get_whiteness, | 77 | .get = s5k83a_get_brightness, |
63 | }, { | 78 | }, |
79 | #define EXPOSURE_IDX 2 | ||
80 | { | ||
64 | { | 81 | { |
65 | .id = V4L2_CID_GAIN, | 82 | .id = V4L2_CID_EXPOSURE, |
66 | .type = V4L2_CTRL_TYPE_INTEGER, | 83 | .type = V4L2_CTRL_TYPE_INTEGER, |
67 | .name = "gain", | 84 | .name = "exposure", |
68 | .minimum = 0x00, | 85 | .minimum = 0x00, |
69 | .maximum = S5K83A_MAXIMUM_GAIN, | 86 | .maximum = S5K83A_MAXIMUM_EXPOSURE, |
70 | .step = 0x01, | 87 | .step = 0x01, |
71 | .default_value = S5K83A_DEFAULT_GAIN, | 88 | .default_value = S5K83A_DEFAULT_EXPOSURE, |
72 | .flags = V4L2_CTRL_FLAG_SLIDER | 89 | .flags = V4L2_CTRL_FLAG_SLIDER |
73 | }, | 90 | }, |
74 | .set = s5k83a_set_gain, | 91 | .set = s5k83a_set_exposure, |
75 | .get = s5k83a_get_gain | 92 | .get = s5k83a_get_exposure |
76 | }, { | 93 | }, |
94 | #define HFLIP_IDX 3 | ||
95 | { | ||
77 | { | 96 | { |
78 | .id = V4L2_CID_HFLIP, | 97 | .id = V4L2_CID_HFLIP, |
79 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 98 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
80 | .name = "horizontal flip", | 99 | .name = "horizontal flip", |
81 | .minimum = 0, | 100 | .minimum = 0, |
82 | .maximum = 1, | 101 | .maximum = 1, |
83 | .step = 1, | 102 | .step = 1, |
84 | .default_value = 0 | 103 | .default_value = 0 |
85 | }, | 104 | }, |
86 | .set = s5k83a_set_hflip, | 105 | .set = s5k83a_set_hflip, |
87 | .get = s5k83a_get_hflip | 106 | .get = s5k83a_get_hflip |
88 | }, { | 107 | }, |
108 | #define VFLIP_IDX 4 | ||
109 | { | ||
89 | { | 110 | { |
90 | .id = V4L2_CID_VFLIP, | 111 | .id = V4L2_CID_VFLIP, |
91 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 112 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
92 | .name = "vertical flip", | 113 | .name = "vertical flip", |
93 | .minimum = 0, | 114 | .minimum = 0, |
94 | .maximum = 1, | 115 | .maximum = 1, |
95 | .step = 1, | 116 | .step = 1, |
96 | .default_value = 0 | 117 | .default_value = 0 |
97 | }, | 118 | }, |
98 | .set = s5k83a_set_vflip, | 119 | .set = s5k83a_set_vflip, |
99 | .get = s5k83a_get_vflip | 120 | .get = s5k83a_get_vflip |
@@ -101,9 +122,14 @@ const static struct ctrl s5k83a_ctrls[] = { | |||
101 | }; | 122 | }; |
102 | 123 | ||
103 | static void s5k83a_dump_registers(struct sd *sd); | 124 | static void s5k83a_dump_registers(struct sd *sd); |
125 | static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data); | ||
126 | static int s5k83a_set_led_indication(struct sd *sd, u8 val); | ||
127 | static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, | ||
128 | __s32 vflip, __s32 hflip); | ||
104 | 129 | ||
105 | int s5k83a_probe(struct sd *sd) | 130 | int s5k83a_probe(struct sd *sd) |
106 | { | 131 | { |
132 | struct s5k83a_priv *sens_priv; | ||
107 | u8 prod_id = 0, ver_id = 0; | 133 | u8 prod_id = 0, ver_id = 0; |
108 | int i, err = 0; | 134 | int i, err = 0; |
109 | 135 | ||
@@ -145,16 +171,36 @@ int s5k83a_probe(struct sd *sd) | |||
145 | info("Detected a s5k83a sensor"); | 171 | info("Detected a s5k83a sensor"); |
146 | 172 | ||
147 | sensor_found: | 173 | sensor_found: |
174 | sens_priv = kmalloc( | ||
175 | sizeof(struct s5k83a_priv), GFP_KERNEL); | ||
176 | if (!sens_priv) | ||
177 | return -ENOMEM; | ||
178 | |||
179 | sens_priv->settings = | ||
180 | kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL); | ||
181 | if (!sens_priv->settings) | ||
182 | return -ENOMEM; | ||
183 | |||
148 | sd->gspca_dev.cam.cam_mode = s5k83a_modes; | 184 | sd->gspca_dev.cam.cam_mode = s5k83a_modes; |
149 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); | 185 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); |
150 | sd->desc->ctrls = s5k83a_ctrls; | 186 | sd->desc->ctrls = s5k83a_ctrls; |
151 | sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); | 187 | sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); |
188 | |||
189 | /* null the pointer! thread is't running now */ | ||
190 | sens_priv->rotation_thread = NULL; | ||
191 | |||
192 | for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++) | ||
193 | sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value; | ||
194 | |||
195 | sd->sensor_priv = sens_priv; | ||
152 | return 0; | 196 | return 0; |
153 | } | 197 | } |
154 | 198 | ||
155 | int s5k83a_init(struct sd *sd) | 199 | int s5k83a_init(struct sd *sd) |
156 | { | 200 | { |
157 | int i, err = 0; | 201 | int i, err = 0; |
202 | s32 *sensor_settings = | ||
203 | ((struct s5k83a_priv *) sd->sensor_priv)->settings; | ||
158 | 204 | ||
159 | for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { | 205 | for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { |
160 | u8 data[2] = {0x00, 0x00}; | 206 | u8 data[2] = {0x00, 0x00}; |
@@ -187,87 +233,138 @@ int s5k83a_init(struct sd *sd) | |||
187 | if (dump_sensor) | 233 | if (dump_sensor) |
188 | s5k83a_dump_registers(sd); | 234 | s5k83a_dump_registers(sd); |
189 | 235 | ||
190 | return (err < 0) ? err : 0; | 236 | err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); |
191 | } | 237 | if (err < 0) |
238 | return err; | ||
192 | 239 | ||
193 | int s5k83a_start(struct sd *sd) | 240 | err = s5k83a_set_brightness(&sd->gspca_dev, |
194 | { | 241 | sensor_settings[BRIGHTNESS_IDX]); |
195 | return s5k83a_set_led_indication(sd, 1); | 242 | if (err < 0) |
196 | } | 243 | return err; |
197 | 244 | ||
198 | int s5k83a_stop(struct sd *sd) | 245 | err = s5k83a_set_exposure(&sd->gspca_dev, |
199 | { | 246 | sensor_settings[EXPOSURE_IDX]); |
200 | return s5k83a_set_led_indication(sd, 0); | 247 | if (err < 0) |
248 | return err; | ||
249 | |||
250 | err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); | ||
251 | if (err < 0) | ||
252 | return err; | ||
253 | |||
254 | err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); | ||
255 | |||
256 | return err; | ||
201 | } | 257 | } |
202 | 258 | ||
203 | int s5k83a_power_down(struct sd *sd) | 259 | static int rotation_thread_function(void *data) |
204 | { | 260 | { |
261 | struct sd *sd = (struct sd *) data; | ||
262 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
263 | u8 reg, previous_rotation = 0; | ||
264 | __s32 vflip, hflip; | ||
265 | |||
266 | set_current_state(TASK_INTERRUPTIBLE); | ||
267 | while (!schedule_timeout(100)) { | ||
268 | if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock)) | ||
269 | break; | ||
270 | |||
271 | s5k83a_get_rotation(sd, ®); | ||
272 | if (previous_rotation != reg) { | ||
273 | previous_rotation = reg; | ||
274 | info("Camera was flipped"); | ||
275 | |||
276 | s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); | ||
277 | s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); | ||
278 | |||
279 | if (reg) { | ||
280 | vflip = !vflip; | ||
281 | hflip = !hflip; | ||
282 | } | ||
283 | s5k83a_set_flip_real((struct gspca_dev *) sd, | ||
284 | vflip, hflip); | ||
285 | } | ||
286 | |||
287 | mutex_unlock(&sd->gspca_dev.usb_lock); | ||
288 | set_current_state(TASK_INTERRUPTIBLE); | ||
289 | } | ||
290 | |||
291 | /* return to "front" flip */ | ||
292 | if (previous_rotation) { | ||
293 | s5k83a_get_vflip((struct gspca_dev *) sd, &vflip); | ||
294 | s5k83a_get_hflip((struct gspca_dev *) sd, &hflip); | ||
295 | s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip); | ||
296 | } | ||
297 | |||
298 | sens_priv->rotation_thread = NULL; | ||
205 | return 0; | 299 | return 0; |
206 | } | 300 | } |
207 | 301 | ||
208 | static void s5k83a_dump_registers(struct sd *sd) | 302 | int s5k83a_start(struct sd *sd) |
209 | { | 303 | { |
210 | int address; | 304 | int i, err = 0; |
211 | u8 page, old_page; | 305 | struct s5k83a_priv *sens_priv = sd->sensor_priv; |
212 | m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
213 | 306 | ||
214 | for (page = 0; page < 16; page++) { | 307 | /* Create another thread, polling the GPIO ports of the camera to check |
215 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | 308 | if it got rotated. This is how the windows driver does it so we have |
216 | info("Dumping the s5k83a register state for page 0x%x", page); | 309 | to assume that there is no better way of accomplishing this */ |
217 | for (address = 0; address <= 0xff; address++) { | 310 | sens_priv->rotation_thread = kthread_create(rotation_thread_function, |
218 | u8 val = 0; | 311 | sd, "rotation thread"); |
219 | m5602_read_sensor(sd, address, &val, 1); | 312 | wake_up_process(sens_priv->rotation_thread); |
220 | info("register 0x%x contains 0x%x", | 313 | |
221 | address, val); | 314 | /* Preinit the sensor */ |
222 | } | 315 | for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) { |
316 | u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]}; | ||
317 | if (start_s5k83a[i][0] == SENSOR) | ||
318 | err = m5602_write_sensor(sd, start_s5k83a[i][1], | ||
319 | data, 2); | ||
320 | else | ||
321 | err = m5602_write_bridge(sd, start_s5k83a[i][1], | ||
322 | data[0]); | ||
223 | } | 323 | } |
224 | info("s5k83a register state dump complete"); | 324 | if (err < 0) |
325 | return err; | ||
225 | 326 | ||
226 | for (page = 0; page < 16; page++) { | 327 | return s5k83a_set_led_indication(sd, 1); |
227 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | 328 | } |
228 | info("Probing for which registers that are read/write " | ||
229 | "for page 0x%x", page); | ||
230 | for (address = 0; address <= 0xff; address++) { | ||
231 | u8 old_val, ctrl_val, test_val = 0xff; | ||
232 | 329 | ||
233 | m5602_read_sensor(sd, address, &old_val, 1); | 330 | int s5k83a_stop(struct sd *sd) |
234 | m5602_write_sensor(sd, address, &test_val, 1); | 331 | { |
235 | m5602_read_sensor(sd, address, &ctrl_val, 1); | 332 | struct s5k83a_priv *sens_priv = sd->sensor_priv; |
236 | 333 | ||
237 | if (ctrl_val == test_val) | 334 | if (sens_priv->rotation_thread) |
238 | info("register 0x%x is writeable", address); | 335 | kthread_stop(sens_priv->rotation_thread); |
239 | else | ||
240 | info("register 0x%x is read only", address); | ||
241 | 336 | ||
242 | /* Restore original val */ | 337 | return s5k83a_set_led_indication(sd, 0); |
243 | m5602_write_sensor(sd, address, &old_val, 1); | ||
244 | } | ||
245 | } | ||
246 | info("Read/write register probing complete"); | ||
247 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
248 | } | 338 | } |
249 | 339 | ||
250 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 340 | void s5k83a_disconnect(struct sd *sd) |
251 | { | 341 | { |
252 | int err; | 342 | struct s5k83a_priv *sens_priv = sd->sensor_priv; |
253 | u8 data[2]; | ||
254 | struct sd *sd = (struct sd *) gspca_dev; | ||
255 | 343 | ||
256 | err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2); | 344 | s5k83a_stop(sd); |
257 | if (err < 0) | 345 | |
258 | return err; | 346 | sd->sensor = NULL; |
347 | kfree(sens_priv->settings); | ||
348 | kfree(sens_priv); | ||
349 | } | ||
259 | 350 | ||
260 | data[1] = data[1] << 1; | 351 | static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
261 | *val = data[1]; | 352 | { |
353 | struct sd *sd = (struct sd *) gspca_dev; | ||
354 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
262 | 355 | ||
263 | return err; | 356 | *val = sens_priv->settings[GAIN_IDX]; |
357 | return 0; | ||
264 | } | 358 | } |
265 | 359 | ||
266 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 360 | static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
267 | { | 361 | { |
268 | int err; | 362 | int err; |
269 | u8 data[2]; | 363 | u8 data[2]; |
270 | struct sd *sd = (struct sd *) gspca_dev; | 364 | struct sd *sd = (struct sd *) gspca_dev; |
365 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
366 | |||
367 | sens_priv->settings[GAIN_IDX] = val; | ||
271 | 368 | ||
272 | data[0] = 0x00; | 369 | data[0] = 0x00; |
273 | data[1] = 0x20; | 370 | data[1] = 0x20; |
@@ -283,89 +380,69 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | |||
283 | 380 | ||
284 | /* FIXME: This is not sane, we need to figure out the composition | 381 | /* FIXME: This is not sane, we need to figure out the composition |
285 | of these registers */ | 382 | of these registers */ |
286 | data[0] = val >> 3; /* brightness, high 5 bits */ | 383 | data[0] = val >> 3; /* gain, high 5 bits */ |
287 | data[1] = val >> 1; /* brightness, high 7 bits */ | 384 | data[1] = val >> 1; /* gain, high 7 bits */ |
288 | err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2); | 385 | err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2); |
289 | 386 | ||
290 | return err; | 387 | return err; |
291 | } | 388 | } |
292 | 389 | ||
293 | int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) | 390 | static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) |
294 | { | 391 | { |
295 | int err; | ||
296 | u8 data; | ||
297 | struct sd *sd = (struct sd *) gspca_dev; | 392 | struct sd *sd = (struct sd *) gspca_dev; |
393 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
298 | 394 | ||
299 | err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1); | 395 | *val = sens_priv->settings[BRIGHTNESS_IDX]; |
300 | if (err < 0) | 396 | return 0; |
301 | return err; | ||
302 | |||
303 | *val = data; | ||
304 | |||
305 | return err; | ||
306 | } | 397 | } |
307 | 398 | ||
308 | int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) | 399 | static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) |
309 | { | 400 | { |
310 | int err; | 401 | int err; |
311 | u8 data[1]; | 402 | u8 data[1]; |
312 | struct sd *sd = (struct sd *) gspca_dev; | 403 | struct sd *sd = (struct sd *) gspca_dev; |
404 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
313 | 405 | ||
406 | sens_priv->settings[BRIGHTNESS_IDX] = val; | ||
314 | data[0] = val; | 407 | data[0] = val; |
315 | err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1); | 408 | err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1); |
316 | |||
317 | return err; | 409 | return err; |
318 | } | 410 | } |
319 | 411 | ||
320 | int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 412 | static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
321 | { | 413 | { |
322 | int err; | ||
323 | u8 data[2]; | ||
324 | struct sd *sd = (struct sd *) gspca_dev; | 414 | struct sd *sd = (struct sd *) gspca_dev; |
415 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
325 | 416 | ||
326 | err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2); | 417 | *val = sens_priv->settings[EXPOSURE_IDX]; |
327 | if (err < 0) | 418 | return 0; |
328 | return err; | ||
329 | |||
330 | data[1] = data[1] & 0x3f; | ||
331 | if (data[1] > S5K83A_MAXIMUM_GAIN) | ||
332 | data[1] = S5K83A_MAXIMUM_GAIN; | ||
333 | |||
334 | *val = data[1]; | ||
335 | |||
336 | return err; | ||
337 | } | 419 | } |
338 | 420 | ||
339 | int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 421 | static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
340 | { | 422 | { |
341 | int err; | 423 | int err; |
342 | u8 data[2]; | 424 | u8 data[2]; |
343 | struct sd *sd = (struct sd *) gspca_dev; | 425 | struct sd *sd = (struct sd *) gspca_dev; |
426 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
344 | 427 | ||
428 | sens_priv->settings[EXPOSURE_IDX] = val; | ||
345 | data[0] = 0; | 429 | data[0] = 0; |
346 | data[1] = val; | 430 | data[1] = val; |
347 | err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2); | 431 | err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2); |
348 | return err; | 432 | return err; |
349 | } | 433 | } |
350 | 434 | ||
351 | int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 435 | static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
352 | { | 436 | { |
353 | int err; | ||
354 | u8 data[1]; | ||
355 | struct sd *sd = (struct sd *) gspca_dev; | 437 | struct sd *sd = (struct sd *) gspca_dev; |
438 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
356 | 439 | ||
357 | data[0] = 0x05; | 440 | *val = sens_priv->settings[VFLIP_IDX]; |
358 | err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); | 441 | return 0; |
359 | if (err < 0) | ||
360 | return err; | ||
361 | |||
362 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | ||
363 | *val = (data[0] | 0x40) ? 1 : 0; | ||
364 | |||
365 | return err; | ||
366 | } | 442 | } |
367 | 443 | ||
368 | int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 444 | static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, |
445 | __s32 vflip, __s32 hflip) | ||
369 | { | 446 | { |
370 | int err; | 447 | int err; |
371 | u8 data[1]; | 448 | u8 data[1]; |
@@ -376,69 +453,83 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
376 | if (err < 0) | 453 | if (err < 0) |
377 | return err; | 454 | return err; |
378 | 455 | ||
379 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | 456 | /* six bit is vflip, seven is hflip */ |
380 | if (err < 0) | 457 | data[0] = S5K83A_FLIP_MASK; |
381 | return err; | 458 | data[0] = (vflip) ? data[0] | 0x40 : data[0]; |
459 | data[0] = (hflip) ? data[0] | 0x80 : data[0]; | ||
382 | 460 | ||
383 | /* set or zero six bit, seven is hflip */ | ||
384 | data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK | ||
385 | : (data[0] & 0x80) | S5K83A_FLIP_MASK; | ||
386 | err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); | 461 | err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); |
387 | if (err < 0) | 462 | if (err < 0) |
388 | return err; | 463 | return err; |
389 | 464 | ||
390 | data[0] = (val) ? 0x0b : 0x0a; | 465 | data[0] = (vflip) ? 0x0b : 0x0a; |
391 | err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); | 466 | err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); |
467 | if (err < 0) | ||
468 | return err; | ||
392 | 469 | ||
470 | data[0] = (hflip) ? 0x0a : 0x0b; | ||
471 | err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); | ||
393 | return err; | 472 | return err; |
394 | } | 473 | } |
395 | 474 | ||
396 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 475 | static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
397 | { | 476 | { |
398 | int err; | 477 | int err; |
399 | u8 data[1]; | 478 | u8 reg; |
479 | __s32 hflip; | ||
400 | struct sd *sd = (struct sd *) gspca_dev; | 480 | struct sd *sd = (struct sd *) gspca_dev; |
481 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
401 | 482 | ||
402 | data[0] = 0x05; | 483 | sens_priv->settings[VFLIP_IDX] = val; |
403 | err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); | 484 | |
485 | s5k83a_get_hflip(gspca_dev, &hflip); | ||
486 | |||
487 | err = s5k83a_get_rotation(sd, ®); | ||
404 | if (err < 0) | 488 | if (err < 0) |
405 | return err; | 489 | return err; |
490 | if (reg) { | ||
491 | val = !val; | ||
492 | hflip = !hflip; | ||
493 | } | ||
406 | 494 | ||
407 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | 495 | err = s5k83a_set_flip_real(gspca_dev, val, hflip); |
408 | *val = (data[0] | 0x80) ? 1 : 0; | ||
409 | |||
410 | return err; | 496 | return err; |
411 | } | 497 | } |
412 | 498 | ||
413 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 499 | static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
500 | { | ||
501 | struct sd *sd = (struct sd *) gspca_dev; | ||
502 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
503 | |||
504 | *val = sens_priv->settings[HFLIP_IDX]; | ||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | ||
414 | { | 509 | { |
415 | int err; | 510 | int err; |
416 | u8 data[1]; | 511 | u8 reg; |
512 | __s32 vflip; | ||
417 | struct sd *sd = (struct sd *) gspca_dev; | 513 | struct sd *sd = (struct sd *) gspca_dev; |
514 | struct s5k83a_priv *sens_priv = sd->sensor_priv; | ||
418 | 515 | ||
419 | data[0] = 0x05; | 516 | sens_priv->settings[HFLIP_IDX] = val; |
420 | err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); | ||
421 | if (err < 0) | ||
422 | return err; | ||
423 | 517 | ||
424 | err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); | 518 | s5k83a_get_vflip(gspca_dev, &vflip); |
425 | if (err < 0) | ||
426 | return err; | ||
427 | 519 | ||
428 | /* set or zero seven bit, six is vflip */ | 520 | err = s5k83a_get_rotation(sd, ®); |
429 | data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK | ||
430 | : (data[0] & 0x40) | S5K83A_FLIP_MASK; | ||
431 | err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); | ||
432 | if (err < 0) | 521 | if (err < 0) |
433 | return err; | 522 | return err; |
523 | if (reg) { | ||
524 | val = !val; | ||
525 | vflip = !vflip; | ||
526 | } | ||
434 | 527 | ||
435 | data[0] = (val) ? 0x0a : 0x0b; | 528 | err = s5k83a_set_flip_real(gspca_dev, vflip, val); |
436 | err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); | ||
437 | |||
438 | return err; | 529 | return err; |
439 | } | 530 | } |
440 | 531 | ||
441 | int s5k83a_set_led_indication(struct sd *sd, u8 val) | 532 | static int s5k83a_set_led_indication(struct sd *sd, u8 val) |
442 | { | 533 | { |
443 | int err = 0; | 534 | int err = 0; |
444 | u8 data[1]; | 535 | u8 data[1]; |
@@ -454,5 +545,55 @@ int s5k83a_set_led_indication(struct sd *sd, u8 val) | |||
454 | 545 | ||
455 | err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); | 546 | err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); |
456 | 547 | ||
457 | return (err < 0) ? err : 0; | 548 | return err; |
549 | } | ||
550 | |||
551 | /* Get camera rotation on Acer notebooks */ | ||
552 | static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data) | ||
553 | { | ||
554 | int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data); | ||
555 | *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1; | ||
556 | return err; | ||
557 | } | ||
558 | |||
559 | static void s5k83a_dump_registers(struct sd *sd) | ||
560 | { | ||
561 | int address; | ||
562 | u8 page, old_page; | ||
563 | m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
564 | |||
565 | for (page = 0; page < 16; page++) { | ||
566 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | ||
567 | info("Dumping the s5k83a register state for page 0x%x", page); | ||
568 | for (address = 0; address <= 0xff; address++) { | ||
569 | u8 val = 0; | ||
570 | m5602_read_sensor(sd, address, &val, 1); | ||
571 | info("register 0x%x contains 0x%x", | ||
572 | address, val); | ||
573 | } | ||
574 | } | ||
575 | info("s5k83a register state dump complete"); | ||
576 | |||
577 | for (page = 0; page < 16; page++) { | ||
578 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); | ||
579 | info("Probing for which registers that are read/write " | ||
580 | "for page 0x%x", page); | ||
581 | for (address = 0; address <= 0xff; address++) { | ||
582 | u8 old_val, ctrl_val, test_val = 0xff; | ||
583 | |||
584 | m5602_read_sensor(sd, address, &old_val, 1); | ||
585 | m5602_write_sensor(sd, address, &test_val, 1); | ||
586 | m5602_read_sensor(sd, address, &ctrl_val, 1); | ||
587 | |||
588 | if (ctrl_val == test_val) | ||
589 | info("register 0x%x is writeable", address); | ||
590 | else | ||
591 | info("register 0x%x is read only", address); | ||
592 | |||
593 | /* Restore original val */ | ||
594 | m5602_write_sensor(sd, address, &old_val, 1); | ||
595 | } | ||
596 | } | ||
597 | info("Read/write register probing complete"); | ||
598 | m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); | ||
458 | } | 599 | } |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h index 819ab25272be..7814b078acde 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h | |||
@@ -21,20 +21,21 @@ | |||
21 | 21 | ||
22 | #include "m5602_sensor.h" | 22 | #include "m5602_sensor.h" |
23 | 23 | ||
24 | #define S5K83A_FLIP 0x01 | 24 | #define S5K83A_FLIP 0x01 |
25 | #define S5K83A_HFLIP_TUNE 0x03 | 25 | #define S5K83A_HFLIP_TUNE 0x03 |
26 | #define S5K83A_VFLIP_TUNE 0x05 | 26 | #define S5K83A_VFLIP_TUNE 0x05 |
27 | #define S5K83A_WHITENESS 0x0a | 27 | #define S5K83A_BRIGHTNESS 0x0a |
28 | #define S5K83A_GAIN 0x18 | 28 | #define S5K83A_EXPOSURE 0x18 |
29 | #define S5K83A_BRIGHTNESS 0x1b | 29 | #define S5K83A_GAIN 0x1b |
30 | #define S5K83A_PAGE_MAP 0xec | 30 | #define S5K83A_PAGE_MAP 0xec |
31 | 31 | ||
32 | #define S5K83A_DEFAULT_BRIGHTNESS 0x71 | 32 | #define S5K83A_DEFAULT_GAIN 0x71 |
33 | #define S5K83A_DEFAULT_WHITENESS 0x7e | 33 | #define S5K83A_DEFAULT_BRIGHTNESS 0x7e |
34 | #define S5K83A_DEFAULT_GAIN 0x00 | 34 | #define S5K83A_DEFAULT_EXPOSURE 0x00 |
35 | #define S5K83A_MAXIMUM_GAIN 0x3c | 35 | #define S5K83A_MAXIMUM_EXPOSURE 0x3c |
36 | #define S5K83A_FLIP_MASK 0x10 | 36 | #define S5K83A_FLIP_MASK 0x10 |
37 | #define S5K83A_GPIO_LED_MASK 0x10 | 37 | #define S5K83A_GPIO_LED_MASK 0x10 |
38 | #define S5K83A_GPIO_ROTATION_MASK 0x40 | ||
38 | 39 | ||
39 | /*****************************************************************************/ | 40 | /*****************************************************************************/ |
40 | 41 | ||
@@ -46,20 +47,7 @@ int s5k83a_probe(struct sd *sd); | |||
46 | int s5k83a_init(struct sd *sd); | 47 | int s5k83a_init(struct sd *sd); |
47 | int s5k83a_start(struct sd *sd); | 48 | int s5k83a_start(struct sd *sd); |
48 | int s5k83a_stop(struct sd *sd); | 49 | int s5k83a_stop(struct sd *sd); |
49 | int s5k83a_power_down(struct sd *sd); | 50 | void s5k83a_disconnect(struct sd *sd); |
50 | |||
51 | int s5k83a_set_led_indication(struct sd *sd, u8 val); | ||
52 | |||
53 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | ||
54 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val); | ||
56 | int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val); | ||
57 | int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
60 | int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
61 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
62 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
63 | 51 | ||
64 | static const struct m5602_sensor s5k83a = { | 52 | static const struct m5602_sensor s5k83a = { |
65 | .name = "S5K83A", | 53 | .name = "S5K83A", |
@@ -67,11 +55,18 @@ static const struct m5602_sensor s5k83a = { | |||
67 | .init = s5k83a_init, | 55 | .init = s5k83a_init, |
68 | .start = s5k83a_start, | 56 | .start = s5k83a_start, |
69 | .stop = s5k83a_stop, | 57 | .stop = s5k83a_stop, |
70 | .power_down = s5k83a_power_down, | 58 | .disconnect = s5k83a_disconnect, |
71 | .i2c_slave_id = 0x5a, | 59 | .i2c_slave_id = 0x5a, |
72 | .i2c_regW = 2, | 60 | .i2c_regW = 2, |
73 | }; | 61 | }; |
74 | 62 | ||
63 | struct s5k83a_priv { | ||
64 | /* We use another thread periodically | ||
65 | probing the orientation of the camera */ | ||
66 | struct task_struct *rotation_thread; | ||
67 | s32 *settings; | ||
68 | }; | ||
69 | |||
75 | static const unsigned char preinit_s5k83a[][4] = | 70 | static const unsigned char preinit_s5k83a[][4] = |
76 | { | 71 | { |
77 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | 72 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, |
@@ -108,8 +103,6 @@ static const unsigned char preinit_s5k83a[][4] = | |||
108 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | 103 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, |
109 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | 104 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, |
110 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, | 105 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, |
111 | |||
112 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00} | ||
113 | }; | 106 | }; |
114 | 107 | ||
115 | /* This could probably be considerably shortened. | 108 | /* This could probably be considerably shortened. |
@@ -117,86 +110,8 @@ static const unsigned char preinit_s5k83a[][4] = | |||
117 | */ | 110 | */ |
118 | static const unsigned char init_s5k83a[][4] = | 111 | static const unsigned char init_s5k83a[][4] = |
119 | { | 112 | { |
120 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, | 113 | /* The following sequence is useless after a clean boot |
121 | {SENSOR, 0xaf, 0x01, 0x00}, | 114 | but is necessary after resume from suspend */ |
122 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, | ||
123 | {SENSOR, 0x7b, 0xff, 0x00}, | ||
124 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
125 | {SENSOR, 0x01, 0x50, 0x00}, | ||
126 | {SENSOR, 0x12, 0x20, 0x00}, | ||
127 | {SENSOR, 0x17, 0x40, 0x00}, | ||
128 | {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, | ||
129 | {SENSOR, 0x1c, 0x00, 0x00}, | ||
130 | {SENSOR, 0x02, 0x70, 0x00}, | ||
131 | {SENSOR, 0x03, 0x0b, 0x00}, | ||
132 | {SENSOR, 0x04, 0xf0, 0x00}, | ||
133 | {SENSOR, 0x05, 0x0b, 0x00}, | ||
134 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
135 | |||
136 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
137 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
138 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
139 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
140 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
141 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
142 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
143 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
144 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
145 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
146 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
147 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
148 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | ||
149 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
150 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
151 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
152 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
153 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
154 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
155 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
156 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, | ||
157 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
158 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
159 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
160 | |||
161 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
162 | {SENSOR, 0x06, 0x71, 0x00}, | ||
163 | {SENSOR, 0x07, 0xe8, 0x00}, | ||
164 | {SENSOR, 0x08, 0x02, 0x00}, | ||
165 | {SENSOR, 0x09, 0x88, 0x00}, | ||
166 | {SENSOR, 0x14, 0x00, 0x00}, | ||
167 | {SENSOR, 0x15, 0x20, 0x00}, | ||
168 | {SENSOR, 0x19, 0x00, 0x00}, | ||
169 | {SENSOR, 0x1a, 0x98, 0x00}, | ||
170 | {SENSOR, 0x0f, 0x02, 0x00}, | ||
171 | {SENSOR, 0x10, 0xe5, 0x00}, | ||
172 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
173 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | ||
174 | {SENSOR_LONG, 0x0d, 0x00, 0x7d}, | ||
175 | {SENSOR_LONG, 0x1b, 0x0d, 0x05}, | ||
176 | |||
177 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
178 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
179 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
180 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
181 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
182 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
183 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
184 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
185 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
186 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
187 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
188 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
189 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | ||
190 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
191 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
192 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
193 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
194 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
195 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
196 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
197 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00}, | ||
198 | |||
199 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
200 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | 115 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, |
201 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, | 116 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, |
202 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, | 117 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, |
@@ -216,7 +131,7 @@ static const unsigned char init_s5k83a[][4] = | |||
216 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 131 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
217 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, | 132 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, |
218 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | 133 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, |
219 | {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, | 134 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, |
220 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | 135 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, |
221 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, | 136 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, |
222 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | 137 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, |
@@ -225,109 +140,34 @@ static const unsigned char init_s5k83a[][4] = | |||
225 | 140 | ||
226 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, | 141 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, |
227 | {SENSOR, 0xaf, 0x01, 0x00}, | 142 | {SENSOR, 0xaf, 0x01, 0x00}, |
228 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | 143 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, |
229 | /* ff ( init value )is very dark) || 71 and f0 better */ | ||
230 | {SENSOR, 0x7b, 0xff, 0x00}, | 144 | {SENSOR, 0x7b, 0xff, 0x00}, |
231 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | 145 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, |
232 | {SENSOR, 0x01, 0x50, 0x00}, | 146 | {SENSOR, 0x01, 0x50, 0x00}, |
233 | {SENSOR, 0x12, 0x20, 0x00}, | 147 | {SENSOR, 0x12, 0x20, 0x00}, |
234 | {SENSOR, 0x17, 0x40, 0x00}, | 148 | {SENSOR, 0x17, 0x40, 0x00}, |
235 | {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, | ||
236 | {SENSOR, 0x1c, 0x00, 0x00}, | 149 | {SENSOR, 0x1c, 0x00, 0x00}, |
237 | {SENSOR, 0x02, 0x70, 0x00}, | 150 | {SENSOR, 0x02, 0x70, 0x00}, |
238 | /* some values like 0x10 give a blue-purple image */ | ||
239 | {SENSOR, 0x03, 0x0b, 0x00}, | 151 | {SENSOR, 0x03, 0x0b, 0x00}, |
240 | {SENSOR, 0x04, 0xf0, 0x00}, | 152 | {SENSOR, 0x04, 0xf0, 0x00}, |
241 | {SENSOR, 0x05, 0x0b, 0x00}, | 153 | {SENSOR, 0x05, 0x0b, 0x00}, |
242 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
243 | |||
244 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | ||
245 | /* under 80 don't work, highter depend on value */ | ||
246 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
247 | |||
248 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
249 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
250 | {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00}, | ||
251 | {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00}, | ||
252 | {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00}, | ||
253 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
254 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
255 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
256 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
257 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | ||
258 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | ||
259 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
260 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | ||
261 | {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, | ||
262 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
263 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | ||
264 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | ||
265 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, | ||
266 | |||
267 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | ||
268 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
269 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
270 | |||
271 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
272 | {SENSOR, 0x06, 0x71, 0x00}, | 154 | {SENSOR, 0x06, 0x71, 0x00}, |
273 | {SENSOR, 0x07, 0xe8, 0x00}, | 155 | {SENSOR, 0x07, 0xe8, 0x00}, /* 488 */ |
274 | {SENSOR, 0x08, 0x02, 0x00}, | 156 | {SENSOR, 0x08, 0x02, 0x00}, |
275 | {SENSOR, 0x09, 0x88, 0x00}, | 157 | {SENSOR, 0x09, 0x88, 0x00}, /* 648 */ |
276 | {SENSOR, 0x14, 0x00, 0x00}, | 158 | {SENSOR, 0x14, 0x00, 0x00}, |
277 | {SENSOR, 0x15, 0x20, 0x00}, | 159 | {SENSOR, 0x15, 0x20, 0x00}, /* 32 */ |
278 | {SENSOR, 0x19, 0x00, 0x00}, | 160 | {SENSOR, 0x19, 0x00, 0x00}, |
279 | {SENSOR, 0x1a, 0x98, 0x00}, | 161 | {SENSOR, 0x1a, 0x98, 0x00}, /* 152 */ |
280 | {SENSOR, 0x0f, 0x02, 0x00}, | 162 | {SENSOR, 0x0f, 0x02, 0x00}, |
281 | {SENSOR, 0x10, 0xe5, 0x00}, | 163 | {SENSOR, 0x10, 0xe5, 0x00}, /* 741 */ |
282 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | 164 | /* normal colors |
283 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | 165 | (this is value after boot, but after tries can be different) */ |
284 | {SENSOR_LONG, 0x0d, 0x00, 0x7d}, | 166 | {SENSOR, 0x00, 0x06, 0x00}, |
285 | {SENSOR_LONG, 0x1b, 0x0d, 0x05}, | 167 | }; |
286 | |||
287 | /* The following sequence is useless after a clean boot | ||
288 | but is necessary after resume from suspend */ | ||
289 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | ||
290 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, | ||
291 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, | ||
292 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00}, | ||
293 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | ||
294 | {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00}, | ||
295 | {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, | ||
296 | {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, | ||
297 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00}, | ||
298 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00}, | ||
299 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
300 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | ||
301 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | ||
302 | {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, | ||
303 | {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, | ||
304 | {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00}, | ||
305 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | ||
306 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, | ||
307 | {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, | ||
308 | {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, | ||
309 | {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, | ||
310 | {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, | ||
311 | {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, | ||
312 | {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, | ||
313 | {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, | ||
314 | |||
315 | {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, | ||
316 | {SENSOR, 0xaf, 0x01, 0x00}, | ||
317 | {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}, | ||
318 | {SENSOR, 0x7b, 0xff, 0x00}, | ||
319 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
320 | {SENSOR, 0x01, 0x50, 0x00}, | ||
321 | {SENSOR, 0x12, 0x20, 0x00}, | ||
322 | {SENSOR, 0x17, 0x40, 0x00}, | ||
323 | {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00}, | ||
324 | {SENSOR, 0x1c, 0x00, 0x00}, | ||
325 | {SENSOR, 0x02, 0x70, 0x00}, | ||
326 | {SENSOR, 0x03, 0x0b, 0x00}, | ||
327 | {SENSOR, 0x04, 0xf0, 0x00}, | ||
328 | {SENSOR, 0x05, 0x0b, 0x00}, | ||
329 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
330 | 168 | ||
169 | static const unsigned char start_s5k83a[][4] = | ||
170 | { | ||
331 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, | 171 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, |
332 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 172 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
333 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, | 173 | {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, |
@@ -340,7 +180,7 @@ static const unsigned char init_s5k83a[][4] = | |||
340 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 180 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
341 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 181 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
342 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, | 182 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, |
343 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, | 183 | {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */ |
344 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 184 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
345 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, | 185 | {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, |
346 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 186 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
@@ -348,50 +188,10 @@ static const unsigned char init_s5k83a[][4] = | |||
348 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 188 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
349 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, | 189 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, |
350 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, | 190 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, |
351 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, | 191 | {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */ |
352 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, | 192 | {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, |
353 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, | 193 | {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, |
354 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, | 194 | {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, |
355 | |||
356 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
357 | {SENSOR, 0x06, 0x71, 0x00}, | ||
358 | {SENSOR, 0x07, 0xe8, 0x00}, | ||
359 | {SENSOR, 0x08, 0x02, 0x00}, | ||
360 | {SENSOR, 0x09, 0x88, 0x00}, | ||
361 | {SENSOR, 0x14, 0x00, 0x00}, | ||
362 | {SENSOR, 0x15, 0x20, 0x00}, | ||
363 | {SENSOR, 0x19, 0x00, 0x00}, | ||
364 | {SENSOR, 0x1a, 0x98, 0x00}, | ||
365 | {SENSOR, 0x0f, 0x02, 0x00}, | ||
366 | |||
367 | {SENSOR, 0x10, 0xe5, 0x00}, | ||
368 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
369 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | ||
370 | {SENSOR_LONG, 0x0d, 0x00, 0x7d}, | ||
371 | {SENSOR_LONG, 0x1b, 0x0d, 0x05}, | ||
372 | |||
373 | /* normal colors | ||
374 | (this is value after boot, but after tries can be different) */ | ||
375 | {SENSOR, 0x00, 0x06, 0x00}, | ||
376 | |||
377 | /* set default brightness */ | ||
378 | {SENSOR_LONG, 0x14, 0x00, 0x20}, | ||
379 | {SENSOR_LONG, 0x0d, 0x01, 0x00}, | ||
380 | {SENSOR_LONG, 0x1b, S5K83A_DEFAULT_BRIGHTNESS >> 3, | ||
381 | S5K83A_DEFAULT_BRIGHTNESS >> 1}, | ||
382 | |||
383 | /* set default whiteness */ | ||
384 | {SENSOR, S5K83A_WHITENESS, S5K83A_DEFAULT_WHITENESS, 0x00}, | ||
385 | |||
386 | /* set default gain */ | ||
387 | {SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN}, | ||
388 | |||
389 | /* set default flip */ | ||
390 | {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, | ||
391 | {SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00}, | ||
392 | {SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00}, | ||
393 | {SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00} | ||
394 | |||
395 | }; | 195 | }; |
396 | 196 | ||
397 | #endif | 197 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h index 0d3026936f2e..edff4f1f586f 100644 --- a/drivers/media/video/gspca/m5602/m5602_sensor.h +++ b/drivers/media/video/gspca/m5602/m5602_sensor.h | |||
@@ -21,13 +21,17 @@ | |||
21 | 21 | ||
22 | #include "m5602_bridge.h" | 22 | #include "m5602_bridge.h" |
23 | 23 | ||
24 | #define M5602_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 0) | ||
25 | #define M5602_V4L2_CID_NOISE_SUPPRESION (V4L2_CID_PRIVATE_BASE + 1) | ||
26 | |||
24 | /* Enumerates all supported sensors */ | 27 | /* Enumerates all supported sensors */ |
25 | enum sensors { | 28 | enum sensors { |
26 | OV9650_SENSOR = 1, | 29 | OV9650_SENSOR = 1, |
27 | S5K83A_SENSOR = 2, | 30 | S5K83A_SENSOR = 2, |
28 | S5K4AA_SENSOR = 3, | 31 | S5K4AA_SENSOR = 3, |
29 | MT9M111_SENSOR = 4, | 32 | MT9M111_SENSOR = 4, |
30 | PO1030_SENSOR = 5 | 33 | PO1030_SENSOR = 5, |
34 | OV7660_SENSOR = 6, | ||
31 | }; | 35 | }; |
32 | 36 | ||
33 | /* Enumerates all possible instruction types */ | 37 | /* Enumerates all possible instruction types */ |
@@ -61,9 +65,6 @@ struct m5602_sensor { | |||
61 | 65 | ||
62 | /* Executed when the device is disconnected */ | 66 | /* Executed when the device is disconnected */ |
63 | void (*disconnect)(struct sd *sd); | 67 | void (*disconnect)(struct sd *sd); |
64 | |||
65 | /* Performs a power down sequence */ | ||
66 | int (*power_down)(struct sd *sd); | ||
67 | }; | 68 | }; |
68 | 69 | ||
69 | #endif | 70 | #endif |
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 2a901a4a6f00..30132513400c 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c | |||
@@ -321,6 +321,7 @@ static const struct sd_desc sd_desc = { | |||
321 | /* -- module initialisation -- */ | 321 | /* -- module initialisation -- */ |
322 | static const __devinitdata struct usb_device_id device_table[] = { | 322 | static const __devinitdata struct usb_device_id device_table[] = { |
323 | {USB_DEVICE(0x08ca, 0x0111)}, | 323 | {USB_DEVICE(0x08ca, 0x0111)}, |
324 | {USB_DEVICE(0x093a, 0x010f)}, | ||
324 | {} | 325 | {} |
325 | }; | 326 | }; |
326 | MODULE_DEVICE_TABLE(usb, device_table); | 327 | MODULE_DEVICE_TABLE(usb, device_table); |
@@ -347,8 +348,11 @@ static struct usb_driver sd_driver = { | |||
347 | /* -- module insert / remove -- */ | 348 | /* -- module insert / remove -- */ |
348 | static int __init sd_mod_init(void) | 349 | static int __init sd_mod_init(void) |
349 | { | 350 | { |
350 | if (usb_register(&sd_driver) < 0) | 351 | int ret; |
351 | return -1; | 352 | |
353 | ret = usb_register(&sd_driver); | ||
354 | if (ret < 0) | ||
355 | return ret; | ||
352 | PDEBUG(D_PROBE, "registered"); | 356 | PDEBUG(D_PROBE, "registered"); |
353 | return 0; | 357 | return 0; |
354 | } | 358 | } |
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 1fff37b79891..188866ac6cef 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -50,6 +50,13 @@ static int i2c_detect_tries = 10; | |||
50 | struct sd { | 50 | struct sd { |
51 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 51 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
52 | 52 | ||
53 | char bridge; | ||
54 | #define BRIDGE_OV511 0 | ||
55 | #define BRIDGE_OV511PLUS 1 | ||
56 | #define BRIDGE_OV518 2 | ||
57 | #define BRIDGE_OV518PLUS 3 | ||
58 | #define BRIDGE_OV519 4 | ||
59 | |||
53 | /* Determined by sensor type */ | 60 | /* Determined by sensor type */ |
54 | __u8 sif; | 61 | __u8 sif; |
55 | 62 | ||
@@ -87,6 +94,9 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | |||
87 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | 94 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); |
88 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | 95 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); |
89 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | 96 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); |
97 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
98 | static void setcontrast(struct gspca_dev *gspca_dev); | ||
99 | static void setcolors(struct gspca_dev *gspca_dev); | ||
90 | 100 | ||
91 | static struct ctrl sd_ctrls[] = { | 101 | static struct ctrl sd_ctrls[] = { |
92 | { | 102 | { |
@@ -164,7 +174,7 @@ static struct ctrl sd_ctrls[] = { | |||
164 | }, | 174 | }, |
165 | }; | 175 | }; |
166 | 176 | ||
167 | static const struct v4l2_pix_format vga_mode[] = { | 177 | static const struct v4l2_pix_format ov519_vga_mode[] = { |
168 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 178 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
169 | .bytesperline = 320, | 179 | .bytesperline = 320, |
170 | .sizeimage = 320 * 240 * 3 / 8 + 590, | 180 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
@@ -176,7 +186,7 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
176 | .colorspace = V4L2_COLORSPACE_JPEG, | 186 | .colorspace = V4L2_COLORSPACE_JPEG, |
177 | .priv = 0}, | 187 | .priv = 0}, |
178 | }; | 188 | }; |
179 | static const struct v4l2_pix_format sif_mode[] = { | 189 | static const struct v4l2_pix_format ov519_sif_mode[] = { |
180 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 190 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
181 | .bytesperline = 176, | 191 | .bytesperline = 176, |
182 | .sizeimage = 176 * 144 * 3 / 8 + 590, | 192 | .sizeimage = 176 * 144 * 3 / 8 + 590, |
@@ -189,6 +199,47 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
189 | .priv = 0}, | 199 | .priv = 0}, |
190 | }; | 200 | }; |
191 | 201 | ||
202 | static const struct v4l2_pix_format ov518_vga_mode[] = { | ||
203 | {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
204 | .bytesperline = 320, | ||
205 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
206 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
207 | .priv = 1}, | ||
208 | {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
209 | .bytesperline = 640, | ||
210 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
211 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
212 | .priv = 0}, | ||
213 | }; | ||
214 | static const struct v4l2_pix_format ov518_sif_mode[] = { | ||
215 | {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
216 | .bytesperline = 176, | ||
217 | .sizeimage = 40000, | ||
218 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
219 | .priv = 1}, | ||
220 | {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, | ||
221 | .bytesperline = 352, | ||
222 | .sizeimage = 352 * 288 * 3 / 8 + 590, | ||
223 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
224 | .priv = 0}, | ||
225 | }; | ||
226 | |||
227 | |||
228 | /* Registers common to OV511 / OV518 */ | ||
229 | #define R51x_SYS_RESET 0x50 | ||
230 | #define R51x_SYS_INIT 0x53 | ||
231 | #define R51x_SYS_SNAP 0x52 | ||
232 | #define R51x_SYS_CUST_ID 0x5F | ||
233 | #define R51x_COMP_LUT_BEGIN 0x80 | ||
234 | |||
235 | /* OV511 Camera interface register numbers */ | ||
236 | #define R511_SYS_LED_CTL 0x55 /* OV511+ only */ | ||
237 | #define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */ | ||
238 | |||
239 | /* OV518 Camera interface register numbers */ | ||
240 | #define R518_GPIO_OUT 0x56 /* OV518(+) only */ | ||
241 | #define R518_GPIO_CTL 0x57 /* OV518(+) only */ | ||
242 | |||
192 | /* OV519 Camera interface register numbers */ | 243 | /* OV519 Camera interface register numbers */ |
193 | #define OV519_R10_H_SIZE 0x10 | 244 | #define OV519_R10_H_SIZE 0x10 |
194 | #define OV519_R11_V_SIZE 0x11 | 245 | #define OV519_R11_V_SIZE 0x11 |
@@ -224,6 +275,8 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
224 | 275 | ||
225 | /* OV7610 registers */ | 276 | /* OV7610 registers */ |
226 | #define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ | 277 | #define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ |
278 | #define OV7610_REG_BLUE 0x01 /* blue channel balance */ | ||
279 | #define OV7610_REG_RED 0x02 /* red channel balance */ | ||
227 | #define OV7610_REG_SAT 0x03 /* saturation */ | 280 | #define OV7610_REG_SAT 0x03 /* saturation */ |
228 | #define OV8610_REG_HUE 0x04 /* 04 reserved */ | 281 | #define OV8610_REG_HUE 0x04 /* 04 reserved */ |
229 | #define OV7610_REG_CNT 0x05 /* Y contrast */ | 282 | #define OV7610_REG_CNT 0x05 /* Y contrast */ |
@@ -846,11 +899,12 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) | |||
846 | static int reg_w(struct sd *sd, __u16 index, __u8 value) | 899 | static int reg_w(struct sd *sd, __u16 index, __u8 value) |
847 | { | 900 | { |
848 | int ret; | 901 | int ret; |
902 | int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1; | ||
849 | 903 | ||
850 | sd->gspca_dev.usb_buf[0] = value; | 904 | sd->gspca_dev.usb_buf[0] = value; |
851 | ret = usb_control_msg(sd->gspca_dev.dev, | 905 | ret = usb_control_msg(sd->gspca_dev.dev, |
852 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | 906 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), |
853 | 1, /* REQ_IO (ov518/519) */ | 907 | req, |
854 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 908 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
855 | 0, index, | 909 | 0, index, |
856 | sd->gspca_dev.usb_buf, 1, 500); | 910 | sd->gspca_dev.usb_buf, 1, 500); |
@@ -864,10 +918,11 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value) | |||
864 | static int reg_r(struct sd *sd, __u16 index) | 918 | static int reg_r(struct sd *sd, __u16 index) |
865 | { | 919 | { |
866 | int ret; | 920 | int ret; |
921 | int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1; | ||
867 | 922 | ||
868 | ret = usb_control_msg(sd->gspca_dev.dev, | 923 | ret = usb_control_msg(sd->gspca_dev.dev, |
869 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | 924 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), |
870 | 1, /* REQ_IO */ | 925 | req, |
871 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 926 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
872 | 0, index, sd->gspca_dev.usb_buf, 1, 500); | 927 | 0, index, sd->gspca_dev.usb_buf, 1, 500); |
873 | 928 | ||
@@ -924,6 +979,28 @@ static int reg_w_mask(struct sd *sd, | |||
924 | } | 979 | } |
925 | 980 | ||
926 | /* | 981 | /* |
982 | * Writes multiple (n) byte value to a single register. Only valid with certain | ||
983 | * registers (0x30 and 0xc4 - 0xce). | ||
984 | */ | ||
985 | static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) | ||
986 | { | ||
987 | int ret; | ||
988 | |||
989 | *((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value); | ||
990 | |||
991 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
992 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | ||
993 | 1 /* REG_IO */, | ||
994 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
995 | 0, index, | ||
996 | sd->gspca_dev.usb_buf, n, 500); | ||
997 | if (ret < 0) | ||
998 | PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value); | ||
999 | return ret; | ||
1000 | } | ||
1001 | |||
1002 | |||
1003 | /* | ||
927 | * The OV518 I2C I/O procedure is different, hence, this function. | 1004 | * The OV518 I2C I/O procedure is different, hence, this function. |
928 | * This is normally only called from i2c_w(). Note that this function | 1005 | * This is normally only called from i2c_w(). Note that this function |
929 | * always succeeds regardless of whether the sensor is present and working. | 1006 | * always succeeds regardless of whether the sensor is present and working. |
@@ -1014,20 +1091,47 @@ static inline int ov51x_stop(struct sd *sd) | |||
1014 | { | 1091 | { |
1015 | PDEBUG(D_STREAM, "stopping"); | 1092 | PDEBUG(D_STREAM, "stopping"); |
1016 | sd->stopped = 1; | 1093 | sd->stopped = 1; |
1017 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | 1094 | switch (sd->bridge) { |
1095 | case BRIDGE_OV511: | ||
1096 | case BRIDGE_OV511PLUS: | ||
1097 | return reg_w(sd, R51x_SYS_RESET, 0x3d); | ||
1098 | case BRIDGE_OV518: | ||
1099 | case BRIDGE_OV518PLUS: | ||
1100 | return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); | ||
1101 | case BRIDGE_OV519: | ||
1102 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | ||
1103 | } | ||
1104 | |||
1105 | return 0; | ||
1018 | } | 1106 | } |
1019 | 1107 | ||
1020 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not | 1108 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not |
1021 | * actually stopped (for performance). */ | 1109 | * actually stopped (for performance). */ |
1022 | static inline int ov51x_restart(struct sd *sd) | 1110 | static inline int ov51x_restart(struct sd *sd) |
1023 | { | 1111 | { |
1112 | int rc; | ||
1113 | |||
1024 | PDEBUG(D_STREAM, "restarting"); | 1114 | PDEBUG(D_STREAM, "restarting"); |
1025 | if (!sd->stopped) | 1115 | if (!sd->stopped) |
1026 | return 0; | 1116 | return 0; |
1027 | sd->stopped = 0; | 1117 | sd->stopped = 0; |
1028 | 1118 | ||
1029 | /* Reinitialize the stream */ | 1119 | /* Reinitialize the stream */ |
1030 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | 1120 | switch (sd->bridge) { |
1121 | case BRIDGE_OV511: | ||
1122 | case BRIDGE_OV511PLUS: | ||
1123 | return reg_w(sd, R51x_SYS_RESET, 0x00); | ||
1124 | case BRIDGE_OV518: | ||
1125 | case BRIDGE_OV518PLUS: | ||
1126 | rc = reg_w(sd, 0x2f, 0x80); | ||
1127 | if (rc < 0) | ||
1128 | return rc; | ||
1129 | return reg_w(sd, R51x_SYS_RESET, 0x00); | ||
1130 | case BRIDGE_OV519: | ||
1131 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | ||
1132 | } | ||
1133 | |||
1134 | return 0; | ||
1031 | } | 1135 | } |
1032 | 1136 | ||
1033 | /* This does an initial reset of an OmniVision sensor and ensures that I2C | 1137 | /* This does an initial reset of an OmniVision sensor and ensures that I2C |
@@ -1287,16 +1391,161 @@ static int ov6xx0_configure(struct sd *sd) | |||
1287 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ | 1391 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ |
1288 | static void ov51x_led_control(struct sd *sd, int on) | 1392 | static void ov51x_led_control(struct sd *sd, int on) |
1289 | { | 1393 | { |
1290 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | 1394 | switch (sd->bridge) { |
1395 | /* OV511 has no LED control */ | ||
1396 | case BRIDGE_OV511PLUS: | ||
1397 | reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); | ||
1398 | break; | ||
1399 | case BRIDGE_OV518: | ||
1400 | case BRIDGE_OV518PLUS: | ||
1401 | reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); | ||
1402 | break; | ||
1403 | case BRIDGE_OV519: | ||
1404 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | ||
1405 | break; | ||
1406 | } | ||
1291 | } | 1407 | } |
1292 | 1408 | ||
1293 | /* this function is called at probe time */ | 1409 | /* OV518 quantization tables are 8x4 (instead of 8x8) */ |
1294 | static int sd_config(struct gspca_dev *gspca_dev, | 1410 | static int ov518_upload_quan_tables(struct sd *sd) |
1295 | const struct usb_device_id *id) | 1411 | { |
1412 | const unsigned char yQuanTable518[] = { | ||
1413 | 5, 4, 5, 6, 6, 7, 7, 7, | ||
1414 | 5, 5, 5, 5, 6, 7, 7, 7, | ||
1415 | 6, 6, 6, 6, 7, 7, 7, 8, | ||
1416 | 7, 7, 6, 7, 7, 7, 8, 8 | ||
1417 | }; | ||
1418 | |||
1419 | const unsigned char uvQuanTable518[] = { | ||
1420 | 6, 6, 6, 7, 7, 7, 7, 7, | ||
1421 | 6, 6, 6, 7, 7, 7, 7, 7, | ||
1422 | 6, 6, 6, 7, 7, 7, 7, 8, | ||
1423 | 7, 7, 7, 7, 7, 7, 8, 8 | ||
1424 | }; | ||
1425 | |||
1426 | const unsigned char *pYTable = yQuanTable518; | ||
1427 | const unsigned char *pUVTable = uvQuanTable518; | ||
1428 | unsigned char val0, val1; | ||
1429 | int i, rc, reg = R51x_COMP_LUT_BEGIN; | ||
1430 | |||
1431 | PDEBUG(D_PROBE, "Uploading quantization tables"); | ||
1432 | |||
1433 | for (i = 0; i < 16; i++) { | ||
1434 | val0 = *pYTable++; | ||
1435 | val1 = *pYTable++; | ||
1436 | val0 &= 0x0f; | ||
1437 | val1 &= 0x0f; | ||
1438 | val0 |= val1 << 4; | ||
1439 | rc = reg_w(sd, reg, val0); | ||
1440 | if (rc < 0) | ||
1441 | return rc; | ||
1442 | |||
1443 | val0 = *pUVTable++; | ||
1444 | val1 = *pUVTable++; | ||
1445 | val0 &= 0x0f; | ||
1446 | val1 &= 0x0f; | ||
1447 | val0 |= val1 << 4; | ||
1448 | rc = reg_w(sd, reg + 16, val0); | ||
1449 | if (rc < 0) | ||
1450 | return rc; | ||
1451 | |||
1452 | reg++; | ||
1453 | } | ||
1454 | |||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1458 | /* This initializes the OV518/OV518+ and the sensor */ | ||
1459 | static int ov518_configure(struct gspca_dev *gspca_dev) | ||
1296 | { | 1460 | { |
1297 | struct sd *sd = (struct sd *) gspca_dev; | 1461 | struct sd *sd = (struct sd *) gspca_dev; |
1298 | struct cam *cam; | 1462 | int rc; |
1463 | |||
1464 | /* For 518 and 518+ */ | ||
1465 | static struct ov_regvals init_518[] = { | ||
1466 | { R51x_SYS_RESET, 0x40 }, | ||
1467 | { R51x_SYS_INIT, 0xe1 }, | ||
1468 | { R51x_SYS_RESET, 0x3e }, | ||
1469 | { R51x_SYS_INIT, 0xe1 }, | ||
1470 | { R51x_SYS_RESET, 0x00 }, | ||
1471 | { R51x_SYS_INIT, 0xe1 }, | ||
1472 | { 0x46, 0x00 }, | ||
1473 | { 0x5d, 0x03 }, | ||
1474 | }; | ||
1475 | |||
1476 | static struct ov_regvals norm_518[] = { | ||
1477 | { R51x_SYS_SNAP, 0x02 }, /* Reset */ | ||
1478 | { R51x_SYS_SNAP, 0x01 }, /* Enable */ | ||
1479 | { 0x31, 0x0f }, | ||
1480 | { 0x5d, 0x03 }, | ||
1481 | { 0x24, 0x9f }, | ||
1482 | { 0x25, 0x90 }, | ||
1483 | { 0x20, 0x00 }, | ||
1484 | { 0x51, 0x04 }, | ||
1485 | { 0x71, 0x19 }, | ||
1486 | { 0x2f, 0x80 }, | ||
1487 | }; | ||
1488 | |||
1489 | static struct ov_regvals norm_518_p[] = { | ||
1490 | { R51x_SYS_SNAP, 0x02 }, /* Reset */ | ||
1491 | { R51x_SYS_SNAP, 0x01 }, /* Enable */ | ||
1492 | { 0x31, 0x0f }, | ||
1493 | { 0x5d, 0x03 }, | ||
1494 | { 0x24, 0x9f }, | ||
1495 | { 0x25, 0x90 }, | ||
1496 | { 0x20, 0x60 }, | ||
1497 | { 0x51, 0x02 }, | ||
1498 | { 0x71, 0x19 }, | ||
1499 | { 0x40, 0xff }, | ||
1500 | { 0x41, 0x42 }, | ||
1501 | { 0x46, 0x00 }, | ||
1502 | { 0x33, 0x04 }, | ||
1503 | { 0x21, 0x19 }, | ||
1504 | { 0x3f, 0x10 }, | ||
1505 | { 0x2f, 0x80 }, | ||
1506 | }; | ||
1507 | |||
1508 | /* First 5 bits of custom ID reg are a revision ID on OV518 */ | ||
1509 | PDEBUG(D_PROBE, "Device revision %d", | ||
1510 | 0x1F & reg_r(sd, R51x_SYS_CUST_ID)); | ||
1511 | |||
1512 | rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518)); | ||
1513 | if (rc < 0) | ||
1514 | return rc; | ||
1515 | |||
1516 | /* Set LED GPIO pin to output mode */ | ||
1517 | rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02); | ||
1518 | if (rc < 0) | ||
1519 | return rc; | ||
1299 | 1520 | ||
1521 | switch (sd->bridge) { | ||
1522 | case BRIDGE_OV518: | ||
1523 | rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518)); | ||
1524 | if (rc < 0) | ||
1525 | return rc; | ||
1526 | break; | ||
1527 | case BRIDGE_OV518PLUS: | ||
1528 | rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p)); | ||
1529 | if (rc < 0) | ||
1530 | return rc; | ||
1531 | break; | ||
1532 | } | ||
1533 | |||
1534 | rc = ov518_upload_quan_tables(sd); | ||
1535 | if (rc < 0) { | ||
1536 | PDEBUG(D_ERR, "Error uploading quantization tables"); | ||
1537 | return rc; | ||
1538 | } | ||
1539 | |||
1540 | rc = reg_w(sd, 0x2f, 0x80); | ||
1541 | if (rc < 0) | ||
1542 | return rc; | ||
1543 | |||
1544 | return 0; | ||
1545 | } | ||
1546 | |||
1547 | static int ov519_configure(struct sd *sd) | ||
1548 | { | ||
1300 | static const struct ov_regvals init_519[] = { | 1549 | static const struct ov_regvals init_519[] = { |
1301 | { 0x5a, 0x6d }, /* EnableSystem */ | 1550 | { 0x5a, 0x6d }, /* EnableSystem */ |
1302 | { 0x53, 0x9b }, | 1551 | { 0x53, 0x9b }, |
@@ -1313,8 +1562,32 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1313 | /* windows reads 0x55 at this point*/ | 1562 | /* windows reads 0x55 at this point*/ |
1314 | }; | 1563 | }; |
1315 | 1564 | ||
1316 | if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) | 1565 | return write_regvals(sd, init_519, ARRAY_SIZE(init_519)); |
1566 | } | ||
1567 | |||
1568 | /* this function is called at probe time */ | ||
1569 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1570 | const struct usb_device_id *id) | ||
1571 | { | ||
1572 | struct sd *sd = (struct sd *) gspca_dev; | ||
1573 | struct cam *cam; | ||
1574 | int ret = 0; | ||
1575 | |||
1576 | sd->bridge = id->driver_info; | ||
1577 | |||
1578 | switch (sd->bridge) { | ||
1579 | case BRIDGE_OV518: | ||
1580 | case BRIDGE_OV518PLUS: | ||
1581 | ret = ov518_configure(gspca_dev); | ||
1582 | break; | ||
1583 | case BRIDGE_OV519: | ||
1584 | ret = ov519_configure(sd); | ||
1585 | break; | ||
1586 | } | ||
1587 | |||
1588 | if (ret) | ||
1317 | goto error; | 1589 | goto error; |
1590 | |||
1318 | ov51x_led_control(sd, 0); /* turn LED off */ | 1591 | ov51x_led_control(sd, 0); /* turn LED off */ |
1319 | 1592 | ||
1320 | /* Test for 76xx */ | 1593 | /* Test for 76xx */ |
@@ -1360,12 +1633,26 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1360 | } | 1633 | } |
1361 | 1634 | ||
1362 | cam = &gspca_dev->cam; | 1635 | cam = &gspca_dev->cam; |
1363 | if (!sd->sif) { | 1636 | switch (sd->bridge) { |
1364 | cam->cam_mode = vga_mode; | 1637 | case BRIDGE_OV518: |
1365 | cam->nmodes = ARRAY_SIZE(vga_mode); | 1638 | case BRIDGE_OV518PLUS: |
1366 | } else { | 1639 | if (!sd->sif) { |
1367 | cam->cam_mode = sif_mode; | 1640 | cam->cam_mode = ov518_vga_mode; |
1368 | cam->nmodes = ARRAY_SIZE(sif_mode); | 1641 | cam->nmodes = ARRAY_SIZE(ov518_vga_mode); |
1642 | } else { | ||
1643 | cam->cam_mode = ov518_sif_mode; | ||
1644 | cam->nmodes = ARRAY_SIZE(ov518_sif_mode); | ||
1645 | } | ||
1646 | break; | ||
1647 | case BRIDGE_OV519: | ||
1648 | if (!sd->sif) { | ||
1649 | cam->cam_mode = ov519_vga_mode; | ||
1650 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
1651 | } else { | ||
1652 | cam->cam_mode = ov519_sif_mode; | ||
1653 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | ||
1654 | } | ||
1655 | break; | ||
1369 | } | 1656 | } |
1370 | sd->brightness = BRIGHTNESS_DEF; | 1657 | sd->brightness = BRIGHTNESS_DEF; |
1371 | sd->contrast = CONTRAST_DEF; | 1658 | sd->contrast = CONTRAST_DEF; |
@@ -1422,6 +1709,106 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1422 | return 0; | 1709 | return 0; |
1423 | } | 1710 | } |
1424 | 1711 | ||
1712 | /* Sets up the OV518/OV518+ with the given image parameters | ||
1713 | * | ||
1714 | * OV518 needs a completely different approach, until we can figure out what | ||
1715 | * the individual registers do. Also, only 15 FPS is supported now. | ||
1716 | * | ||
1717 | * Do not put any sensor-specific code in here (including I2C I/O functions) | ||
1718 | */ | ||
1719 | static int ov518_mode_init_regs(struct sd *sd) | ||
1720 | { | ||
1721 | int hsegs, vsegs; | ||
1722 | |||
1723 | /******** Set the mode ********/ | ||
1724 | |||
1725 | reg_w(sd, 0x2b, 0); | ||
1726 | reg_w(sd, 0x2c, 0); | ||
1727 | reg_w(sd, 0x2d, 0); | ||
1728 | reg_w(sd, 0x2e, 0); | ||
1729 | reg_w(sd, 0x3b, 0); | ||
1730 | reg_w(sd, 0x3c, 0); | ||
1731 | reg_w(sd, 0x3d, 0); | ||
1732 | reg_w(sd, 0x3e, 0); | ||
1733 | |||
1734 | if (sd->bridge == BRIDGE_OV518) { | ||
1735 | /* Set 8-bit (YVYU) input format */ | ||
1736 | reg_w_mask(sd, 0x20, 0x08, 0x08); | ||
1737 | |||
1738 | /* Set 12-bit (4:2:0) output format */ | ||
1739 | reg_w_mask(sd, 0x28, 0x80, 0xf0); | ||
1740 | reg_w_mask(sd, 0x38, 0x80, 0xf0); | ||
1741 | } else { | ||
1742 | reg_w(sd, 0x28, 0x80); | ||
1743 | reg_w(sd, 0x38, 0x80); | ||
1744 | } | ||
1745 | |||
1746 | hsegs = sd->gspca_dev.width / 16; | ||
1747 | vsegs = sd->gspca_dev.height / 4; | ||
1748 | |||
1749 | reg_w(sd, 0x29, hsegs); | ||
1750 | reg_w(sd, 0x2a, vsegs); | ||
1751 | |||
1752 | reg_w(sd, 0x39, hsegs); | ||
1753 | reg_w(sd, 0x3a, vsegs); | ||
1754 | |||
1755 | /* Windows driver does this here; who knows why */ | ||
1756 | reg_w(sd, 0x2f, 0x80); | ||
1757 | |||
1758 | /******** Set the framerate (to 30 FPS) ********/ | ||
1759 | if (sd->bridge == BRIDGE_OV518PLUS) | ||
1760 | sd->clockdiv = 1; | ||
1761 | else | ||
1762 | sd->clockdiv = 0; | ||
1763 | |||
1764 | /* Mode independent, but framerate dependent, regs */ | ||
1765 | reg_w(sd, 0x51, 0x04); /* Clock divider; lower==faster */ | ||
1766 | reg_w(sd, 0x22, 0x18); | ||
1767 | reg_w(sd, 0x23, 0xff); | ||
1768 | |||
1769 | if (sd->bridge == BRIDGE_OV518PLUS) | ||
1770 | reg_w(sd, 0x21, 0x19); | ||
1771 | else | ||
1772 | reg_w(sd, 0x71, 0x17); /* Compression-related? */ | ||
1773 | |||
1774 | /* FIXME: Sensor-specific */ | ||
1775 | /* Bit 5 is what matters here. Of course, it is "reserved" */ | ||
1776 | i2c_w(sd, 0x54, 0x23); | ||
1777 | |||
1778 | reg_w(sd, 0x2f, 0x80); | ||
1779 | |||
1780 | if (sd->bridge == BRIDGE_OV518PLUS) { | ||
1781 | reg_w(sd, 0x24, 0x94); | ||
1782 | reg_w(sd, 0x25, 0x90); | ||
1783 | ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */ | ||
1784 | ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */ | ||
1785 | ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */ | ||
1786 | ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */ | ||
1787 | ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */ | ||
1788 | ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */ | ||
1789 | ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */ | ||
1790 | ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */ | ||
1791 | ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */ | ||
1792 | } else { | ||
1793 | reg_w(sd, 0x24, 0x9f); | ||
1794 | reg_w(sd, 0x25, 0x90); | ||
1795 | ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */ | ||
1796 | ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */ | ||
1797 | ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */ | ||
1798 | ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */ | ||
1799 | ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */ | ||
1800 | ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */ | ||
1801 | ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */ | ||
1802 | ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */ | ||
1803 | ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */ | ||
1804 | } | ||
1805 | |||
1806 | reg_w(sd, 0x2f, 0x80); | ||
1807 | |||
1808 | return 0; | ||
1809 | } | ||
1810 | |||
1811 | |||
1425 | /* Sets up the OV519 with the given image parameters | 1812 | /* Sets up the OV519 with the given image parameters |
1426 | * | 1813 | * |
1427 | * OV519 needs a completely different approach, until we can figure out what | 1814 | * OV519 needs a completely different approach, until we can figure out what |
@@ -1740,6 +2127,11 @@ static int set_ov_sensor_window(struct sd *sd) | |||
1740 | hwebase = 0x3a; | 2127 | hwebase = 0x3a; |
1741 | vwsbase = 0x05; | 2128 | vwsbase = 0x05; |
1742 | vwebase = 0x06; | 2129 | vwebase = 0x06; |
2130 | if (qvga) { | ||
2131 | /* HDG: this fixes U and V getting swapped */ | ||
2132 | hwsbase--; | ||
2133 | vwsbase--; | ||
2134 | } | ||
1743 | break; | 2135 | break; |
1744 | case SEN_OV7620: | 2136 | case SEN_OV7620: |
1745 | hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ | 2137 | hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ |
@@ -1855,15 +2247,28 @@ static int set_ov_sensor_window(struct sd *sd) | |||
1855 | static int sd_start(struct gspca_dev *gspca_dev) | 2247 | static int sd_start(struct gspca_dev *gspca_dev) |
1856 | { | 2248 | { |
1857 | struct sd *sd = (struct sd *) gspca_dev; | 2249 | struct sd *sd = (struct sd *) gspca_dev; |
1858 | int ret; | 2250 | int ret = 0; |
1859 | 2251 | ||
1860 | ret = ov519_mode_init_regs(sd); | 2252 | switch (sd->bridge) { |
2253 | case BRIDGE_OV518: | ||
2254 | case BRIDGE_OV518PLUS: | ||
2255 | ret = ov518_mode_init_regs(sd); | ||
2256 | break; | ||
2257 | case BRIDGE_OV519: | ||
2258 | ret = ov519_mode_init_regs(sd); | ||
2259 | break; | ||
2260 | } | ||
1861 | if (ret < 0) | 2261 | if (ret < 0) |
1862 | goto out; | 2262 | goto out; |
2263 | |||
1863 | ret = set_ov_sensor_window(sd); | 2264 | ret = set_ov_sensor_window(sd); |
1864 | if (ret < 0) | 2265 | if (ret < 0) |
1865 | goto out; | 2266 | goto out; |
1866 | 2267 | ||
2268 | setcontrast(gspca_dev); | ||
2269 | setbrightness(gspca_dev); | ||
2270 | setcolors(gspca_dev); | ||
2271 | |||
1867 | ret = ov51x_restart(sd); | 2272 | ret = ov51x_restart(sd); |
1868 | if (ret < 0) | 2273 | if (ret < 0) |
1869 | goto out; | 2274 | goto out; |
@@ -1882,7 +2287,30 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1882 | ov51x_led_control(sd, 0); | 2287 | ov51x_led_control(sd, 0); |
1883 | } | 2288 | } |
1884 | 2289 | ||
1885 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 2290 | static void ov518_pkt_scan(struct gspca_dev *gspca_dev, |
2291 | struct gspca_frame *frame, /* target */ | ||
2292 | __u8 *data, /* isoc packet */ | ||
2293 | int len) /* iso packet length */ | ||
2294 | { | ||
2295 | PDEBUG(D_STREAM, "ov518_pkt_scan: %d bytes", len); | ||
2296 | |||
2297 | if (len & 7) { | ||
2298 | len--; | ||
2299 | PDEBUG(D_STREAM, "packet number: %d\n", (int)data[len]); | ||
2300 | } | ||
2301 | |||
2302 | /* A false positive here is likely, until OVT gives me | ||
2303 | * the definitive SOF/EOF format */ | ||
2304 | if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { | ||
2305 | gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); | ||
2306 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); | ||
2307 | } | ||
2308 | |||
2309 | /* intermediate packet */ | ||
2310 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
2311 | } | ||
2312 | |||
2313 | static void ov519_pkt_scan(struct gspca_dev *gspca_dev, | ||
1886 | struct gspca_frame *frame, /* target */ | 2314 | struct gspca_frame *frame, /* target */ |
1887 | __u8 *data, /* isoc packet */ | 2315 | __u8 *data, /* isoc packet */ |
1888 | int len) /* iso packet length */ | 2316 | int len) /* iso packet length */ |
@@ -1926,6 +2354,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1926 | data, len); | 2354 | data, len); |
1927 | } | 2355 | } |
1928 | 2356 | ||
2357 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
2358 | struct gspca_frame *frame, /* target */ | ||
2359 | __u8 *data, /* isoc packet */ | ||
2360 | int len) /* iso packet length */ | ||
2361 | { | ||
2362 | struct sd *sd = (struct sd *) gspca_dev; | ||
2363 | |||
2364 | switch (sd->bridge) { | ||
2365 | case BRIDGE_OV511: | ||
2366 | case BRIDGE_OV511PLUS: | ||
2367 | break; | ||
2368 | case BRIDGE_OV518: | ||
2369 | case BRIDGE_OV518PLUS: | ||
2370 | ov518_pkt_scan(gspca_dev, frame, data, len); | ||
2371 | break; | ||
2372 | case BRIDGE_OV519: | ||
2373 | ov519_pkt_scan(gspca_dev, frame, data, len); | ||
2374 | break; | ||
2375 | } | ||
2376 | } | ||
2377 | |||
1929 | /* -- management routines -- */ | 2378 | /* -- management routines -- */ |
1930 | 2379 | ||
1931 | static void setbrightness(struct gspca_dev *gspca_dev) | 2380 | static void setbrightness(struct gspca_dev *gspca_dev) |
@@ -1970,6 +2419,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
1970 | break; | 2419 | break; |
1971 | case SEN_OV6630: | 2420 | case SEN_OV6630: |
1972 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); | 2421 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); |
2422 | break; | ||
1973 | case SEN_OV8610: { | 2423 | case SEN_OV8610: { |
1974 | static const __u8 ctab[] = { | 2424 | static const __u8 ctab[] = { |
1975 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f | 2425 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f |
@@ -2136,19 +2586,21 @@ static const struct sd_desc sd_desc = { | |||
2136 | 2586 | ||
2137 | /* -- module initialisation -- */ | 2587 | /* -- module initialisation -- */ |
2138 | static const __devinitdata struct usb_device_id device_table[] = { | 2588 | static const __devinitdata struct usb_device_id device_table[] = { |
2139 | {USB_DEVICE(0x041e, 0x4052)}, | 2589 | {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 }, |
2140 | {USB_DEVICE(0x041e, 0x405f)}, | 2590 | {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, |
2141 | {USB_DEVICE(0x041e, 0x4060)}, | 2591 | {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, |
2142 | {USB_DEVICE(0x041e, 0x4061)}, | 2592 | {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, |
2143 | {USB_DEVICE(0x041e, 0x4064)}, | 2593 | {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 }, |
2144 | {USB_DEVICE(0x041e, 0x4068)}, | 2594 | {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 }, |
2145 | {USB_DEVICE(0x045e, 0x028c)}, | 2595 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, |
2146 | {USB_DEVICE(0x054c, 0x0154)}, | 2596 | {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, |
2147 | {USB_DEVICE(0x054c, 0x0155)}, | 2597 | {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 }, |
2148 | {USB_DEVICE(0x05a9, 0x0519)}, | 2598 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, |
2149 | {USB_DEVICE(0x05a9, 0x0530)}, | 2599 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, |
2150 | {USB_DEVICE(0x05a9, 0x4519)}, | 2600 | {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 }, |
2151 | {USB_DEVICE(0x05a9, 0x8519)}, | 2601 | {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 }, |
2602 | {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 }, | ||
2603 | {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS }, | ||
2152 | {} | 2604 | {} |
2153 | }; | 2605 | }; |
2154 | 2606 | ||
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 19e0bc60de14..4b528b372911 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c | |||
@@ -60,10 +60,23 @@ struct sd { | |||
60 | static struct ctrl sd_ctrls[] = { | 60 | static struct ctrl sd_ctrls[] = { |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static const struct v4l2_pix_format vga_mode[] = { | 63 | static const struct v4l2_pix_format vga_yuyv_mode[] = { |
64 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 64 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
65 | .bytesperline = 640 * 2, | 65 | .bytesperline = 640 * 2, |
66 | .sizeimage = 640 * 480 * 2, | 66 | .sizeimage = 640 * 480 * 2, |
67 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
68 | .priv = 0}, | ||
69 | }; | ||
70 | |||
71 | static const struct v4l2_pix_format vga_jpeg_mode[] = { | ||
72 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
73 | .bytesperline = 320, | ||
74 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
75 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
76 | .priv = 1}, | ||
77 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
78 | .bytesperline = 640, | ||
79 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
67 | .colorspace = V4L2_COLORSPACE_JPEG, | 80 | .colorspace = V4L2_COLORSPACE_JPEG, |
68 | .priv = 0}, | 81 | .priv = 0}, |
69 | }; | 82 | }; |
@@ -244,7 +257,7 @@ static const u8 bridge_init_ov965x[][2] = { | |||
244 | }; | 257 | }; |
245 | 258 | ||
246 | static const u8 sensor_init_ov965x[][2] = { | 259 | static const u8 sensor_init_ov965x[][2] = { |
247 | {0x12, 0x80}, /* com7 - reset */ | 260 | {0x12, 0x80}, /* com7 - SSCB reset */ |
248 | {0x00, 0x00}, /* gain */ | 261 | {0x00, 0x00}, /* gain */ |
249 | {0x01, 0x80}, /* blue */ | 262 | {0x01, 0x80}, /* blue */ |
250 | {0x02, 0x80}, /* red */ | 263 | {0x02, 0x80}, /* red */ |
@@ -254,10 +267,10 @@ static const u8 sensor_init_ov965x[][2] = { | |||
254 | {0x0e, 0x61}, /* com5 */ | 267 | {0x0e, 0x61}, /* com5 */ |
255 | {0x0f, 0x42}, /* com6 */ | 268 | {0x0f, 0x42}, /* com6 */ |
256 | {0x11, 0x00}, /* clkrc */ | 269 | {0x11, 0x00}, /* clkrc */ |
257 | {0x12, 0x02}, /* com7 */ | 270 | {0x12, 0x02}, /* com7 - 15fps VGA YUYV */ |
258 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 271 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
259 | {0x14, 0x28}, /* com9 */ | 272 | {0x14, 0x28}, /* com9 */ |
260 | {0x16, 0x24}, /* rsvd16 */ | 273 | {0x16, 0x24}, /* reg16 */ |
261 | {0x17, 0x1d}, /* hstart*/ | 274 | {0x17, 0x1d}, /* hstart*/ |
262 | {0x18, 0xbd}, /* hstop */ | 275 | {0x18, 0xbd}, /* hstop */ |
263 | {0x19, 0x01}, /* vstrt */ | 276 | {0x19, 0x01}, /* vstrt */ |
@@ -269,24 +282,24 @@ static const u8 sensor_init_ov965x[][2] = { | |||
269 | {0x27, 0x08}, /* bbias */ | 282 | {0x27, 0x08}, /* bbias */ |
270 | {0x28, 0x08}, /* gbbias */ | 283 | {0x28, 0x08}, /* gbbias */ |
271 | {0x29, 0x15}, /* gr com */ | 284 | {0x29, 0x15}, /* gr com */ |
272 | {0x2a, 0x00}, | 285 | {0x2a, 0x00}, /* exhch */ |
273 | {0x2b, 0x00}, | 286 | {0x2b, 0x00}, /* exhcl */ |
274 | {0x2c, 0x08}, /* rbias */ | 287 | {0x2c, 0x08}, /* rbias */ |
275 | {0x32, 0xff}, /* href */ | 288 | {0x32, 0xff}, /* href */ |
276 | {0x33, 0x00}, /* chlf */ | 289 | {0x33, 0x00}, /* chlf */ |
277 | {0x34, 0x3f}, /* arblm */ | 290 | {0x34, 0x3f}, /* aref1 */ |
278 | {0x35, 0x00}, /* rsvd35 */ | 291 | {0x35, 0x00}, /* aref2 */ |
279 | {0x36, 0xf8}, /* rsvd36 */ | 292 | {0x36, 0xf8}, /* aref3 */ |
280 | {0x38, 0x72}, /* acom38 */ | 293 | {0x38, 0x72}, /* adc2 */ |
281 | {0x39, 0x57}, /* ofon */ | 294 | {0x39, 0x57}, /* aref4 */ |
282 | {0x3a, 0x80}, /* tslb */ | 295 | {0x3a, 0x80}, /* tslb - yuyv */ |
283 | {0x3b, 0xc4}, | 296 | {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ |
284 | {0x3d, 0x99}, /* com13 */ | 297 | {0x3d, 0x99}, /* com13 */ |
285 | {0x3f, 0xc1}, | 298 | {0x3f, 0xc1}, /* edge */ |
286 | {0x40, 0xc0}, /* com15 */ | 299 | {0x40, 0xc0}, /* com15 */ |
287 | {0x41, 0x40}, /* com16 */ | 300 | {0x41, 0x40}, /* com16 */ |
288 | {0x42, 0xc0}, | 301 | {0x42, 0xc0}, /* com17 */ |
289 | {0x43, 0x0a}, | 302 | {0x43, 0x0a}, /* rsvd */ |
290 | {0x44, 0xf0}, | 303 | {0x44, 0xf0}, |
291 | {0x45, 0x46}, | 304 | {0x45, 0x46}, |
292 | {0x46, 0x62}, | 305 | {0x46, 0x62}, |
@@ -297,22 +310,22 @@ static const u8 sensor_init_ov965x[][2] = { | |||
297 | {0x4c, 0x7f}, | 310 | {0x4c, 0x7f}, |
298 | {0x4d, 0x7f}, | 311 | {0x4d, 0x7f}, |
299 | {0x4e, 0x7f}, | 312 | {0x4e, 0x7f}, |
300 | {0x4f, 0x98}, | 313 | {0x4f, 0x98}, /* matrix */ |
301 | {0x50, 0x98}, | 314 | {0x50, 0x98}, |
302 | {0x51, 0x00}, | 315 | {0x51, 0x00}, |
303 | {0x52, 0x28}, | 316 | {0x52, 0x28}, |
304 | {0x53, 0x70}, | 317 | {0x53, 0x70}, |
305 | {0x54, 0x98}, | 318 | {0x54, 0x98}, |
306 | {0x58, 0x1a}, | 319 | {0x58, 0x1a}, /* matrix coef sign */ |
307 | {0x59, 0x85}, | 320 | {0x59, 0x85}, /* AWB control */ |
308 | {0x5a, 0xa9}, | 321 | {0x5a, 0xa9}, |
309 | {0x5b, 0x64}, | 322 | {0x5b, 0x64}, |
310 | {0x5c, 0x84}, | 323 | {0x5c, 0x84}, |
311 | {0x5d, 0x53}, | 324 | {0x5d, 0x53}, |
312 | {0x5e, 0x0e}, | 325 | {0x5e, 0x0e}, |
313 | {0x5f, 0xf0}, | 326 | {0x5f, 0xf0}, /* AWB blue limit */ |
314 | {0x60, 0xf0}, | 327 | {0x60, 0xf0}, /* AWB red limit */ |
315 | {0x61, 0xf0}, | 328 | {0x61, 0xf0}, /* AWB green limit */ |
316 | {0x62, 0x00}, /* lcc1 */ | 329 | {0x62, 0x00}, /* lcc1 */ |
317 | {0x63, 0x00}, /* lcc2 */ | 330 | {0x63, 0x00}, /* lcc2 */ |
318 | {0x64, 0x02}, /* lcc3 */ | 331 | {0x64, 0x02}, /* lcc3 */ |
@@ -324,15 +337,15 @@ static const u8 sensor_init_ov965x[][2] = { | |||
324 | {0x6d, 0x55}, | 337 | {0x6d, 0x55}, |
325 | {0x6e, 0x00}, | 338 | {0x6e, 0x00}, |
326 | {0x6f, 0x9d}, | 339 | {0x6f, 0x9d}, |
327 | {0x70, 0x21}, | 340 | {0x70, 0x21}, /* dnsth */ |
328 | {0x71, 0x78}, | 341 | {0x71, 0x78}, |
329 | {0x72, 0x00}, | 342 | {0x72, 0x00}, /* poidx */ |
330 | {0x73, 0x01}, | 343 | {0x73, 0x01}, /* pckdv */ |
331 | {0x74, 0x3a}, | 344 | {0x74, 0x3a}, /* xindx */ |
332 | {0x75, 0x35}, | 345 | {0x75, 0x35}, /* yindx */ |
333 | {0x76, 0x01}, | 346 | {0x76, 0x01}, |
334 | {0x77, 0x02}, | 347 | {0x77, 0x02}, |
335 | {0x7a, 0x12}, | 348 | {0x7a, 0x12}, /* gamma curve */ |
336 | {0x7b, 0x08}, | 349 | {0x7b, 0x08}, |
337 | {0x7c, 0x16}, | 350 | {0x7c, 0x16}, |
338 | {0x7d, 0x30}, | 351 | {0x7d, 0x30}, |
@@ -349,33 +362,33 @@ static const u8 sensor_init_ov965x[][2] = { | |||
349 | {0x88, 0xe6}, | 362 | {0x88, 0xe6}, |
350 | {0x89, 0xf2}, | 363 | {0x89, 0xf2}, |
351 | {0x8a, 0x03}, | 364 | {0x8a, 0x03}, |
352 | {0x8c, 0x89}, | 365 | {0x8c, 0x89}, /* com19 */ |
353 | {0x14, 0x28}, /* com9 */ | 366 | {0x14, 0x28}, /* com9 */ |
354 | {0x90, 0x7d}, | 367 | {0x90, 0x7d}, |
355 | {0x91, 0x7b}, | 368 | {0x91, 0x7b}, |
356 | {0x9d, 0x03}, | 369 | {0x9d, 0x03}, /* lcc6 */ |
357 | {0x9e, 0x04}, | 370 | {0x9e, 0x04}, /* lcc7 */ |
358 | {0x9f, 0x7a}, | 371 | {0x9f, 0x7a}, |
359 | {0xa0, 0x79}, | 372 | {0xa0, 0x79}, |
360 | {0xa1, 0x40}, /* aechm */ | 373 | {0xa1, 0x40}, /* aechm */ |
361 | {0xa4, 0x50}, | 374 | {0xa4, 0x50}, /* com21 */ |
362 | {0xa5, 0x68}, /* com26 */ | 375 | {0xa5, 0x68}, /* com26 */ |
363 | {0xa6, 0x4a}, | 376 | {0xa6, 0x4a}, /* AWB green */ |
364 | {0xa8, 0xc1}, /* acoma8 */ | 377 | {0xa8, 0xc1}, /* refa8 */ |
365 | {0xa9, 0xef}, /* acoma9 */ | 378 | {0xa9, 0xef}, /* refa9 */ |
366 | {0xaa, 0x92}, | 379 | {0xaa, 0x92}, |
367 | {0xab, 0x04}, | 380 | {0xab, 0x04}, |
368 | {0xac, 0x80}, | 381 | {0xac, 0x80}, /* black level control */ |
369 | {0xad, 0x80}, | 382 | {0xad, 0x80}, |
370 | {0xae, 0x80}, | 383 | {0xae, 0x80}, |
371 | {0xaf, 0x80}, | 384 | {0xaf, 0x80}, |
372 | {0xb2, 0xf2}, | 385 | {0xb2, 0xf2}, |
373 | {0xb3, 0x20}, | 386 | {0xb3, 0x20}, |
374 | {0xb4, 0x20}, | 387 | {0xb4, 0x20}, /* ctrlb4 */ |
375 | {0xb5, 0x00}, | 388 | {0xb5, 0x00}, |
376 | {0xb6, 0xaf}, | 389 | {0xb6, 0xaf}, |
377 | {0xbb, 0xae}, | 390 | {0xbb, 0xae}, |
378 | {0xbc, 0x7f}, | 391 | {0xbc, 0x7f}, /* ADC channel offsets */ |
379 | {0xdb, 0x7f}, | 392 | {0xdb, 0x7f}, |
380 | {0xbe, 0x7f}, | 393 | {0xbe, 0x7f}, |
381 | {0xbf, 0x7f}, | 394 | {0xbf, 0x7f}, |
@@ -384,7 +397,7 @@ static const u8 sensor_init_ov965x[][2] = { | |||
384 | {0xc2, 0x01}, | 397 | {0xc2, 0x01}, |
385 | {0xc3, 0x4e}, | 398 | {0xc3, 0x4e}, |
386 | {0xc6, 0x85}, | 399 | {0xc6, 0x85}, |
387 | {0xc7, 0x80}, | 400 | {0xc7, 0x80}, /* com24 */ |
388 | {0xc9, 0xe0}, | 401 | {0xc9, 0xe0}, |
389 | {0xca, 0xe8}, | 402 | {0xca, 0xe8}, |
390 | {0xcb, 0xf0}, | 403 | {0xcb, 0xf0}, |
@@ -399,11 +412,11 @@ static const u8 sensor_init_ov965x[][2] = { | |||
399 | {0x58, 0x1a}, | 412 | {0x58, 0x1a}, |
400 | {0xff, 0x41}, /* read 41, write ff 00 */ | 413 | {0xff, 0x41}, /* read 41, write ff 00 */ |
401 | {0x41, 0x40}, /* com16 */ | 414 | {0x41, 0x40}, /* com16 */ |
402 | {0xc5, 0x03}, | 415 | {0xc5, 0x03}, /* 60 Hz banding filter */ |
403 | {0x6a, 0x02}, | 416 | {0x6a, 0x02}, /* 50 Hz banding filter */ |
404 | 417 | ||
405 | {0x12, 0x62}, /* com7 - VGA + CIF */ | 418 | {0x12, 0x62}, /* com7 - 30fps VGA YUV */ |
406 | {0x36, 0xfa}, /* rsvd36 */ | 419 | {0x36, 0xfa}, /* aref3 */ |
407 | {0x69, 0x0a}, /* hv */ | 420 | {0x69, 0x0a}, /* hv */ |
408 | {0x8c, 0x89}, /* com22 */ | 421 | {0x8c, 0x89}, /* com22 */ |
409 | {0x14, 0x28}, /* com9 */ | 422 | {0x14, 0x28}, /* com9 */ |
@@ -442,8 +455,8 @@ static const u8 bridge_init_ov965x_2[][2] = { | |||
442 | {0x52, 0x3c}, | 455 | {0x52, 0x3c}, |
443 | {0x53, 0x00}, | 456 | {0x53, 0x00}, |
444 | {0x54, 0x00}, | 457 | {0x54, 0x00}, |
445 | {0x55, 0x00}, | 458 | {0x55, 0x00}, /* brightness */ |
446 | {0x57, 0x00}, | 459 | {0x57, 0x00}, /* contrast 2 */ |
447 | {0x5c, 0x00}, | 460 | {0x5c, 0x00}, |
448 | {0x5a, 0xa0}, | 461 | {0x5a, 0xa0}, |
449 | {0x5b, 0x78}, | 462 | {0x5b, 0x78}, |
@@ -489,9 +502,66 @@ static const u8 sensor_init_ov965x_2[][2] = { | |||
489 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 502 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
490 | }; | 503 | }; |
491 | 504 | ||
505 | static const u8 sensor_start_ov965x[][2] = { | ||
506 | {0x12, 0x62}, /* com7 - 30fps VGA YUV */ | ||
507 | {0x36, 0xfa}, /* aref3 */ | ||
508 | {0x69, 0x0a}, /* hv */ | ||
509 | {0x8c, 0x89}, /* com22 */ | ||
510 | {0x14, 0x28}, /* com9 */ | ||
511 | {0x3e, 0x0c}, /* com14 */ | ||
512 | {0x41, 0x40}, /* com16 */ | ||
513 | {0x72, 0x00}, | ||
514 | {0x73, 0x00}, | ||
515 | {0x74, 0x3a}, | ||
516 | {0x75, 0x35}, | ||
517 | {0x76, 0x01}, | ||
518 | {0xc7, 0x80}, /* com24 */ | ||
519 | {0x03, 0x12}, /* vref */ | ||
520 | {0x17, 0x16}, /* hstart */ | ||
521 | {0x18, 0x02}, /* hstop */ | ||
522 | {0x19, 0x01}, /* vstrt */ | ||
523 | {0x1a, 0x3d}, /* vstop */ | ||
524 | {0x32, 0xff}, /* href */ | ||
525 | {0xc0, 0xaa}, | ||
526 | {} | ||
527 | }; | ||
528 | |||
492 | static const u8 bridge_start_ov965x[][2] = { | 529 | static const u8 bridge_start_ov965x[][2] = { |
530 | {0x94, 0xaa}, | ||
531 | {0xf1, 0x60}, | ||
532 | {0xe5, 0x04}, | ||
533 | {0xc0, 0x50}, | ||
534 | {0xc1, 0x3c}, | ||
535 | {0x8c, 0x00}, | ||
536 | {0x8d, 0x1c}, | ||
537 | {0x34, 0x05}, | ||
538 | {} | ||
539 | }; | ||
540 | |||
541 | static const u8 bridge_start_ov965x_vga[][2] = { | ||
542 | {0xc2, 0x0c}, | ||
543 | {0xc3, 0xf9}, | ||
544 | {0xda, 0x01}, | ||
545 | {0x50, 0x00}, | ||
546 | {0x51, 0xa0}, | ||
547 | {0x52, 0x3c}, | ||
548 | {0x53, 0x00}, | ||
549 | {0x54, 0x00}, | ||
550 | {0x55, 0x00}, | ||
551 | {0x57, 0x00}, | ||
552 | {0x5c, 0x00}, | ||
553 | {0x5a, 0xa0}, | ||
554 | {0x5b, 0x78}, | ||
555 | {0x35, 0x02}, | ||
556 | {0xd9, 0x10}, | ||
557 | {0x94, 0x11}, | ||
558 | {} | ||
559 | }; | ||
560 | |||
561 | static const u8 bridge_start_ov965x_cif[][2] = { | ||
493 | {0xc2, 0x4c}, | 562 | {0xc2, 0x4c}, |
494 | {0xc3, 0xf9}, | 563 | {0xc3, 0xf9}, |
564 | {0xda, 0x00}, | ||
495 | {0x50, 0x00}, | 565 | {0x50, 0x00}, |
496 | {0x51, 0xa0}, | 566 | {0x51, 0xa0}, |
497 | {0x52, 0x78}, | 567 | {0x52, 0x78}, |
@@ -500,30 +570,54 @@ static const u8 bridge_start_ov965x[][2] = { | |||
500 | {0x55, 0x00}, | 570 | {0x55, 0x00}, |
501 | {0x57, 0x00}, | 571 | {0x57, 0x00}, |
502 | {0x5c, 0x00}, | 572 | {0x5c, 0x00}, |
503 | {0x5a, 0x28}, | 573 | {0x5a, 0x50}, |
504 | {0x5b, 0x1e}, | 574 | {0x5b, 0x3c}, |
505 | {0x35, 0x00}, | 575 | {0x35, 0x02}, |
506 | {0xd9, 0x21}, | 576 | {0xd9, 0x10}, |
507 | {0x94, 0x11}, | 577 | {0x94, 0x11}, |
578 | {} | ||
508 | }; | 579 | }; |
509 | 580 | ||
510 | static const u8 sensor_start_ov965x[][2] = { | 581 | static const u8 sensor_start_ov965x_vga[][2] = { |
511 | {0x3b, 0xe4}, | 582 | {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ |
583 | {0x1e, 0x04}, /* mvfp */ | ||
584 | {0x13, 0xe0}, /* com8 */ | ||
585 | {0x00, 0x00}, | ||
586 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | ||
587 | {0x11, 0x03}, /* clkrc */ | ||
588 | {0x6b, 0x5a}, /* dblv */ | ||
589 | {0x6a, 0x05}, /* 50 Hz banding filter */ | ||
590 | {0xc5, 0x07}, /* 60 Hz banding filter */ | ||
591 | {0xa2, 0x4b}, /* bd50 */ | ||
592 | {0xa3, 0x3e}, /* bd60 */ | ||
593 | |||
594 | {0x2d, 0x00}, /* advfl */ | ||
595 | {} | ||
596 | }; | ||
597 | |||
598 | static const u8 sensor_start_ov965x_cif[][2] = { | ||
599 | {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ | ||
512 | {0x1e, 0x04}, /* mvfp */ | 600 | {0x1e, 0x04}, /* mvfp */ |
513 | {0x13, 0xe0}, /* com8 */ | 601 | {0x13, 0xe0}, /* com8 */ |
514 | {0x00, 0x00}, | 602 | {0x00, 0x00}, |
515 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 603 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
516 | {0x11, 0x01}, /* clkrc */ | 604 | {0x11, 0x01}, /* clkrc */ |
517 | {0x6b, 0x5a}, /* dblv */ | 605 | {0x6b, 0x5a}, /* dblv */ |
518 | {0x6a, 0x02}, | 606 | {0x6a, 0x02}, /* 50 Hz banding filter */ |
519 | {0xc5, 0x03}, | 607 | {0xc5, 0x03}, /* 60 Hz banding filter */ |
520 | {0xa2, 0x96}, | 608 | {0xa2, 0x96}, /* bd50 */ |
521 | {0xa3, 0x7d}, | 609 | {0xa3, 0x7d}, /* bd60 */ |
610 | |||
522 | {0xff, 0x13}, /* read 13, write ff 00 */ | 611 | {0xff, 0x13}, /* read 13, write ff 00 */ |
523 | {0x13, 0xe7}, | 612 | {0x13, 0xe7}, |
524 | {0x3a, 0x80}, | 613 | {0x3a, 0x80}, /* tslb - yuyv */ |
614 | {} | ||
615 | }; | ||
616 | |||
617 | static const u8 sensor_start_ov965x_2[][2] = { | ||
525 | {0xff, 0x42}, /* read 42, write ff 00 */ | 618 | {0xff, 0x42}, /* read 42, write ff 00 */ |
526 | {0x42, 0xc1}, | 619 | {0x42, 0xc1}, /* com17 - 50 Hz filter */ |
620 | {} | ||
527 | }; | 621 | }; |
528 | 622 | ||
529 | 623 | ||
@@ -705,11 +799,17 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
705 | 799 | ||
706 | cam = &gspca_dev->cam; | 800 | cam = &gspca_dev->cam; |
707 | 801 | ||
708 | cam->cam_mode = vga_mode; | 802 | if (sd->sensor == SENSOR_OV772X) { |
709 | cam->nmodes = ARRAY_SIZE(vga_mode); | 803 | cam->cam_mode = vga_yuyv_mode; |
804 | cam->nmodes = ARRAY_SIZE(vga_yuyv_mode); | ||
710 | 805 | ||
711 | cam->bulk_size = 16384; | 806 | cam->bulk = 1; |
712 | cam->bulk_nurbs = 2; | 807 | cam->bulk_size = 16384; |
808 | cam->bulk_nurbs = 2; | ||
809 | } else { /* ov965x */ | ||
810 | cam->cam_mode = vga_jpeg_mode; | ||
811 | cam->nmodes = ARRAY_SIZE(vga_jpeg_mode); | ||
812 | } | ||
713 | 813 | ||
714 | return 0; | 814 | return 0; |
715 | } | 815 | } |
@@ -778,6 +878,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
778 | static int sd_start(struct gspca_dev *gspca_dev) | 878 | static int sd_start(struct gspca_dev *gspca_dev) |
779 | { | 879 | { |
780 | struct sd *sd = (struct sd *) gspca_dev; | 880 | struct sd *sd = (struct sd *) gspca_dev; |
881 | int mode; | ||
781 | 882 | ||
782 | switch (sd->sensor) { | 883 | switch (sd->sensor) { |
783 | case SENSOR_OV772X: | 884 | case SENSOR_OV772X: |
@@ -786,13 +887,28 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
786 | break; | 887 | break; |
787 | default: | 888 | default: |
788 | /* case SENSOR_OV965X: */ | 889 | /* case SENSOR_OV965X: */ |
789 | reg_w_array(gspca_dev, bridge_start_ov965x, | 890 | |
790 | ARRAY_SIZE(bridge_start_ov965x)); | ||
791 | sccb_w_array(gspca_dev, sensor_start_ov965x, | 891 | sccb_w_array(gspca_dev, sensor_start_ov965x, |
792 | ARRAY_SIZE(sensor_start_ov965x)); | 892 | ARRAY_SIZE(sensor_start_ov965x)); |
893 | reg_w_array(gspca_dev, bridge_start_ov965x, | ||
894 | ARRAY_SIZE(bridge_start_ov965x)); | ||
895 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | ||
896 | if (mode != 0) { /* 320x240 */ | ||
897 | reg_w_array(gspca_dev, bridge_start_ov965x_cif, | ||
898 | ARRAY_SIZE(bridge_start_ov965x_cif)); | ||
899 | sccb_w_array(gspca_dev, sensor_start_ov965x_cif, | ||
900 | ARRAY_SIZE(sensor_start_ov965x_cif)); | ||
901 | } else { /* 640x480 */ | ||
902 | reg_w_array(gspca_dev, bridge_start_ov965x_vga, | ||
903 | ARRAY_SIZE(bridge_start_ov965x_vga)); | ||
904 | sccb_w_array(gspca_dev, sensor_start_ov965x_vga, | ||
905 | ARRAY_SIZE(sensor_start_ov965x_vga)); | ||
906 | } | ||
907 | sccb_w_array(gspca_dev, sensor_start_ov965x_2, | ||
908 | ARRAY_SIZE(sensor_start_ov965x_2)); | ||
909 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | ||
793 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | 910 | ov534_reg_write(gspca_dev, 0xe0, 0x00); |
794 | ov534_set_led(gspca_dev, 1); | 911 | ov534_set_led(gspca_dev, 1); |
795 | /*fixme: other sensor start omitted*/ | ||
796 | } | 912 | } |
797 | return 0; | 913 | return 0; |
798 | } | 914 | } |
@@ -832,9 +948,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, | |||
832 | __u32 this_pts; | 948 | __u32 this_pts; |
833 | u16 this_fid; | 949 | u16 this_fid; |
834 | int remaining_len = len; | 950 | int remaining_len = len; |
951 | int payload_len; | ||
835 | 952 | ||
953 | payload_len = gspca_dev->cam.bulk ? 2048 : 2040; | ||
836 | do { | 954 | do { |
837 | len = min(remaining_len, 2040); /*fixme: was 2048*/ | 955 | len = min(remaining_len, payload_len); |
838 | 956 | ||
839 | /* Payloads are prefixed with a UVC-style header. We | 957 | /* Payloads are prefixed with a UVC-style header. We |
840 | consider a frame to start when the FID toggles, or the PTS | 958 | consider a frame to start when the FID toggles, or the PTS |
@@ -864,30 +982,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, | |||
864 | 982 | ||
865 | /* If PTS or FID has changed, start a new frame. */ | 983 | /* If PTS or FID has changed, start a new frame. */ |
866 | if (this_pts != sd->last_pts || this_fid != sd->last_fid) { | 984 | if (this_pts != sd->last_pts || this_fid != sd->last_fid) { |
867 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 985 | if (gspca_dev->last_packet_type == INTER_PACKET) |
868 | NULL, 0); | 986 | frame = gspca_frame_add(gspca_dev, |
987 | LAST_PACKET, frame, | ||
988 | NULL, 0); | ||
869 | sd->last_pts = this_pts; | 989 | sd->last_pts = this_pts; |
870 | sd->last_fid = this_fid; | 990 | sd->last_fid = this_fid; |
871 | } | 991 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, |
872 | |||
873 | /* Add the data from this payload */ | ||
874 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
875 | data + 12, len - 12); | 992 | data + 12, len - 12); |
876 | |||
877 | /* If this packet is marked as EOF, end the frame */ | 993 | /* If this packet is marked as EOF, end the frame */ |
878 | if (data[1] & UVC_STREAM_EOF) { | 994 | } else if (data[1] & UVC_STREAM_EOF) { |
879 | sd->last_pts = 0; | 995 | sd->last_pts = 0; |
880 | |||
881 | if (frame->data_end - frame->data != | ||
882 | gspca_dev->width * gspca_dev->height * 2) { | ||
883 | PDEBUG(D_PACK, "short frame"); | ||
884 | goto discard; | ||
885 | } | ||
886 | |||
887 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 996 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
888 | NULL, 0); | 997 | data + 12, len - 12); |
998 | } else { | ||
999 | |||
1000 | /* Add the data from this payload */ | ||
1001 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1002 | data + 12, len - 12); | ||
889 | } | 1003 | } |
890 | 1004 | ||
1005 | |||
891 | /* Done this payload */ | 1006 | /* Done this payload */ |
892 | goto scan_next; | 1007 | goto scan_next; |
893 | 1008 | ||
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 153d0a91d4b5..cf3af8de6e97 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -877,6 +877,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
877 | cam->cam_mode = sif_mode; | 877 | cam->cam_mode = sif_mode; |
878 | cam->nmodes = ARRAY_SIZE(sif_mode); | 878 | cam->nmodes = ARRAY_SIZE(sif_mode); |
879 | } | 879 | } |
880 | cam->npkt = 36; /* 36 packets per ISOC message */ | ||
881 | |||
880 | sd->brightness = BRIGHTNESS_DEF; | 882 | sd->brightness = BRIGHTNESS_DEF; |
881 | sd->gain = GAIN_DEF; | 883 | sd->gain = GAIN_DEF; |
882 | sd->exposure = EXPOSURE_DEF; | 884 | sd->exposure = EXPOSURE_DEF; |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index c72e19d3ac37..dc6a6f11354a 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -62,7 +62,6 @@ struct sd { | |||
62 | #define BRIDGE_SN9C105 1 | 62 | #define BRIDGE_SN9C105 1 |
63 | #define BRIDGE_SN9C110 2 | 63 | #define BRIDGE_SN9C110 2 |
64 | #define BRIDGE_SN9C120 3 | 64 | #define BRIDGE_SN9C120 3 |
65 | #define BRIDGE_SN9C325 4 | ||
66 | u8 sensor; /* Type of image sensor chip */ | 65 | u8 sensor; /* Type of image sensor chip */ |
67 | #define SENSOR_HV7131R 0 | 66 | #define SENSOR_HV7131R 0 |
68 | #define SENSOR_MI0360 1 | 67 | #define SENSOR_MI0360 1 |
@@ -354,9 +353,9 @@ static const u8 sn_ov7648[0x1c] = { | |||
354 | 353 | ||
355 | static const u8 sn_ov7660[0x1c] = { | 354 | static const u8 sn_ov7660[0x1c] = { |
356 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | 355 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
357 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, | 356 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, |
358 | /* reg8 reg9 rega regb regc regd rege regf */ | 357 | /* reg8 reg9 rega regb regc regd rege regf */ |
359 | 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, | 358 | 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
360 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | 359 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
361 | 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, | 360 | 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, |
362 | /* reg18 reg19 reg1a reg1b */ | 361 | /* reg18 reg19 reg1a reg1b */ |
@@ -757,6 +756,7 @@ static const u8 ov7660_sensor_init[][8] = { | |||
757 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ | 756 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ |
758 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ | 757 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ |
759 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ | 758 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ |
759 | {0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
760 | /****** (some exchanges in the win trace) ******/ | 760 | /****** (some exchanges in the win trace) ******/ |
761 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ | 761 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ |
762 | /* bits[3..0]reserved */ | 762 | /* bits[3..0]reserved */ |
@@ -1065,9 +1065,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1065 | struct sd *sd = (struct sd *) gspca_dev; | 1065 | struct sd *sd = (struct sd *) gspca_dev; |
1066 | const u8 *reg9a; | 1066 | const u8 *reg9a; |
1067 | static const u8 reg9a_def[] = | 1067 | static const u8 reg9a_def[] = |
1068 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; | 1068 | {0x00, 0x40, 0x20, 0x00, 0x00, 0x00}; |
1069 | static const u8 reg9a_sn9c325[] = | 1069 | static const u8 reg9a_spec[] = |
1070 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; | 1070 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; |
1071 | static const u8 regd4[] = {0x60, 0x00, 0x00}; | 1071 | static const u8 regd4[] = {0x60, 0x00, 0x00}; |
1072 | 1072 | ||
1073 | reg_w1(gspca_dev, 0xf1, 0x00); | 1073 | reg_w1(gspca_dev, 0xf1, 0x00); |
@@ -1077,9 +1077,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1077 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); | 1077 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); |
1078 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); | 1078 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); |
1079 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ | 1079 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ |
1080 | switch (sd->bridge) { | 1080 | switch (sd->sensor) { |
1081 | case BRIDGE_SN9C325: | 1081 | case SENSOR_OV7660: |
1082 | reg9a = reg9a_sn9c325; | 1082 | case SENSOR_SP80708: |
1083 | reg9a = reg9a_spec; | ||
1083 | break; | 1084 | break; |
1084 | default: | 1085 | default: |
1085 | reg9a = reg9a_def; | 1086 | reg9a = reg9a_def; |
@@ -1104,7 +1105,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1104 | reg_w1(gspca_dev, 0x17, 0x64); | 1105 | reg_w1(gspca_dev, 0x17, 0x64); |
1105 | reg_w1(gspca_dev, 0x01, 0x42); | 1106 | reg_w1(gspca_dev, 0x01, 0x42); |
1106 | break; | 1107 | break; |
1107 | /*jfm: from win trace */ | ||
1108 | case SENSOR_OV7630: | 1108 | case SENSOR_OV7630: |
1109 | reg_w1(gspca_dev, 0x01, 0x61); | 1109 | reg_w1(gspca_dev, 0x01, 0x61); |
1110 | reg_w1(gspca_dev, 0x17, 0xe2); | 1110 | reg_w1(gspca_dev, 0x17, 0xe2); |
@@ -1114,18 +1114,15 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1114 | case SENSOR_OV7648: | 1114 | case SENSOR_OV7648: |
1115 | reg_w1(gspca_dev, 0x01, 0x63); | 1115 | reg_w1(gspca_dev, 0x01, 0x63); |
1116 | reg_w1(gspca_dev, 0x17, 0x20); | 1116 | reg_w1(gspca_dev, 0x17, 0x20); |
1117 | reg_w1(gspca_dev, 0x01, 0x62); | ||
1117 | reg_w1(gspca_dev, 0x01, 0x42); | 1118 | reg_w1(gspca_dev, 0x01, 0x42); |
1118 | break; | 1119 | break; |
1119 | /*jfm: from win trace */ | ||
1120 | case SENSOR_OV7660: | 1120 | case SENSOR_OV7660: |
1121 | if (sd->bridge == BRIDGE_SN9C120) { | 1121 | reg_w1(gspca_dev, 0x01, 0x61); |
1122 | reg_w1(gspca_dev, 0x01, 0x61); | 1122 | reg_w1(gspca_dev, 0x17, 0x20); |
1123 | reg_w1(gspca_dev, 0x17, 0x20); | 1123 | reg_w1(gspca_dev, 0x01, 0x60); |
1124 | reg_w1(gspca_dev, 0x01, 0x60); | 1124 | reg_w1(gspca_dev, 0x01, 0x40); |
1125 | reg_w1(gspca_dev, 0x01, 0x40); | 1125 | break; |
1126 | break; | ||
1127 | } | ||
1128 | /* fall thru */ | ||
1129 | case SENSOR_SP80708: | 1126 | case SENSOR_SP80708: |
1130 | reg_w1(gspca_dev, 0x01, 0x63); | 1127 | reg_w1(gspca_dev, 0x01, 0x63); |
1131 | reg_w1(gspca_dev, 0x17, 0x20); | 1128 | reg_w1(gspca_dev, 0x17, 0x20); |
@@ -1134,6 +1131,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
1134 | mdelay(100); | 1131 | mdelay(100); |
1135 | reg_w1(gspca_dev, 0x02, 0x62); | 1132 | reg_w1(gspca_dev, 0x02, 0x62); |
1136 | break; | 1133 | break; |
1134 | /* case SENSOR_HV7131R: */ | ||
1135 | /* case SENSOR_MI0360: */ | ||
1136 | /* case SENSOR_MO4000: */ | ||
1137 | default: | 1137 | default: |
1138 | reg_w1(gspca_dev, 0x01, 0x43); | 1138 | reg_w1(gspca_dev, 0x01, 0x43); |
1139 | reg_w1(gspca_dev, 0x17, 0x61); | 1139 | reg_w1(gspca_dev, 0x17, 0x61); |
@@ -1280,6 +1280,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1280 | cam = &gspca_dev->cam; | 1280 | cam = &gspca_dev->cam; |
1281 | cam->cam_mode = vga_mode; | 1281 | cam->cam_mode = vga_mode; |
1282 | cam->nmodes = ARRAY_SIZE(vga_mode); | 1282 | cam->nmodes = ARRAY_SIZE(vga_mode); |
1283 | cam->npkt = 24; /* 24 packets per ISOC message */ | ||
1283 | 1284 | ||
1284 | sd->bridge = id->driver_info >> 16; | 1285 | sd->bridge = id->driver_info >> 16; |
1285 | sd->sensor = id->driver_info >> 8; | 1286 | sd->sensor = id->driver_info >> 8; |
@@ -1683,13 +1684,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1683 | case SENSOR_OV7648: | 1684 | case SENSOR_OV7648: |
1684 | reg17 = 0x20; | 1685 | reg17 = 0x20; |
1685 | break; | 1686 | break; |
1686 | /*jfm: from win trace */ | ||
1687 | case SENSOR_OV7660: | 1687 | case SENSOR_OV7660: |
1688 | if (sd->bridge == BRIDGE_SN9C120) { | 1688 | reg17 = 0xa0; |
1689 | reg17 = 0xa0; | 1689 | break; |
1690 | break; | ||
1691 | } | ||
1692 | /* fall thru */ | ||
1693 | default: | 1690 | default: |
1694 | reg17 = 0x60; | 1691 | reg17 = 0x60; |
1695 | break; | 1692 | break; |
@@ -1714,16 +1711,17 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1714 | reg_w1(gspca_dev, 0x9a, 0x0a); | 1711 | reg_w1(gspca_dev, 0x9a, 0x0a); |
1715 | reg_w1(gspca_dev, 0x99, 0x60); | 1712 | reg_w1(gspca_dev, 0x99, 0x60); |
1716 | break; | 1713 | break; |
1714 | case SENSOR_OV7660: | ||
1715 | reg_w1(gspca_dev, 0x9a, 0x05); | ||
1716 | if (sd->bridge == BRIDGE_SN9C105) | ||
1717 | reg_w1(gspca_dev, 0x99, 0xff); | ||
1718 | else | ||
1719 | reg_w1(gspca_dev, 0x99, 0x5b); | ||
1720 | break; | ||
1717 | case SENSOR_SP80708: | 1721 | case SENSOR_SP80708: |
1718 | reg_w1(gspca_dev, 0x9a, 0x05); | 1722 | reg_w1(gspca_dev, 0x9a, 0x05); |
1719 | reg_w1(gspca_dev, 0x99, 0x59); | 1723 | reg_w1(gspca_dev, 0x99, 0x59); |
1720 | break; | 1724 | break; |
1721 | case SENSOR_OV7660: | ||
1722 | if (sd->bridge == BRIDGE_SN9C120) { | ||
1723 | reg_w1(gspca_dev, 0x9a, 0x05); | ||
1724 | break; | ||
1725 | } | ||
1726 | /* fall thru */ | ||
1727 | default: | 1725 | default: |
1728 | reg_w1(gspca_dev, 0x9a, 0x08); | 1726 | reg_w1(gspca_dev, 0x9a, 0x08); |
1729 | reg_w1(gspca_dev, 0x99, 0x59); | 1727 | reg_w1(gspca_dev, 0x99, 0x59); |
@@ -2193,6 +2191,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
2193 | {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, | 2191 | {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, |
2194 | {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, | 2192 | {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, |
2195 | {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, | 2193 | {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, |
2194 | {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)}, | ||
2196 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, | 2195 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, |
2197 | /* bw600.inf: | 2196 | /* bw600.inf: |
2198 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ | 2197 | {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ |
@@ -2211,7 +2210,12 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
2211 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 2210 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
2212 | {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, | 2211 | {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, |
2213 | #endif | 2212 | #endif |
2213 | {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/ | ||
2214 | /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ | 2214 | /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ |
2215 | {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/ | ||
2216 | {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/ | ||
2217 | {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/ | ||
2218 | {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/ | ||
2215 | /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ | 2219 | /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ |
2216 | /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ | 2220 | /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ |
2217 | {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ | 2221 | {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ |
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 6f38fa6d86b6..8806b2ff82be 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c | |||
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL"); | |||
32 | struct sd { | 32 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 34 | ||
35 | __u8 packet[ISO_MAX_SIZE + 128]; | ||
36 | /* !! no more than 128 ff in an ISO packet */ | ||
37 | |||
38 | unsigned char brightness; | 35 | unsigned char brightness; |
39 | unsigned char contrast; | 36 | unsigned char contrast; |
40 | unsigned char colors; | 37 | unsigned char colors; |
@@ -906,7 +903,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
906 | { | 903 | { |
907 | struct sd *sd = (struct sd *) gspca_dev; | 904 | struct sd *sd = (struct sd *) gspca_dev; |
908 | int i; | 905 | int i; |
909 | __u8 *s, *d; | ||
910 | static __u8 ffd9[] = {0xff, 0xd9}; | 906 | static __u8 ffd9[] = {0xff, 0xd9}; |
911 | 907 | ||
912 | /* frames are jpeg 4.1.1 without 0xff escape */ | 908 | /* frames are jpeg 4.1.1 without 0xff escape */ |
@@ -930,22 +926,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
930 | } | 926 | } |
931 | 927 | ||
932 | /* add 0x00 after 0xff */ | 928 | /* add 0x00 after 0xff */ |
933 | for (i = len; --i >= 0; ) | 929 | i = 0; |
934 | if (data[i] == 0xff) | 930 | do { |
935 | break; | 931 | if (data[i] == 0xff) { |
936 | if (i < 0) { /* no 0xff */ | 932 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
937 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | 933 | data, i + 1); |
938 | return; | 934 | len -= i; |
939 | } | 935 | data += i; |
940 | s = data; | 936 | *data = 0x00; |
941 | d = sd->packet; | 937 | i = 0; |
942 | for (i = 0; i < len; i++) { | 938 | } |
943 | *d++ = *s++; | 939 | i++; |
944 | if (s[-1] == 0xff) | 940 | } while (i < len); |
945 | *d++ = 0x00; | 941 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); |
946 | } | ||
947 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
948 | sd->packet, d - sd->packet); | ||
949 | } | 942 | } |
950 | 943 | ||
951 | static void setbrightness(struct gspca_dev *gspca_dev) | 944 | static void setbrightness(struct gspca_dev *gspca_dev) |
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 2acec58b1b97..ea8c9fe2e961 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c | |||
@@ -637,19 +637,19 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
637 | cam->nmodes = ARRAY_SIZE(vga_mode) - 1; | 637 | cam->nmodes = ARRAY_SIZE(vga_mode) - 1; |
638 | sd->brightness = BRIGHTNESS_DEF; | 638 | sd->brightness = BRIGHTNESS_DEF; |
639 | 639 | ||
640 | if (sd->subtype == Nxultra) { | ||
641 | if (write_vector(gspca_dev, spca505b_init_data)) | ||
642 | return -EIO; | ||
643 | } else { | ||
644 | if (write_vector(gspca_dev, spca505_init_data)) | ||
645 | return -EIO; | ||
646 | } | ||
647 | return 0; | 640 | return 0; |
648 | } | 641 | } |
649 | 642 | ||
650 | /* this function is called at probe and resume time */ | 643 | /* this function is called at probe and resume time */ |
651 | static int sd_init(struct gspca_dev *gspca_dev) | 644 | static int sd_init(struct gspca_dev *gspca_dev) |
652 | { | 645 | { |
646 | struct sd *sd = (struct sd *) gspca_dev; | ||
647 | |||
648 | if (write_vector(gspca_dev, | ||
649 | sd->subtype == Nxultra | ||
650 | ? spca505b_init_data | ||
651 | : spca505_init_data)) | ||
652 | return -EIO; | ||
653 | return 0; | 653 | return 0; |
654 | } | 654 | } |
655 | 655 | ||
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index adacf8437661..2ed2669bac3e 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SPCA508 chip based cameras subdriver | 2 | * SPCA508 chip based cameras subdriver |
3 | * | 3 | * |
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | 4 | * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 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 | 7 | * it under the terms of the GNU General Public License as published by |
@@ -30,9 +30,9 @@ MODULE_LICENSE("GPL"); | |||
30 | struct sd { | 30 | struct sd { |
31 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 31 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
32 | 32 | ||
33 | unsigned char brightness; | 33 | u8 brightness; |
34 | 34 | ||
35 | char subtype; | 35 | u8 subtype; |
36 | #define CreativeVista 0 | 36 | #define CreativeVista 0 |
37 | #define HamaUSBSightcam 1 | 37 | #define HamaUSBSightcam 1 |
38 | #define HamaUSBSightcam2 2 | 38 | #define HamaUSBSightcam2 2 |
@@ -86,58 +86,34 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
86 | }; | 86 | }; |
87 | 87 | ||
88 | /* Frame packet header offsets for the spca508 */ | 88 | /* Frame packet header offsets for the spca508 */ |
89 | #define SPCA508_OFFSET_TYPE 1 | ||
90 | #define SPCA508_OFFSET_COMPRESS 2 | ||
91 | #define SPCA508_OFFSET_FRAMSEQ 8 | ||
92 | #define SPCA508_OFFSET_WIN1LUM 11 | ||
93 | #define SPCA508_OFFSET_DATA 37 | 89 | #define SPCA508_OFFSET_DATA 37 |
94 | 90 | ||
95 | #define SPCA508_SNAPBIT 0x20 | ||
96 | #define SPCA508_SNAPCTRL 0x40 | ||
97 | /*************** I2c ****************/ | ||
98 | #define SPCA508_INDEX_I2C_BASE 0x8800 | ||
99 | |||
100 | /* | 91 | /* |
101 | * Initialization data: this is the first set-up data written to the | 92 | * Initialization data: this is the first set-up data written to the |
102 | * device (before the open data). | 93 | * device (before the open data). |
103 | */ | 94 | */ |
104 | static const u16 spca508_init_data[][2] = | 95 | static const u16 spca508_init_data[][2] = |
105 | { | 96 | { |
106 | /* line URB value, index */ | 97 | {0x0000, 0x870b}, |
107 | /* 44274 1804 */ {0x0000, 0x870b}, | 98 | |
108 | 99 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ | |
109 | /* 44299 1805 */ {0x0020, 0x8112}, | 100 | {0x0003, 0x8111}, /* Reset compression & memory */ |
110 | /* Video drop enable, ISO streaming disable */ | 101 | {0x0000, 0x8110}, /* Disable all outputs */ |
111 | /* 44324 1806 */ {0x0003, 0x8111}, | 102 | /* READ {0x0000, 0x8114} -> 0000: 00 */ |
112 | /* Reset compression & memory */ | 103 | {0x0000, 0x8114}, /* SW GPIO data */ |
113 | /* 44349 1807 */ {0x0000, 0x8110}, | 104 | {0x0008, 0x8110}, /* Enable charge pump output */ |
114 | /* Disable all outputs */ | 105 | {0x0002, 0x8116}, /* 200 kHz pump clock */ |
115 | /* 44372 1808 */ /* READ {0x0000, 0x8114} -> 0000: 00 */ | 106 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */ |
116 | /* 44398 1809 */ {0x0000, 0x8114}, | 107 | {0x0003, 0x8111}, /* Reset compression & memory */ |
117 | /* SW GPIO data */ | 108 | {0x0000, 0x8111}, /* Normal mode (not reset) */ |
118 | /* 44423 1810 */ {0x0008, 0x8110}, | 109 | {0x0098, 0x8110}, |
119 | /* Enable charge pump output */ | 110 | /* Enable charge pump output, sync.serial,external 2x clock */ |
120 | /* 44527 1811 */ {0x0002, 0x8116}, | 111 | {0x000d, 0x8114}, /* SW GPIO data */ |
121 | /* 200 kHz pump clock */ | 112 | {0x0002, 0x8116}, /* 200 kHz pump clock */ |
122 | /* 44555 1812 */ | 113 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ |
123 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */ | ||
124 | /* 44590 1813 */ {0x0003, 0x8111}, | ||
125 | /* Reset compression & memory */ | ||
126 | /* 44615 1814 */ {0x0000, 0x8111}, | ||
127 | /* Normal mode (not reset) */ | ||
128 | /* 44640 1815 */ {0x0098, 0x8110}, | ||
129 | /* Enable charge pump output, sync.serial,external 2x clock */ | ||
130 | /* 44665 1816 */ {0x000d, 0x8114}, | ||
131 | /* SW GPIO data */ | ||
132 | /* 44690 1817 */ {0x0002, 0x8116}, | ||
133 | /* 200 kHz pump clock */ | ||
134 | /* 44715 1818 */ {0x0020, 0x8112}, | ||
135 | /* Video drop enable, ISO streaming disable */ | ||
136 | /* --------------------------------------- */ | 114 | /* --------------------------------------- */ |
137 | /* 44740 1819 */ {0x000f, 0x8402}, | 115 | {0x000f, 0x8402}, /* memory bank */ |
138 | /* memory bank */ | 116 | {0x0000, 0x8403}, /* ... address */ |
139 | /* 44765 1820 */ {0x0000, 0x8403}, | ||
140 | /* ... address */ | ||
141 | /* --------------------------------------- */ | 117 | /* --------------------------------------- */ |
142 | /* 0x88__ is Synchronous Serial Interface. */ | 118 | /* 0x88__ is Synchronous Serial Interface. */ |
143 | /* TBD: This table could be expressed more compactly */ | 119 | /* TBD: This table could be expressed more compactly */ |
@@ -145,446 +121,384 @@ static const u16 spca508_init_data[][2] = | |||
145 | /* TBD: Should see if the values in spca50x_i2c_data */ | 121 | /* TBD: Should see if the values in spca50x_i2c_data */ |
146 | /* would work with the VQ110 instead of the values */ | 122 | /* would work with the VQ110 instead of the values */ |
147 | /* below. */ | 123 | /* below. */ |
148 | /* 44790 1821 */ {0x00c0, 0x8804}, | 124 | {0x00c0, 0x8804}, /* SSI slave addr */ |
149 | /* SSI slave addr */ | 125 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
150 | /* 44815 1822 */ {0x0008, 0x8802}, | 126 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
151 | /* 375 Khz SSI clock */ | 127 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
152 | /* 44838 1823 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 128 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
153 | /* 44862 1824 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 129 | {0x0012, 0x8801}, /* SSI reg addr */ |
154 | /* 44888 1825 */ {0x0008, 0x8802}, | 130 | {0x0080, 0x8800}, /* SSI data to write */ |
155 | /* 375 Khz SSI clock */ | 131 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
156 | /* 44913 1826 */ {0x0012, 0x8801}, | 132 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
157 | /* SSI reg addr */ | 133 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
158 | /* 44938 1827 */ {0x0080, 0x8800}, | 134 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
159 | /* SSI data to write */ | 135 | {0x0012, 0x8801}, /* SSI reg addr */ |
160 | /* 44961 1828 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 136 | {0x0000, 0x8800}, /* SSI data to write */ |
161 | /* 44985 1829 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 137 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
162 | /* 45009 1830 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 138 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
163 | /* 45035 1831 */ {0x0008, 0x8802}, | 139 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
164 | /* 375 Khz SSI clock */ | 140 | {0x0008, 0x8802}, /* 375 Khz SSI clock */ |
165 | /* 45060 1832 */ {0x0012, 0x8801}, | 141 | {0x0011, 0x8801}, /* SSI reg addr */ |
166 | /* SSI reg addr */ | 142 | {0x0040, 0x8800}, /* SSI data to write */ |
167 | /* 45085 1833 */ {0x0000, 0x8800}, | 143 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
168 | /* SSI data to write */ | 144 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
169 | /* 45108 1834 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 145 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
170 | /* 45132 1835 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 146 | {0x0008, 0x8802}, |
171 | /* 45156 1836 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 147 | {0x0013, 0x8801}, |
172 | /* 45182 1837 */ {0x0008, 0x8802}, | 148 | {0x0000, 0x8800}, |
173 | /* 375 Khz SSI clock */ | 149 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
174 | /* 45207 1838 */ {0x0011, 0x8801}, | 150 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
175 | /* SSI reg addr */ | 151 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
176 | /* 45232 1839 */ {0x0040, 0x8800}, | 152 | {0x0008, 0x8802}, |
177 | /* SSI data to write */ | 153 | {0x0014, 0x8801}, |
178 | /* 45255 1840 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 154 | {0x0000, 0x8800}, |
179 | /* 45279 1841 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 155 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
180 | /* 45303 1842 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 156 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
181 | /* 45329 1843 */ {0x0008, 0x8802}, | 157 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
182 | /* 45354 1844 */ {0x0013, 0x8801}, | 158 | {0x0008, 0x8802}, |
183 | /* 45379 1845 */ {0x0000, 0x8800}, | 159 | {0x0015, 0x8801}, |
184 | /* 45402 1846 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 160 | {0x0001, 0x8800}, |
185 | /* 45426 1847 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 161 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
186 | /* 45450 1848 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 162 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
187 | /* 45476 1849 */ {0x0008, 0x8802}, | 163 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
188 | /* 45501 1850 */ {0x0014, 0x8801}, | 164 | {0x0008, 0x8802}, |
189 | /* 45526 1851 */ {0x0000, 0x8800}, | 165 | {0x0016, 0x8801}, |
190 | /* 45549 1852 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 166 | {0x0003, 0x8800}, |
191 | /* 45573 1853 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 167 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
192 | /* 45597 1854 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 168 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
193 | /* 45623 1855 */ {0x0008, 0x8802}, | 169 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
194 | /* 45648 1856 */ {0x0015, 0x8801}, | 170 | {0x0008, 0x8802}, |
195 | /* 45673 1857 */ {0x0001, 0x8800}, | 171 | {0x0017, 0x8801}, |
196 | /* 45696 1858 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 172 | {0x0036, 0x8800}, |
197 | /* 45720 1859 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 173 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
198 | /* 45744 1860 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 174 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
199 | /* 45770 1861 */ {0x0008, 0x8802}, | 175 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
200 | /* 45795 1862 */ {0x0016, 0x8801}, | 176 | {0x0008, 0x8802}, |
201 | /* 45820 1863 */ {0x0003, 0x8800}, | 177 | {0x0018, 0x8801}, |
202 | /* 45843 1864 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 178 | {0x00ec, 0x8800}, |
203 | /* 45867 1865 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 179 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
204 | /* 45891 1866 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 180 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
205 | /* 45917 1867 */ {0x0008, 0x8802}, | 181 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
206 | /* 45942 1868 */ {0x0017, 0x8801}, | 182 | {0x0008, 0x8802}, |
207 | /* 45967 1869 */ {0x0036, 0x8800}, | 183 | {0x001a, 0x8801}, |
208 | /* 45990 1870 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 184 | {0x0094, 0x8800}, |
209 | /* 46014 1871 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 185 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
210 | /* 46038 1872 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 186 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
211 | /* 46064 1873 */ {0x0008, 0x8802}, | 187 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
212 | /* 46089 1874 */ {0x0018, 0x8801}, | 188 | {0x0008, 0x8802}, |
213 | /* 46114 1875 */ {0x00ec, 0x8800}, | 189 | {0x001b, 0x8801}, |
214 | /* 46137 1876 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 190 | {0x0000, 0x8800}, |
215 | /* 46161 1877 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 191 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
216 | /* 46185 1878 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 192 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
217 | /* 46211 1879 */ {0x0008, 0x8802}, | 193 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
218 | /* 46236 1880 */ {0x001a, 0x8801}, | 194 | {0x0008, 0x8802}, |
219 | /* 46261 1881 */ {0x0094, 0x8800}, | 195 | {0x0027, 0x8801}, |
220 | /* 46284 1882 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 196 | {0x00a2, 0x8800}, |
221 | /* 46308 1883 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 197 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
222 | /* 46332 1884 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 198 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
223 | /* 46358 1885 */ {0x0008, 0x8802}, | 199 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
224 | /* 46383 1886 */ {0x001b, 0x8801}, | 200 | {0x0008, 0x8802}, |
225 | /* 46408 1887 */ {0x0000, 0x8800}, | 201 | {0x0028, 0x8801}, |
226 | /* 46431 1888 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 202 | {0x0040, 0x8800}, |
227 | /* 46455 1889 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 203 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
228 | /* 46479 1890 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 204 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
229 | /* 46505 1891 */ {0x0008, 0x8802}, | 205 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
230 | /* 46530 1892 */ {0x0027, 0x8801}, | 206 | {0x0008, 0x8802}, |
231 | /* 46555 1893 */ {0x00a2, 0x8800}, | 207 | {0x002a, 0x8801}, |
232 | /* 46578 1894 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 208 | {0x0084, 0x8800}, |
233 | /* 46602 1895 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 209 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
234 | /* 46626 1896 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 210 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
235 | /* 46652 1897 */ {0x0008, 0x8802}, | 211 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
236 | /* 46677 1898 */ {0x0028, 0x8801}, | 212 | {0x0008, 0x8802}, |
237 | /* 46702 1899 */ {0x0040, 0x8800}, | 213 | {0x002b, 0x8801}, |
238 | /* 46725 1900 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 214 | {0x00a8, 0x8800}, |
239 | /* 46749 1901 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 215 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
240 | /* 46773 1902 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 216 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
241 | /* 46799 1903 */ {0x0008, 0x8802}, | 217 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
242 | /* 46824 1904 */ {0x002a, 0x8801}, | 218 | {0x0008, 0x8802}, |
243 | /* 46849 1905 */ {0x0084, 0x8800}, | 219 | {0x002c, 0x8801}, |
244 | /* 46872 1906 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 220 | {0x00fe, 0x8800}, |
245 | /* 46896 1907 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 221 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
246 | /* 46920 1908 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 222 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
247 | /* 46946 1909 */ {0x0008, 0x8802}, | 223 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
248 | /* 46971 1910 */ {0x002b, 0x8801}, | 224 | {0x0008, 0x8802}, |
249 | /* 46996 1911 */ {0x00a8, 0x8800}, | 225 | {0x002d, 0x8801}, |
250 | /* 47019 1912 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 226 | {0x0003, 0x8800}, |
251 | /* 47043 1913 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 227 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
252 | /* 47067 1914 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 228 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
253 | /* 47093 1915 */ {0x0008, 0x8802}, | 229 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
254 | /* 47118 1916 */ {0x002c, 0x8801}, | 230 | {0x0008, 0x8802}, |
255 | /* 47143 1917 */ {0x00fe, 0x8800}, | 231 | {0x0038, 0x8801}, |
256 | /* 47166 1918 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 232 | {0x0083, 0x8800}, |
257 | /* 47190 1919 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 233 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
258 | /* 47214 1920 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 234 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
259 | /* 47240 1921 */ {0x0008, 0x8802}, | 235 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
260 | /* 47265 1922 */ {0x002d, 0x8801}, | 236 | {0x0008, 0x8802}, |
261 | /* 47290 1923 */ {0x0003, 0x8800}, | 237 | {0x0033, 0x8801}, |
262 | /* 47313 1924 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 238 | {0x0081, 0x8800}, |
263 | /* 47337 1925 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 239 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
264 | /* 47361 1926 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 240 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
265 | /* 47387 1927 */ {0x0008, 0x8802}, | 241 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
266 | /* 47412 1928 */ {0x0038, 0x8801}, | 242 | {0x0008, 0x8802}, |
267 | /* 47437 1929 */ {0x0083, 0x8800}, | 243 | {0x0034, 0x8801}, |
268 | /* 47460 1930 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 244 | {0x004a, 0x8800}, |
269 | /* 47484 1931 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 245 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
270 | /* 47508 1932 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 246 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
271 | /* 47534 1933 */ {0x0008, 0x8802}, | 247 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
272 | /* 47559 1934 */ {0x0033, 0x8801}, | 248 | {0x0008, 0x8802}, |
273 | /* 47584 1935 */ {0x0081, 0x8800}, | 249 | {0x0039, 0x8801}, |
274 | /* 47607 1936 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 250 | {0x0000, 0x8800}, |
275 | /* 47631 1937 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 251 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
276 | /* 47655 1938 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 252 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
277 | /* 47681 1939 */ {0x0008, 0x8802}, | 253 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
278 | /* 47706 1940 */ {0x0034, 0x8801}, | 254 | {0x0008, 0x8802}, |
279 | /* 47731 1941 */ {0x004a, 0x8800}, | 255 | {0x0010, 0x8801}, |
280 | /* 47754 1942 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 256 | {0x00a8, 0x8800}, |
281 | /* 47778 1943 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 257 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
282 | /* 47802 1944 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 258 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
283 | /* 47828 1945 */ {0x0008, 0x8802}, | 259 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
284 | /* 47853 1946 */ {0x0039, 0x8801}, | 260 | {0x0008, 0x8802}, |
285 | /* 47878 1947 */ {0x0000, 0x8800}, | 261 | {0x0006, 0x8801}, |
286 | /* 47901 1948 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 262 | {0x0058, 0x8800}, |
287 | /* 47925 1949 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 263 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
288 | /* 47949 1950 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 264 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
289 | /* 47975 1951 */ {0x0008, 0x8802}, | 265 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
290 | /* 48000 1952 */ {0x0010, 0x8801}, | 266 | {0x0008, 0x8802}, |
291 | /* 48025 1953 */ {0x00a8, 0x8800}, | 267 | {0x0000, 0x8801}, |
292 | /* 48048 1954 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 268 | {0x0004, 0x8800}, |
293 | /* 48072 1955 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 269 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
294 | /* 48096 1956 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 270 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
295 | /* 48122 1957 */ {0x0008, 0x8802}, | 271 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
296 | /* 48147 1958 */ {0x0006, 0x8801}, | 272 | {0x0008, 0x8802}, |
297 | /* 48172 1959 */ {0x0058, 0x8800}, | 273 | {0x0040, 0x8801}, |
298 | /* 48195 1960 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 274 | {0x0080, 0x8800}, |
299 | /* 48219 1961 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 275 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
300 | /* 48243 1962 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 276 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
301 | /* 48269 1963 */ {0x0008, 0x8802}, | 277 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
302 | /* 48294 1964 */ {0x0000, 0x8801}, | 278 | {0x0008, 0x8802}, |
303 | /* 48319 1965 */ {0x0004, 0x8800}, | 279 | {0x0041, 0x8801}, |
304 | /* 48342 1966 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 280 | {0x000c, 0x8800}, |
305 | /* 48366 1967 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 281 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
306 | /* 48390 1968 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 282 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
307 | /* 48416 1969 */ {0x0008, 0x8802}, | 283 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
308 | /* 48441 1970 */ {0x0040, 0x8801}, | 284 | {0x0008, 0x8802}, |
309 | /* 48466 1971 */ {0x0080, 0x8800}, | 285 | {0x0042, 0x8801}, |
310 | /* 48489 1972 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 286 | {0x000c, 0x8800}, |
311 | /* 48513 1973 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 287 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
312 | /* 48537 1974 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 288 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
313 | /* 48563 1975 */ {0x0008, 0x8802}, | 289 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
314 | /* 48588 1976 */ {0x0041, 0x8801}, | 290 | {0x0008, 0x8802}, |
315 | /* 48613 1977 */ {0x000c, 0x8800}, | 291 | {0x0043, 0x8801}, |
316 | /* 48636 1978 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 292 | {0x0028, 0x8800}, |
317 | /* 48660 1979 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 293 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
318 | /* 48684 1980 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 294 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
319 | /* 48710 1981 */ {0x0008, 0x8802}, | 295 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
320 | /* 48735 1982 */ {0x0042, 0x8801}, | 296 | {0x0008, 0x8802}, |
321 | /* 48760 1983 */ {0x000c, 0x8800}, | 297 | {0x0044, 0x8801}, |
322 | /* 48783 1984 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 298 | {0x0080, 0x8800}, |
323 | /* 48807 1985 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 299 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
324 | /* 48831 1986 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 300 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
325 | /* 48857 1987 */ {0x0008, 0x8802}, | 301 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
326 | /* 48882 1988 */ {0x0043, 0x8801}, | 302 | {0x0008, 0x8802}, |
327 | /* 48907 1989 */ {0x0028, 0x8800}, | 303 | {0x0045, 0x8801}, |
328 | /* 48930 1990 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 304 | {0x0020, 0x8800}, |
329 | /* 48954 1991 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 305 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
330 | /* 48978 1992 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 306 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
331 | /* 49004 1993 */ {0x0008, 0x8802}, | 307 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
332 | /* 49029 1994 */ {0x0044, 0x8801}, | 308 | {0x0008, 0x8802}, |
333 | /* 49054 1995 */ {0x0080, 0x8800}, | 309 | {0x0046, 0x8801}, |
334 | /* 49077 1996 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 310 | {0x0020, 0x8800}, |
335 | /* 49101 1997 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 311 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
336 | /* 49125 1998 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 312 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
337 | /* 49151 1999 */ {0x0008, 0x8802}, | 313 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
338 | /* 49176 2000 */ {0x0045, 0x8801}, | 314 | {0x0008, 0x8802}, |
339 | /* 49201 2001 */ {0x0020, 0x8800}, | 315 | {0x0047, 0x8801}, |
340 | /* 49224 2002 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 316 | {0x0080, 0x8800}, |
341 | /* 49248 2003 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 317 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
342 | /* 49272 2004 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 318 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
343 | /* 49298 2005 */ {0x0008, 0x8802}, | 319 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
344 | /* 49323 2006 */ {0x0046, 0x8801}, | 320 | {0x0008, 0x8802}, |
345 | /* 49348 2007 */ {0x0020, 0x8800}, | 321 | {0x0048, 0x8801}, |
346 | /* 49371 2008 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 322 | {0x004c, 0x8800}, |
347 | /* 49395 2009 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 323 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
348 | /* 49419 2010 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 324 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
349 | /* 49445 2011 */ {0x0008, 0x8802}, | 325 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
350 | /* 49470 2012 */ {0x0047, 0x8801}, | 326 | {0x0008, 0x8802}, |
351 | /* 49495 2013 */ {0x0080, 0x8800}, | 327 | {0x0049, 0x8801}, |
352 | /* 49518 2014 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 328 | {0x0084, 0x8800}, |
353 | /* 49542 2015 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 329 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
354 | /* 49566 2016 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 330 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
355 | /* 49592 2017 */ {0x0008, 0x8802}, | 331 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
356 | /* 49617 2018 */ {0x0048, 0x8801}, | 332 | {0x0008, 0x8802}, |
357 | /* 49642 2019 */ {0x004c, 0x8800}, | 333 | {0x004a, 0x8801}, |
358 | /* 49665 2020 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 334 | {0x0084, 0x8800}, |
359 | /* 49689 2021 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 335 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
360 | /* 49713 2022 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 336 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
361 | /* 49739 2023 */ {0x0008, 0x8802}, | 337 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
362 | /* 49764 2024 */ {0x0049, 0x8801}, | 338 | {0x0008, 0x8802}, |
363 | /* 49789 2025 */ {0x0084, 0x8800}, | 339 | {0x004b, 0x8801}, |
364 | /* 49812 2026 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 340 | {0x0084, 0x8800}, |
365 | /* 49836 2027 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 341 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
366 | /* 49860 2028 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
367 | /* 49886 2029 */ {0x0008, 0x8802}, | ||
368 | /* 49911 2030 */ {0x004a, 0x8801}, | ||
369 | /* 49936 2031 */ {0x0084, 0x8800}, | ||
370 | /* 49959 2032 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
371 | /* 49983 2033 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
372 | /* 50007 2034 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
373 | /* 50033 2035 */ {0x0008, 0x8802}, | ||
374 | /* 50058 2036 */ {0x004b, 0x8801}, | ||
375 | /* 50083 2037 */ {0x0084, 0x8800}, | ||
376 | /* 50106 2038 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
377 | /* --------------------------------------- */ | 342 | /* --------------------------------------- */ |
378 | /* 50132 2039 */ {0x0012, 0x8700}, | 343 | {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ |
379 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | 344 | {0x0000, 0x8701}, /* CKx1 clock delay adj */ |
380 | /* 50157 2040 */ {0x0000, 0x8701}, | 345 | {0x0000, 0x8701}, /* CKx1 clock delay adj */ |
381 | /* CKx1 clock delay adj */ | 346 | {0x0001, 0x870c}, /* CKOx2 output */ |
382 | /* 50182 2041 */ {0x0000, 0x8701}, | ||
383 | /* CKx1 clock delay adj */ | ||
384 | /* 50207 2042 */ {0x0001, 0x870c}, | ||
385 | /* CKOx2 output */ | ||
386 | /* --------------------------------------- */ | 347 | /* --------------------------------------- */ |
387 | /* 50232 2043 */ {0x0080, 0x8600}, | 348 | {0x0080, 0x8600}, /* Line memory read counter (L) */ |
388 | /* Line memory read counter (L) */ | 349 | {0x0001, 0x8606}, /* reserved */ |
389 | /* 50257 2044 */ {0x0001, 0x8606}, | 350 | {0x0064, 0x8607}, /* Line memory read counter (H) 0x6480=25,728 */ |
390 | /* reserved */ | 351 | {0x002a, 0x8601}, /* CDSP sharp interpolation mode, |
391 | /* 50282 2045 */ {0x0064, 0x8607}, | ||
392 | /* Line memory read counter (H) 0x6480=25,728 */ | ||
393 | /* 50307 2046 */ {0x002a, 0x8601}, | ||
394 | /* CDSP sharp interpolation mode, | ||
395 | * line sel for color sep, edge enhance enab */ | 352 | * line sel for color sep, edge enhance enab */ |
396 | /* 50332 2047 */ {0x0000, 0x8602}, | 353 | {0x0000, 0x8602}, /* optical black level for user settng = 0 */ |
397 | /* optical black level for user settng = 0 */ | 354 | {0x0080, 0x8600}, /* Line memory read counter (L) */ |
398 | /* 50357 2048 */ {0x0080, 0x8600}, | 355 | {0x000a, 0x8603}, /* optical black level calc mode: |
399 | /* Line memory read counter (L) */ | 356 | * auto; optical black offset = 10 */ |
400 | /* 50382 2049 */ {0x000a, 0x8603}, | 357 | {0x00df, 0x865b}, /* Horiz offset for valid pixels (L)=0xdf */ |
401 | /* optical black level calc mode: auto; optical black offset = 10 */ | 358 | {0x0012, 0x865c}, /* Vert offset for valid lines (L)=0x12 */ |
402 | /* 50407 2050 */ {0x00df, 0x865b}, | ||
403 | /* Horiz offset for valid pixels (L)=0xdf */ | ||
404 | /* 50432 2051 */ {0x0012, 0x865c}, | ||
405 | /* Vert offset for valid lines (L)=0x12 */ | ||
406 | 359 | ||
407 | /* The following two lines seem to be the "wrong" resolution. */ | 360 | /* The following two lines seem to be the "wrong" resolution. */ |
408 | /* But perhaps these indicate the actual size of the sensor */ | 361 | /* But perhaps these indicate the actual size of the sensor */ |
409 | /* rather than the size of the current video mode. */ | 362 | /* rather than the size of the current video mode. */ |
410 | /* 50457 2052 */ {0x0058, 0x865d}, | 363 | {0x0058, 0x865d}, /* Horiz valid pixels (*4) (L) = 352 */ |
411 | /* Horiz valid pixels (*4) (L) = 352 */ | 364 | {0x0048, 0x865e}, /* Vert valid lines (*4) (L) = 288 */ |
412 | /* 50482 2053 */ {0x0048, 0x865e}, | 365 | |
413 | /* Vert valid lines (*4) (L) = 288 */ | 366 | {0x0015, 0x8608}, /* A11 Coef ... */ |
414 | 367 | {0x0030, 0x8609}, | |
415 | /* 50507 2054 */ {0x0015, 0x8608}, | 368 | {0x00fb, 0x860a}, |
416 | /* A11 Coef ... */ | 369 | {0x003e, 0x860b}, |
417 | /* 50532 2055 */ {0x0030, 0x8609}, | 370 | {0x00ce, 0x860c}, |
418 | /* 50557 2056 */ {0x00fb, 0x860a}, | 371 | {0x00f4, 0x860d}, |
419 | /* 50582 2057 */ {0x003e, 0x860b}, | 372 | {0x00eb, 0x860e}, |
420 | /* 50607 2058 */ {0x00ce, 0x860c}, | 373 | {0x00dc, 0x860f}, |
421 | /* 50632 2059 */ {0x00f4, 0x860d}, | 374 | {0x0039, 0x8610}, |
422 | /* 50657 2060 */ {0x00eb, 0x860e}, | 375 | {0x0001, 0x8611}, /* R offset for white balance ... */ |
423 | /* 50682 2061 */ {0x00dc, 0x860f}, | 376 | {0x0000, 0x8612}, |
424 | /* 50707 2062 */ {0x0039, 0x8610}, | 377 | {0x0001, 0x8613}, |
425 | /* 50732 2063 */ {0x0001, 0x8611}, | 378 | {0x0000, 0x8614}, |
426 | /* R offset for white balance ... */ | 379 | {0x005b, 0x8651}, /* R gain for white balance ... */ |
427 | /* 50757 2064 */ {0x0000, 0x8612}, | 380 | {0x0040, 0x8652}, |
428 | /* 50782 2065 */ {0x0001, 0x8613}, | 381 | {0x0060, 0x8653}, |
429 | /* 50807 2066 */ {0x0000, 0x8614}, | 382 | {0x0040, 0x8654}, |
430 | /* 50832 2067 */ {0x005b, 0x8651}, | 383 | {0x0000, 0x8655}, |
431 | /* R gain for white balance ... */ | 384 | {0x0001, 0x863f}, /* Fixed gamma correction enable, USB control, |
432 | /* 50857 2068 */ {0x0040, 0x8652}, | 385 | * lum filter disable, lum noise clip disable */ |
433 | /* 50882 2069 */ {0x0060, 0x8653}, | 386 | {0x00a1, 0x8656}, /* Window1 size 256x256, Windows2 size 64x64, |
434 | /* 50907 2070 */ {0x0040, 0x8654}, | 387 | * gamma look-up disable, |
435 | /* 50932 2071 */ {0x0000, 0x8655}, | 388 | * new edge enhancement enable */ |
436 | /* 50957 2072 */ {0x0001, 0x863f}, | 389 | {0x0018, 0x8657}, /* Edge gain high thresh */ |
437 | /* Fixed gamma correction enable, USB control, | 390 | {0x0020, 0x8658}, /* Edge gain low thresh */ |
438 | * lum filter disable, lum noise clip disable */ | 391 | {0x000a, 0x8659}, /* Edge bandwidth high threshold */ |
439 | /* 50982 2073 */ {0x00a1, 0x8656}, | 392 | {0x0005, 0x865a}, /* Edge bandwidth low threshold */ |
440 | /* Window1 size 256x256, Windows2 size 64x64, | ||
441 | * gamma look-up disable, new edge enhancement enable */ | ||
442 | /* 51007 2074 */ {0x0018, 0x8657}, | ||
443 | /* Edge gain high thresh */ | ||
444 | /* 51032 2075 */ {0x0020, 0x8658}, | ||
445 | /* Edge gain low thresh */ | ||
446 | /* 51057 2076 */ {0x000a, 0x8659}, | ||
447 | /* Edge bandwidth high threshold */ | ||
448 | /* 51082 2077 */ {0x0005, 0x865a}, | ||
449 | /* Edge bandwidth low threshold */ | ||
450 | /* -------------------------------- */ | 393 | /* -------------------------------- */ |
451 | /* 51107 2078 */ {0x0030, 0x8112}, | 394 | {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */ |
452 | /* Video drop enable, ISO streaming enable */ | 395 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
453 | /* 51130 2079 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 396 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
454 | /* 51154 2080 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 397 | {0xa908, 0x8802}, |
455 | /* 51180 2081 */ {0xa908, 0x8802}, | 398 | {0x0034, 0x8801}, /* SSI reg addr */ |
456 | /* 51205 2082 */ {0x0034, 0x8801}, | 399 | {0x00ca, 0x8800}, |
457 | /* SSI reg addr */ | ||
458 | /* 51230 2083 */ {0x00ca, 0x8800}, | ||
459 | /* SSI data to write */ | 400 | /* SSI data to write */ |
460 | /* 51253 2084 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 401 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
461 | /* 51277 2085 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 402 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
462 | /* 51301 2086 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 403 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
463 | /* 51327 2087 */ {0x1f08, 0x8802}, | 404 | {0x1f08, 0x8802}, |
464 | /* 51352 2088 */ {0x0006, 0x8801}, | 405 | {0x0006, 0x8801}, |
465 | /* 51377 2089 */ {0x0080, 0x8800}, | 406 | {0x0080, 0x8800}, |
466 | /* 51400 2090 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 407 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
467 | 408 | ||
468 | /* ----- Read back coefs we wrote earlier. */ | 409 | /* ----- Read back coefs we wrote earlier. */ |
469 | /* 51424 2091 */ /* READ { 0, 0x0000, 0x8608 } -> 0000: 15 */ | 410 | /* READ { 0x0000, 0x8608 } -> 0000: 15 */ |
470 | /* 51448 2092 */ /* READ { 0, 0x0000, 0x8609 } -> 0000: 30 */ | 411 | /* READ { 0x0000, 0x8609 } -> 0000: 30 */ |
471 | /* 51472 2093 */ /* READ { 0, 0x0000, 0x860a } -> 0000: fb */ | 412 | /* READ { 0x0000, 0x860a } -> 0000: fb */ |
472 | /* 51496 2094 */ /* READ { 0, 0x0000, 0x860b } -> 0000: 3e */ | 413 | /* READ { 0x0000, 0x860b } -> 0000: 3e */ |
473 | /* 51520 2095 */ /* READ { 0, 0x0000, 0x860c } -> 0000: ce */ | 414 | /* READ { 0x0000, 0x860c } -> 0000: ce */ |
474 | /* 51544 2096 */ /* READ { 0, 0x0000, 0x860d } -> 0000: f4 */ | 415 | /* READ { 0x0000, 0x860d } -> 0000: f4 */ |
475 | /* 51568 2097 */ /* READ { 0, 0x0000, 0x860e } -> 0000: eb */ | 416 | /* READ { 0x0000, 0x860e } -> 0000: eb */ |
476 | /* 51592 2098 */ /* READ { 0, 0x0000, 0x860f } -> 0000: dc */ | 417 | /* READ { 0x0000, 0x860f } -> 0000: dc */ |
477 | /* 51616 2099 */ /* READ { 0, 0x0000, 0x8610 } -> 0000: 39 */ | 418 | /* READ { 0x0000, 0x8610 } -> 0000: 39 */ |
478 | /* 51640 2100 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 419 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
479 | /* 51664 2101 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | 420 | /* READ { 0x0001, 0x8802 } -> 0000: 08 */ |
480 | /* 51690 2102 */ {0xb008, 0x8802}, | 421 | {0xb008, 0x8802}, |
481 | /* 51715 2103 */ {0x0006, 0x8801}, | 422 | {0x0006, 0x8801}, |
482 | /* 51740 2104 */ {0x007d, 0x8800}, | 423 | {0x007d, 0x8800}, |
483 | /* 51763 2105 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 424 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
484 | 425 | ||
485 | 426 | ||
486 | /* This chunk is seemingly redundant with */ | 427 | /* This chunk is seemingly redundant with */ |
487 | /* earlier commands (A11 Coef...), but if I disable it, */ | 428 | /* earlier commands (A11 Coef...), but if I disable it, */ |
488 | /* the image appears too dark. Maybe there was some kind of */ | 429 | /* the image appears too dark. Maybe there was some kind of */ |
489 | /* reset since the earlier commands, so this is necessary again. */ | 430 | /* reset since the earlier commands, so this is necessary again. */ |
490 | /* 51789 2106 */ {0x0015, 0x8608}, | 431 | {0x0015, 0x8608}, |
491 | /* 51814 2107 */ {0x0030, 0x8609}, | 432 | {0x0030, 0x8609}, |
492 | /* 51839 2108 */ {0xfffb, 0x860a}, | 433 | {0xfffb, 0x860a}, |
493 | /* 51864 2109 */ {0x003e, 0x860b}, | 434 | {0x003e, 0x860b}, |
494 | /* 51889 2110 */ {0xffce, 0x860c}, | 435 | {0xffce, 0x860c}, |
495 | /* 51914 2111 */ {0xfff4, 0x860d}, | 436 | {0xfff4, 0x860d}, |
496 | /* 51939 2112 */ {0xffeb, 0x860e}, | 437 | {0xffeb, 0x860e}, |
497 | /* 51964 2113 */ {0xffdc, 0x860f}, | 438 | {0xffdc, 0x860f}, |
498 | /* 51989 2114 */ {0x0039, 0x8610}, | 439 | {0x0039, 0x8610}, |
499 | /* 52014 2115 */ {0x0018, 0x8657}, | 440 | {0x0018, 0x8657}, |
500 | 441 | ||
501 | /* 52039 2116 */ {0x0000, 0x8508}, | 442 | {0x0000, 0x8508}, /* Disable compression. */ |
502 | /* Disable compression. */ | ||
503 | /* Previous line was: | 443 | /* Previous line was: |
504 | * 52039 2116 * { 0, 0x0021, 0x8508 }, * Enable compression. */ | 444 | {0x0021, 0x8508}, * Enable compression. */ |
505 | /* 52064 2117 */ {0x0032, 0x850b}, | 445 | {0x0032, 0x850b}, /* compression stuff */ |
506 | /* compression stuff */ | 446 | {0x0003, 0x8509}, /* compression stuff */ |
507 | /* 52089 2118 */ {0x0003, 0x8509}, | 447 | {0x0011, 0x850a}, /* compression stuff */ |
508 | /* compression stuff */ | 448 | {0x0021, 0x850d}, /* compression stuff */ |
509 | /* 52114 2119 */ {0x0011, 0x850a}, | 449 | {0x0010, 0x850c}, /* compression stuff */ |
510 | /* compression stuff */ | 450 | {0x0003, 0x8500}, /* *** Video mode: 160x120 */ |
511 | /* 52139 2120 */ {0x0021, 0x850d}, | 451 | {0x0001, 0x8501}, /* Hardware-dominated snap control */ |
512 | /* compression stuff */ | 452 | {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128, |
513 | /* 52164 2121 */ {0x0010, 0x850c}, | 453 | * gamma look-up disable, |
514 | /* compression stuff */ | 454 | * new edge enhancement enable */ |
515 | /* 52189 2122 */ {0x0003, 0x8500}, | 455 | {0x0018, 0x8617}, /* Window1 start X (*2) */ |
516 | /* *** Video mode: 160x120 */ | 456 | {0x0008, 0x8618}, /* Window1 start Y (*2) */ |
517 | /* 52214 2123 */ {0x0001, 0x8501}, | 457 | {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128, |
518 | /* Hardware-dominated snap control */ | 458 | * gamma look-up disable, |
519 | /* 52239 2124 */ {0x0061, 0x8656}, | 459 | * new edge enhancement enable */ |
520 | /* Window1 size 128x128, Windows2 size 128x128, | 460 | {0x0058, 0x8619}, /* Window2 start X (*2) */ |
521 | * gamma look-up disable, new edge enhancement enable */ | 461 | {0x0008, 0x861a}, /* Window2 start Y (*2) */ |
522 | /* 52264 2125 */ {0x0018, 0x8617}, | 462 | {0x00ff, 0x8615}, /* High lum thresh for white balance */ |
523 | /* Window1 start X (*2) */ | 463 | {0x0000, 0x8616}, /* Low lum thresh for white balance */ |
524 | /* 52289 2126 */ {0x0008, 0x8618}, | 464 | {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ |
525 | /* Window1 start Y (*2) */ | 465 | {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ |
526 | /* 52314 2127 */ {0x0061, 0x8656}, | 466 | /* READ { 0x0000, 0x8656 } -> 0000: 61 */ |
527 | /* Window1 size 128x128, Windows2 size 128x128, | 467 | {0x0028, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ |
528 | * gamma look-up disable, new edge enhancement enable */ | 468 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
529 | /* 52339 2128 */ {0x0058, 0x8619}, | 469 | /* READ { 0x0001, 0x8802 } -> 0000: 28 */ |
530 | /* Window2 start X (*2) */ | 470 | {0x1f28, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ |
531 | /* 52364 2129 */ {0x0008, 0x861a}, | 471 | {0x0010, 0x8801}, /* SSI reg addr */ |
532 | /* Window2 start Y (*2) */ | 472 | {0x003e, 0x8800}, /* SSI data to write */ |
533 | /* 52389 2130 */ {0x00ff, 0x8615}, | 473 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
534 | /* High lum thresh for white balance */ | 474 | {0x0028, 0x8802}, |
535 | /* 52414 2131 */ {0x0000, 0x8616}, | 475 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
536 | /* Low lum thresh for white balance */ | 476 | /* READ { 0x0001, 0x8802 } -> 0000: 28 */ |
537 | /* 52439 2132 */ {0x0012, 0x8700}, | 477 | {0x1f28, 0x8802}, |
538 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | 478 | {0x0000, 0x8801}, |
539 | /* 52464 2133 */ {0x0012, 0x8700}, | 479 | {0x001f, 0x8800}, |
540 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | 480 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
541 | /* 52487 2134 */ /* READ { 0, 0x0000, 0x8656 } -> 0000: 61 */ | 481 | {0x0001, 0x8602}, /* optical black level for user settning = 1 */ |
542 | /* 52513 2135 */ {0x0028, 0x8802}, | ||
543 | /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ | ||
544 | /* 52536 2136 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
545 | /* 52560 2137 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
546 | /* 52586 2138 */ {0x1f28, 0x8802}, | ||
547 | /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ | ||
548 | /* 52611 2139 */ {0x0010, 0x8801}, | ||
549 | /* SSI reg addr */ | ||
550 | /* 52636 2140 */ {0x003e, 0x8800}, | ||
551 | /* SSI data to write */ | ||
552 | /* 52659 2141 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
553 | /* 52685 2142 */ {0x0028, 0x8802}, | ||
554 | /* 52708 2143 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
555 | /* 52732 2144 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
556 | /* 52758 2145 */ {0x1f28, 0x8802}, | ||
557 | /* 52783 2146 */ {0x0000, 0x8801}, | ||
558 | /* 52808 2147 */ {0x001f, 0x8800}, | ||
559 | /* 52831 2148 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
560 | /* 52857 2149 */ {0x0001, 0x8602}, | ||
561 | /* optical black level for user settning = 1 */ | ||
562 | 482 | ||
563 | /* Original: */ | 483 | /* Original: */ |
564 | /* 52882 2150 */ {0x0023, 0x8700}, | 484 | {0x0023, 0x8700}, /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ |
565 | /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ | 485 | {0x000f, 0x8602}, /* optical black level for user settning = 15 */ |
566 | /* 52907 2151 */ {0x000f, 0x8602}, | 486 | |
567 | /* optical black level for user settning = 15 */ | 487 | {0x0028, 0x8802}, |
568 | 488 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ | |
569 | /* 52932 2152 */ {0x0028, 0x8802}, | 489 | /* READ { 0x0001, 0x8802 } -> 0000: 28 */ |
570 | /* 52955 2153 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 490 | {0x1f28, 0x8802}, |
571 | /* 52979 2154 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | 491 | {0x0010, 0x8801}, |
572 | /* 53005 2155 */ {0x1f28, 0x8802}, | 492 | {0x007b, 0x8800}, |
573 | /* 53030 2156 */ {0x0010, 0x8801}, | 493 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
574 | /* 53055 2157 */ {0x007b, 0x8800}, | 494 | {0x002f, 0x8651}, /* R gain for white balance ... */ |
575 | /* 53078 2158 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | 495 | {0x0080, 0x8653}, |
576 | /* 53104 2159 */ {0x002f, 0x8651}, | 496 | /* READ { 0x0000, 0x8655 } -> 0000: 00 */ |
577 | /* R gain for white balance ... */ | 497 | {0x0000, 0x8655}, |
578 | /* 53129 2160 */ {0x0080, 0x8653}, | 498 | |
579 | /* 53152 2161 */ /* READ { 0, 0x0000, 0x8655 } -> 0000: 00 */ | 499 | {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */ |
580 | /* 53178 2162 */ {0x0000, 0x8655}, | 500 | {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */ |
581 | 501 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ | |
582 | /* 53203 2163 */ {0x0030, 0x8112}, | ||
583 | /* Video drop enable, ISO streaming enable */ | ||
584 | /* 53228 2164 */ {0x0020, 0x8112}, | ||
585 | /* Video drop enable, ISO streaming disable */ | ||
586 | /* 53252 2165 */ | ||
587 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ | ||
588 | {} | 502 | {} |
589 | }; | 503 | }; |
590 | 504 | ||
@@ -592,27 +506,27 @@ static const u16 spca508_init_data[][2] = | |||
592 | * Initialization data for Intel EasyPC Camera CS110 | 506 | * Initialization data for Intel EasyPC Camera CS110 |
593 | */ | 507 | */ |
594 | static const u16 spca508cs110_init_data[][2] = { | 508 | static const u16 spca508cs110_init_data[][2] = { |
595 | {0x0000, 0x870b}, /* Reset CTL3 */ | 509 | {0x0000, 0x870b}, /* Reset CTL3 */ |
596 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ | 510 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ |
597 | {0x0000, 0x8111}, /* Normal operation on reset */ | 511 | {0x0000, 0x8111}, /* Normal operation on reset */ |
598 | {0x0090, 0x8110}, | 512 | {0x0090, 0x8110}, |
599 | /* External Clock 2x & Synchronous Serial Interface Output */ | 513 | /* External Clock 2x & Synchronous Serial Interface Output */ |
600 | {0x0020, 0x8112}, /* Video Drop packet enable */ | 514 | {0x0020, 0x8112}, /* Video Drop packet enable */ |
601 | {0x0000, 0x8114}, /* Software GPIO output data */ | 515 | {0x0000, 0x8114}, /* Software GPIO output data */ |
602 | {0x0001, 0x8114}, | 516 | {0x0001, 0x8114}, |
603 | {0x0001, 0x8114}, | 517 | {0x0001, 0x8114}, |
604 | {0x0001, 0x8114}, | 518 | {0x0001, 0x8114}, |
605 | {0x0003, 0x8114}, | 519 | {0x0003, 0x8114}, |
606 | 520 | ||
607 | /* Initial sequence Synchronous Serial Interface */ | 521 | /* Initial sequence Synchronous Serial Interface */ |
608 | {0x000f, 0x8402}, /* Memory bank Address */ | 522 | {0x000f, 0x8402}, /* Memory bank Address */ |
609 | {0x0000, 0x8403}, /* Memory bank Address */ | 523 | {0x0000, 0x8403}, /* Memory bank Address */ |
610 | {0x00ba, 0x8804}, /* SSI Slave address */ | 524 | {0x00ba, 0x8804}, /* SSI Slave address */ |
611 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ | 525 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ |
612 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ | 526 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ |
613 | 527 | ||
614 | {0x0001, 0x8801}, | 528 | {0x0001, 0x8801}, |
615 | {0x000a, 0x8805},/* a - NWG: Dunno what this is about */ | 529 | {0x000a, 0x8805}, /* a - NWG: Dunno what this is about */ |
616 | {0x0000, 0x8800}, | 530 | {0x0000, 0x8800}, |
617 | {0x0010, 0x8802}, | 531 | {0x0010, 0x8802}, |
618 | 532 | ||
@@ -646,459 +560,459 @@ static const u16 spca508cs110_init_data[][2] = { | |||
646 | {0x0000, 0x8800}, | 560 | {0x0000, 0x8800}, |
647 | {0x0010, 0x8802}, | 561 | {0x0010, 0x8802}, |
648 | 562 | ||
649 | {0x0002, 0x8704}, /* External input CKIx1 */ | 563 | {0x0002, 0x8704}, /* External input CKIx1 */ |
650 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ | 564 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ |
651 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ | 565 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ |
652 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ | 566 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ |
653 | {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ | 567 | {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ |
654 | {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ | 568 | {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ |
655 | 569 | ||
656 | {0x0006, 0x8660}, /* Nibble data + input order */ | 570 | {0x0006, 0x8660}, /* Nibble data + input order */ |
657 | 571 | ||
658 | {0x000a, 0x8602}, /* Optical black level set to 0x0a */ | 572 | {0x000a, 0x8602}, /* Optical black level set to 0x0a */ |
659 | /* 1945 */ {0x0000, 0x8603}, /* Optical black level Offset */ | 573 | {0x0000, 0x8603}, /* Optical black level Offset */ |
660 | 574 | ||
661 | /* 1962 * {0, 0x0000, 0x8611}, * 0 R Offset for white Balance */ | 575 | /* {0x0000, 0x8611}, * 0 R Offset for white Balance */ |
662 | /* 1963 * {0, 0x0000, 0x8612}, * 1 Gr Offset for white Balance */ | 576 | /* {0x0000, 0x8612}, * 1 Gr Offset for white Balance */ |
663 | /* 1964 * {0, 0x0000, 0x8613}, * 1f B Offset for white Balance */ | 577 | /* {0x0000, 0x8613}, * 1f B Offset for white Balance */ |
664 | /* 1965 * {0, 0x0000, 0x8614}, * f0 Gb Offset for white Balance */ | 578 | /* {0x0000, 0x8614}, * f0 Gb Offset for white Balance */ |
665 | 579 | ||
666 | {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ | 580 | {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ |
667 | {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ | 581 | {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ |
668 | {0x0035, 0x8653}, /* 26 RED gain for white balance */ | 582 | {0x0035, 0x8653}, /* 26 RED gain for white balance */ |
669 | {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ | 583 | {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ |
670 | {0x0041, 0x863f}, | 584 | {0x0041, 0x863f}, |
671 | /* Fixed Gamma correction enabled (makes colours look better) */ | 585 | /* Fixed Gamma correction enabled (makes colours look better) */ |
672 | 586 | ||
673 | /* 2422 */ {0x0000, 0x8655}, | 587 | {0x0000, 0x8655}, |
674 | /* High bits for white balance*****brightness control*** */ | 588 | /* High bits for white balance*****brightness control*** */ |
675 | {} | 589 | {} |
676 | }; | 590 | }; |
677 | 591 | ||
678 | static const u16 spca508_sightcam_init_data[][2] = { | 592 | static const u16 spca508_sightcam_init_data[][2] = { |
679 | /* This line seems to setup the frame/canvas */ | 593 | /* This line seems to setup the frame/canvas */ |
680 | /*368 */ {0x000f, 0x8402}, | 594 | {0x000f, 0x8402}, |
681 | 595 | ||
682 | /* Theese 6 lines are needed to startup the webcam */ | 596 | /* Theese 6 lines are needed to startup the webcam */ |
683 | /*398 */ {0x0090, 0x8110}, | 597 | {0x0090, 0x8110}, |
684 | /*399 */ {0x0001, 0x8114}, | 598 | {0x0001, 0x8114}, |
685 | /*400 */ {0x0001, 0x8114}, | 599 | {0x0001, 0x8114}, |
686 | /*401 */ {0x0001, 0x8114}, | 600 | {0x0001, 0x8114}, |
687 | /*402 */ {0x0003, 0x8114}, | 601 | {0x0003, 0x8114}, |
688 | /*403 */ {0x0080, 0x8804}, | 602 | {0x0080, 0x8804}, |
689 | 603 | ||
690 | /* This part seems to make the pictures darker? (autobrightness?) */ | 604 | /* This part seems to make the pictures darker? (autobrightness?) */ |
691 | /*436 */ {0x0001, 0x8801}, | 605 | {0x0001, 0x8801}, |
692 | /*437 */ {0x0004, 0x8800}, | 606 | {0x0004, 0x8800}, |
693 | /*439 */ {0x0003, 0x8801}, | 607 | {0x0003, 0x8801}, |
694 | /*440 */ {0x00e0, 0x8800}, | 608 | {0x00e0, 0x8800}, |
695 | /*442 */ {0x0004, 0x8801}, | 609 | {0x0004, 0x8801}, |
696 | /*443 */ {0x00b4, 0x8800}, | 610 | {0x00b4, 0x8800}, |
697 | /*445 */ {0x0005, 0x8801}, | 611 | {0x0005, 0x8801}, |
698 | /*446 */ {0x0000, 0x8800}, | 612 | {0x0000, 0x8800}, |
699 | 613 | ||
700 | /*448 */ {0x0006, 0x8801}, | 614 | {0x0006, 0x8801}, |
701 | /*449 */ {0x00e0, 0x8800}, | 615 | {0x00e0, 0x8800}, |
702 | /*451 */ {0x0007, 0x8801}, | 616 | {0x0007, 0x8801}, |
703 | /*452 */ {0x000c, 0x8800}, | 617 | {0x000c, 0x8800}, |
704 | 618 | ||
705 | /* This section is just needed, it probably | 619 | /* This section is just needed, it probably |
706 | * does something like the previous section, | 620 | * does something like the previous section, |
707 | * but the cam won't start if it's not included. | 621 | * but the cam won't start if it's not included. |
708 | */ | 622 | */ |
709 | /*484 */ {0x0014, 0x8801}, | 623 | {0x0014, 0x8801}, |
710 | /*485 */ {0x0008, 0x8800}, | 624 | {0x0008, 0x8800}, |
711 | /*487 */ {0x0015, 0x8801}, | 625 | {0x0015, 0x8801}, |
712 | /*488 */ {0x0067, 0x8800}, | 626 | {0x0067, 0x8800}, |
713 | /*490 */ {0x0016, 0x8801}, | 627 | {0x0016, 0x8801}, |
714 | /*491 */ {0x0000, 0x8800}, | 628 | {0x0000, 0x8800}, |
715 | /*493 */ {0x0017, 0x8801}, | 629 | {0x0017, 0x8801}, |
716 | /*494 */ {0x0020, 0x8800}, | 630 | {0x0020, 0x8800}, |
717 | /*496 */ {0x0018, 0x8801}, | 631 | {0x0018, 0x8801}, |
718 | /*497 */ {0x0044, 0x8800}, | 632 | {0x0044, 0x8800}, |
719 | 633 | ||
720 | /* Makes the picture darker - and the | 634 | /* Makes the picture darker - and the |
721 | * cam won't start if not included | 635 | * cam won't start if not included |
722 | */ | 636 | */ |
723 | /*505 */ {0x001e, 0x8801}, | 637 | {0x001e, 0x8801}, |
724 | /*506 */ {0x00ea, 0x8800}, | 638 | {0x00ea, 0x8800}, |
725 | /*508 */ {0x001f, 0x8801}, | 639 | {0x001f, 0x8801}, |
726 | /*509 */ {0x0001, 0x8800}, | 640 | {0x0001, 0x8800}, |
727 | /*511 */ {0x0003, 0x8801}, | 641 | {0x0003, 0x8801}, |
728 | /*512 */ {0x00e0, 0x8800}, | 642 | {0x00e0, 0x8800}, |
729 | 643 | ||
730 | /* seems to place the colors ontop of each other #1 */ | 644 | /* seems to place the colors ontop of each other #1 */ |
731 | /*517 */ {0x0006, 0x8704}, | 645 | {0x0006, 0x8704}, |
732 | /*518 */ {0x0001, 0x870c}, | 646 | {0x0001, 0x870c}, |
733 | /*519 */ {0x0016, 0x8600}, | 647 | {0x0016, 0x8600}, |
734 | /*520 */ {0x0002, 0x8606}, | 648 | {0x0002, 0x8606}, |
735 | 649 | ||
736 | /* if not included the pictures becomes _very_ dark */ | 650 | /* if not included the pictures becomes _very_ dark */ |
737 | /*521 */ {0x0064, 0x8607}, | 651 | {0x0064, 0x8607}, |
738 | /*522 */ {0x003a, 0x8601}, | 652 | {0x003a, 0x8601}, |
739 | /*523 */ {0x0000, 0x8602}, | 653 | {0x0000, 0x8602}, |
740 | 654 | ||
741 | /* seems to place the colors ontop of each other #2 */ | 655 | /* seems to place the colors ontop of each other #2 */ |
742 | /*524 */ {0x0016, 0x8600}, | 656 | {0x0016, 0x8600}, |
743 | /*525 */ {0x0018, 0x8617}, | 657 | {0x0018, 0x8617}, |
744 | /*526 */ {0x0008, 0x8618}, | 658 | {0x0008, 0x8618}, |
745 | /*527 */ {0x00a1, 0x8656}, | 659 | {0x00a1, 0x8656}, |
746 | 660 | ||
747 | /* webcam won't start if not included */ | 661 | /* webcam won't start if not included */ |
748 | /*528 */ {0x0007, 0x865b}, | 662 | {0x0007, 0x865b}, |
749 | /*529 */ {0x0001, 0x865c}, | 663 | {0x0001, 0x865c}, |
750 | /*530 */ {0x0058, 0x865d}, | 664 | {0x0058, 0x865d}, |
751 | /*531 */ {0x0048, 0x865e}, | 665 | {0x0048, 0x865e}, |
752 | 666 | ||
753 | /* adjusts the colors */ | 667 | /* adjusts the colors */ |
754 | /*541 */ {0x0049, 0x8651}, | 668 | {0x0049, 0x8651}, |
755 | /*542 */ {0x0040, 0x8652}, | 669 | {0x0040, 0x8652}, |
756 | /*543 */ {0x004c, 0x8653}, | 670 | {0x004c, 0x8653}, |
757 | /*544 */ {0x0040, 0x8654}, | 671 | {0x0040, 0x8654}, |
758 | {} | 672 | {} |
759 | }; | 673 | }; |
760 | 674 | ||
761 | static const u16 spca508_sightcam2_init_data[][2] = { | 675 | static const u16 spca508_sightcam2_init_data[][2] = { |
762 | /* 35 */ {0x0020, 0x8112}, | 676 | {0x0020, 0x8112}, |
763 | 677 | ||
764 | /* 36 */ {0x000f, 0x8402}, | 678 | {0x000f, 0x8402}, |
765 | /* 37 */ {0x0000, 0x8403}, | 679 | {0x0000, 0x8403}, |
766 | 680 | ||
767 | /* 38 */ {0x0008, 0x8201}, | 681 | {0x0008, 0x8201}, |
768 | /* 39 */ {0x0008, 0x8200}, | 682 | {0x0008, 0x8200}, |
769 | /* 40 */ {0x0001, 0x8200}, | 683 | {0x0001, 0x8200}, |
770 | /* 43 */ {0x0009, 0x8201}, | 684 | {0x0009, 0x8201}, |
771 | /* 44 */ {0x0008, 0x8200}, | 685 | {0x0008, 0x8200}, |
772 | /* 45 */ {0x0001, 0x8200}, | 686 | {0x0001, 0x8200}, |
773 | /* 48 */ {0x000a, 0x8201}, | 687 | {0x000a, 0x8201}, |
774 | /* 49 */ {0x0008, 0x8200}, | 688 | {0x0008, 0x8200}, |
775 | /* 50 */ {0x0001, 0x8200}, | 689 | {0x0001, 0x8200}, |
776 | /* 53 */ {0x000b, 0x8201}, | 690 | {0x000b, 0x8201}, |
777 | /* 54 */ {0x0008, 0x8200}, | 691 | {0x0008, 0x8200}, |
778 | /* 55 */ {0x0001, 0x8200}, | 692 | {0x0001, 0x8200}, |
779 | /* 58 */ {0x000c, 0x8201}, | 693 | {0x000c, 0x8201}, |
780 | /* 59 */ {0x0008, 0x8200}, | 694 | {0x0008, 0x8200}, |
781 | /* 60 */ {0x0001, 0x8200}, | 695 | {0x0001, 0x8200}, |
782 | /* 63 */ {0x000d, 0x8201}, | 696 | {0x000d, 0x8201}, |
783 | /* 64 */ {0x0008, 0x8200}, | 697 | {0x0008, 0x8200}, |
784 | /* 65 */ {0x0001, 0x8200}, | 698 | {0x0001, 0x8200}, |
785 | /* 68 */ {0x000e, 0x8201}, | 699 | {0x000e, 0x8201}, |
786 | /* 69 */ {0x0008, 0x8200}, | 700 | {0x0008, 0x8200}, |
787 | /* 70 */ {0x0001, 0x8200}, | 701 | {0x0001, 0x8200}, |
788 | /* 73 */ {0x0007, 0x8201}, | 702 | {0x0007, 0x8201}, |
789 | /* 74 */ {0x0008, 0x8200}, | 703 | {0x0008, 0x8200}, |
790 | /* 75 */ {0x0001, 0x8200}, | 704 | {0x0001, 0x8200}, |
791 | /* 78 */ {0x000f, 0x8201}, | 705 | {0x000f, 0x8201}, |
792 | /* 79 */ {0x0008, 0x8200}, | 706 | {0x0008, 0x8200}, |
793 | /* 80 */ {0x0001, 0x8200}, | 707 | {0x0001, 0x8200}, |
794 | 708 | ||
795 | /* 84 */ {0x0018, 0x8660}, | 709 | {0x0018, 0x8660}, |
796 | /* 85 */ {0x0010, 0x8201}, | 710 | {0x0010, 0x8201}, |
797 | 711 | ||
798 | /* 86 */ {0x0008, 0x8200}, | 712 | {0x0008, 0x8200}, |
799 | /* 87 */ {0x0001, 0x8200}, | 713 | {0x0001, 0x8200}, |
800 | /* 90 */ {0x0011, 0x8201}, | 714 | {0x0011, 0x8201}, |
801 | /* 91 */ {0x0008, 0x8200}, | 715 | {0x0008, 0x8200}, |
802 | /* 92 */ {0x0001, 0x8200}, | 716 | {0x0001, 0x8200}, |
803 | 717 | ||
804 | /* 95 */ {0x0000, 0x86b0}, | 718 | {0x0000, 0x86b0}, |
805 | /* 96 */ {0x0034, 0x86b1}, | 719 | {0x0034, 0x86b1}, |
806 | /* 97 */ {0x0000, 0x86b2}, | 720 | {0x0000, 0x86b2}, |
807 | /* 98 */ {0x0049, 0x86b3}, | 721 | {0x0049, 0x86b3}, |
808 | /* 99 */ {0x0000, 0x86b4}, | 722 | {0x0000, 0x86b4}, |
809 | /* 100 */ {0x0000, 0x86b4}, | 723 | {0x0000, 0x86b4}, |
810 | 724 | ||
811 | /* 101 */ {0x0012, 0x8201}, | 725 | {0x0012, 0x8201}, |
812 | /* 102 */ {0x0008, 0x8200}, | 726 | {0x0008, 0x8200}, |
813 | /* 103 */ {0x0001, 0x8200}, | 727 | {0x0001, 0x8200}, |
814 | /* 106 */ {0x0013, 0x8201}, | 728 | {0x0013, 0x8201}, |
815 | /* 107 */ {0x0008, 0x8200}, | 729 | {0x0008, 0x8200}, |
816 | /* 108 */ {0x0001, 0x8200}, | 730 | {0x0001, 0x8200}, |
817 | 731 | ||
818 | /* 111 */ {0x0001, 0x86b0}, | 732 | {0x0001, 0x86b0}, |
819 | /* 112 */ {0x00aa, 0x86b1}, | 733 | {0x00aa, 0x86b1}, |
820 | /* 113 */ {0x0000, 0x86b2}, | 734 | {0x0000, 0x86b2}, |
821 | /* 114 */ {0x00e4, 0x86b3}, | 735 | {0x00e4, 0x86b3}, |
822 | /* 115 */ {0x0000, 0x86b4}, | 736 | {0x0000, 0x86b4}, |
823 | /* 116 */ {0x0000, 0x86b4}, | 737 | {0x0000, 0x86b4}, |
824 | 738 | ||
825 | /* 118 */ {0x0018, 0x8660}, | 739 | {0x0018, 0x8660}, |
826 | 740 | ||
827 | /* 119 */ {0x0090, 0x8110}, | 741 | {0x0090, 0x8110}, |
828 | /* 120 */ {0x0001, 0x8114}, | 742 | {0x0001, 0x8114}, |
829 | /* 121 */ {0x0001, 0x8114}, | 743 | {0x0001, 0x8114}, |
830 | /* 122 */ {0x0001, 0x8114}, | 744 | {0x0001, 0x8114}, |
831 | /* 123 */ {0x0003, 0x8114}, | 745 | {0x0003, 0x8114}, |
832 | 746 | ||
833 | /* 124 */ {0x0080, 0x8804}, | 747 | {0x0080, 0x8804}, |
834 | /* 157 */ {0x0003, 0x8801}, | 748 | {0x0003, 0x8801}, |
835 | /* 158 */ {0x0012, 0x8800}, | 749 | {0x0012, 0x8800}, |
836 | /* 160 */ {0x0004, 0x8801}, | 750 | {0x0004, 0x8801}, |
837 | /* 161 */ {0x0005, 0x8800}, | 751 | {0x0005, 0x8800}, |
838 | /* 163 */ {0x0005, 0x8801}, | 752 | {0x0005, 0x8801}, |
839 | /* 164 */ {0x0000, 0x8800}, | 753 | {0x0000, 0x8800}, |
840 | /* 166 */ {0x0006, 0x8801}, | 754 | {0x0006, 0x8801}, |
841 | /* 167 */ {0x0000, 0x8800}, | 755 | {0x0000, 0x8800}, |
842 | /* 169 */ {0x0007, 0x8801}, | 756 | {0x0007, 0x8801}, |
843 | /* 170 */ {0x0000, 0x8800}, | 757 | {0x0000, 0x8800}, |
844 | /* 172 */ {0x0008, 0x8801}, | 758 | {0x0008, 0x8801}, |
845 | /* 173 */ {0x0005, 0x8800}, | 759 | {0x0005, 0x8800}, |
846 | /* 175 */ {0x000a, 0x8700}, | 760 | {0x000a, 0x8700}, |
847 | /* 176 */ {0x000e, 0x8801}, | 761 | {0x000e, 0x8801}, |
848 | /* 177 */ {0x0004, 0x8800}, | 762 | {0x0004, 0x8800}, |
849 | /* 179 */ {0x0005, 0x8801}, | 763 | {0x0005, 0x8801}, |
850 | /* 180 */ {0x0047, 0x8800}, | 764 | {0x0047, 0x8800}, |
851 | /* 182 */ {0x0006, 0x8801}, | 765 | {0x0006, 0x8801}, |
852 | /* 183 */ {0x0000, 0x8800}, | 766 | {0x0000, 0x8800}, |
853 | /* 185 */ {0x0007, 0x8801}, | 767 | {0x0007, 0x8801}, |
854 | /* 186 */ {0x00c0, 0x8800}, | 768 | {0x00c0, 0x8800}, |
855 | /* 188 */ {0x0008, 0x8801}, | 769 | {0x0008, 0x8801}, |
856 | /* 189 */ {0x0003, 0x8800}, | 770 | {0x0003, 0x8800}, |
857 | /* 191 */ {0x0013, 0x8801}, | 771 | {0x0013, 0x8801}, |
858 | /* 192 */ {0x0001, 0x8800}, | 772 | {0x0001, 0x8800}, |
859 | /* 194 */ {0x0009, 0x8801}, | 773 | {0x0009, 0x8801}, |
860 | /* 195 */ {0x0000, 0x8800}, | 774 | {0x0000, 0x8800}, |
861 | /* 197 */ {0x000a, 0x8801}, | 775 | {0x000a, 0x8801}, |
862 | /* 198 */ {0x0000, 0x8800}, | 776 | {0x0000, 0x8800}, |
863 | /* 200 */ {0x000b, 0x8801}, | 777 | {0x000b, 0x8801}, |
864 | /* 201 */ {0x0000, 0x8800}, | 778 | {0x0000, 0x8800}, |
865 | /* 203 */ {0x000c, 0x8801}, | 779 | {0x000c, 0x8801}, |
866 | /* 204 */ {0x0000, 0x8800}, | 780 | {0x0000, 0x8800}, |
867 | /* 206 */ {0x000e, 0x8801}, | 781 | {0x000e, 0x8801}, |
868 | /* 207 */ {0x0004, 0x8800}, | 782 | {0x0004, 0x8800}, |
869 | /* 209 */ {0x000f, 0x8801}, | 783 | {0x000f, 0x8801}, |
870 | /* 210 */ {0x0000, 0x8800}, | 784 | {0x0000, 0x8800}, |
871 | /* 212 */ {0x0010, 0x8801}, | 785 | {0x0010, 0x8801}, |
872 | /* 213 */ {0x0006, 0x8800}, | 786 | {0x0006, 0x8800}, |
873 | /* 215 */ {0x0011, 0x8801}, | 787 | {0x0011, 0x8801}, |
874 | /* 216 */ {0x0006, 0x8800}, | 788 | {0x0006, 0x8800}, |
875 | /* 218 */ {0x0012, 0x8801}, | 789 | {0x0012, 0x8801}, |
876 | /* 219 */ {0x0000, 0x8800}, | 790 | {0x0000, 0x8800}, |
877 | /* 221 */ {0x0013, 0x8801}, | 791 | {0x0013, 0x8801}, |
878 | /* 222 */ {0x0001, 0x8800}, | 792 | {0x0001, 0x8800}, |
879 | 793 | ||
880 | /* 224 */ {0x000a, 0x8700}, | 794 | {0x000a, 0x8700}, |
881 | /* 225 */ {0x0000, 0x8702}, | 795 | {0x0000, 0x8702}, |
882 | /* 226 */ {0x0000, 0x8703}, | 796 | {0x0000, 0x8703}, |
883 | /* 227 */ {0x00c2, 0x8704}, | 797 | {0x00c2, 0x8704}, |
884 | /* 228 */ {0x0001, 0x870c}, | 798 | {0x0001, 0x870c}, |
885 | 799 | ||
886 | /* 229 */ {0x0044, 0x8600}, | 800 | {0x0044, 0x8600}, |
887 | /* 230 */ {0x0002, 0x8606}, | 801 | {0x0002, 0x8606}, |
888 | /* 231 */ {0x0064, 0x8607}, | 802 | {0x0064, 0x8607}, |
889 | /* 232 */ {0x003a, 0x8601}, | 803 | {0x003a, 0x8601}, |
890 | /* 233 */ {0x0008, 0x8602}, | 804 | {0x0008, 0x8602}, |
891 | /* 234 */ {0x0044, 0x8600}, | 805 | {0x0044, 0x8600}, |
892 | /* 235 */ {0x0018, 0x8617}, | 806 | {0x0018, 0x8617}, |
893 | /* 236 */ {0x0008, 0x8618}, | 807 | {0x0008, 0x8618}, |
894 | /* 237 */ {0x00a1, 0x8656}, | 808 | {0x00a1, 0x8656}, |
895 | /* 238 */ {0x0004, 0x865b}, | 809 | {0x0004, 0x865b}, |
896 | /* 239 */ {0x0002, 0x865c}, | 810 | {0x0002, 0x865c}, |
897 | /* 240 */ {0x0058, 0x865d}, | 811 | {0x0058, 0x865d}, |
898 | /* 241 */ {0x0048, 0x865e}, | 812 | {0x0048, 0x865e}, |
899 | /* 242 */ {0x0012, 0x8608}, | 813 | {0x0012, 0x8608}, |
900 | /* 243 */ {0x002c, 0x8609}, | 814 | {0x002c, 0x8609}, |
901 | /* 244 */ {0x0002, 0x860a}, | 815 | {0x0002, 0x860a}, |
902 | /* 245 */ {0x002c, 0x860b}, | 816 | {0x002c, 0x860b}, |
903 | /* 246 */ {0x00db, 0x860c}, | 817 | {0x00db, 0x860c}, |
904 | /* 247 */ {0x00f9, 0x860d}, | 818 | {0x00f9, 0x860d}, |
905 | /* 248 */ {0x00f1, 0x860e}, | 819 | {0x00f1, 0x860e}, |
906 | /* 249 */ {0x00e3, 0x860f}, | 820 | {0x00e3, 0x860f}, |
907 | /* 250 */ {0x002c, 0x8610}, | 821 | {0x002c, 0x8610}, |
908 | /* 251 */ {0x006c, 0x8651}, | 822 | {0x006c, 0x8651}, |
909 | /* 252 */ {0x0041, 0x8652}, | 823 | {0x0041, 0x8652}, |
910 | /* 253 */ {0x0059, 0x8653}, | 824 | {0x0059, 0x8653}, |
911 | /* 254 */ {0x0040, 0x8654}, | 825 | {0x0040, 0x8654}, |
912 | /* 255 */ {0x00fa, 0x8611}, | 826 | {0x00fa, 0x8611}, |
913 | /* 256 */ {0x00ff, 0x8612}, | 827 | {0x00ff, 0x8612}, |
914 | /* 257 */ {0x00f8, 0x8613}, | 828 | {0x00f8, 0x8613}, |
915 | /* 258 */ {0x0000, 0x8614}, | 829 | {0x0000, 0x8614}, |
916 | /* 259 */ {0x0001, 0x863f}, | 830 | {0x0001, 0x863f}, |
917 | /* 260 */ {0x0000, 0x8640}, | 831 | {0x0000, 0x8640}, |
918 | /* 261 */ {0x0026, 0x8641}, | 832 | {0x0026, 0x8641}, |
919 | /* 262 */ {0x0045, 0x8642}, | 833 | {0x0045, 0x8642}, |
920 | /* 263 */ {0x0060, 0x8643}, | 834 | {0x0060, 0x8643}, |
921 | /* 264 */ {0x0075, 0x8644}, | 835 | {0x0075, 0x8644}, |
922 | /* 265 */ {0x0088, 0x8645}, | 836 | {0x0088, 0x8645}, |
923 | /* 266 */ {0x009b, 0x8646}, | 837 | {0x009b, 0x8646}, |
924 | /* 267 */ {0x00b0, 0x8647}, | 838 | {0x00b0, 0x8647}, |
925 | /* 268 */ {0x00c5, 0x8648}, | 839 | {0x00c5, 0x8648}, |
926 | /* 269 */ {0x00d2, 0x8649}, | 840 | {0x00d2, 0x8649}, |
927 | /* 270 */ {0x00dc, 0x864a}, | 841 | {0x00dc, 0x864a}, |
928 | /* 271 */ {0x00e5, 0x864b}, | 842 | {0x00e5, 0x864b}, |
929 | /* 272 */ {0x00eb, 0x864c}, | 843 | {0x00eb, 0x864c}, |
930 | /* 273 */ {0x00f0, 0x864d}, | 844 | {0x00f0, 0x864d}, |
931 | /* 274 */ {0x00f6, 0x864e}, | 845 | {0x00f6, 0x864e}, |
932 | /* 275 */ {0x00fa, 0x864f}, | 846 | {0x00fa, 0x864f}, |
933 | /* 276 */ {0x00ff, 0x8650}, | 847 | {0x00ff, 0x8650}, |
934 | /* 277 */ {0x0060, 0x8657}, | 848 | {0x0060, 0x8657}, |
935 | /* 278 */ {0x0010, 0x8658}, | 849 | {0x0010, 0x8658}, |
936 | /* 279 */ {0x0018, 0x8659}, | 850 | {0x0018, 0x8659}, |
937 | /* 280 */ {0x0005, 0x865a}, | 851 | {0x0005, 0x865a}, |
938 | /* 281 */ {0x0018, 0x8660}, | 852 | {0x0018, 0x8660}, |
939 | /* 282 */ {0x0003, 0x8509}, | 853 | {0x0003, 0x8509}, |
940 | /* 283 */ {0x0011, 0x850a}, | 854 | {0x0011, 0x850a}, |
941 | /* 284 */ {0x0032, 0x850b}, | 855 | {0x0032, 0x850b}, |
942 | /* 285 */ {0x0010, 0x850c}, | 856 | {0x0010, 0x850c}, |
943 | /* 286 */ {0x0021, 0x850d}, | 857 | {0x0021, 0x850d}, |
944 | /* 287 */ {0x0001, 0x8500}, | 858 | {0x0001, 0x8500}, |
945 | /* 288 */ {0x0000, 0x8508}, | 859 | {0x0000, 0x8508}, |
946 | /* 289 */ {0x0012, 0x8608}, | 860 | {0x0012, 0x8608}, |
947 | /* 290 */ {0x002c, 0x8609}, | 861 | {0x002c, 0x8609}, |
948 | /* 291 */ {0x0002, 0x860a}, | 862 | {0x0002, 0x860a}, |
949 | /* 292 */ {0x0039, 0x860b}, | 863 | {0x0039, 0x860b}, |
950 | /* 293 */ {0x00d0, 0x860c}, | 864 | {0x00d0, 0x860c}, |
951 | /* 294 */ {0x00f7, 0x860d}, | 865 | {0x00f7, 0x860d}, |
952 | /* 295 */ {0x00ed, 0x860e}, | 866 | {0x00ed, 0x860e}, |
953 | /* 296 */ {0x00db, 0x860f}, | 867 | {0x00db, 0x860f}, |
954 | /* 297 */ {0x0039, 0x8610}, | 868 | {0x0039, 0x8610}, |
955 | /* 298 */ {0x0012, 0x8657}, | 869 | {0x0012, 0x8657}, |
956 | /* 299 */ {0x000c, 0x8619}, | 870 | {0x000c, 0x8619}, |
957 | /* 300 */ {0x0004, 0x861a}, | 871 | {0x0004, 0x861a}, |
958 | /* 301 */ {0x00a1, 0x8656}, | 872 | {0x00a1, 0x8656}, |
959 | /* 302 */ {0x00c8, 0x8615}, | 873 | {0x00c8, 0x8615}, |
960 | /* 303 */ {0x0032, 0x8616}, | 874 | {0x0032, 0x8616}, |
961 | 875 | ||
962 | /* 306 */ {0x0030, 0x8112}, | 876 | {0x0030, 0x8112}, |
963 | /* 313 */ {0x0020, 0x8112}, | 877 | {0x0020, 0x8112}, |
964 | /* 314 */ {0x0020, 0x8112}, | 878 | {0x0020, 0x8112}, |
965 | /* 315 */ {0x000f, 0x8402}, | 879 | {0x000f, 0x8402}, |
966 | /* 316 */ {0x0000, 0x8403}, | 880 | {0x0000, 0x8403}, |
967 | 881 | ||
968 | /* 317 */ {0x0090, 0x8110}, | 882 | {0x0090, 0x8110}, |
969 | /* 318 */ {0x0001, 0x8114}, | 883 | {0x0001, 0x8114}, |
970 | /* 319 */ {0x0001, 0x8114}, | 884 | {0x0001, 0x8114}, |
971 | /* 320 */ {0x0001, 0x8114}, | 885 | {0x0001, 0x8114}, |
972 | /* 321 */ {0x0003, 0x8114}, | 886 | {0x0003, 0x8114}, |
973 | /* 322 */ {0x0080, 0x8804}, | 887 | {0x0080, 0x8804}, |
974 | 888 | ||
975 | /* 355 */ {0x0003, 0x8801}, | 889 | {0x0003, 0x8801}, |
976 | /* 356 */ {0x0012, 0x8800}, | 890 | {0x0012, 0x8800}, |
977 | /* 358 */ {0x0004, 0x8801}, | 891 | {0x0004, 0x8801}, |
978 | /* 359 */ {0x0005, 0x8800}, | 892 | {0x0005, 0x8800}, |
979 | /* 361 */ {0x0005, 0x8801}, | 893 | {0x0005, 0x8801}, |
980 | /* 362 */ {0x0047, 0x8800}, | 894 | {0x0047, 0x8800}, |
981 | /* 364 */ {0x0006, 0x8801}, | 895 | {0x0006, 0x8801}, |
982 | /* 365 */ {0x0000, 0x8800}, | 896 | {0x0000, 0x8800}, |
983 | /* 367 */ {0x0007, 0x8801}, | 897 | {0x0007, 0x8801}, |
984 | /* 368 */ {0x00c0, 0x8800}, | 898 | {0x00c0, 0x8800}, |
985 | /* 370 */ {0x0008, 0x8801}, | 899 | {0x0008, 0x8801}, |
986 | /* 371 */ {0x0003, 0x8800}, | 900 | {0x0003, 0x8800}, |
987 | /* 373 */ {0x000a, 0x8700}, | 901 | {0x000a, 0x8700}, |
988 | /* 374 */ {0x000e, 0x8801}, | 902 | {0x000e, 0x8801}, |
989 | /* 375 */ {0x0004, 0x8800}, | 903 | {0x0004, 0x8800}, |
990 | /* 377 */ {0x0005, 0x8801}, | 904 | {0x0005, 0x8801}, |
991 | /* 378 */ {0x0047, 0x8800}, | 905 | {0x0047, 0x8800}, |
992 | /* 380 */ {0x0006, 0x8801}, | 906 | {0x0006, 0x8801}, |
993 | /* 381 */ {0x0000, 0x8800}, | 907 | {0x0000, 0x8800}, |
994 | /* 383 */ {0x0007, 0x8801}, | 908 | {0x0007, 0x8801}, |
995 | /* 384 */ {0x00c0, 0x8800}, | 909 | {0x00c0, 0x8800}, |
996 | /* 386 */ {0x0008, 0x8801}, | 910 | {0x0008, 0x8801}, |
997 | /* 387 */ {0x0003, 0x8800}, | 911 | {0x0003, 0x8800}, |
998 | /* 389 */ {0x0013, 0x8801}, | 912 | {0x0013, 0x8801}, |
999 | /* 390 */ {0x0001, 0x8800}, | 913 | {0x0001, 0x8800}, |
1000 | /* 392 */ {0x0009, 0x8801}, | 914 | {0x0009, 0x8801}, |
1001 | /* 393 */ {0x0000, 0x8800}, | 915 | {0x0000, 0x8800}, |
1002 | /* 395 */ {0x000a, 0x8801}, | 916 | {0x000a, 0x8801}, |
1003 | /* 396 */ {0x0000, 0x8800}, | 917 | {0x0000, 0x8800}, |
1004 | /* 398 */ {0x000b, 0x8801}, | 918 | {0x000b, 0x8801}, |
1005 | /* 399 */ {0x0000, 0x8800}, | 919 | {0x0000, 0x8800}, |
1006 | /* 401 */ {0x000c, 0x8801}, | 920 | {0x000c, 0x8801}, |
1007 | /* 402 */ {0x0000, 0x8800}, | 921 | {0x0000, 0x8800}, |
1008 | /* 404 */ {0x000e, 0x8801}, | 922 | {0x000e, 0x8801}, |
1009 | /* 405 */ {0x0004, 0x8800}, | 923 | {0x0004, 0x8800}, |
1010 | /* 407 */ {0x000f, 0x8801}, | 924 | {0x000f, 0x8801}, |
1011 | /* 408 */ {0x0000, 0x8800}, | 925 | {0x0000, 0x8800}, |
1012 | /* 410 */ {0x0010, 0x8801}, | 926 | {0x0010, 0x8801}, |
1013 | /* 411 */ {0x0006, 0x8800}, | 927 | {0x0006, 0x8800}, |
1014 | /* 413 */ {0x0011, 0x8801}, | 928 | {0x0011, 0x8801}, |
1015 | /* 414 */ {0x0006, 0x8800}, | 929 | {0x0006, 0x8800}, |
1016 | /* 416 */ {0x0012, 0x8801}, | 930 | {0x0012, 0x8801}, |
1017 | /* 417 */ {0x0000, 0x8800}, | 931 | {0x0000, 0x8800}, |
1018 | /* 419 */ {0x0013, 0x8801}, | 932 | {0x0013, 0x8801}, |
1019 | /* 420 */ {0x0001, 0x8800}, | 933 | {0x0001, 0x8800}, |
1020 | /* 422 */ {0x000a, 0x8700}, | 934 | {0x000a, 0x8700}, |
1021 | /* 423 */ {0x0000, 0x8702}, | 935 | {0x0000, 0x8702}, |
1022 | /* 424 */ {0x0000, 0x8703}, | 936 | {0x0000, 0x8703}, |
1023 | /* 425 */ {0x00c2, 0x8704}, | 937 | {0x00c2, 0x8704}, |
1024 | /* 426 */ {0x0001, 0x870c}, | 938 | {0x0001, 0x870c}, |
1025 | /* 427 */ {0x0044, 0x8600}, | 939 | {0x0044, 0x8600}, |
1026 | /* 428 */ {0x0002, 0x8606}, | 940 | {0x0002, 0x8606}, |
1027 | /* 429 */ {0x0064, 0x8607}, | 941 | {0x0064, 0x8607}, |
1028 | /* 430 */ {0x003a, 0x8601}, | 942 | {0x003a, 0x8601}, |
1029 | /* 431 */ {0x0008, 0x8602}, | 943 | {0x0008, 0x8602}, |
1030 | /* 432 */ {0x0044, 0x8600}, | 944 | {0x0044, 0x8600}, |
1031 | /* 433 */ {0x0018, 0x8617}, | 945 | {0x0018, 0x8617}, |
1032 | /* 434 */ {0x0008, 0x8618}, | 946 | {0x0008, 0x8618}, |
1033 | /* 435 */ {0x00a1, 0x8656}, | 947 | {0x00a1, 0x8656}, |
1034 | /* 436 */ {0x0004, 0x865b}, | 948 | {0x0004, 0x865b}, |
1035 | /* 437 */ {0x0002, 0x865c}, | 949 | {0x0002, 0x865c}, |
1036 | /* 438 */ {0x0058, 0x865d}, | 950 | {0x0058, 0x865d}, |
1037 | /* 439 */ {0x0048, 0x865e}, | 951 | {0x0048, 0x865e}, |
1038 | /* 440 */ {0x0012, 0x8608}, | 952 | {0x0012, 0x8608}, |
1039 | /* 441 */ {0x002c, 0x8609}, | 953 | {0x002c, 0x8609}, |
1040 | /* 442 */ {0x0002, 0x860a}, | 954 | {0x0002, 0x860a}, |
1041 | /* 443 */ {0x002c, 0x860b}, | 955 | {0x002c, 0x860b}, |
1042 | /* 444 */ {0x00db, 0x860c}, | 956 | {0x00db, 0x860c}, |
1043 | /* 445 */ {0x00f9, 0x860d}, | 957 | {0x00f9, 0x860d}, |
1044 | /* 446 */ {0x00f1, 0x860e}, | 958 | {0x00f1, 0x860e}, |
1045 | /* 447 */ {0x00e3, 0x860f}, | 959 | {0x00e3, 0x860f}, |
1046 | /* 448 */ {0x002c, 0x8610}, | 960 | {0x002c, 0x8610}, |
1047 | /* 449 */ {0x006c, 0x8651}, | 961 | {0x006c, 0x8651}, |
1048 | /* 450 */ {0x0041, 0x8652}, | 962 | {0x0041, 0x8652}, |
1049 | /* 451 */ {0x0059, 0x8653}, | 963 | {0x0059, 0x8653}, |
1050 | /* 452 */ {0x0040, 0x8654}, | 964 | {0x0040, 0x8654}, |
1051 | /* 453 */ {0x00fa, 0x8611}, | 965 | {0x00fa, 0x8611}, |
1052 | /* 454 */ {0x00ff, 0x8612}, | 966 | {0x00ff, 0x8612}, |
1053 | /* 455 */ {0x00f8, 0x8613}, | 967 | {0x00f8, 0x8613}, |
1054 | /* 456 */ {0x0000, 0x8614}, | 968 | {0x0000, 0x8614}, |
1055 | /* 457 */ {0x0001, 0x863f}, | 969 | {0x0001, 0x863f}, |
1056 | /* 458 */ {0x0000, 0x8640}, | 970 | {0x0000, 0x8640}, |
1057 | /* 459 */ {0x0026, 0x8641}, | 971 | {0x0026, 0x8641}, |
1058 | /* 460 */ {0x0045, 0x8642}, | 972 | {0x0045, 0x8642}, |
1059 | /* 461 */ {0x0060, 0x8643}, | 973 | {0x0060, 0x8643}, |
1060 | /* 462 */ {0x0075, 0x8644}, | 974 | {0x0075, 0x8644}, |
1061 | /* 463 */ {0x0088, 0x8645}, | 975 | {0x0088, 0x8645}, |
1062 | /* 464 */ {0x009b, 0x8646}, | 976 | {0x009b, 0x8646}, |
1063 | /* 465 */ {0x00b0, 0x8647}, | 977 | {0x00b0, 0x8647}, |
1064 | /* 466 */ {0x00c5, 0x8648}, | 978 | {0x00c5, 0x8648}, |
1065 | /* 467 */ {0x00d2, 0x8649}, | 979 | {0x00d2, 0x8649}, |
1066 | /* 468 */ {0x00dc, 0x864a}, | 980 | {0x00dc, 0x864a}, |
1067 | /* 469 */ {0x00e5, 0x864b}, | 981 | {0x00e5, 0x864b}, |
1068 | /* 470 */ {0x00eb, 0x864c}, | 982 | {0x00eb, 0x864c}, |
1069 | /* 471 */ {0x00f0, 0x864d}, | 983 | {0x00f0, 0x864d}, |
1070 | /* 472 */ {0x00f6, 0x864e}, | 984 | {0x00f6, 0x864e}, |
1071 | /* 473 */ {0x00fa, 0x864f}, | 985 | {0x00fa, 0x864f}, |
1072 | /* 474 */ {0x00ff, 0x8650}, | 986 | {0x00ff, 0x8650}, |
1073 | /* 475 */ {0x0060, 0x8657}, | 987 | {0x0060, 0x8657}, |
1074 | /* 476 */ {0x0010, 0x8658}, | 988 | {0x0010, 0x8658}, |
1075 | /* 477 */ {0x0018, 0x8659}, | 989 | {0x0018, 0x8659}, |
1076 | /* 478 */ {0x0005, 0x865a}, | 990 | {0x0005, 0x865a}, |
1077 | /* 479 */ {0x0018, 0x8660}, | 991 | {0x0018, 0x8660}, |
1078 | /* 480 */ {0x0003, 0x8509}, | 992 | {0x0003, 0x8509}, |
1079 | /* 481 */ {0x0011, 0x850a}, | 993 | {0x0011, 0x850a}, |
1080 | /* 482 */ {0x0032, 0x850b}, | 994 | {0x0032, 0x850b}, |
1081 | /* 483 */ {0x0010, 0x850c}, | 995 | {0x0010, 0x850c}, |
1082 | /* 484 */ {0x0021, 0x850d}, | 996 | {0x0021, 0x850d}, |
1083 | /* 485 */ {0x0001, 0x8500}, | 997 | {0x0001, 0x8500}, |
1084 | /* 486 */ {0x0000, 0x8508}, | 998 | {0x0000, 0x8508}, |
1085 | 999 | ||
1086 | /* 487 */ {0x0012, 0x8608}, | 1000 | {0x0012, 0x8608}, |
1087 | /* 488 */ {0x002c, 0x8609}, | 1001 | {0x002c, 0x8609}, |
1088 | /* 489 */ {0x0002, 0x860a}, | 1002 | {0x0002, 0x860a}, |
1089 | /* 490 */ {0x0039, 0x860b}, | 1003 | {0x0039, 0x860b}, |
1090 | /* 491 */ {0x00d0, 0x860c}, | 1004 | {0x00d0, 0x860c}, |
1091 | /* 492 */ {0x00f7, 0x860d}, | 1005 | {0x00f7, 0x860d}, |
1092 | /* 493 */ {0x00ed, 0x860e}, | 1006 | {0x00ed, 0x860e}, |
1093 | /* 494 */ {0x00db, 0x860f}, | 1007 | {0x00db, 0x860f}, |
1094 | /* 495 */ {0x0039, 0x8610}, | 1008 | {0x0039, 0x8610}, |
1095 | /* 496 */ {0x0012, 0x8657}, | 1009 | {0x0012, 0x8657}, |
1096 | /* 497 */ {0x0064, 0x8619}, | 1010 | {0x0064, 0x8619}, |
1097 | 1011 | ||
1098 | /* This line starts it all, it is not needed here */ | 1012 | /* This line starts it all, it is not needed here */ |
1099 | /* since it has been build into the driver */ | 1013 | /* since it has been build into the driver */ |
1100 | /* jfm: don't start now */ | 1014 | /* jfm: don't start now */ |
1101 | /* 590 * {0x0030, 0x8112}, */ | 1015 | /* {0x0030, 0x8112}, */ |
1102 | {} | 1016 | {} |
1103 | }; | 1017 | }; |
1104 | 1018 | ||
@@ -1109,14 +1023,14 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1109 | {0x0008, 0x8200}, /* Clear register */ | 1023 | {0x0008, 0x8200}, /* Clear register */ |
1110 | {0x0000, 0x870b}, /* Reset CTL3 */ | 1024 | {0x0000, 0x870b}, /* Reset CTL3 */ |
1111 | {0x0020, 0x8112}, /* Video Drop packet enable */ | 1025 | {0x0020, 0x8112}, /* Video Drop packet enable */ |
1112 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ | 1026 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ |
1113 | {0x0000, 0x8110}, /* Disable everything */ | 1027 | {0x0000, 0x8110}, /* Disable everything */ |
1114 | {0x0000, 0x8114}, /* Software GPIO output data */ | 1028 | {0x0000, 0x8114}, /* Software GPIO output data */ |
1115 | {0x0000, 0x8114}, | 1029 | {0x0000, 0x8114}, |
1116 | 1030 | ||
1117 | {0x0003, 0x8111}, | 1031 | {0x0003, 0x8111}, |
1118 | {0x0000, 0x8111}, | 1032 | {0x0000, 0x8111}, |
1119 | {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ | 1033 | {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ |
1120 | {0x0020, 0x8112}, | 1034 | {0x0020, 0x8112}, |
1121 | {0x0000, 0x8114}, | 1035 | {0x0000, 0x8114}, |
1122 | {0x0001, 0x8114}, | 1036 | {0x0001, 0x8114}, |
@@ -1129,191 +1043,143 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1129 | {0x00ba, 0x8804}, /* SSI Slave address */ | 1043 | {0x00ba, 0x8804}, /* SSI Slave address */ |
1130 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ | 1044 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ |
1131 | 1045 | ||
1132 | /* READ { 0, 0x0001, 0x8803 } -> | 1046 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1133 | 0000: 00 */ | 1047 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1134 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1135 | 0000: 10 */ | ||
1136 | {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ | 1048 | {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ |
1137 | {0x0020, 0x8801}, /* Register address for SSI read/write */ | 1049 | {0x0020, 0x8801}, /* Register address for SSI read/write */ |
1138 | {0x0044, 0x8805}, /* DATA2 */ | 1050 | {0x0044, 0x8805}, /* DATA2 */ |
1139 | {0x0004, 0x8800}, /* DATA1 -> write triggered */ | 1051 | {0x0004, 0x8800}, /* DATA1 -> write triggered */ |
1140 | /* READ { 0, 0x0001, 0x8803 } -> | 1052 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1141 | 0000: 00 */ | ||
1142 | 1053 | ||
1143 | /* READ { 0, 0x0001, 0x8803 } -> | 1054 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1144 | 0000: 00 */ | 1055 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1145 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1146 | 0000: 10 */ | ||
1147 | {0x0010, 0x8802}, | 1056 | {0x0010, 0x8802}, |
1148 | {0x0009, 0x8801}, | 1057 | {0x0009, 0x8801}, |
1149 | {0x0042, 0x8805}, | 1058 | {0x0042, 0x8805}, |
1150 | {0x0001, 0x8800}, | 1059 | {0x0001, 0x8800}, |
1151 | /* READ { 0, 0x0001, 0x8803 } -> | 1060 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1152 | 0000: 00 */ | ||
1153 | 1061 | ||
1154 | /* READ { 0, 0x0001, 0x8803 } -> | 1062 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1155 | 0000: 00 */ | 1063 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1156 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1157 | 0000: 10 */ | ||
1158 | {0x0010, 0x8802}, | 1064 | {0x0010, 0x8802}, |
1159 | {0x003c, 0x8801}, | 1065 | {0x003c, 0x8801}, |
1160 | {0x0001, 0x8805}, | 1066 | {0x0001, 0x8805}, |
1161 | {0x0000, 0x8800}, | 1067 | {0x0000, 0x8800}, |
1162 | /* READ { 0, 0x0001, 0x8803 } -> | 1068 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1163 | 0000: 00 */ | ||
1164 | 1069 | ||
1165 | /* READ { 0, 0x0001, 0x8803 } -> | 1070 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1166 | 0000: 00 */ | 1071 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1167 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1168 | 0000: 10 */ | ||
1169 | {0x0010, 0x8802}, | 1072 | {0x0010, 0x8802}, |
1170 | {0x0001, 0x8801}, | 1073 | {0x0001, 0x8801}, |
1171 | {0x000a, 0x8805}, | 1074 | {0x000a, 0x8805}, |
1172 | {0x0000, 0x8800}, | 1075 | {0x0000, 0x8800}, |
1173 | /* READ { 0, 0x0001, 0x8803 } -> | 1076 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1174 | 0000: 00 */ | ||
1175 | 1077 | ||
1176 | /* READ { 0, 0x0001, 0x8803 } -> | 1078 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1177 | 0000: 00 */ | 1079 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1178 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1179 | 0000: 10 */ | ||
1180 | {0x0010, 0x8802}, | 1080 | {0x0010, 0x8802}, |
1181 | {0x0002, 0x8801}, | 1081 | {0x0002, 0x8801}, |
1182 | {0x0000, 0x8805}, | 1082 | {0x0000, 0x8805}, |
1183 | {0x0000, 0x8800}, | 1083 | {0x0000, 0x8800}, |
1184 | /* READ { 0, 0x0001, 0x8803 } -> | 1084 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1185 | 0000: 00 */ | ||
1186 | 1085 | ||
1187 | /* READ { 0, 0x0001, 0x8803 } -> | 1086 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1188 | 0000: 00 */ | 1087 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1189 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1190 | 0000: 10 */ | ||
1191 | {0x0010, 0x8802}, | 1088 | {0x0010, 0x8802}, |
1192 | {0x0003, 0x8801}, | 1089 | {0x0003, 0x8801}, |
1193 | {0x0027, 0x8805}, | 1090 | {0x0027, 0x8805}, |
1194 | {0x0001, 0x8800}, | 1091 | {0x0001, 0x8800}, |
1195 | /* READ { 0, 0x0001, 0x8803 } -> | 1092 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1196 | 0000: 00 */ | ||
1197 | 1093 | ||
1198 | /* READ { 0, 0x0001, 0x8803 } -> | 1094 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1199 | 0000: 00 */ | 1095 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1200 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1201 | 0000: 10 */ | ||
1202 | {0x0010, 0x8802}, | 1096 | {0x0010, 0x8802}, |
1203 | {0x0004, 0x8801}, | 1097 | {0x0004, 0x8801}, |
1204 | {0x0065, 0x8805}, | 1098 | {0x0065, 0x8805}, |
1205 | {0x0001, 0x8800}, | 1099 | {0x0001, 0x8800}, |
1206 | /* READ { 0, 0x0001, 0x8803 } -> | 1100 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1207 | 0000: 00 */ | ||
1208 | 1101 | ||
1209 | /* READ { 0, 0x0001, 0x8803 } -> | 1102 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1210 | 0000: 00 */ | 1103 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1211 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1212 | 0000: 10 */ | ||
1213 | {0x0010, 0x8802}, | 1104 | {0x0010, 0x8802}, |
1214 | {0x0005, 0x8801}, | 1105 | {0x0005, 0x8801}, |
1215 | {0x0003, 0x8805}, | 1106 | {0x0003, 0x8805}, |
1216 | {0x0000, 0x8800}, | 1107 | {0x0000, 0x8800}, |
1217 | /* READ { 0, 0x0001, 0x8803 } -> | 1108 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1218 | 0000: 00 */ | ||
1219 | 1109 | ||
1220 | /* READ { 0, 0x0001, 0x8803 } -> | 1110 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1221 | 0000: 00 */ | 1111 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1222 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1223 | 0000: 10 */ | ||
1224 | {0x0010, 0x8802}, | 1112 | {0x0010, 0x8802}, |
1225 | {0x0006, 0x8801}, | 1113 | {0x0006, 0x8801}, |
1226 | {0x001c, 0x8805}, | 1114 | {0x001c, 0x8805}, |
1227 | {0x0000, 0x8800}, | 1115 | {0x0000, 0x8800}, |
1228 | /* READ { 0, 0x0001, 0x8803 } -> | 1116 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1229 | 0000: 00 */ | ||
1230 | 1117 | ||
1231 | /* READ { 0, 0x0001, 0x8803 } -> | 1118 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1232 | 0000: 00 */ | 1119 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1233 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1234 | 0000: 10 */ | ||
1235 | {0x0010, 0x8802}, | 1120 | {0x0010, 0x8802}, |
1236 | {0x0007, 0x8801}, | 1121 | {0x0007, 0x8801}, |
1237 | {0x002a, 0x8805}, | 1122 | {0x002a, 0x8805}, |
1238 | {0x0000, 0x8800}, | 1123 | {0x0000, 0x8800}, |
1239 | /* READ { 0, 0x0001, 0x8803 } -> | 1124 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1240 | 0000: 00 */ | ||
1241 | 1125 | ||
1242 | /* READ { 0, 0x0001, 0x8803 } -> | 1126 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1243 | 0000: 00 */ | 1127 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1244 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1245 | 0000: 10 */ | ||
1246 | {0x0010, 0x8802}, | 1128 | {0x0010, 0x8802}, |
1247 | {0x000e, 0x8801}, | 1129 | {0x000e, 0x8801}, |
1248 | {0x0000, 0x8805}, | 1130 | {0x0000, 0x8805}, |
1249 | {0x0000, 0x8800}, | 1131 | {0x0000, 0x8800}, |
1250 | /* READ { 0, 0x0001, 0x8803 } -> | 1132 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1251 | 0000: 00 */ | ||
1252 | 1133 | ||
1253 | /* READ { 0, 0x0001, 0x8803 } -> | 1134 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1254 | 0000: 00 */ | 1135 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1255 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1256 | 0000: 10 */ | ||
1257 | {0x0010, 0x8802}, | 1136 | {0x0010, 0x8802}, |
1258 | {0x0028, 0x8801}, | 1137 | {0x0028, 0x8801}, |
1259 | {0x002e, 0x8805}, | 1138 | {0x002e, 0x8805}, |
1260 | {0x0000, 0x8800}, | 1139 | {0x0000, 0x8800}, |
1261 | /* READ { 0, 0x0001, 0x8803 } -> | 1140 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1262 | 0000: 00 */ | ||
1263 | 1141 | ||
1264 | /* READ { 0, 0x0001, 0x8803 } -> | 1142 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1265 | 0000: 00 */ | 1143 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1266 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1267 | 0000: 10 */ | ||
1268 | {0x0010, 0x8802}, | 1144 | {0x0010, 0x8802}, |
1269 | {0x0039, 0x8801}, | 1145 | {0x0039, 0x8801}, |
1270 | {0x0013, 0x8805}, | 1146 | {0x0013, 0x8805}, |
1271 | {0x0000, 0x8800}, | 1147 | {0x0000, 0x8800}, |
1272 | /* READ { 0, 0x0001, 0x8803 } -> | 1148 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1273 | 0000: 00 */ | ||
1274 | 1149 | ||
1275 | /* READ { 0, 0x0001, 0x8803 } -> | 1150 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1276 | 0000: 00 */ | 1151 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1277 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1278 | 0000: 10 */ | ||
1279 | {0x0010, 0x8802}, | 1152 | {0x0010, 0x8802}, |
1280 | {0x003b, 0x8801}, | 1153 | {0x003b, 0x8801}, |
1281 | {0x000c, 0x8805}, | 1154 | {0x000c, 0x8805}, |
1282 | {0x0000, 0x8800}, | 1155 | {0x0000, 0x8800}, |
1283 | /* READ { 0, 0x0001, 0x8803 } -> | 1156 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1284 | 0000: 00 */ | ||
1285 | 1157 | ||
1286 | /* READ { 0, 0x0001, 0x8803 } -> | 1158 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1287 | 0000: 00 */ | 1159 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1288 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1289 | 0000: 10 */ | ||
1290 | {0x0010, 0x8802}, | 1160 | {0x0010, 0x8802}, |
1291 | {0x0035, 0x8801}, | 1161 | {0x0035, 0x8801}, |
1292 | {0x0028, 0x8805}, | 1162 | {0x0028, 0x8805}, |
1293 | {0x0000, 0x8800}, | 1163 | {0x0000, 0x8800}, |
1294 | /* READ { 0, 0x0001, 0x8803 } -> | 1164 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1295 | 0000: 00 */ | ||
1296 | 1165 | ||
1297 | /* READ { 0, 0x0001, 0x8803 } -> | 1166 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1298 | 0000: 00 */ | 1167 | /* READ { 0x0001, 0x8802 } -> 0000: 10 */ |
1299 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1300 | 0000: 10 */ | ||
1301 | {0x0010, 0x8802}, | 1168 | {0x0010, 0x8802}, |
1302 | {0x0009, 0x8801}, | 1169 | {0x0009, 0x8801}, |
1303 | {0x0042, 0x8805}, | 1170 | {0x0042, 0x8805}, |
1304 | {0x0001, 0x8800}, | 1171 | {0x0001, 0x8800}, |
1305 | /* READ { 0, 0x0001, 0x8803 } -> | 1172 | /* READ { 0x0001, 0x8803 } -> 0000: 00 */ |
1306 | 0000: 00 */ | ||
1307 | 1173 | ||
1308 | {0x0050, 0x8703}, | 1174 | {0x0050, 0x8703}, |
1309 | {0x0002, 0x8704}, /* External input CKIx1 */ | 1175 | {0x0002, 0x8704}, /* External input CKIx1 */ |
1310 | {0x0001, 0x870c}, /* Select CKOx2 output */ | 1176 | {0x0001, 0x870c}, /* Select CKOx2 output */ |
1311 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ | 1177 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ |
1312 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ | 1178 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ |
1313 | {0x0023, 0x8601}, | 1179 | {0x0023, 0x8601}, |
1314 | {0x0010, 0x8602}, | 1180 | {0x0010, 0x8602}, |
1315 | {0x000a, 0x8603}, | 1181 | {0x000a, 0x8603}, |
1316 | {0x009A, 0x8600}, | 1182 | {0x009a, 0x8600}, |
1317 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ | 1183 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ |
1318 | {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ | 1184 | {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ |
1319 | {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ | 1185 | {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ |
@@ -1329,7 +1195,7 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1329 | {0x0005, 0x860a}, /* ... */ | 1195 | {0x0005, 0x860a}, /* ... */ |
1330 | {0x0025, 0x860b}, | 1196 | {0x0025, 0x860b}, |
1331 | {0x00e1, 0x860c}, | 1197 | {0x00e1, 0x860c}, |
1332 | {0x00fa, 0x860D}, | 1198 | {0x00fa, 0x860d}, |
1333 | {0x00f4, 0x860e}, | 1199 | {0x00f4, 0x860e}, |
1334 | {0x00e8, 0x860f}, | 1200 | {0x00e8, 0x860f}, |
1335 | {0x0025, 0x8610}, /* A33 Coef. */ | 1201 | {0x0025, 0x8610}, /* A33 Coef. */ |
@@ -1344,11 +1210,12 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1344 | {0x0040, 0x8654}, /* Gb gain for white balance (L) */ | 1210 | {0x0040, 0x8654}, /* Gb gain for white balance (L) */ |
1345 | {0x0001, 0x863f}, /* Enable fixed gamma correction */ | 1211 | {0x0001, 0x863f}, /* Enable fixed gamma correction */ |
1346 | 1212 | ||
1347 | {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ | 1213 | {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128, |
1348 | /* UV division: UV no change, Enable New edge enhancement */ | 1214 | * UV division: UV no change, |
1215 | * Enable New edge enhancement */ | ||
1349 | {0x0018, 0x8657}, /* Edge gain high threshold */ | 1216 | {0x0018, 0x8657}, /* Edge gain high threshold */ |
1350 | {0x0020, 0x8658}, /* Edge gain low threshold */ | 1217 | {0x0020, 0x8658}, /* Edge gain low threshold */ |
1351 | {0x000A, 0x8659}, /* Edge bandwidth high threshold */ | 1218 | {0x000a, 0x8659}, /* Edge bandwidth high threshold */ |
1352 | {0x0005, 0x865a}, /* Edge bandwidth low threshold */ | 1219 | {0x0005, 0x865a}, /* Edge bandwidth low threshold */ |
1353 | {0x0064, 0x8607}, /* UV filter enable */ | 1220 | {0x0064, 0x8607}, /* UV filter enable */ |
1354 | 1221 | ||
@@ -1384,29 +1251,20 @@ static const u16 spca508_vista_init_data[][2] = { | |||
1384 | {0x0000, 0x86b4}, | 1251 | {0x0000, 0x86b4}, |
1385 | {0x001e, 0x8660}, | 1252 | {0x001e, 0x8660}, |
1386 | 1253 | ||
1387 | /* READ { 0, 0x0000, 0x8608 } -> | 1254 | /* READ { 0x0000, 0x8608 } -> 0000: 13 */ |
1388 | 0000: 13 */ | 1255 | /* READ { 0x0000, 0x8609 } -> 0000: 28 */ |
1389 | /* READ { 0, 0x0000, 0x8609 } -> | 1256 | /* READ { 0x0000, 0x8610 } -> 0000: 05 */ |
1390 | 0000: 28 */ | 1257 | /* READ { 0x0000, 0x8611 } -> 0000: 25 */ |
1391 | /* READ { 0, 0x0000, 0x8610 } -> | 1258 | /* READ { 0x0000, 0x8612 } -> 0000: e1 */ |
1392 | 0000: 05 */ | 1259 | /* READ { 0x0000, 0x8613 } -> 0000: fa */ |
1393 | /* READ { 0, 0x0000, 0x8611 } -> | 1260 | /* READ { 0x0000, 0x8614 } -> 0000: f4 */ |
1394 | 0000: 25 */ | 1261 | /* READ { 0x0000, 0x8615 } -> 0000: e8 */ |
1395 | /* READ { 0, 0x0000, 0x8612 } -> | 1262 | /* READ { 0x0000, 0x8616 } -> 0000: 25 */ |
1396 | 0000: e1 */ | ||
1397 | /* READ { 0, 0x0000, 0x8613 } -> | ||
1398 | 0000: fa */ | ||
1399 | /* READ { 0, 0x0000, 0x8614 } -> | ||
1400 | 0000: f4 */ | ||
1401 | /* READ { 0, 0x0000, 0x8615 } -> | ||
1402 | 0000: e8 */ | ||
1403 | /* READ { 0, 0x0000, 0x8616 } -> | ||
1404 | 0000: 25 */ | ||
1405 | {} | 1263 | {} |
1406 | }; | 1264 | }; |
1407 | 1265 | ||
1408 | static int reg_write(struct usb_device *dev, | 1266 | static int reg_write(struct usb_device *dev, |
1409 | __u16 index, __u16 value) | 1267 | u16 index, u16 value) |
1410 | { | 1268 | { |
1411 | int ret; | 1269 | int ret; |
1412 | 1270 | ||
@@ -1425,7 +1283,7 @@ static int reg_write(struct usb_device *dev, | |||
1425 | /* read 1 byte */ | 1283 | /* read 1 byte */ |
1426 | /* returns: negative is error, pos or zero is data */ | 1284 | /* returns: negative is error, pos or zero is data */ |
1427 | static int reg_read(struct gspca_dev *gspca_dev, | 1285 | static int reg_read(struct gspca_dev *gspca_dev, |
1428 | __u16 index) /* wIndex */ | 1286 | u16 index) /* wIndex */ |
1429 | { | 1287 | { |
1430 | int ret; | 1288 | int ret; |
1431 | 1289 | ||
@@ -1447,16 +1305,16 @@ static int reg_read(struct gspca_dev *gspca_dev, | |||
1447 | } | 1305 | } |
1448 | 1306 | ||
1449 | static int write_vector(struct gspca_dev *gspca_dev, | 1307 | static int write_vector(struct gspca_dev *gspca_dev, |
1450 | const u16 data[][2]) | 1308 | const u16 (*data)[2]) |
1451 | { | 1309 | { |
1452 | struct usb_device *dev = gspca_dev->dev; | 1310 | struct usb_device *dev = gspca_dev->dev; |
1453 | int ret, i = 0; | 1311 | int ret; |
1454 | 1312 | ||
1455 | while (data[i][1] != 0) { | 1313 | while ((*data)[1] != 0) { |
1456 | ret = reg_write(dev, data[i][1], data[i][0]); | 1314 | ret = reg_write(dev, (*data)[1], (*data)[0]); |
1457 | if (ret < 0) | 1315 | if (ret < 0) |
1458 | return ret; | 1316 | return ret; |
1459 | i++; | 1317 | data++; |
1460 | } | 1318 | } |
1461 | return 0; | 1319 | return 0; |
1462 | } | 1320 | } |
@@ -1468,6 +1326,15 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1468 | struct sd *sd = (struct sd *) gspca_dev; | 1326 | struct sd *sd = (struct sd *) gspca_dev; |
1469 | struct cam *cam; | 1327 | struct cam *cam; |
1470 | int data1, data2; | 1328 | int data1, data2; |
1329 | const u16 (*init_data)[2]; | ||
1330 | static const u16 (*(init_data_tb[]))[2] = { | ||
1331 | spca508_vista_init_data, /* CreativeVista 0 */ | ||
1332 | spca508_sightcam_init_data, /* HamaUSBSightcam 1 */ | ||
1333 | spca508_sightcam2_init_data, /* HamaUSBSightcam2 2 */ | ||
1334 | spca508cs110_init_data, /* IntelEasyPCCamera 3 */ | ||
1335 | spca508cs110_init_data, /* MicroInnovationIC200 4 */ | ||
1336 | spca508_init_data, /* ViewQuestVQ110 5 */ | ||
1337 | }; | ||
1471 | 1338 | ||
1472 | /* Read from global register the USB product and vendor IDs, just to | 1339 | /* Read from global register the USB product and vendor IDs, just to |
1473 | * prove that we can communicate with the device. This works, which | 1340 | * prove that we can communicate with the device. This works, which |
@@ -1491,37 +1358,13 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1491 | sd->subtype = id->driver_info; | 1358 | sd->subtype = id->driver_info; |
1492 | sd->brightness = BRIGHTNESS_DEF; | 1359 | sd->brightness = BRIGHTNESS_DEF; |
1493 | 1360 | ||
1494 | switch (sd->subtype) { | 1361 | init_data = init_data_tb[sd->subtype]; |
1495 | case ViewQuestVQ110: | 1362 | return write_vector(gspca_dev, init_data); |
1496 | if (write_vector(gspca_dev, spca508_init_data)) | ||
1497 | return -1; | ||
1498 | break; | ||
1499 | default: | ||
1500 | /* case MicroInnovationIC200: */ | ||
1501 | /* case IntelEasyPCCamera: */ | ||
1502 | if (write_vector(gspca_dev, spca508cs110_init_data)) | ||
1503 | return -1; | ||
1504 | break; | ||
1505 | case HamaUSBSightcam: | ||
1506 | if (write_vector(gspca_dev, spca508_sightcam_init_data)) | ||
1507 | return -1; | ||
1508 | break; | ||
1509 | case HamaUSBSightcam2: | ||
1510 | if (write_vector(gspca_dev, spca508_sightcam2_init_data)) | ||
1511 | return -1; | ||
1512 | break; | ||
1513 | case CreativeVista: | ||
1514 | if (write_vector(gspca_dev, spca508_vista_init_data)) | ||
1515 | return -1; | ||
1516 | break; | ||
1517 | } | ||
1518 | return 0; /* success */ | ||
1519 | } | 1363 | } |
1520 | 1364 | ||
1521 | /* this function is called at probe and resume time */ | 1365 | /* this function is called at probe and resume time */ |
1522 | static int sd_init(struct gspca_dev *gspca_dev) | 1366 | static int sd_init(struct gspca_dev *gspca_dev) |
1523 | { | 1367 | { |
1524 | /* write_vector(gspca_dev, spca508_open_data); */ | ||
1525 | return 0; | 1368 | return 0; |
1526 | } | 1369 | } |
1527 | 1370 | ||
@@ -1529,7 +1372,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1529 | { | 1372 | { |
1530 | int mode; | 1373 | int mode; |
1531 | 1374 | ||
1532 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | 1375 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
1533 | reg_write(gspca_dev->dev, 0x8500, mode); | 1376 | reg_write(gspca_dev->dev, 0x8500, mode); |
1534 | switch (mode) { | 1377 | switch (mode) { |
1535 | case 0: | 1378 | case 0: |
@@ -1554,7 +1397,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1554 | 1397 | ||
1555 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1398 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
1556 | struct gspca_frame *frame, /* target */ | 1399 | struct gspca_frame *frame, /* target */ |
1557 | __u8 *data, /* isoc packet */ | 1400 | u8 *data, /* isoc packet */ |
1558 | int len) /* iso packet length */ | 1401 | int len) /* iso packet length */ |
1559 | { | 1402 | { |
1560 | switch (data[0]) { | 1403 | switch (data[0]) { |
@@ -1567,7 +1410,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1567 | data, len); | 1410 | data, len); |
1568 | break; | 1411 | break; |
1569 | case 0xff: /* drop */ | 1412 | case 0xff: /* drop */ |
1570 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1571 | break; | 1413 | break; |
1572 | default: | 1414 | default: |
1573 | data += 1; | 1415 | data += 1; |
@@ -1581,7 +1423,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1581 | static void setbrightness(struct gspca_dev *gspca_dev) | 1423 | static void setbrightness(struct gspca_dev *gspca_dev) |
1582 | { | 1424 | { |
1583 | struct sd *sd = (struct sd *) gspca_dev; | 1425 | struct sd *sd = (struct sd *) gspca_dev; |
1584 | __u8 brightness = sd->brightness; | 1426 | u8 brightness = sd->brightness; |
1585 | 1427 | ||
1586 | /* MX seem contrast */ | 1428 | /* MX seem contrast */ |
1587 | reg_write(gspca_dev->dev, 0x8651, brightness); | 1429 | reg_write(gspca_dev->dev, 0x8651, brightness); |
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index c99c5e34e211..27e82b35f3e7 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -34,8 +34,8 @@ struct sd { | |||
34 | 34 | ||
35 | __u16 exposure; /* rev12a only */ | 35 | __u16 exposure; /* rev12a only */ |
36 | #define EXPOSURE_MIN 1 | 36 | #define EXPOSURE_MIN 1 |
37 | #define EXPOSURE_DEF 200 | 37 | #define EXPOSURE_DEF 700 /* == 10 fps */ |
38 | #define EXPOSURE_MAX (4095 - 900) /* see set_exposure */ | 38 | #define EXPOSURE_MAX (2047 + 325) /* see setexposure */ |
39 | 39 | ||
40 | __u8 contrast; /* rev72a only */ | 40 | __u8 contrast; /* rev72a only */ |
41 | #define CONTRAST_MIN 0x00 | 41 | #define CONTRAST_MIN 0x00 |
@@ -48,9 +48,9 @@ struct sd { | |||
48 | #define BRIGHTNESS_MAX 0x3f | 48 | #define BRIGHTNESS_MAX 0x3f |
49 | 49 | ||
50 | __u8 white; | 50 | __u8 white; |
51 | #define WHITE_MIN 1 | 51 | #define HUE_MIN 1 |
52 | #define WHITE_DEF 0x40 | 52 | #define HUE_DEF 0x40 |
53 | #define WHITE_MAX 0x7f | 53 | #define HUE_MAX 0x7f |
54 | 54 | ||
55 | __u8 autogain; | 55 | __u8 autogain; |
56 | #define AUTOGAIN_MIN 0 | 56 | #define AUTOGAIN_MIN 0 |
@@ -58,9 +58,9 @@ struct sd { | |||
58 | #define AUTOGAIN_MAX 1 | 58 | #define AUTOGAIN_MAX 1 |
59 | 59 | ||
60 | __u8 gain; /* rev12a only */ | 60 | __u8 gain; /* rev12a only */ |
61 | #define GAIN_MIN 0x0 | 61 | #define GAIN_MIN 0 |
62 | #define GAIN_DEF 0x24 | 62 | #define GAIN_DEF 63 |
63 | #define GAIN_MAX 0x24 | 63 | #define GAIN_MAX 255 |
64 | 64 | ||
65 | #define EXPO12A_DEF 3 | 65 | #define EXPO12A_DEF 3 |
66 | __u8 expo12a; /* expo/gain? for rev 12a */ | 66 | __u8 expo12a; /* expo/gain? for rev 12a */ |
@@ -461,7 +461,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
461 | } | 461 | } |
462 | sd->brightness = BRIGHTNESS_DEF; | 462 | sd->brightness = BRIGHTNESS_DEF; |
463 | sd->contrast = CONTRAST_DEF; | 463 | sd->contrast = CONTRAST_DEF; |
464 | sd->white = WHITE_DEF; | 464 | sd->white = HUE_DEF; |
465 | sd->exposure = EXPOSURE_DEF; | 465 | sd->exposure = EXPOSURE_DEF; |
466 | sd->autogain = AUTOGAIN_DEF; | 466 | sd->autogain = AUTOGAIN_DEF; |
467 | sd->gain = GAIN_DEF; | 467 | sd->gain = GAIN_DEF; |
@@ -549,8 +549,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
549 | static void setexposure(struct gspca_dev *gspca_dev) | 549 | static void setexposure(struct gspca_dev *gspca_dev) |
550 | { | 550 | { |
551 | struct sd *sd = (struct sd *) gspca_dev; | 551 | struct sd *sd = (struct sd *) gspca_dev; |
552 | int expo; | 552 | int i, expo = 0; |
553 | int clock_divider; | ||
554 | 553 | ||
555 | /* Register 0x8309 controls exposure for the spca561, | 554 | /* Register 0x8309 controls exposure for the spca561, |
556 | the basic exposure setting goes from 1-2047, where 1 is completely | 555 | the basic exposure setting goes from 1-2047, where 1 is completely |
@@ -564,16 +563,22 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
564 | configure a divider for the base framerate which us used at the | 563 | configure a divider for the base framerate which us used at the |
565 | exposure setting of 1-300. These bits configure the base framerate | 564 | exposure setting of 1-300. These bits configure the base framerate |
566 | according to the following formula: fps = 60 / (value + 2) */ | 565 | according to the following formula: fps = 60 / (value + 2) */ |
567 | if (sd->exposure < 2048) { | 566 | |
568 | expo = sd->exposure; | 567 | /* We choose to use the high bits setting the fixed framerate divisor |
569 | clock_divider = 0; | 568 | asap, as setting high basic exposure setting without the fixed |
570 | } else { | 569 | divider in combination with high gains makes the cam stop */ |
571 | /* Add 900 to make the 0 setting of the second part of the | 570 | int table[] = { 0, 450, 550, 625, EXPOSURE_MAX }; |
572 | exposure equal to the 2047 setting of the first part. */ | 571 | |
573 | expo = (sd->exposure - 2048) + 900; | 572 | for (i = 0; i < ARRAY_SIZE(table) - 1; i++) { |
574 | clock_divider = 3; | 573 | if (sd->exposure <= table[i + 1]) { |
574 | expo = sd->exposure - table[i]; | ||
575 | if (i) | ||
576 | expo += 300; | ||
577 | expo |= i << 11; | ||
578 | break; | ||
579 | } | ||
575 | } | 580 | } |
576 | expo |= clock_divider << 11; | 581 | |
577 | gspca_dev->usb_buf[0] = expo; | 582 | gspca_dev->usb_buf[0] = expo; |
578 | gspca_dev->usb_buf[1] = expo >> 8; | 583 | gspca_dev->usb_buf[1] = expo >> 8; |
579 | reg_w_buf(gspca_dev, 0x8309, 2); | 584 | reg_w_buf(gspca_dev, 0x8309, 2); |
@@ -584,7 +589,16 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
584 | { | 589 | { |
585 | struct sd *sd = (struct sd *) gspca_dev; | 590 | struct sd *sd = (struct sd *) gspca_dev; |
586 | 591 | ||
587 | gspca_dev->usb_buf[0] = sd->gain; | 592 | /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the |
593 | sensitivity when set, so 31 + one of them set == 63, and 15 | ||
594 | with both of them set == 63 */ | ||
595 | if (sd->gain < 64) | ||
596 | gspca_dev->usb_buf[0] = sd->gain; | ||
597 | else if (sd->gain < 128) | ||
598 | gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40; | ||
599 | else | ||
600 | gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0; | ||
601 | |||
588 | gspca_dev->usb_buf[1] = 0; | 602 | gspca_dev->usb_buf[1] = 0; |
589 | reg_w_buf(gspca_dev, 0x8335, 2); | 603 | reg_w_buf(gspca_dev, 0x8335, 2); |
590 | } | 604 | } |
@@ -629,8 +643,7 @@ static int sd_start_12a(struct gspca_dev *gspca_dev) | |||
629 | reg_w_buf(gspca_dev, 0x8391, 8); | 643 | reg_w_buf(gspca_dev, 0x8391, 8); |
630 | reg_w_buf(gspca_dev, 0x8390, 8); | 644 | reg_w_buf(gspca_dev, 0x8390, 8); |
631 | setwhite(gspca_dev); | 645 | setwhite(gspca_dev); |
632 | setautogain(gspca_dev); | 646 | setgain(gspca_dev); |
633 | /* setgain(gspca_dev); */ | ||
634 | setexposure(gspca_dev); | 647 | setexposure(gspca_dev); |
635 | return 0; | 648 | return 0; |
636 | } | 649 | } |
@@ -762,18 +775,6 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
762 | i2c_write(gspca_dev, expotimes | pixelclk, 0x09); | 775 | i2c_write(gspca_dev, expotimes | pixelclk, 0x09); |
763 | } | 776 | } |
764 | break; | 777 | break; |
765 | case Rev012A: | ||
766 | reg_r(gspca_dev, 0x8330, 2); | ||
767 | if (gspca_dev->usb_buf[1] > 0x08) { | ||
768 | gspca_dev->usb_buf[0] = ++sd->expo12a; | ||
769 | gspca_dev->usb_buf[1] = 0; | ||
770 | reg_w_buf(gspca_dev, 0x8339, 2); | ||
771 | } else if (gspca_dev->usb_buf[1] < 0x02) { | ||
772 | gspca_dev->usb_buf[0] = --sd->expo12a; | ||
773 | gspca_dev->usb_buf[1] = 0; | ||
774 | reg_w_buf(gspca_dev, 0x8339, 2); | ||
775 | } | ||
776 | break; | ||
777 | } | 778 | } |
778 | } | 779 | } |
779 | 780 | ||
@@ -928,13 +929,13 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | |||
928 | static struct ctrl sd_ctrls_12a[] = { | 929 | static struct ctrl sd_ctrls_12a[] = { |
929 | { | 930 | { |
930 | { | 931 | { |
931 | .id = V4L2_CID_DO_WHITE_BALANCE, | 932 | .id = V4L2_CID_HUE, |
932 | .type = V4L2_CTRL_TYPE_INTEGER, | 933 | .type = V4L2_CTRL_TYPE_INTEGER, |
933 | .name = "White Balance", | 934 | .name = "Hue", |
934 | .minimum = WHITE_MIN, | 935 | .minimum = HUE_MIN, |
935 | .maximum = WHITE_MAX, | 936 | .maximum = HUE_MAX, |
936 | .step = 1, | 937 | .step = 1, |
937 | .default_value = WHITE_DEF, | 938 | .default_value = HUE_DEF, |
938 | }, | 939 | }, |
939 | .set = sd_setwhite, | 940 | .set = sd_setwhite, |
940 | .get = sd_getwhite, | 941 | .get = sd_getwhite, |
@@ -954,19 +955,6 @@ static struct ctrl sd_ctrls_12a[] = { | |||
954 | }, | 955 | }, |
955 | { | 956 | { |
956 | { | 957 | { |
957 | .id = V4L2_CID_AUTOGAIN, | ||
958 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
959 | .name = "Auto Gain", | ||
960 | .minimum = AUTOGAIN_MIN, | ||
961 | .maximum = AUTOGAIN_MAX, | ||
962 | .step = 1, | ||
963 | .default_value = AUTOGAIN_DEF, | ||
964 | }, | ||
965 | .set = sd_setautogain, | ||
966 | .get = sd_getautogain, | ||
967 | }, | ||
968 | { | ||
969 | { | ||
970 | .id = V4L2_CID_GAIN, | 958 | .id = V4L2_CID_GAIN, |
971 | .type = V4L2_CTRL_TYPE_INTEGER, | 959 | .type = V4L2_CTRL_TYPE_INTEGER, |
972 | .name = "Gain", | 960 | .name = "Gain", |
@@ -983,13 +971,13 @@ static struct ctrl sd_ctrls_12a[] = { | |||
983 | static struct ctrl sd_ctrls_72a[] = { | 971 | static struct ctrl sd_ctrls_72a[] = { |
984 | { | 972 | { |
985 | { | 973 | { |
986 | .id = V4L2_CID_DO_WHITE_BALANCE, | 974 | .id = V4L2_CID_HUE, |
987 | .type = V4L2_CTRL_TYPE_INTEGER, | 975 | .type = V4L2_CTRL_TYPE_INTEGER, |
988 | .name = "White Balance", | 976 | .name = "Hue", |
989 | .minimum = WHITE_MIN, | 977 | .minimum = HUE_MIN, |
990 | .maximum = WHITE_MAX, | 978 | .maximum = HUE_MAX, |
991 | .step = 1, | 979 | .step = 1, |
992 | .default_value = WHITE_DEF, | 980 | .default_value = HUE_DEF, |
993 | }, | 981 | }, |
994 | .set = sd_setwhite, | 982 | .set = sd_setwhite, |
995 | .get = sd_getwhite, | 983 | .get = sd_getwhite, |
@@ -1046,7 +1034,6 @@ static const struct sd_desc sd_desc_12a = { | |||
1046 | .stopN = sd_stopN, | 1034 | .stopN = sd_stopN, |
1047 | .stop0 = sd_stop0, | 1035 | .stop0 = sd_stop0, |
1048 | .pkt_scan = sd_pkt_scan, | 1036 | .pkt_scan = sd_pkt_scan, |
1049 | /* .dq_callback = do_autogain, * fixme */ | ||
1050 | }; | 1037 | }; |
1051 | static const struct sd_desc sd_desc_72a = { | 1038 | static const struct sd_desc sd_desc_72a = { |
1052 | .name = MODULE_NAME, | 1039 | .name = MODULE_NAME, |
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c index 2e1cdf068fda..715a68f0156e 100644 --- a/drivers/media/video/gspca/sq905.c +++ b/drivers/media/video/gspca/sq905.c | |||
@@ -309,6 +309,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
309 | struct sd *dev = (struct sd *) gspca_dev; | 309 | struct sd *dev = (struct sd *) gspca_dev; |
310 | 310 | ||
311 | /* We don't use the buffer gspca allocates so make it small. */ | 311 | /* We don't use the buffer gspca allocates so make it small. */ |
312 | cam->bulk = 1; | ||
312 | cam->bulk_size = 64; | 313 | cam->bulk_size = 64; |
313 | 314 | ||
314 | INIT_WORK(&dev->work_struct, sq905_dostream); | 315 | INIT_WORK(&dev->work_struct, sq905_dostream); |
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index 0bcb74a1b143..916892505432 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c | |||
@@ -206,6 +206,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
206 | cam->nmodes = 1; | 206 | cam->nmodes = 1; |
207 | /* We don't use the buffer gspca allocates so make it small. */ | 207 | /* We don't use the buffer gspca allocates so make it small. */ |
208 | cam->bulk_size = 32; | 208 | cam->bulk_size = 32; |
209 | cam->bulk = 1; | ||
209 | INIT_WORK(&dev->work_struct, sq905c_dostream); | 210 | INIT_WORK(&dev->work_struct, sq905c_dostream); |
210 | return 0; | 211 | return 0; |
211 | } | 212 | } |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c index 9dff2e65b116..e573c3406324 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx.c | |||
@@ -293,8 +293,6 @@ static void stv06xx_stopN(struct gspca_dev *gspca_dev) | |||
293 | goto out; | 293 | goto out; |
294 | 294 | ||
295 | err = sd->sensor->stop(sd); | 295 | err = sd->sensor->stop(sd); |
296 | if (err < 0) | ||
297 | goto out; | ||
298 | 296 | ||
299 | out: | 297 | out: |
300 | if (err < 0) | 298 | if (err < 0) |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c index 69c77c932fc0..11a0c002f5dc 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c | |||
@@ -80,12 +80,26 @@ static const struct ctrl vv6410_ctrl[] = { | |||
80 | .minimum = 0, | 80 | .minimum = 0, |
81 | .maximum = 15, | 81 | .maximum = 15, |
82 | .step = 1, | 82 | .step = 1, |
83 | .default_value = 0 | 83 | .default_value = 10 |
84 | }, | 84 | }, |
85 | .set = vv6410_set_analog_gain, | 85 | .set = vv6410_set_analog_gain, |
86 | .get = vv6410_get_analog_gain | 86 | .get = vv6410_get_analog_gain |
87 | }, | ||
88 | #define EXPOSURE_IDX 3 | ||
89 | { | ||
90 | { | ||
91 | .id = V4L2_CID_EXPOSURE, | ||
92 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
93 | .name = "exposure", | ||
94 | .minimum = 0, | ||
95 | .maximum = 32768, | ||
96 | .step = 1, | ||
97 | .default_value = 20000 | ||
98 | }, | ||
99 | .set = vv6410_set_exposure, | ||
100 | .get = vv6410_get_exposure | ||
87 | } | 101 | } |
88 | }; | 102 | }; |
89 | 103 | ||
90 | static int vv6410_probe(struct sd *sd) | 104 | static int vv6410_probe(struct sd *sd) |
91 | { | 105 | { |
@@ -121,6 +135,7 @@ static int vv6410_probe(struct sd *sd) | |||
121 | static int vv6410_init(struct sd *sd) | 135 | static int vv6410_init(struct sd *sd) |
122 | { | 136 | { |
123 | int err = 0, i; | 137 | int err = 0, i; |
138 | s32 *sensor_settings = sd->sensor_priv; | ||
124 | 139 | ||
125 | for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { | 140 | for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { |
126 | /* if NULL then len contains single value */ | 141 | /* if NULL then len contains single value */ |
@@ -142,6 +157,16 @@ static int vv6410_init(struct sd *sd) | |||
142 | 157 | ||
143 | err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, | 158 | err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, |
144 | ARRAY_SIZE(vv6410_sensor_init)); | 159 | ARRAY_SIZE(vv6410_sensor_init)); |
160 | if (err < 0) | ||
161 | return err; | ||
162 | |||
163 | err = vv6410_set_exposure(&sd->gspca_dev, | ||
164 | sensor_settings[EXPOSURE_IDX]); | ||
165 | if (err < 0) | ||
166 | return err; | ||
167 | |||
168 | err = vv6410_set_analog_gain(&sd->gspca_dev, | ||
169 | sensor_settings[GAIN_IDX]); | ||
145 | 170 | ||
146 | return (err < 0) ? err : 0; | 171 | return (err < 0) ? err : 0; |
147 | } | 172 | } |
@@ -318,3 +343,50 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
318 | 343 | ||
319 | return (err < 0) ? err : 0; | 344 | return (err < 0) ? err : 0; |
320 | } | 345 | } |
346 | |||
347 | static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
348 | { | ||
349 | struct sd *sd = (struct sd *) gspca_dev; | ||
350 | s32 *sensor_settings = sd->sensor_priv; | ||
351 | |||
352 | *val = sensor_settings[EXPOSURE_IDX]; | ||
353 | |||
354 | PDEBUG(D_V4L2, "Read exposure %d", *val); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | ||
360 | { | ||
361 | int err; | ||
362 | struct sd *sd = (struct sd *) gspca_dev; | ||
363 | s32 *sensor_settings = sd->sensor_priv; | ||
364 | unsigned int fine, coarse; | ||
365 | |||
366 | sensor_settings[EXPOSURE_IDX] = val; | ||
367 | |||
368 | val = (val * val >> 14) + val / 4; | ||
369 | |||
370 | fine = val % VV6410_CIF_LINELENGTH; | ||
371 | coarse = min(512, val / VV6410_CIF_LINELENGTH); | ||
372 | |||
373 | PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d", | ||
374 | coarse, fine); | ||
375 | |||
376 | err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8); | ||
377 | if (err < 0) | ||
378 | goto out; | ||
379 | |||
380 | err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff); | ||
381 | if (err < 0) | ||
382 | goto out; | ||
383 | |||
384 | err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8); | ||
385 | if (err < 0) | ||
386 | goto out; | ||
387 | |||
388 | err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff); | ||
389 | |||
390 | out: | ||
391 | return err; | ||
392 | } | ||
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h index 95ac55891bd4..487d40555343 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | |||
@@ -173,6 +173,8 @@ | |||
173 | #define VV6410_SUBSAMPLE 0x01 | 173 | #define VV6410_SUBSAMPLE 0x01 |
174 | #define VV6410_CROP_TO_QVGA 0x02 | 174 | #define VV6410_CROP_TO_QVGA 0x02 |
175 | 175 | ||
176 | #define VV6410_CIF_LINELENGTH 415 | ||
177 | |||
176 | static int vv6410_probe(struct sd *sd); | 178 | static int vv6410_probe(struct sd *sd); |
177 | static int vv6410_start(struct sd *sd); | 179 | static int vv6410_start(struct sd *sd); |
178 | static int vv6410_init(struct sd *sd); | 180 | static int vv6410_init(struct sd *sd); |
@@ -187,6 +189,8 @@ static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | |||
187 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | 189 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); |
188 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); | 190 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); |
189 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); | 191 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); |
192 | static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
193 | static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
190 | 194 | ||
191 | const struct stv06xx_sensor stv06xx_sensor_vv6410 = { | 195 | const struct stv06xx_sensor stv06xx_sensor_vv6410 = { |
192 | .name = "ST VV6410", | 196 | .name = "ST VV6410", |
@@ -242,12 +246,6 @@ static const u8 vv6410_sensor_init[][2] = { | |||
242 | /* Pre-clock generator divide off */ | 246 | /* Pre-clock generator divide off */ |
243 | {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, | 247 | {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, |
244 | 248 | ||
245 | /* Exposure registers */ | ||
246 | {VV6410_FINEH, VV6410_FINE_EXPOSURE >> 8}, | ||
247 | {VV6410_FINEL, VV6410_FINE_EXPOSURE & 0xff}, | ||
248 | {VV6410_COARSEH, VV6410_COARSE_EXPOSURE >> 8}, | ||
249 | {VV6410_COARSEL, VV6410_COARSE_EXPOSURE & 0xff}, | ||
250 | {VV6410_ANALOGGAIN, 0xf0 | VV6410_DEFAULT_GAIN}, | ||
251 | {VV6410_CLKDIV, VV6410_CLK_DIV_2}, | 249 | {VV6410_CLKDIV, VV6410_CLK_DIV_2}, |
252 | 250 | ||
253 | /* System registers */ | 251 | /* System registers */ |
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index c2b8c10c075a..9623f294bdac 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c | |||
@@ -32,9 +32,6 @@ MODULE_LICENSE("GPL"); | |||
32 | struct sd { | 32 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 34 | ||
35 | __u8 packet[ISO_MAX_SIZE + 128]; | ||
36 | /* !! no more than 128 ff in an ISO packet */ | ||
37 | |||
38 | unsigned char brightness; | 35 | unsigned char brightness; |
39 | unsigned char contrast; | 36 | unsigned char contrast; |
40 | unsigned char colors; | 37 | unsigned char colors; |
@@ -1103,7 +1100,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1103 | { | 1100 | { |
1104 | struct sd *sd = (struct sd *) gspca_dev; | 1101 | struct sd *sd = (struct sd *) gspca_dev; |
1105 | int i, sof = 0; | 1102 | int i, sof = 0; |
1106 | unsigned char *s, *d; | ||
1107 | static unsigned char ffd9[] = {0xff, 0xd9}; | 1103 | static unsigned char ffd9[] = {0xff, 0xd9}; |
1108 | 1104 | ||
1109 | /* frames are jpeg 4.1.1 without 0xff escape */ | 1105 | /* frames are jpeg 4.1.1 without 0xff escape */ |
@@ -1177,22 +1173,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1177 | } | 1173 | } |
1178 | 1174 | ||
1179 | /* add 0x00 after 0xff */ | 1175 | /* add 0x00 after 0xff */ |
1180 | for (i = len; --i >= 0; ) | 1176 | i = 0; |
1181 | if (data[i] == 0xff) | 1177 | do { |
1182 | break; | 1178 | if (data[i] == 0xff) { |
1183 | if (i < 0) { /* no 0xff */ | 1179 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, |
1184 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | 1180 | data, i + 1); |
1185 | return; | 1181 | len -= i; |
1186 | } | 1182 | data += i; |
1187 | s = data; | 1183 | *data = 0x00; |
1188 | d = sd->packet; | 1184 | i = 0; |
1189 | for (i = 0; i < len; i++) { | 1185 | } |
1190 | *d++ = *s++; | 1186 | i++; |
1191 | if (s[-1] == 0xff) | 1187 | } while (i < len); |
1192 | *d++ = 0x00; | 1188 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); |
1193 | } | ||
1194 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1195 | sd->packet, d - sd->packet); | ||
1196 | } | 1189 | } |
1197 | 1190 | ||
1198 | static void setbrightness(struct gspca_dev *gspca_dev) | 1191 | static void setbrightness(struct gspca_dev *gspca_dev) |
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index f63e37e2e4fd..404214b8cd2b 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c | |||
@@ -697,7 +697,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
697 | return -EINVAL; | 697 | return -EINVAL; |
698 | } | 698 | } |
699 | 699 | ||
700 | if (sd->sensor != SENSOR_OTHER) { | 700 | if (sd->sensor == SENSOR_OM6802) { |
701 | reg_w_buf(gspca_dev, n1, sizeof n1); | 701 | reg_w_buf(gspca_dev, n1, sizeof n1); |
702 | i = 5; | 702 | i = 5; |
703 | while (--i >= 0) { | 703 | while (--i >= 0) { |
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index e4e933c400bc..26dd155efcc3 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -42,7 +42,7 @@ struct sd { | |||
42 | char bridge; | 42 | char bridge; |
43 | #define BRIDGE_VC0321 0 | 43 | #define BRIDGE_VC0321 0 |
44 | #define BRIDGE_VC0323 1 | 44 | #define BRIDGE_VC0323 1 |
45 | char sensor; | 45 | u8 sensor; |
46 | #define SENSOR_HV7131R 0 | 46 | #define SENSOR_HV7131R 0 |
47 | #define SENSOR_MI0360 1 | 47 | #define SENSOR_MI0360 1 |
48 | #define SENSOR_MI1310_SOC 2 | 48 | #define SENSOR_MI1310_SOC 2 |
@@ -159,17 +159,17 @@ static const struct v4l2_pix_format vc0323_mode[] = { | |||
159 | .priv = 2}, | 159 | .priv = 2}, |
160 | }; | 160 | }; |
161 | static const struct v4l2_pix_format bi_mode[] = { | 161 | static const struct v4l2_pix_format bi_mode[] = { |
162 | {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 162 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
163 | .bytesperline = 320, | 163 | .bytesperline = 320, |
164 | .sizeimage = 320 * 240 * 2, | 164 | .sizeimage = 320 * 240 * 2, |
165 | .colorspace = V4L2_COLORSPACE_SRGB, | 165 | .colorspace = V4L2_COLORSPACE_SRGB, |
166 | .priv = 2}, | 166 | .priv = 2}, |
167 | {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 167 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
168 | .bytesperline = 640, | 168 | .bytesperline = 640, |
169 | .sizeimage = 640 * 480 * 2, | 169 | .sizeimage = 640 * 480 * 2, |
170 | .colorspace = V4L2_COLORSPACE_SRGB, | 170 | .colorspace = V4L2_COLORSPACE_SRGB, |
171 | .priv = 1}, | 171 | .priv = 1}, |
172 | {1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, | 172 | {1280, 1024, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
173 | .bytesperline = 1280, | 173 | .bytesperline = 1280, |
174 | .sizeimage = 1280 * 1024 * 2, | 174 | .sizeimage = 1280 * 1024 * 2, |
175 | .colorspace = V4L2_COLORSPACE_SRGB, | 175 | .colorspace = V4L2_COLORSPACE_SRGB, |
@@ -2453,6 +2453,17 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2453 | struct usb_device *dev = gspca_dev->dev; | 2453 | struct usb_device *dev = gspca_dev->dev; |
2454 | struct cam *cam; | 2454 | struct cam *cam; |
2455 | int sensor; | 2455 | int sensor; |
2456 | static u8 npkt[] = { /* number of packets per ISOC message */ | ||
2457 | 64, /* HV7131R 0 */ | ||
2458 | 32, /* MI0360 1 */ | ||
2459 | 32, /* MI1310_SOC 2 */ | ||
2460 | 64, /* MI1320 3 */ | ||
2461 | 128, /* MI1320_SOC 4 */ | ||
2462 | 32, /* OV7660 5 */ | ||
2463 | 64, /* OV7670 6 */ | ||
2464 | 128, /* PO1200 7 */ | ||
2465 | 128, /* PO3130NC 8 */ | ||
2466 | }; | ||
2456 | 2467 | ||
2457 | cam = &gspca_dev->cam; | 2468 | cam = &gspca_dev->cam; |
2458 | sd->bridge = id->driver_info; | 2469 | sd->bridge = id->driver_info; |
@@ -2508,6 +2519,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2508 | case SENSOR_MI1320_SOC: | 2519 | case SENSOR_MI1320_SOC: |
2509 | cam->cam_mode = bi_mode; | 2520 | cam->cam_mode = bi_mode; |
2510 | cam->nmodes = ARRAY_SIZE(bi_mode); | 2521 | cam->nmodes = ARRAY_SIZE(bi_mode); |
2522 | cam->input_flags = V4L2_IN_ST_VFLIP | | ||
2523 | V4L2_IN_ST_HFLIP; | ||
2511 | break; | 2524 | break; |
2512 | default: | 2525 | default: |
2513 | cam->cam_mode = vc0323_mode; | 2526 | cam->cam_mode = vc0323_mode; |
@@ -2515,6 +2528,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2515 | break; | 2528 | break; |
2516 | } | 2529 | } |
2517 | } | 2530 | } |
2531 | cam->npkt = npkt[sd->sensor]; | ||
2518 | 2532 | ||
2519 | sd->hflip = HFLIP_DEF; | 2533 | sd->hflip = HFLIP_DEF; |
2520 | sd->vflip = VFLIP_DEF; | 2534 | sd->vflip = VFLIP_DEF; |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 4fe01d8b6c87..08422d315e68 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -6307,7 +6307,7 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev, | |||
6307 | retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ | 6307 | retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ |
6308 | retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ | 6308 | retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ |
6309 | retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ | 6309 | retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ |
6310 | PDEBUG(D_USBO, "i2c r [%02x] -> %04x (%02x)", | 6310 | PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)", |
6311 | reg, retval, retbyte); | 6311 | reg, retval, retbyte); |
6312 | return retval; | 6312 | return retval; |
6313 | } | 6313 | } |
@@ -6868,7 +6868,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { | |||
6868 | {0x8001, 0x13}, | 6868 | {0x8001, 0x13}, |
6869 | {0x8000, 0x14}, /* CS2102K */ | 6869 | {0x8000, 0x14}, /* CS2102K */ |
6870 | {0x8400, 0x15}, /* TAS5130K */ | 6870 | {0x8400, 0x15}, /* TAS5130K */ |
6871 | {0x4001, 0x16}, /* ADCM2700 */ | ||
6872 | }; | 6871 | }; |
6873 | 6872 | ||
6874 | static int vga_3wr_probe(struct gspca_dev *gspca_dev) | 6873 | static int vga_3wr_probe(struct gspca_dev *gspca_dev) |
@@ -6904,12 +6903,15 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6904 | retword |= reg_r(gspca_dev, 0x000a); | 6903 | retword |= reg_r(gspca_dev, 0x000a); |
6905 | PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); | 6904 | PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); |
6906 | reg_r(gspca_dev, 0x0010); | 6905 | reg_r(gspca_dev, 0x0010); |
6907 | /* this is tested only once anyway */ | 6906 | /* value 0x4001 is meaningless */ |
6908 | for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { | 6907 | if (retword != 0x4001) { |
6909 | if (chipset_revision_sensor[i].revision == retword) { | 6908 | for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { |
6910 | sd->chip_revision = retword; | 6909 | if (chipset_revision_sensor[i].revision == retword) { |
6911 | send_unknown(dev, SENSOR_PB0330); | 6910 | sd->chip_revision = retword; |
6912 | return chipset_revision_sensor[i].internal_sensor_id; | 6911 | send_unknown(dev, SENSOR_PB0330); |
6912 | return chipset_revision_sensor[i] | ||
6913 | .internal_sensor_id; | ||
6914 | } | ||
6913 | } | 6915 | } |
6914 | } | 6916 | } |
6915 | 6917 | ||
@@ -6980,12 +6982,12 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6980 | reg_w(dev, 0x01, 0x0001); | 6982 | reg_w(dev, 0x01, 0x0001); |
6981 | reg_w(dev, 0x03, 0x0012); | 6983 | reg_w(dev, 0x03, 0x0012); |
6982 | reg_w(dev, 0x01, 0x0012); | 6984 | reg_w(dev, 0x01, 0x0012); |
6983 | reg_w(dev, 0x05, 0x0001); | 6985 | reg_w(dev, 0x05, 0x0012); |
6984 | reg_w(dev, 0xd3, 0x008b); | 6986 | reg_w(dev, 0xd3, 0x008b); |
6985 | retword = i2c_read(gspca_dev, 0x01); | 6987 | retword = i2c_read(gspca_dev, 0x01); |
6986 | if (retword != 0) { | 6988 | if (retword != 0) { |
6987 | PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); | 6989 | PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); |
6988 | return retword; | 6990 | return 0x16; /* adcm2700 (6100/6200) */ |
6989 | } | 6991 | } |
6990 | return -1; | 6992 | return -1; |
6991 | } | 6993 | } |
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index 8e1463ee1b64..71c211402eb5 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c | |||
@@ -224,7 +224,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) | |||
224 | { | 224 | { |
225 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); | 225 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); |
226 | 226 | ||
227 | if (i->index < 0 || i->index >= HEXIUM_INPUTS) | 227 | if (i->index >= HEXIUM_INPUTS) |
228 | return -EINVAL; | 228 | return -EINVAL; |
229 | 229 | ||
230 | memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); | 230 | memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); |
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index 2bc39f628455..39d65ca41c62 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c | |||
@@ -325,7 +325,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) | |||
325 | { | 325 | { |
326 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); | 326 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); |
327 | 327 | ||
328 | if (i->index < 0 || i->index >= HEXIUM_INPUTS) | 328 | if (i->index >= HEXIUM_INPUTS) |
329 | return -EINVAL; | 329 | return -EINVAL; |
330 | 330 | ||
331 | memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); | 331 | memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 092c7da0f37a..86f2fefe1edf 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -74,7 +74,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, | |||
74 | int start, range, toggle, dev, code, ircode; | 74 | int start, range, toggle, dev, code, ircode; |
75 | 75 | ||
76 | /* poll IR chip */ | 76 | /* poll IR chip */ |
77 | if (size != i2c_master_recv(&ir->c,buf,size)) | 77 | if (size != i2c_master_recv(ir->c, buf, size)) |
78 | return -EIO; | 78 | return -EIO; |
79 | 79 | ||
80 | /* split rc5 data block ... */ | 80 | /* split rc5 data block ... */ |
@@ -137,7 +137,7 @@ static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
137 | unsigned char b; | 137 | unsigned char b; |
138 | 138 | ||
139 | /* poll IR chip */ | 139 | /* poll IR chip */ |
140 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 140 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
141 | dprintk(1,"read error\n"); | 141 | dprintk(1,"read error\n"); |
142 | return -EIO; | 142 | return -EIO; |
143 | } | 143 | } |
@@ -151,7 +151,7 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
151 | unsigned char b; | 151 | unsigned char b; |
152 | 152 | ||
153 | /* poll IR chip */ | 153 | /* poll IR chip */ |
154 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 154 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
155 | dprintk(1,"read error\n"); | 155 | dprintk(1,"read error\n"); |
156 | return -EIO; | 156 | return -EIO; |
157 | } | 157 | } |
@@ -171,7 +171,7 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
171 | unsigned char buf[4]; | 171 | unsigned char buf[4]; |
172 | 172 | ||
173 | /* poll IR chip */ | 173 | /* poll IR chip */ |
174 | if (4 != i2c_master_recv(&ir->c,buf,4)) { | 174 | if (4 != i2c_master_recv(ir->c, buf, 4)) { |
175 | dprintk(1,"read error\n"); | 175 | dprintk(1,"read error\n"); |
176 | return -EIO; | 176 | return -EIO; |
177 | } | 177 | } |
@@ -195,7 +195,7 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
195 | unsigned char b; | 195 | unsigned char b; |
196 | 196 | ||
197 | /* poll IR chip */ | 197 | /* poll IR chip */ |
198 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 198 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
199 | dprintk(1,"read error\n"); | 199 | dprintk(1,"read error\n"); |
200 | return -EIO; | 200 | return -EIO; |
201 | } | 201 | } |
@@ -222,12 +222,12 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, | |||
222 | u32 *ir_key, u32 *ir_raw) | 222 | u32 *ir_key, u32 *ir_raw) |
223 | { | 223 | { |
224 | unsigned char subaddr, key, keygroup; | 224 | unsigned char subaddr, key, keygroup; |
225 | struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0, | 225 | struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, |
226 | .buf = &subaddr, .len = 1}, | 226 | .buf = &subaddr, .len = 1}, |
227 | { .addr = ir->c.addr, .flags = I2C_M_RD, | 227 | { .addr = ir->c->addr, .flags = I2C_M_RD, |
228 | .buf = &key, .len = 1} }; | 228 | .buf = &key, .len = 1} }; |
229 | subaddr = 0x0d; | 229 | subaddr = 0x0d; |
230 | if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { | 230 | if (2 != i2c_transfer(ir->c->adapter, msg, 2)) { |
231 | dprintk(1, "read error\n"); | 231 | dprintk(1, "read error\n"); |
232 | return -EIO; | 232 | return -EIO; |
233 | } | 233 | } |
@@ -237,7 +237,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, | |||
237 | 237 | ||
238 | subaddr = 0x0b; | 238 | subaddr = 0x0b; |
239 | msg[1].buf = &keygroup; | 239 | msg[1].buf = &keygroup; |
240 | if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { | 240 | if (2 != i2c_transfer(ir->c->adapter, msg, 2)) { |
241 | dprintk(1, "read error\n"); | 241 | dprintk(1, "read error\n"); |
242 | return -EIO; | 242 | return -EIO; |
243 | } | 243 | } |
@@ -286,7 +286,7 @@ static void ir_work(struct work_struct *work) | |||
286 | 286 | ||
287 | /* MSI TV@nywhere Plus requires more frequent polling | 287 | /* MSI TV@nywhere Plus requires more frequent polling |
288 | otherwise it will miss some keypresses */ | 288 | otherwise it will miss some keypresses */ |
289 | if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30) | 289 | if (ir->c->adapter->id == I2C_HW_SAA7134 && ir->c->addr == 0x30) |
290 | polling_interval = 50; | 290 | polling_interval = 50; |
291 | 291 | ||
292 | ir_key_poll(ir); | 292 | ir_key_poll(ir); |
@@ -295,34 +295,15 @@ static void ir_work(struct work_struct *work) | |||
295 | 295 | ||
296 | /* ----------------------------------------------------------------------- */ | 296 | /* ----------------------------------------------------------------------- */ |
297 | 297 | ||
298 | static int ir_attach(struct i2c_adapter *adap, int addr, | 298 | static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) |
299 | unsigned short flags, int kind); | ||
300 | static int ir_detach(struct i2c_client *client); | ||
301 | static int ir_probe(struct i2c_adapter *adap); | ||
302 | |||
303 | static struct i2c_driver driver = { | ||
304 | .driver = { | ||
305 | .name = "ir-kbd-i2c", | ||
306 | }, | ||
307 | .id = I2C_DRIVERID_INFRARED, | ||
308 | .attach_adapter = ir_probe, | ||
309 | .detach_client = ir_detach, | ||
310 | }; | ||
311 | |||
312 | static struct i2c_client client_template = | ||
313 | { | ||
314 | .name = "unset", | ||
315 | .driver = &driver | ||
316 | }; | ||
317 | |||
318 | static int ir_attach(struct i2c_adapter *adap, int addr, | ||
319 | unsigned short flags, int kind) | ||
320 | { | 299 | { |
321 | IR_KEYTAB_TYPE *ir_codes = NULL; | 300 | IR_KEYTAB_TYPE *ir_codes = NULL; |
322 | char *name; | 301 | const char *name = NULL; |
323 | int ir_type; | 302 | int ir_type; |
324 | struct IR_i2c *ir; | 303 | struct IR_i2c *ir; |
325 | struct input_dev *input_dev; | 304 | struct input_dev *input_dev; |
305 | struct i2c_adapter *adap = client->adapter; | ||
306 | unsigned short addr = client->addr; | ||
326 | int err; | 307 | int err; |
327 | 308 | ||
328 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); | 309 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); |
@@ -332,13 +313,9 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
332 | goto err_out_free; | 313 | goto err_out_free; |
333 | } | 314 | } |
334 | 315 | ||
335 | ir->c = client_template; | 316 | ir->c = client; |
336 | ir->input = input_dev; | 317 | ir->input = input_dev; |
337 | 318 | i2c_set_clientdata(client, ir); | |
338 | ir->c.adapter = adap; | ||
339 | ir->c.addr = addr; | ||
340 | |||
341 | i2c_set_clientdata(&ir->c, ir); | ||
342 | 319 | ||
343 | switch(addr) { | 320 | switch(addr) { |
344 | case 0x64: | 321 | case 0x64: |
@@ -403,44 +380,46 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
403 | ir_codes = ir_codes_avermedia_cardbus; | 380 | ir_codes = ir_codes_avermedia_cardbus; |
404 | break; | 381 | break; |
405 | default: | 382 | default: |
406 | /* shouldn't happen */ | 383 | dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr); |
407 | printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr); | ||
408 | err = -ENODEV; | 384 | err = -ENODEV; |
409 | goto err_out_free; | 385 | goto err_out_free; |
410 | } | 386 | } |
411 | 387 | ||
412 | /* Sets name */ | 388 | /* Let the caller override settings */ |
413 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); | 389 | if (client->dev.platform_data) { |
414 | ir->ir_codes = ir_codes; | 390 | const struct IR_i2c_init_data *init_data = |
391 | client->dev.platform_data; | ||
415 | 392 | ||
416 | /* register i2c device | 393 | ir_codes = init_data->ir_codes; |
417 | * At device register, IR codes may be changed to be | 394 | name = init_data->name; |
418 | * board dependent. | 395 | ir->get_key = init_data->get_key; |
419 | */ | 396 | } |
420 | err = i2c_attach_client(&ir->c); | ||
421 | if (err) | ||
422 | goto err_out_free; | ||
423 | 397 | ||
424 | /* If IR not supported or disabled, unregisters driver */ | 398 | /* Make sure we are all setup before going on */ |
425 | if (ir->get_key == NULL) { | 399 | if (!name || !ir->get_key || !ir_codes) { |
400 | dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n", | ||
401 | addr); | ||
426 | err = -ENODEV; | 402 | err = -ENODEV; |
427 | goto err_out_detach; | 403 | goto err_out_free; |
428 | } | 404 | } |
429 | 405 | ||
430 | /* Phys addr can only be set after attaching (for ir->c.dev) */ | 406 | /* Sets name */ |
407 | snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name); | ||
408 | ir->ir_codes = ir_codes; | ||
409 | |||
431 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", | 410 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", |
432 | dev_name(&ir->c.adapter->dev), | 411 | dev_name(&adap->dev), |
433 | dev_name(&ir->c.dev)); | 412 | dev_name(&client->dev)); |
434 | 413 | ||
435 | /* init + register input device */ | 414 | /* init + register input device */ |
436 | ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); | 415 | ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); |
437 | input_dev->id.bustype = BUS_I2C; | 416 | input_dev->id.bustype = BUS_I2C; |
438 | input_dev->name = ir->c.name; | 417 | input_dev->name = ir->name; |
439 | input_dev->phys = ir->phys; | 418 | input_dev->phys = ir->phys; |
440 | 419 | ||
441 | err = input_register_device(ir->input); | 420 | err = input_register_device(ir->input); |
442 | if (err) | 421 | if (err) |
443 | goto err_out_detach; | 422 | goto err_out_free; |
444 | 423 | ||
445 | printk(DEVNAME ": %s detected at %s [%s]\n", | 424 | printk(DEVNAME ": %s detected at %s [%s]\n", |
446 | ir->input->name, ir->input->phys, adap->name); | 425 | ir->input->name, ir->input->phys, adap->name); |
@@ -451,135 +430,42 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
451 | 430 | ||
452 | return 0; | 431 | return 0; |
453 | 432 | ||
454 | err_out_detach: | ||
455 | i2c_detach_client(&ir->c); | ||
456 | err_out_free: | 433 | err_out_free: |
457 | input_free_device(input_dev); | 434 | input_free_device(input_dev); |
458 | kfree(ir); | 435 | kfree(ir); |
459 | return err; | 436 | return err; |
460 | } | 437 | } |
461 | 438 | ||
462 | static int ir_detach(struct i2c_client *client) | 439 | static int ir_remove(struct i2c_client *client) |
463 | { | 440 | { |
464 | struct IR_i2c *ir = i2c_get_clientdata(client); | 441 | struct IR_i2c *ir = i2c_get_clientdata(client); |
465 | 442 | ||
466 | /* kill outstanding polls */ | 443 | /* kill outstanding polls */ |
467 | cancel_delayed_work_sync(&ir->work); | 444 | cancel_delayed_work_sync(&ir->work); |
468 | 445 | ||
469 | /* unregister devices */ | 446 | /* unregister device */ |
470 | input_unregister_device(ir->input); | 447 | input_unregister_device(ir->input); |
471 | i2c_detach_client(&ir->c); | ||
472 | 448 | ||
473 | /* free memory */ | 449 | /* free memory */ |
474 | kfree(ir); | 450 | kfree(ir); |
475 | return 0; | 451 | return 0; |
476 | } | 452 | } |
477 | 453 | ||
478 | static int ir_probe(struct i2c_adapter *adap) | 454 | static const struct i2c_device_id ir_kbd_id[] = { |
479 | { | 455 | /* Generic entry for any IR receiver */ |
480 | 456 | { "ir_video", 0 }, | |
481 | /* The external IR receiver is at i2c address 0x34 (0x35 for | 457 | /* IR device specific entries could be added here */ |
482 | reads). Future Hauppauge cards will have an internal | 458 | { } |
483 | receiver at 0x30 (0x31 for reads). In theory, both can be | 459 | }; |
484 | fitted, and Hauppauge suggest an external overrides an | ||
485 | internal. | ||
486 | |||
487 | That's why we probe 0x1a (~0x34) first. CB | ||
488 | */ | ||
489 | |||
490 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; | ||
491 | static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 }; | ||
492 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; | ||
493 | static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; | ||
494 | static const int probe_cx23885[] = { 0x6b, -1 }; | ||
495 | const int *probe; | ||
496 | struct i2c_msg msg = { | ||
497 | .flags = I2C_M_RD, | ||
498 | .len = 0, | ||
499 | .buf = NULL, | ||
500 | }; | ||
501 | int i, rc; | ||
502 | |||
503 | switch (adap->id) { | ||
504 | case I2C_HW_B_BT848: | ||
505 | probe = probe_bttv; | ||
506 | break; | ||
507 | case I2C_HW_B_CX2341X: | ||
508 | probe = probe_bttv; | ||
509 | break; | ||
510 | case I2C_HW_SAA7134: | ||
511 | probe = probe_saa7134; | ||
512 | break; | ||
513 | case I2C_HW_B_EM28XX: | ||
514 | probe = probe_em28XX; | ||
515 | break; | ||
516 | case I2C_HW_B_CX2388x: | ||
517 | probe = probe_cx88; | ||
518 | break; | ||
519 | case I2C_HW_B_CX23885: | ||
520 | probe = probe_cx23885; | ||
521 | break; | ||
522 | default: | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | for (i = 0; -1 != probe[i]; i++) { | ||
527 | msg.addr = probe[i]; | ||
528 | rc = i2c_transfer(adap, &msg, 1); | ||
529 | dprintk(1,"probe 0x%02x @ %s: %s\n", | ||
530 | probe[i], adap->name, | ||
531 | (1 == rc) ? "yes" : "no"); | ||
532 | if (1 == rc) { | ||
533 | ir_attach(adap, probe[i], 0, 0); | ||
534 | return 0; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | /* Special case for MSI TV@nywhere Plus remote */ | ||
539 | if (adap->id == I2C_HW_SAA7134) { | ||
540 | u8 temp; | ||
541 | |||
542 | /* MSI TV@nywhere Plus controller doesn't seem to | ||
543 | respond to probes unless we read something from | ||
544 | an existing device. Weird... */ | ||
545 | |||
546 | msg.addr = 0x50; | ||
547 | rc = i2c_transfer(adap, &msg, 1); | ||
548 | dprintk(1, "probe 0x%02x @ %s: %s\n", | ||
549 | msg.addr, adap->name, | ||
550 | (1 == rc) ? "yes" : "no"); | ||
551 | |||
552 | /* Now do the probe. The controller does not respond | ||
553 | to 0-byte reads, so we use a 1-byte read instead. */ | ||
554 | msg.addr = 0x30; | ||
555 | msg.len = 1; | ||
556 | msg.buf = &temp; | ||
557 | rc = i2c_transfer(adap, &msg, 1); | ||
558 | dprintk(1, "probe 0x%02x @ %s: %s\n", | ||
559 | msg.addr, adap->name, | ||
560 | (1 == rc) ? "yes" : "no"); | ||
561 | if (1 == rc) | ||
562 | ir_attach(adap, msg.addr, 0, 0); | ||
563 | } | ||
564 | |||
565 | /* Special case for AVerMedia Cardbus remote */ | ||
566 | if (adap->id == I2C_HW_SAA7134) { | ||
567 | unsigned char subaddr, data; | ||
568 | struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0, | ||
569 | .buf = &subaddr, .len = 1}, | ||
570 | { .addr = 0x40, .flags = I2C_M_RD, | ||
571 | .buf = &data, .len = 1} }; | ||
572 | subaddr = 0x0d; | ||
573 | rc = i2c_transfer(adap, msg, 2); | ||
574 | dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n", | ||
575 | msg[0].addr, subaddr, adap->name, | ||
576 | (2 == rc) ? "yes" : "no"); | ||
577 | if (2 == rc) | ||
578 | ir_attach(adap, msg[0].addr, 0, 0); | ||
579 | } | ||
580 | 460 | ||
581 | return 0; | 461 | static struct i2c_driver driver = { |
582 | } | 462 | .driver = { |
463 | .name = "ir-kbd-i2c", | ||
464 | }, | ||
465 | .probe = ir_probe, | ||
466 | .remove = ir_remove, | ||
467 | .id_table = ir_kbd_id, | ||
468 | }; | ||
583 | 469 | ||
584 | /* ----------------------------------------------------------------------- */ | 470 | /* ----------------------------------------------------------------------- */ |
585 | 471 | ||
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index db2ac9a99acd..558f8a837ff4 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -455,7 +455,7 @@ static void ivtv_process_eeprom(struct ivtv *itv) | |||
455 | break; | 455 | break; |
456 | } | 456 | } |
457 | if (tv.tuner_type == TUNER_ABSENT) | 457 | if (tv.tuner_type == TUNER_ABSENT) |
458 | IVTV_ERR("tveeprom cannot autodetect tuner!"); | 458 | IVTV_ERR("tveeprom cannot autodetect tuner!\n"); |
459 | 459 | ||
460 | if (itv->options.tuner == -1) | 460 | if (itv->options.tuner == -1) |
461 | itv->options.tuner = tv.tuner_type; | 461 | itv->options.tuner = tv.tuner_type; |
@@ -946,17 +946,14 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, | |||
946 | if (itv == NULL) | 946 | if (itv == NULL) |
947 | return -ENOMEM; | 947 | return -ENOMEM; |
948 | itv->pdev = pdev; | 948 | itv->pdev = pdev; |
949 | itv->instance = atomic_inc_return(&ivtv_instance) - 1; | 949 | itv->instance = v4l2_device_set_name(&itv->v4l2_dev, "ivtv", |
950 | &ivtv_instance); | ||
950 | 951 | ||
951 | retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev); | 952 | retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev); |
952 | if (retval) { | 953 | if (retval) { |
953 | kfree(itv); | 954 | kfree(itv); |
954 | return retval; | 955 | return retval; |
955 | } | 956 | } |
956 | /* "ivtv + PCI ID" is a bit of a mouthful, so use | ||
957 | "ivtv + instance" instead. */ | ||
958 | snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name), | ||
959 | "ivtv%d", itv->instance); | ||
960 | IVTV_INFO("Initializing card %d\n", itv->instance); | 957 | IVTV_INFO("Initializing card %d\n", itv->instance); |
961 | 958 | ||
962 | ivtv_process_options(itv); | 959 | ivtv_process_options(itv); |
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 9e3d32b8004c..e52aa322b134 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c | |||
@@ -579,9 +579,11 @@ static struct i2c_client ivtv_i2c_client_template = { | |||
579 | .name = "ivtv internal", | 579 | .name = "ivtv internal", |
580 | }; | 580 | }; |
581 | 581 | ||
582 | /* init + register i2c algo-bit adapter */ | 582 | /* init + register i2c adapter + instantiate IR receiver */ |
583 | int init_ivtv_i2c(struct ivtv *itv) | 583 | int init_ivtv_i2c(struct ivtv *itv) |
584 | { | 584 | { |
585 | int retval; | ||
586 | |||
585 | IVTV_DEBUG_I2C("i2c init\n"); | 587 | IVTV_DEBUG_I2C("i2c init\n"); |
586 | 588 | ||
587 | /* Sanity checks for the I2C hardware arrays. They must be the | 589 | /* Sanity checks for the I2C hardware arrays. They must be the |
@@ -619,9 +621,37 @@ int init_ivtv_i2c(struct ivtv *itv) | |||
619 | ivtv_setsda(itv, 1); | 621 | ivtv_setsda(itv, 1); |
620 | 622 | ||
621 | if (itv->options.newi2c > 0) | 623 | if (itv->options.newi2c > 0) |
622 | return i2c_add_adapter(&itv->i2c_adap); | 624 | retval = i2c_add_adapter(&itv->i2c_adap); |
623 | else | 625 | else |
624 | return i2c_bit_add_bus(&itv->i2c_adap); | 626 | retval = i2c_bit_add_bus(&itv->i2c_adap); |
627 | |||
628 | /* Instantiate the IR receiver device, if present */ | ||
629 | if (retval == 0) { | ||
630 | struct i2c_board_info info; | ||
631 | /* The external IR receiver is at i2c address 0x34 (0x35 for | ||
632 | reads). Future Hauppauge cards will have an internal | ||
633 | receiver at 0x30 (0x31 for reads). In theory, both can be | ||
634 | fitted, and Hauppauge suggest an external overrides an | ||
635 | internal. | ||
636 | |||
637 | That's why we probe 0x1a (~0x34) first. CB | ||
638 | */ | ||
639 | const unsigned short addr_list[] = { | ||
640 | 0x1a, /* Hauppauge IR external */ | ||
641 | 0x18, /* Hauppauge IR internal */ | ||
642 | 0x71, /* Hauppauge IR (PVR150) */ | ||
643 | 0x64, /* Pixelview IR */ | ||
644 | 0x30, /* KNC ONE IR */ | ||
645 | 0x6b, /* Adaptec IR */ | ||
646 | I2C_CLIENT_END | ||
647 | }; | ||
648 | |||
649 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
650 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
651 | i2c_new_probed_device(&itv->i2c_adap, &info, addr_list); | ||
652 | } | ||
653 | |||
654 | return retval; | ||
625 | } | 655 | } |
626 | 656 | ||
627 | void exit_ivtv_i2c(struct ivtv *itv) | 657 | void exit_ivtv_i2c(struct ivtv *itv) |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index c342a9fe983e..99f3c39a118b 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -709,7 +709,7 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) | |||
709 | else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && | 709 | else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && |
710 | regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) | 710 | regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) |
711 | reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; | 711 | reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; |
712 | else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE) | 712 | else if (regs->reg < IVTV_ENCODER_SIZE) |
713 | reg_start = itv->enc_mem; | 713 | reg_start = itv->enc_mem; |
714 | else | 714 | else |
715 | return -EINVAL; | 715 | return -EINVAL; |
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 684f62fa7897..459c04cbf69d 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c | |||
@@ -75,53 +75,50 @@ struct mt9m001 { | |||
75 | unsigned char autoexposure; | 75 | unsigned char autoexposure; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static int reg_read(struct soc_camera_device *icd, const u8 reg) | 78 | static int reg_read(struct i2c_client *client, const u8 reg) |
79 | { | 79 | { |
80 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | ||
81 | struct i2c_client *client = mt9m001->client; | ||
82 | s32 data = i2c_smbus_read_word_data(client, reg); | 80 | s32 data = i2c_smbus_read_word_data(client, reg); |
83 | return data < 0 ? data : swab16(data); | 81 | return data < 0 ? data : swab16(data); |
84 | } | 82 | } |
85 | 83 | ||
86 | static int reg_write(struct soc_camera_device *icd, const u8 reg, | 84 | static int reg_write(struct i2c_client *client, const u8 reg, |
87 | const u16 data) | 85 | const u16 data) |
88 | { | 86 | { |
89 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 87 | return i2c_smbus_write_word_data(client, reg, swab16(data)); |
90 | return i2c_smbus_write_word_data(mt9m001->client, reg, swab16(data)); | ||
91 | } | 88 | } |
92 | 89 | ||
93 | static int reg_set(struct soc_camera_device *icd, const u8 reg, | 90 | static int reg_set(struct i2c_client *client, const u8 reg, |
94 | const u16 data) | 91 | const u16 data) |
95 | { | 92 | { |
96 | int ret; | 93 | int ret; |
97 | 94 | ||
98 | ret = reg_read(icd, reg); | 95 | ret = reg_read(client, reg); |
99 | if (ret < 0) | 96 | if (ret < 0) |
100 | return ret; | 97 | return ret; |
101 | return reg_write(icd, reg, ret | data); | 98 | return reg_write(client, reg, ret | data); |
102 | } | 99 | } |
103 | 100 | ||
104 | static int reg_clear(struct soc_camera_device *icd, const u8 reg, | 101 | static int reg_clear(struct i2c_client *client, const u8 reg, |
105 | const u16 data) | 102 | const u16 data) |
106 | { | 103 | { |
107 | int ret; | 104 | int ret; |
108 | 105 | ||
109 | ret = reg_read(icd, reg); | 106 | ret = reg_read(client, reg); |
110 | if (ret < 0) | 107 | if (ret < 0) |
111 | return ret; | 108 | return ret; |
112 | return reg_write(icd, reg, ret & ~data); | 109 | return reg_write(client, reg, ret & ~data); |
113 | } | 110 | } |
114 | 111 | ||
115 | static int mt9m001_init(struct soc_camera_device *icd) | 112 | static int mt9m001_init(struct soc_camera_device *icd) |
116 | { | 113 | { |
117 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 114 | struct i2c_client *client = to_i2c_client(icd->control); |
118 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | 115 | struct soc_camera_link *icl = client->dev.platform_data; |
119 | int ret; | 116 | int ret; |
120 | 117 | ||
121 | dev_dbg(icd->vdev->parent, "%s\n", __func__); | 118 | dev_dbg(icd->vdev->parent, "%s\n", __func__); |
122 | 119 | ||
123 | if (icl->power) { | 120 | if (icl->power) { |
124 | ret = icl->power(&mt9m001->client->dev, 1); | 121 | ret = icl->power(&client->dev, 1); |
125 | if (ret < 0) { | 122 | if (ret < 0) { |
126 | dev_err(icd->vdev->parent, | 123 | dev_err(icd->vdev->parent, |
127 | "Platform failed to power-on the camera.\n"); | 124 | "Platform failed to power-on the camera.\n"); |
@@ -131,49 +128,53 @@ static int mt9m001_init(struct soc_camera_device *icd) | |||
131 | 128 | ||
132 | /* The camera could have been already on, we reset it additionally */ | 129 | /* The camera could have been already on, we reset it additionally */ |
133 | if (icl->reset) | 130 | if (icl->reset) |
134 | ret = icl->reset(&mt9m001->client->dev); | 131 | ret = icl->reset(&client->dev); |
135 | else | 132 | else |
136 | ret = -ENODEV; | 133 | ret = -ENODEV; |
137 | 134 | ||
138 | if (ret < 0) { | 135 | if (ret < 0) { |
139 | /* Either no platform reset, or platform reset failed */ | 136 | /* Either no platform reset, or platform reset failed */ |
140 | ret = reg_write(icd, MT9M001_RESET, 1); | 137 | ret = reg_write(client, MT9M001_RESET, 1); |
141 | if (!ret) | 138 | if (!ret) |
142 | ret = reg_write(icd, MT9M001_RESET, 0); | 139 | ret = reg_write(client, MT9M001_RESET, 0); |
143 | } | 140 | } |
144 | /* Disable chip, synchronous option update */ | 141 | /* Disable chip, synchronous option update */ |
145 | if (!ret) | 142 | if (!ret) |
146 | ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); | 143 | ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0); |
147 | 144 | ||
148 | return ret; | 145 | return ret; |
149 | } | 146 | } |
150 | 147 | ||
151 | static int mt9m001_release(struct soc_camera_device *icd) | 148 | static int mt9m001_release(struct soc_camera_device *icd) |
152 | { | 149 | { |
153 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 150 | struct i2c_client *client = to_i2c_client(icd->control); |
154 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | 151 | struct soc_camera_link *icl = client->dev.platform_data; |
155 | 152 | ||
156 | /* Disable the chip */ | 153 | /* Disable the chip */ |
157 | reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); | 154 | reg_write(client, MT9M001_OUTPUT_CONTROL, 0); |
158 | 155 | ||
159 | if (icl->power) | 156 | if (icl->power) |
160 | icl->power(&mt9m001->client->dev, 0); | 157 | icl->power(&client->dev, 0); |
161 | 158 | ||
162 | return 0; | 159 | return 0; |
163 | } | 160 | } |
164 | 161 | ||
165 | static int mt9m001_start_capture(struct soc_camera_device *icd) | 162 | static int mt9m001_start_capture(struct soc_camera_device *icd) |
166 | { | 163 | { |
164 | struct i2c_client *client = to_i2c_client(icd->control); | ||
165 | |||
167 | /* Switch to master "normal" mode */ | 166 | /* Switch to master "normal" mode */ |
168 | if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 2) < 0) | 167 | if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0) |
169 | return -EIO; | 168 | return -EIO; |
170 | return 0; | 169 | return 0; |
171 | } | 170 | } |
172 | 171 | ||
173 | static int mt9m001_stop_capture(struct soc_camera_device *icd) | 172 | static int mt9m001_stop_capture(struct soc_camera_device *icd) |
174 | { | 173 | { |
174 | struct i2c_client *client = to_i2c_client(icd->control); | ||
175 | |||
175 | /* Stop sensor readout */ | 176 | /* Stop sensor readout */ |
176 | if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 0) < 0) | 177 | if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0) |
177 | return -EIO; | 178 | return -EIO; |
178 | return 0; | 179 | return 0; |
179 | } | 180 | } |
@@ -222,28 +223,29 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) | |||
222 | static int mt9m001_set_crop(struct soc_camera_device *icd, | 223 | static int mt9m001_set_crop(struct soc_camera_device *icd, |
223 | struct v4l2_rect *rect) | 224 | struct v4l2_rect *rect) |
224 | { | 225 | { |
226 | struct i2c_client *client = to_i2c_client(icd->control); | ||
225 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 227 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
226 | int ret; | 228 | int ret; |
227 | const u16 hblank = 9, vblank = 25; | 229 | const u16 hblank = 9, vblank = 25; |
228 | 230 | ||
229 | /* Blanking and start values - default... */ | 231 | /* Blanking and start values - default... */ |
230 | ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank); | 232 | ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); |
231 | if (!ret) | 233 | if (!ret) |
232 | ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); | 234 | ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank); |
233 | 235 | ||
234 | /* The caller provides a supported format, as verified per | 236 | /* The caller provides a supported format, as verified per |
235 | * call to icd->try_fmt() */ | 237 | * call to icd->try_fmt() */ |
236 | if (!ret) | 238 | if (!ret) |
237 | ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); | 239 | ret = reg_write(client, MT9M001_COLUMN_START, rect->left); |
238 | if (!ret) | 240 | if (!ret) |
239 | ret = reg_write(icd, MT9M001_ROW_START, rect->top); | 241 | ret = reg_write(client, MT9M001_ROW_START, rect->top); |
240 | if (!ret) | 242 | if (!ret) |
241 | ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1); | 243 | ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect->width - 1); |
242 | if (!ret) | 244 | if (!ret) |
243 | ret = reg_write(icd, MT9M001_WINDOW_HEIGHT, | 245 | ret = reg_write(client, MT9M001_WINDOW_HEIGHT, |
244 | rect->height + icd->y_skip_top - 1); | 246 | rect->height + icd->y_skip_top - 1); |
245 | if (!ret && mt9m001->autoexposure) { | 247 | if (!ret && mt9m001->autoexposure) { |
246 | ret = reg_write(icd, MT9M001_SHUTTER_WIDTH, | 248 | ret = reg_write(client, MT9M001_SHUTTER_WIDTH, |
247 | rect->height + icd->y_skip_top + vblank); | 249 | rect->height + icd->y_skip_top + vblank); |
248 | if (!ret) { | 250 | if (!ret) { |
249 | const struct v4l2_queryctrl *qctrl = | 251 | const struct v4l2_queryctrl *qctrl = |
@@ -312,16 +314,16 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd, | |||
312 | static int mt9m001_get_register(struct soc_camera_device *icd, | 314 | static int mt9m001_get_register(struct soc_camera_device *icd, |
313 | struct v4l2_dbg_register *reg) | 315 | struct v4l2_dbg_register *reg) |
314 | { | 316 | { |
315 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 317 | struct i2c_client *client = to_i2c_client(icd->control); |
316 | 318 | ||
317 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 319 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
318 | return -EINVAL; | 320 | return -EINVAL; |
319 | 321 | ||
320 | if (reg->match.addr != mt9m001->client->addr) | 322 | if (reg->match.addr != client->addr) |
321 | return -ENODEV; | 323 | return -ENODEV; |
322 | 324 | ||
323 | reg->size = 2; | 325 | reg->size = 2; |
324 | reg->val = reg_read(icd, reg->reg); | 326 | reg->val = reg_read(client, reg->reg); |
325 | 327 | ||
326 | if (reg->val > 0xffff) | 328 | if (reg->val > 0xffff) |
327 | return -EIO; | 329 | return -EIO; |
@@ -332,15 +334,15 @@ static int mt9m001_get_register(struct soc_camera_device *icd, | |||
332 | static int mt9m001_set_register(struct soc_camera_device *icd, | 334 | static int mt9m001_set_register(struct soc_camera_device *icd, |
333 | struct v4l2_dbg_register *reg) | 335 | struct v4l2_dbg_register *reg) |
334 | { | 336 | { |
335 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 337 | struct i2c_client *client = to_i2c_client(icd->control); |
336 | 338 | ||
337 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 339 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
338 | return -EINVAL; | 340 | return -EINVAL; |
339 | 341 | ||
340 | if (reg->match.addr != mt9m001->client->addr) | 342 | if (reg->match.addr != client->addr) |
341 | return -ENODEV; | 343 | return -ENODEV; |
342 | 344 | ||
343 | if (reg_write(icd, reg->reg, reg->val) < 0) | 345 | if (reg_write(client, reg->reg, reg->val) < 0) |
344 | return -EIO; | 346 | return -EIO; |
345 | 347 | ||
346 | return 0; | 348 | return 0; |
@@ -416,12 +418,13 @@ static struct soc_camera_ops mt9m001_ops = { | |||
416 | 418 | ||
417 | static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 419 | static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
418 | { | 420 | { |
421 | struct i2c_client *client = to_i2c_client(icd->control); | ||
419 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 422 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
420 | int data; | 423 | int data; |
421 | 424 | ||
422 | switch (ctrl->id) { | 425 | switch (ctrl->id) { |
423 | case V4L2_CID_VFLIP: | 426 | case V4L2_CID_VFLIP: |
424 | data = reg_read(icd, MT9M001_READ_OPTIONS2); | 427 | data = reg_read(client, MT9M001_READ_OPTIONS2); |
425 | if (data < 0) | 428 | if (data < 0) |
426 | return -EIO; | 429 | return -EIO; |
427 | ctrl->value = !!(data & 0x8000); | 430 | ctrl->value = !!(data & 0x8000); |
@@ -435,6 +438,7 @@ static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_contro | |||
435 | 438 | ||
436 | static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 439 | static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
437 | { | 440 | { |
441 | struct i2c_client *client = to_i2c_client(icd->control); | ||
438 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 442 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
439 | const struct v4l2_queryctrl *qctrl; | 443 | const struct v4l2_queryctrl *qctrl; |
440 | int data; | 444 | int data; |
@@ -447,9 +451,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
447 | switch (ctrl->id) { | 451 | switch (ctrl->id) { |
448 | case V4L2_CID_VFLIP: | 452 | case V4L2_CID_VFLIP: |
449 | if (ctrl->value) | 453 | if (ctrl->value) |
450 | data = reg_set(icd, MT9M001_READ_OPTIONS2, 0x8000); | 454 | data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000); |
451 | else | 455 | else |
452 | data = reg_clear(icd, MT9M001_READ_OPTIONS2, 0x8000); | 456 | data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000); |
453 | if (data < 0) | 457 | if (data < 0) |
454 | return -EIO; | 458 | return -EIO; |
455 | break; | 459 | break; |
@@ -463,7 +467,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
463 | data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; | 467 | data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; |
464 | 468 | ||
465 | dev_dbg(&icd->dev, "Setting gain %d\n", data); | 469 | dev_dbg(&icd->dev, "Setting gain %d\n", data); |
466 | data = reg_write(icd, MT9M001_GLOBAL_GAIN, data); | 470 | data = reg_write(client, MT9M001_GLOBAL_GAIN, data); |
467 | if (data < 0) | 471 | if (data < 0) |
468 | return -EIO; | 472 | return -EIO; |
469 | } else { | 473 | } else { |
@@ -481,8 +485,8 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
481 | data = ((gain - 64) * 7 + 28) / 56 + 96; | 485 | data = ((gain - 64) * 7 + 28) / 56 + 96; |
482 | 486 | ||
483 | dev_dbg(&icd->dev, "Setting gain from %d to %d\n", | 487 | dev_dbg(&icd->dev, "Setting gain from %d to %d\n", |
484 | reg_read(icd, MT9M001_GLOBAL_GAIN), data); | 488 | reg_read(client, MT9M001_GLOBAL_GAIN), data); |
485 | data = reg_write(icd, MT9M001_GLOBAL_GAIN, data); | 489 | data = reg_write(client, MT9M001_GLOBAL_GAIN, data); |
486 | if (data < 0) | 490 | if (data < 0) |
487 | return -EIO; | 491 | return -EIO; |
488 | } | 492 | } |
@@ -500,8 +504,8 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
500 | range / 2) / range + 1; | 504 | range / 2) / range + 1; |
501 | 505 | ||
502 | dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n", | 506 | dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n", |
503 | reg_read(icd, MT9M001_SHUTTER_WIDTH), shutter); | 507 | reg_read(client, MT9M001_SHUTTER_WIDTH), shutter); |
504 | if (reg_write(icd, MT9M001_SHUTTER_WIDTH, shutter) < 0) | 508 | if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0) |
505 | return -EIO; | 509 | return -EIO; |
506 | icd->exposure = ctrl->value; | 510 | icd->exposure = ctrl->value; |
507 | mt9m001->autoexposure = 0; | 511 | mt9m001->autoexposure = 0; |
@@ -510,7 +514,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
510 | case V4L2_CID_EXPOSURE_AUTO: | 514 | case V4L2_CID_EXPOSURE_AUTO: |
511 | if (ctrl->value) { | 515 | if (ctrl->value) { |
512 | const u16 vblank = 25; | 516 | const u16 vblank = 25; |
513 | if (reg_write(icd, MT9M001_SHUTTER_WIDTH, icd->height + | 517 | if (reg_write(client, MT9M001_SHUTTER_WIDTH, icd->height + |
514 | icd->y_skip_top + vblank) < 0) | 518 | icd->y_skip_top + vblank) < 0) |
515 | return -EIO; | 519 | return -EIO; |
516 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | 520 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); |
@@ -529,8 +533,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
529 | * this wasn't our capture interface, so, we wait for the right one */ | 533 | * this wasn't our capture interface, so, we wait for the right one */ |
530 | static int mt9m001_video_probe(struct soc_camera_device *icd) | 534 | static int mt9m001_video_probe(struct soc_camera_device *icd) |
531 | { | 535 | { |
536 | struct i2c_client *client = to_i2c_client(icd->control); | ||
532 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 537 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
533 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | 538 | struct soc_camera_link *icl = client->dev.platform_data; |
534 | s32 data; | 539 | s32 data; |
535 | int ret; | 540 | int ret; |
536 | unsigned long flags; | 541 | unsigned long flags; |
@@ -542,11 +547,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd) | |||
542 | return -ENODEV; | 547 | return -ENODEV; |
543 | 548 | ||
544 | /* Enable the chip */ | 549 | /* Enable the chip */ |
545 | data = reg_write(icd, MT9M001_CHIP_ENABLE, 1); | 550 | data = reg_write(client, MT9M001_CHIP_ENABLE, 1); |
546 | dev_dbg(&icd->dev, "write: %d\n", data); | 551 | dev_dbg(&icd->dev, "write: %d\n", data); |
547 | 552 | ||
548 | /* Read out the chip version register */ | 553 | /* Read out the chip version register */ |
549 | data = reg_read(icd, MT9M001_CHIP_VERSION); | 554 | data = reg_read(client, MT9M001_CHIP_VERSION); |
550 | 555 | ||
551 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ | 556 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ |
552 | switch (data) { | 557 | switch (data) { |
@@ -604,10 +609,13 @@ ei2c: | |||
604 | static void mt9m001_video_remove(struct soc_camera_device *icd) | 609 | static void mt9m001_video_remove(struct soc_camera_device *icd) |
605 | { | 610 | { |
606 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 611 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
612 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | ||
607 | 613 | ||
608 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, | 614 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, |
609 | icd->dev.parent, icd->vdev); | 615 | icd->dev.parent, icd->vdev); |
610 | soc_camera_video_stop(icd); | 616 | soc_camera_video_stop(icd); |
617 | if (icl->free_bus) | ||
618 | icl->free_bus(icl); | ||
611 | } | 619 | } |
612 | 620 | ||
613 | static int mt9m001_probe(struct i2c_client *client, | 621 | static int mt9m001_probe(struct i2c_client *client, |
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index cdd1ddb51388..fc5e2de03766 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
@@ -113,10 +113,10 @@ | |||
113 | * mt9m111: Camera control register addresses (0x200..0x2ff not implemented) | 113 | * mt9m111: Camera control register addresses (0x200..0x2ff not implemented) |
114 | */ | 114 | */ |
115 | 115 | ||
116 | #define reg_read(reg) mt9m111_reg_read(icd, MT9M111_##reg) | 116 | #define reg_read(reg) mt9m111_reg_read(client, MT9M111_##reg) |
117 | #define reg_write(reg, val) mt9m111_reg_write(icd, MT9M111_##reg, (val)) | 117 | #define reg_write(reg, val) mt9m111_reg_write(client, MT9M111_##reg, (val)) |
118 | #define reg_set(reg, val) mt9m111_reg_set(icd, MT9M111_##reg, (val)) | 118 | #define reg_set(reg, val) mt9m111_reg_set(client, MT9M111_##reg, (val)) |
119 | #define reg_clear(reg, val) mt9m111_reg_clear(icd, MT9M111_##reg, (val)) | 119 | #define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val)) |
120 | 120 | ||
121 | #define MT9M111_MIN_DARK_ROWS 8 | 121 | #define MT9M111_MIN_DARK_ROWS 8 |
122 | #define MT9M111_MIN_DARK_COLS 24 | 122 | #define MT9M111_MIN_DARK_COLS 24 |
@@ -184,58 +184,55 @@ static int reg_page_map_set(struct i2c_client *client, const u16 reg) | |||
184 | return ret; | 184 | return ret; |
185 | } | 185 | } |
186 | 186 | ||
187 | static int mt9m111_reg_read(struct soc_camera_device *icd, const u16 reg) | 187 | static int mt9m111_reg_read(struct i2c_client *client, const u16 reg) |
188 | { | 188 | { |
189 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | ||
190 | struct i2c_client *client = mt9m111->client; | ||
191 | int ret; | 189 | int ret; |
192 | 190 | ||
193 | ret = reg_page_map_set(client, reg); | 191 | ret = reg_page_map_set(client, reg); |
194 | if (!ret) | 192 | if (!ret) |
195 | ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); | 193 | ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); |
196 | 194 | ||
197 | dev_dbg(&icd->dev, "read reg.%03x -> %04x\n", reg, ret); | 195 | dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret); |
198 | return ret; | 196 | return ret; |
199 | } | 197 | } |
200 | 198 | ||
201 | static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg, | 199 | static int mt9m111_reg_write(struct i2c_client *client, const u16 reg, |
202 | const u16 data) | 200 | const u16 data) |
203 | { | 201 | { |
204 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | ||
205 | struct i2c_client *client = mt9m111->client; | ||
206 | int ret; | 202 | int ret; |
207 | 203 | ||
208 | ret = reg_page_map_set(client, reg); | 204 | ret = reg_page_map_set(client, reg); |
209 | if (!ret) | 205 | if (!ret) |
210 | ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff), | 206 | ret = i2c_smbus_write_word_data(client, (reg & 0xff), |
211 | swab16(data)); | 207 | swab16(data)); |
212 | dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); | 208 | dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); |
213 | return ret; | 209 | return ret; |
214 | } | 210 | } |
215 | 211 | ||
216 | static int mt9m111_reg_set(struct soc_camera_device *icd, const u16 reg, | 212 | static int mt9m111_reg_set(struct i2c_client *client, const u16 reg, |
217 | const u16 data) | 213 | const u16 data) |
218 | { | 214 | { |
219 | int ret; | 215 | int ret; |
220 | 216 | ||
221 | ret = mt9m111_reg_read(icd, reg); | 217 | ret = mt9m111_reg_read(client, reg); |
222 | if (ret >= 0) | 218 | if (ret >= 0) |
223 | ret = mt9m111_reg_write(icd, reg, ret | data); | 219 | ret = mt9m111_reg_write(client, reg, ret | data); |
224 | return ret; | 220 | return ret; |
225 | } | 221 | } |
226 | 222 | ||
227 | static int mt9m111_reg_clear(struct soc_camera_device *icd, const u16 reg, | 223 | static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg, |
228 | const u16 data) | 224 | const u16 data) |
229 | { | 225 | { |
230 | int ret; | 226 | int ret; |
231 | 227 | ||
232 | ret = mt9m111_reg_read(icd, reg); | 228 | ret = mt9m111_reg_read(client, reg); |
233 | return mt9m111_reg_write(icd, reg, ret & ~data); | 229 | return mt9m111_reg_write(client, reg, ret & ~data); |
234 | } | 230 | } |
235 | 231 | ||
236 | static int mt9m111_set_context(struct soc_camera_device *icd, | 232 | static int mt9m111_set_context(struct soc_camera_device *icd, |
237 | enum mt9m111_context ctxt) | 233 | enum mt9m111_context ctxt) |
238 | { | 234 | { |
235 | struct i2c_client *client = to_i2c_client(icd->control); | ||
239 | int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B | 236 | int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B |
240 | | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B | 237 | | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B |
241 | | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B | 238 | | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B |
@@ -252,6 +249,7 @@ static int mt9m111_set_context(struct soc_camera_device *icd, | |||
252 | static int mt9m111_setup_rect(struct soc_camera_device *icd, | 249 | static int mt9m111_setup_rect(struct soc_camera_device *icd, |
253 | struct v4l2_rect *rect) | 250 | struct v4l2_rect *rect) |
254 | { | 251 | { |
252 | struct i2c_client *client = to_i2c_client(icd->control); | ||
255 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 253 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
256 | int ret, is_raw_format; | 254 | int ret, is_raw_format; |
257 | int width = rect->width; | 255 | int width = rect->width; |
@@ -296,6 +294,7 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd, | |||
296 | 294 | ||
297 | static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) | 295 | static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) |
298 | { | 296 | { |
297 | struct i2c_client *client = to_i2c_client(icd->control); | ||
299 | int ret; | 298 | int ret; |
300 | 299 | ||
301 | ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); | 300 | ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); |
@@ -357,12 +356,13 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) | |||
357 | 356 | ||
358 | static int mt9m111_enable(struct soc_camera_device *icd) | 357 | static int mt9m111_enable(struct soc_camera_device *icd) |
359 | { | 358 | { |
359 | struct i2c_client *client = to_i2c_client(icd->control); | ||
360 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 360 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
361 | struct soc_camera_link *icl = mt9m111->client->dev.platform_data; | 361 | struct soc_camera_link *icl = client->dev.platform_data; |
362 | int ret; | 362 | int ret; |
363 | 363 | ||
364 | if (icl->power) { | 364 | if (icl->power) { |
365 | ret = icl->power(&mt9m111->client->dev, 1); | 365 | ret = icl->power(&client->dev, 1); |
366 | if (ret < 0) { | 366 | if (ret < 0) { |
367 | dev_err(icd->vdev->parent, | 367 | dev_err(icd->vdev->parent, |
368 | "Platform failed to power-on the camera.\n"); | 368 | "Platform failed to power-on the camera.\n"); |
@@ -378,8 +378,9 @@ static int mt9m111_enable(struct soc_camera_device *icd) | |||
378 | 378 | ||
379 | static int mt9m111_disable(struct soc_camera_device *icd) | 379 | static int mt9m111_disable(struct soc_camera_device *icd) |
380 | { | 380 | { |
381 | struct i2c_client *client = to_i2c_client(icd->control); | ||
381 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 382 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
382 | struct soc_camera_link *icl = mt9m111->client->dev.platform_data; | 383 | struct soc_camera_link *icl = client->dev.platform_data; |
383 | int ret; | 384 | int ret; |
384 | 385 | ||
385 | ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); | 386 | ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); |
@@ -387,15 +388,15 @@ static int mt9m111_disable(struct soc_camera_device *icd) | |||
387 | mt9m111->powered = 0; | 388 | mt9m111->powered = 0; |
388 | 389 | ||
389 | if (icl->power) | 390 | if (icl->power) |
390 | icl->power(&mt9m111->client->dev, 0); | 391 | icl->power(&client->dev, 0); |
391 | 392 | ||
392 | return ret; | 393 | return ret; |
393 | } | 394 | } |
394 | 395 | ||
395 | static int mt9m111_reset(struct soc_camera_device *icd) | 396 | static int mt9m111_reset(struct soc_camera_device *icd) |
396 | { | 397 | { |
397 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 398 | struct i2c_client *client = to_i2c_client(icd->control); |
398 | struct soc_camera_link *icl = mt9m111->client->dev.platform_data; | 399 | struct soc_camera_link *icl = client->dev.platform_data; |
399 | int ret; | 400 | int ret; |
400 | 401 | ||
401 | ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); | 402 | ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); |
@@ -406,7 +407,7 @@ static int mt9m111_reset(struct soc_camera_device *icd) | |||
406 | | MT9M111_RESET_RESET_SOC); | 407 | | MT9M111_RESET_RESET_SOC); |
407 | 408 | ||
408 | if (icl->reset) | 409 | if (icl->reset) |
409 | icl->reset(&mt9m111->client->dev); | 410 | icl->reset(&client->dev); |
410 | 411 | ||
411 | return ret; | 412 | return ret; |
412 | } | 413 | } |
@@ -562,15 +563,14 @@ static int mt9m111_get_register(struct soc_camera_device *icd, | |||
562 | struct v4l2_dbg_register *reg) | 563 | struct v4l2_dbg_register *reg) |
563 | { | 564 | { |
564 | int val; | 565 | int val; |
565 | 566 | struct i2c_client *client = to_i2c_client(icd->control); | |
566 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | ||
567 | 567 | ||
568 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) | 568 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) |
569 | return -EINVAL; | 569 | return -EINVAL; |
570 | if (reg->match.addr != mt9m111->client->addr) | 570 | if (reg->match.addr != client->addr) |
571 | return -ENODEV; | 571 | return -ENODEV; |
572 | 572 | ||
573 | val = mt9m111_reg_read(icd, reg->reg); | 573 | val = mt9m111_reg_read(client, reg->reg); |
574 | reg->size = 2; | 574 | reg->size = 2; |
575 | reg->val = (u64)val; | 575 | reg->val = (u64)val; |
576 | 576 | ||
@@ -583,15 +583,15 @@ static int mt9m111_get_register(struct soc_camera_device *icd, | |||
583 | static int mt9m111_set_register(struct soc_camera_device *icd, | 583 | static int mt9m111_set_register(struct soc_camera_device *icd, |
584 | struct v4l2_dbg_register *reg) | 584 | struct v4l2_dbg_register *reg) |
585 | { | 585 | { |
586 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 586 | struct i2c_client *client = to_i2c_client(icd->control); |
587 | 587 | ||
588 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) | 588 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) |
589 | return -EINVAL; | 589 | return -EINVAL; |
590 | 590 | ||
591 | if (reg->match.addr != mt9m111->client->addr) | 591 | if (reg->match.addr != client->addr) |
592 | return -ENODEV; | 592 | return -ENODEV; |
593 | 593 | ||
594 | if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0) | 594 | if (mt9m111_reg_write(client, reg->reg, reg->val) < 0) |
595 | return -EIO; | 595 | return -EIO; |
596 | 596 | ||
597 | return 0; | 597 | return 0; |
@@ -672,6 +672,7 @@ static struct soc_camera_ops mt9m111_ops = { | |||
672 | 672 | ||
673 | static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) | 673 | static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) |
674 | { | 674 | { |
675 | struct i2c_client *client = to_i2c_client(icd->control); | ||
675 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 676 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
676 | int ret; | 677 | int ret; |
677 | 678 | ||
@@ -692,6 +693,7 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) | |||
692 | 693 | ||
693 | static int mt9m111_get_global_gain(struct soc_camera_device *icd) | 694 | static int mt9m111_get_global_gain(struct soc_camera_device *icd) |
694 | { | 695 | { |
696 | struct i2c_client *client = to_i2c_client(icd->control); | ||
695 | int data; | 697 | int data; |
696 | 698 | ||
697 | data = reg_read(GLOBAL_GAIN); | 699 | data = reg_read(GLOBAL_GAIN); |
@@ -703,6 +705,7 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd) | |||
703 | 705 | ||
704 | static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) | 706 | static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) |
705 | { | 707 | { |
708 | struct i2c_client *client = to_i2c_client(icd->control); | ||
706 | u16 val; | 709 | u16 val; |
707 | 710 | ||
708 | if (gain > 63 * 2 * 2) | 711 | if (gain > 63 * 2 * 2) |
@@ -721,6 +724,7 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) | |||
721 | 724 | ||
722 | static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) | 725 | static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) |
723 | { | 726 | { |
727 | struct i2c_client *client = to_i2c_client(icd->control); | ||
724 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 728 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
725 | int ret; | 729 | int ret; |
726 | 730 | ||
@@ -737,6 +741,7 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) | |||
737 | 741 | ||
738 | static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) | 742 | static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) |
739 | { | 743 | { |
744 | struct i2c_client *client = to_i2c_client(icd->control); | ||
740 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 745 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
741 | int ret; | 746 | int ret; |
742 | 747 | ||
@@ -754,6 +759,7 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) | |||
754 | static int mt9m111_get_control(struct soc_camera_device *icd, | 759 | static int mt9m111_get_control(struct soc_camera_device *icd, |
755 | struct v4l2_control *ctrl) | 760 | struct v4l2_control *ctrl) |
756 | { | 761 | { |
762 | struct i2c_client *client = to_i2c_client(icd->control); | ||
757 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 763 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
758 | int data; | 764 | int data; |
759 | 765 | ||
@@ -898,6 +904,7 @@ static int mt9m111_release(struct soc_camera_device *icd) | |||
898 | */ | 904 | */ |
899 | static int mt9m111_video_probe(struct soc_camera_device *icd) | 905 | static int mt9m111_video_probe(struct soc_camera_device *icd) |
900 | { | 906 | { |
907 | struct i2c_client *client = to_i2c_client(icd->control); | ||
901 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); | 908 | struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); |
902 | s32 data; | 909 | s32 data; |
903 | int ret; | 910 | int ret; |
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 2b0927bfd217..f72aeb7c4deb 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
@@ -76,64 +76,61 @@ struct mt9t031 { | |||
76 | u16 yskip; | 76 | u16 yskip; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static int reg_read(struct soc_camera_device *icd, const u8 reg) | 79 | static int reg_read(struct i2c_client *client, const u8 reg) |
80 | { | 80 | { |
81 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | ||
82 | struct i2c_client *client = mt9t031->client; | ||
83 | s32 data = i2c_smbus_read_word_data(client, reg); | 81 | s32 data = i2c_smbus_read_word_data(client, reg); |
84 | return data < 0 ? data : swab16(data); | 82 | return data < 0 ? data : swab16(data); |
85 | } | 83 | } |
86 | 84 | ||
87 | static int reg_write(struct soc_camera_device *icd, const u8 reg, | 85 | static int reg_write(struct i2c_client *client, const u8 reg, |
88 | const u16 data) | 86 | const u16 data) |
89 | { | 87 | { |
90 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 88 | return i2c_smbus_write_word_data(client, reg, swab16(data)); |
91 | return i2c_smbus_write_word_data(mt9t031->client, reg, swab16(data)); | ||
92 | } | 89 | } |
93 | 90 | ||
94 | static int reg_set(struct soc_camera_device *icd, const u8 reg, | 91 | static int reg_set(struct i2c_client *client, const u8 reg, |
95 | const u16 data) | 92 | const u16 data) |
96 | { | 93 | { |
97 | int ret; | 94 | int ret; |
98 | 95 | ||
99 | ret = reg_read(icd, reg); | 96 | ret = reg_read(client, reg); |
100 | if (ret < 0) | 97 | if (ret < 0) |
101 | return ret; | 98 | return ret; |
102 | return reg_write(icd, reg, ret | data); | 99 | return reg_write(client, reg, ret | data); |
103 | } | 100 | } |
104 | 101 | ||
105 | static int reg_clear(struct soc_camera_device *icd, const u8 reg, | 102 | static int reg_clear(struct i2c_client *client, const u8 reg, |
106 | const u16 data) | 103 | const u16 data) |
107 | { | 104 | { |
108 | int ret; | 105 | int ret; |
109 | 106 | ||
110 | ret = reg_read(icd, reg); | 107 | ret = reg_read(client, reg); |
111 | if (ret < 0) | 108 | if (ret < 0) |
112 | return ret; | 109 | return ret; |
113 | return reg_write(icd, reg, ret & ~data); | 110 | return reg_write(client, reg, ret & ~data); |
114 | } | 111 | } |
115 | 112 | ||
116 | static int set_shutter(struct soc_camera_device *icd, const u32 data) | 113 | static int set_shutter(struct i2c_client *client, const u32 data) |
117 | { | 114 | { |
118 | int ret; | 115 | int ret; |
119 | 116 | ||
120 | ret = reg_write(icd, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16); | 117 | ret = reg_write(client, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16); |
121 | 118 | ||
122 | if (ret >= 0) | 119 | if (ret >= 0) |
123 | ret = reg_write(icd, MT9T031_SHUTTER_WIDTH, data & 0xffff); | 120 | ret = reg_write(client, MT9T031_SHUTTER_WIDTH, data & 0xffff); |
124 | 121 | ||
125 | return ret; | 122 | return ret; |
126 | } | 123 | } |
127 | 124 | ||
128 | static int get_shutter(struct soc_camera_device *icd, u32 *data) | 125 | static int get_shutter(struct i2c_client *client, u32 *data) |
129 | { | 126 | { |
130 | int ret; | 127 | int ret; |
131 | 128 | ||
132 | ret = reg_read(icd, MT9T031_SHUTTER_WIDTH_UPPER); | 129 | ret = reg_read(client, MT9T031_SHUTTER_WIDTH_UPPER); |
133 | *data = ret << 16; | 130 | *data = ret << 16; |
134 | 131 | ||
135 | if (ret >= 0) | 132 | if (ret >= 0) |
136 | ret = reg_read(icd, MT9T031_SHUTTER_WIDTH); | 133 | ret = reg_read(client, MT9T031_SHUTTER_WIDTH); |
137 | *data |= ret & 0xffff; | 134 | *data |= ret & 0xffff; |
138 | 135 | ||
139 | return ret < 0 ? ret : 0; | 136 | return ret < 0 ? ret : 0; |
@@ -141,12 +138,12 @@ static int get_shutter(struct soc_camera_device *icd, u32 *data) | |||
141 | 138 | ||
142 | static int mt9t031_init(struct soc_camera_device *icd) | 139 | static int mt9t031_init(struct soc_camera_device *icd) |
143 | { | 140 | { |
144 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 141 | struct i2c_client *client = to_i2c_client(icd->control); |
145 | struct soc_camera_link *icl = mt9t031->client->dev.platform_data; | 142 | struct soc_camera_link *icl = client->dev.platform_data; |
146 | int ret; | 143 | int ret; |
147 | 144 | ||
148 | if (icl->power) { | 145 | if (icl->power) { |
149 | ret = icl->power(&mt9t031->client->dev, 1); | 146 | ret = icl->power(&client->dev, 1); |
150 | if (ret < 0) { | 147 | if (ret < 0) { |
151 | dev_err(icd->vdev->parent, | 148 | dev_err(icd->vdev->parent, |
152 | "Platform failed to power-on the camera.\n"); | 149 | "Platform failed to power-on the camera.\n"); |
@@ -155,44 +152,48 @@ static int mt9t031_init(struct soc_camera_device *icd) | |||
155 | } | 152 | } |
156 | 153 | ||
157 | /* Disable chip output, synchronous option update */ | 154 | /* Disable chip output, synchronous option update */ |
158 | ret = reg_write(icd, MT9T031_RESET, 1); | 155 | ret = reg_write(client, MT9T031_RESET, 1); |
159 | if (ret >= 0) | 156 | if (ret >= 0) |
160 | ret = reg_write(icd, MT9T031_RESET, 0); | 157 | ret = reg_write(client, MT9T031_RESET, 0); |
161 | if (ret >= 0) | 158 | if (ret >= 0) |
162 | ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2); | 159 | ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); |
163 | 160 | ||
164 | if (ret < 0 && icl->power) | 161 | if (ret < 0 && icl->power) |
165 | icl->power(&mt9t031->client->dev, 0); | 162 | icl->power(&client->dev, 0); |
166 | 163 | ||
167 | return ret >= 0 ? 0 : -EIO; | 164 | return ret >= 0 ? 0 : -EIO; |
168 | } | 165 | } |
169 | 166 | ||
170 | static int mt9t031_release(struct soc_camera_device *icd) | 167 | static int mt9t031_release(struct soc_camera_device *icd) |
171 | { | 168 | { |
172 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 169 | struct i2c_client *client = to_i2c_client(icd->control); |
173 | struct soc_camera_link *icl = mt9t031->client->dev.platform_data; | 170 | struct soc_camera_link *icl = client->dev.platform_data; |
174 | 171 | ||
175 | /* Disable the chip */ | 172 | /* Disable the chip */ |
176 | reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2); | 173 | reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); |
177 | 174 | ||
178 | if (icl->power) | 175 | if (icl->power) |
179 | icl->power(&mt9t031->client->dev, 0); | 176 | icl->power(&client->dev, 0); |
180 | 177 | ||
181 | return 0; | 178 | return 0; |
182 | } | 179 | } |
183 | 180 | ||
184 | static int mt9t031_start_capture(struct soc_camera_device *icd) | 181 | static int mt9t031_start_capture(struct soc_camera_device *icd) |
185 | { | 182 | { |
183 | struct i2c_client *client = to_i2c_client(icd->control); | ||
184 | |||
186 | /* Switch to master "normal" mode */ | 185 | /* Switch to master "normal" mode */ |
187 | if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 2) < 0) | 186 | if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0) |
188 | return -EIO; | 187 | return -EIO; |
189 | return 0; | 188 | return 0; |
190 | } | 189 | } |
191 | 190 | ||
192 | static int mt9t031_stop_capture(struct soc_camera_device *icd) | 191 | static int mt9t031_stop_capture(struct soc_camera_device *icd) |
193 | { | 192 | { |
193 | struct i2c_client *client = to_i2c_client(icd->control); | ||
194 | |||
194 | /* Stop sensor readout */ | 195 | /* Stop sensor readout */ |
195 | if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2) < 0) | 196 | if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0) |
196 | return -EIO; | 197 | return -EIO; |
197 | return 0; | 198 | return 0; |
198 | } | 199 | } |
@@ -200,14 +201,16 @@ static int mt9t031_stop_capture(struct soc_camera_device *icd) | |||
200 | static int mt9t031_set_bus_param(struct soc_camera_device *icd, | 201 | static int mt9t031_set_bus_param(struct soc_camera_device *icd, |
201 | unsigned long flags) | 202 | unsigned long flags) |
202 | { | 203 | { |
204 | struct i2c_client *client = to_i2c_client(icd->control); | ||
205 | |||
203 | /* The caller should have queried our parameters, check anyway */ | 206 | /* The caller should have queried our parameters, check anyway */ |
204 | if (flags & ~MT9T031_BUS_PARAM) | 207 | if (flags & ~MT9T031_BUS_PARAM) |
205 | return -EINVAL; | 208 | return -EINVAL; |
206 | 209 | ||
207 | if (flags & SOCAM_PCLK_SAMPLE_FALLING) | 210 | if (flags & SOCAM_PCLK_SAMPLE_FALLING) |
208 | reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); | 211 | reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); |
209 | else | 212 | else |
210 | reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); | 213 | reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); |
211 | 214 | ||
212 | return 0; | 215 | return 0; |
213 | } | 216 | } |
@@ -235,6 +238,7 @@ static void recalculate_limits(struct soc_camera_device *icd, | |||
235 | static int mt9t031_set_params(struct soc_camera_device *icd, | 238 | static int mt9t031_set_params(struct soc_camera_device *icd, |
236 | struct v4l2_rect *rect, u16 xskip, u16 yskip) | 239 | struct v4l2_rect *rect, u16 xskip, u16 yskip) |
237 | { | 240 | { |
241 | struct i2c_client *client = to_i2c_client(icd->control); | ||
238 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 242 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
239 | int ret; | 243 | int ret; |
240 | u16 xbin, ybin, width, height, left, top; | 244 | u16 xbin, ybin, width, height, left, top; |
@@ -277,22 +281,22 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
277 | } | 281 | } |
278 | 282 | ||
279 | /* Disable register update, reconfigure atomically */ | 283 | /* Disable register update, reconfigure atomically */ |
280 | ret = reg_set(icd, MT9T031_OUTPUT_CONTROL, 1); | 284 | ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1); |
281 | if (ret < 0) | 285 | if (ret < 0) |
282 | return ret; | 286 | return ret; |
283 | 287 | ||
284 | /* Blanking and start values - default... */ | 288 | /* Blanking and start values - default... */ |
285 | ret = reg_write(icd, MT9T031_HORIZONTAL_BLANKING, hblank); | 289 | ret = reg_write(client, MT9T031_HORIZONTAL_BLANKING, hblank); |
286 | if (ret >= 0) | 290 | if (ret >= 0) |
287 | ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank); | 291 | ret = reg_write(client, MT9T031_VERTICAL_BLANKING, vblank); |
288 | 292 | ||
289 | if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) { | 293 | if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) { |
290 | /* Binning, skipping */ | 294 | /* Binning, skipping */ |
291 | if (ret >= 0) | 295 | if (ret >= 0) |
292 | ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE, | 296 | ret = reg_write(client, MT9T031_COLUMN_ADDRESS_MODE, |
293 | ((xbin - 1) << 4) | (xskip - 1)); | 297 | ((xbin - 1) << 4) | (xskip - 1)); |
294 | if (ret >= 0) | 298 | if (ret >= 0) |
295 | ret = reg_write(icd, MT9T031_ROW_ADDRESS_MODE, | 299 | ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE, |
296 | ((ybin - 1) << 4) | (yskip - 1)); | 300 | ((ybin - 1) << 4) | (yskip - 1)); |
297 | } | 301 | } |
298 | dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top); | 302 | dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top); |
@@ -300,16 +304,16 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
300 | /* The caller provides a supported format, as guaranteed by | 304 | /* The caller provides a supported format, as guaranteed by |
301 | * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ | 305 | * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ |
302 | if (ret >= 0) | 306 | if (ret >= 0) |
303 | ret = reg_write(icd, MT9T031_COLUMN_START, left); | 307 | ret = reg_write(client, MT9T031_COLUMN_START, left); |
304 | if (ret >= 0) | 308 | if (ret >= 0) |
305 | ret = reg_write(icd, MT9T031_ROW_START, top); | 309 | ret = reg_write(client, MT9T031_ROW_START, top); |
306 | if (ret >= 0) | 310 | if (ret >= 0) |
307 | ret = reg_write(icd, MT9T031_WINDOW_WIDTH, width - 1); | 311 | ret = reg_write(client, MT9T031_WINDOW_WIDTH, width - 1); |
308 | if (ret >= 0) | 312 | if (ret >= 0) |
309 | ret = reg_write(icd, MT9T031_WINDOW_HEIGHT, | 313 | ret = reg_write(client, MT9T031_WINDOW_HEIGHT, |
310 | height + icd->y_skip_top - 1); | 314 | height + icd->y_skip_top - 1); |
311 | if (ret >= 0 && mt9t031->autoexposure) { | 315 | if (ret >= 0 && mt9t031->autoexposure) { |
312 | ret = set_shutter(icd, height + icd->y_skip_top + vblank); | 316 | ret = set_shutter(client, height + icd->y_skip_top + vblank); |
313 | if (ret >= 0) { | 317 | if (ret >= 0) { |
314 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 318 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
315 | const struct v4l2_queryctrl *qctrl = | 319 | const struct v4l2_queryctrl *qctrl = |
@@ -324,7 +328,7 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
324 | 328 | ||
325 | /* Re-enable register update, commit all changes */ | 329 | /* Re-enable register update, commit all changes */ |
326 | if (ret >= 0) | 330 | if (ret >= 0) |
327 | ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1); | 331 | ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1); |
328 | 332 | ||
329 | return ret < 0 ? ret : 0; | 333 | return ret < 0 ? ret : 0; |
330 | } | 334 | } |
@@ -417,15 +421,15 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd, | |||
417 | static int mt9t031_get_register(struct soc_camera_device *icd, | 421 | static int mt9t031_get_register(struct soc_camera_device *icd, |
418 | struct v4l2_dbg_register *reg) | 422 | struct v4l2_dbg_register *reg) |
419 | { | 423 | { |
420 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 424 | struct i2c_client *client = to_i2c_client(icd->control); |
421 | 425 | ||
422 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 426 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
423 | return -EINVAL; | 427 | return -EINVAL; |
424 | 428 | ||
425 | if (reg->match.addr != mt9t031->client->addr) | 429 | if (reg->match.addr != client->addr) |
426 | return -ENODEV; | 430 | return -ENODEV; |
427 | 431 | ||
428 | reg->val = reg_read(icd, reg->reg); | 432 | reg->val = reg_read(client, reg->reg); |
429 | 433 | ||
430 | if (reg->val > 0xffff) | 434 | if (reg->val > 0xffff) |
431 | return -EIO; | 435 | return -EIO; |
@@ -436,15 +440,15 @@ static int mt9t031_get_register(struct soc_camera_device *icd, | |||
436 | static int mt9t031_set_register(struct soc_camera_device *icd, | 440 | static int mt9t031_set_register(struct soc_camera_device *icd, |
437 | struct v4l2_dbg_register *reg) | 441 | struct v4l2_dbg_register *reg) |
438 | { | 442 | { |
439 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 443 | struct i2c_client *client = to_i2c_client(icd->control); |
440 | 444 | ||
441 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 445 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
442 | return -EINVAL; | 446 | return -EINVAL; |
443 | 447 | ||
444 | if (reg->match.addr != mt9t031->client->addr) | 448 | if (reg->match.addr != client->addr) |
445 | return -ENODEV; | 449 | return -ENODEV; |
446 | 450 | ||
447 | if (reg_write(icd, reg->reg, reg->val) < 0) | 451 | if (reg_write(client, reg->reg, reg->val) < 0) |
448 | return -EIO; | 452 | return -EIO; |
449 | 453 | ||
450 | return 0; | 454 | return 0; |
@@ -528,18 +532,19 @@ static struct soc_camera_ops mt9t031_ops = { | |||
528 | 532 | ||
529 | static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 533 | static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
530 | { | 534 | { |
535 | struct i2c_client *client = to_i2c_client(icd->control); | ||
531 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 536 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
532 | int data; | 537 | int data; |
533 | 538 | ||
534 | switch (ctrl->id) { | 539 | switch (ctrl->id) { |
535 | case V4L2_CID_VFLIP: | 540 | case V4L2_CID_VFLIP: |
536 | data = reg_read(icd, MT9T031_READ_MODE_2); | 541 | data = reg_read(client, MT9T031_READ_MODE_2); |
537 | if (data < 0) | 542 | if (data < 0) |
538 | return -EIO; | 543 | return -EIO; |
539 | ctrl->value = !!(data & 0x8000); | 544 | ctrl->value = !!(data & 0x8000); |
540 | break; | 545 | break; |
541 | case V4L2_CID_HFLIP: | 546 | case V4L2_CID_HFLIP: |
542 | data = reg_read(icd, MT9T031_READ_MODE_2); | 547 | data = reg_read(client, MT9T031_READ_MODE_2); |
543 | if (data < 0) | 548 | if (data < 0) |
544 | return -EIO; | 549 | return -EIO; |
545 | ctrl->value = !!(data & 0x4000); | 550 | ctrl->value = !!(data & 0x4000); |
@@ -553,6 +558,7 @@ static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_contro | |||
553 | 558 | ||
554 | static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 559 | static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
555 | { | 560 | { |
561 | struct i2c_client *client = to_i2c_client(icd->control); | ||
556 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 562 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
557 | const struct v4l2_queryctrl *qctrl; | 563 | const struct v4l2_queryctrl *qctrl; |
558 | int data; | 564 | int data; |
@@ -565,17 +571,17 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
565 | switch (ctrl->id) { | 571 | switch (ctrl->id) { |
566 | case V4L2_CID_VFLIP: | 572 | case V4L2_CID_VFLIP: |
567 | if (ctrl->value) | 573 | if (ctrl->value) |
568 | data = reg_set(icd, MT9T031_READ_MODE_2, 0x8000); | 574 | data = reg_set(client, MT9T031_READ_MODE_2, 0x8000); |
569 | else | 575 | else |
570 | data = reg_clear(icd, MT9T031_READ_MODE_2, 0x8000); | 576 | data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000); |
571 | if (data < 0) | 577 | if (data < 0) |
572 | return -EIO; | 578 | return -EIO; |
573 | break; | 579 | break; |
574 | case V4L2_CID_HFLIP: | 580 | case V4L2_CID_HFLIP: |
575 | if (ctrl->value) | 581 | if (ctrl->value) |
576 | data = reg_set(icd, MT9T031_READ_MODE_2, 0x4000); | 582 | data = reg_set(client, MT9T031_READ_MODE_2, 0x4000); |
577 | else | 583 | else |
578 | data = reg_clear(icd, MT9T031_READ_MODE_2, 0x4000); | 584 | data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000); |
579 | if (data < 0) | 585 | if (data < 0) |
580 | return -EIO; | 586 | return -EIO; |
581 | break; | 587 | break; |
@@ -589,7 +595,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
589 | data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; | 595 | data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; |
590 | 596 | ||
591 | dev_dbg(&icd->dev, "Setting gain %d\n", data); | 597 | dev_dbg(&icd->dev, "Setting gain %d\n", data); |
592 | data = reg_write(icd, MT9T031_GLOBAL_GAIN, data); | 598 | data = reg_write(client, MT9T031_GLOBAL_GAIN, data); |
593 | if (data < 0) | 599 | if (data < 0) |
594 | return -EIO; | 600 | return -EIO; |
595 | } else { | 601 | } else { |
@@ -609,8 +615,8 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
609 | data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60; | 615 | data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60; |
610 | 616 | ||
611 | dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n", | 617 | dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n", |
612 | reg_read(icd, MT9T031_GLOBAL_GAIN), data); | 618 | reg_read(client, MT9T031_GLOBAL_GAIN), data); |
613 | data = reg_write(icd, MT9T031_GLOBAL_GAIN, data); | 619 | data = reg_write(client, MT9T031_GLOBAL_GAIN, data); |
614 | if (data < 0) | 620 | if (data < 0) |
615 | return -EIO; | 621 | return -EIO; |
616 | } | 622 | } |
@@ -628,10 +634,10 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
628 | range / 2) / range + 1; | 634 | range / 2) / range + 1; |
629 | u32 old; | 635 | u32 old; |
630 | 636 | ||
631 | get_shutter(icd, &old); | 637 | get_shutter(client, &old); |
632 | dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n", | 638 | dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n", |
633 | old, shutter); | 639 | old, shutter); |
634 | if (set_shutter(icd, shutter) < 0) | 640 | if (set_shutter(client, shutter) < 0) |
635 | return -EIO; | 641 | return -EIO; |
636 | icd->exposure = ctrl->value; | 642 | icd->exposure = ctrl->value; |
637 | mt9t031->autoexposure = 0; | 643 | mt9t031->autoexposure = 0; |
@@ -641,7 +647,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
641 | if (ctrl->value) { | 647 | if (ctrl->value) { |
642 | const u16 vblank = MT9T031_VERTICAL_BLANK; | 648 | const u16 vblank = MT9T031_VERTICAL_BLANK; |
643 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 649 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
644 | if (set_shutter(icd, icd->height + | 650 | if (set_shutter(client, icd->height + |
645 | icd->y_skip_top + vblank) < 0) | 651 | icd->y_skip_top + vblank) < 0) |
646 | return -EIO; | 652 | return -EIO; |
647 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | 653 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); |
@@ -661,6 +667,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
661 | * this wasn't our capture interface, so, we wait for the right one */ | 667 | * this wasn't our capture interface, so, we wait for the right one */ |
662 | static int mt9t031_video_probe(struct soc_camera_device *icd) | 668 | static int mt9t031_video_probe(struct soc_camera_device *icd) |
663 | { | 669 | { |
670 | struct i2c_client *client = to_i2c_client(icd->control); | ||
664 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 671 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); |
665 | s32 data; | 672 | s32 data; |
666 | int ret; | 673 | int ret; |
@@ -672,11 +679,11 @@ static int mt9t031_video_probe(struct soc_camera_device *icd) | |||
672 | return -ENODEV; | 679 | return -ENODEV; |
673 | 680 | ||
674 | /* Enable the chip */ | 681 | /* Enable the chip */ |
675 | data = reg_write(icd, MT9T031_CHIP_ENABLE, 1); | 682 | data = reg_write(client, MT9T031_CHIP_ENABLE, 1); |
676 | dev_dbg(&icd->dev, "write: %d\n", data); | 683 | dev_dbg(&icd->dev, "write: %d\n", data); |
677 | 684 | ||
678 | /* Read out the chip version register */ | 685 | /* Read out the chip version register */ |
679 | data = reg_read(icd, MT9T031_CHIP_VERSION); | 686 | data = reg_read(client, MT9T031_CHIP_VERSION); |
680 | 687 | ||
681 | switch (data) { | 688 | switch (data) { |
682 | case 0x1621: | 689 | case 0x1621: |
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 4d3b4813c322..be20d312b1dc 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
@@ -91,51 +91,49 @@ struct mt9v022 { | |||
91 | u16 chip_control; | 91 | u16 chip_control; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static int reg_read(struct soc_camera_device *icd, const u8 reg) | 94 | static int reg_read(struct i2c_client *client, const u8 reg) |
95 | { | 95 | { |
96 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
97 | struct i2c_client *client = mt9v022->client; | ||
98 | s32 data = i2c_smbus_read_word_data(client, reg); | 96 | s32 data = i2c_smbus_read_word_data(client, reg); |
99 | return data < 0 ? data : swab16(data); | 97 | return data < 0 ? data : swab16(data); |
100 | } | 98 | } |
101 | 99 | ||
102 | static int reg_write(struct soc_camera_device *icd, const u8 reg, | 100 | static int reg_write(struct i2c_client *client, const u8 reg, |
103 | const u16 data) | 101 | const u16 data) |
104 | { | 102 | { |
105 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 103 | return i2c_smbus_write_word_data(client, reg, swab16(data)); |
106 | return i2c_smbus_write_word_data(mt9v022->client, reg, swab16(data)); | ||
107 | } | 104 | } |
108 | 105 | ||
109 | static int reg_set(struct soc_camera_device *icd, const u8 reg, | 106 | static int reg_set(struct i2c_client *client, const u8 reg, |
110 | const u16 data) | 107 | const u16 data) |
111 | { | 108 | { |
112 | int ret; | 109 | int ret; |
113 | 110 | ||
114 | ret = reg_read(icd, reg); | 111 | ret = reg_read(client, reg); |
115 | if (ret < 0) | 112 | if (ret < 0) |
116 | return ret; | 113 | return ret; |
117 | return reg_write(icd, reg, ret | data); | 114 | return reg_write(client, reg, ret | data); |
118 | } | 115 | } |
119 | 116 | ||
120 | static int reg_clear(struct soc_camera_device *icd, const u8 reg, | 117 | static int reg_clear(struct i2c_client *client, const u8 reg, |
121 | const u16 data) | 118 | const u16 data) |
122 | { | 119 | { |
123 | int ret; | 120 | int ret; |
124 | 121 | ||
125 | ret = reg_read(icd, reg); | 122 | ret = reg_read(client, reg); |
126 | if (ret < 0) | 123 | if (ret < 0) |
127 | return ret; | 124 | return ret; |
128 | return reg_write(icd, reg, ret & ~data); | 125 | return reg_write(client, reg, ret & ~data); |
129 | } | 126 | } |
130 | 127 | ||
131 | static int mt9v022_init(struct soc_camera_device *icd) | 128 | static int mt9v022_init(struct soc_camera_device *icd) |
132 | { | 129 | { |
130 | struct i2c_client *client = to_i2c_client(icd->control); | ||
133 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 131 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
134 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | 132 | struct soc_camera_link *icl = client->dev.platform_data; |
135 | int ret; | 133 | int ret; |
136 | 134 | ||
137 | if (icl->power) { | 135 | if (icl->power) { |
138 | ret = icl->power(&mt9v022->client->dev, 1); | 136 | ret = icl->power(&client->dev, 1); |
139 | if (ret < 0) { | 137 | if (ret < 0) { |
140 | dev_err(icd->vdev->parent, | 138 | dev_err(icd->vdev->parent, |
141 | "Platform failed to power-on the camera.\n"); | 139 | "Platform failed to power-on the camera.\n"); |
@@ -148,27 +146,27 @@ static int mt9v022_init(struct soc_camera_device *icd) | |||
148 | * if available. Soft reset is done in video_probe(). | 146 | * if available. Soft reset is done in video_probe(). |
149 | */ | 147 | */ |
150 | if (icl->reset) | 148 | if (icl->reset) |
151 | icl->reset(&mt9v022->client->dev); | 149 | icl->reset(&client->dev); |
152 | 150 | ||
153 | /* Almost the default mode: master, parallel, simultaneous, and an | 151 | /* Almost the default mode: master, parallel, simultaneous, and an |
154 | * undocumented bit 0x200, which is present in table 7, but not in 8, | 152 | * undocumented bit 0x200, which is present in table 7, but not in 8, |
155 | * plus snapshot mode to disable scan for now */ | 153 | * plus snapshot mode to disable scan for now */ |
156 | mt9v022->chip_control |= 0x10; | 154 | mt9v022->chip_control |= 0x10; |
157 | ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); | 155 | ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); |
158 | if (!ret) | 156 | if (!ret) |
159 | ret = reg_write(icd, MT9V022_READ_MODE, 0x300); | 157 | ret = reg_write(client, MT9V022_READ_MODE, 0x300); |
160 | 158 | ||
161 | /* All defaults */ | 159 | /* All defaults */ |
162 | if (!ret) | 160 | if (!ret) |
163 | /* AEC, AGC on */ | 161 | /* AEC, AGC on */ |
164 | ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3); | 162 | ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3); |
165 | if (!ret) | 163 | if (!ret) |
166 | ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); | 164 | ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); |
167 | if (!ret) | 165 | if (!ret) |
168 | /* default - auto */ | 166 | /* default - auto */ |
169 | ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); | 167 | ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); |
170 | if (!ret) | 168 | if (!ret) |
171 | ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0); | 169 | ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0); |
172 | 170 | ||
173 | return ret; | 171 | return ret; |
174 | } | 172 | } |
@@ -186,10 +184,11 @@ static int mt9v022_release(struct soc_camera_device *icd) | |||
186 | 184 | ||
187 | static int mt9v022_start_capture(struct soc_camera_device *icd) | 185 | static int mt9v022_start_capture(struct soc_camera_device *icd) |
188 | { | 186 | { |
187 | struct i2c_client *client = to_i2c_client(icd->control); | ||
189 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 188 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
190 | /* Switch to master "normal" mode */ | 189 | /* Switch to master "normal" mode */ |
191 | mt9v022->chip_control &= ~0x10; | 190 | mt9v022->chip_control &= ~0x10; |
192 | if (reg_write(icd, MT9V022_CHIP_CONTROL, | 191 | if (reg_write(client, MT9V022_CHIP_CONTROL, |
193 | mt9v022->chip_control) < 0) | 192 | mt9v022->chip_control) < 0) |
194 | return -EIO; | 193 | return -EIO; |
195 | return 0; | 194 | return 0; |
@@ -197,10 +196,11 @@ static int mt9v022_start_capture(struct soc_camera_device *icd) | |||
197 | 196 | ||
198 | static int mt9v022_stop_capture(struct soc_camera_device *icd) | 197 | static int mt9v022_stop_capture(struct soc_camera_device *icd) |
199 | { | 198 | { |
199 | struct i2c_client *client = to_i2c_client(icd->control); | ||
200 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 200 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
201 | /* Switch to snapshot mode */ | 201 | /* Switch to snapshot mode */ |
202 | mt9v022->chip_control |= 0x10; | 202 | mt9v022->chip_control |= 0x10; |
203 | if (reg_write(icd, MT9V022_CHIP_CONTROL, | 203 | if (reg_write(client, MT9V022_CHIP_CONTROL, |
204 | mt9v022->chip_control) < 0) | 204 | mt9v022->chip_control) < 0) |
205 | return -EIO; | 205 | return -EIO; |
206 | return 0; | 206 | return 0; |
@@ -209,8 +209,9 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd) | |||
209 | static int mt9v022_set_bus_param(struct soc_camera_device *icd, | 209 | static int mt9v022_set_bus_param(struct soc_camera_device *icd, |
210 | unsigned long flags) | 210 | unsigned long flags) |
211 | { | 211 | { |
212 | struct i2c_client *client = to_i2c_client(icd->control); | ||
212 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 213 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
213 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | 214 | struct soc_camera_link *icl = client->dev.platform_data; |
214 | unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; | 215 | unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; |
215 | int ret; | 216 | int ret; |
216 | u16 pixclk = 0; | 217 | u16 pixclk = 0; |
@@ -243,14 +244,14 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd, | |||
243 | if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH)) | 244 | if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH)) |
244 | pixclk |= 0x2; | 245 | pixclk |= 0x2; |
245 | 246 | ||
246 | ret = reg_write(icd, MT9V022_PIXCLK_FV_LV, pixclk); | 247 | ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk); |
247 | if (ret < 0) | 248 | if (ret < 0) |
248 | return ret; | 249 | return ret; |
249 | 250 | ||
250 | if (!(flags & SOCAM_MASTER)) | 251 | if (!(flags & SOCAM_MASTER)) |
251 | mt9v022->chip_control &= ~0x8; | 252 | mt9v022->chip_control &= ~0x8; |
252 | 253 | ||
253 | ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); | 254 | ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); |
254 | if (ret < 0) | 255 | if (ret < 0) |
255 | return ret; | 256 | return ret; |
256 | 257 | ||
@@ -282,35 +283,36 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) | |||
282 | static int mt9v022_set_crop(struct soc_camera_device *icd, | 283 | static int mt9v022_set_crop(struct soc_camera_device *icd, |
283 | struct v4l2_rect *rect) | 284 | struct v4l2_rect *rect) |
284 | { | 285 | { |
286 | struct i2c_client *client = to_i2c_client(icd->control); | ||
285 | int ret; | 287 | int ret; |
286 | 288 | ||
287 | /* Like in example app. Contradicts the datasheet though */ | 289 | /* Like in example app. Contradicts the datasheet though */ |
288 | ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | 290 | ret = reg_read(client, MT9V022_AEC_AGC_ENABLE); |
289 | if (ret >= 0) { | 291 | if (ret >= 0) { |
290 | if (ret & 1) /* Autoexposure */ | 292 | if (ret & 1) /* Autoexposure */ |
291 | ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, | 293 | ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, |
292 | rect->height + icd->y_skip_top + 43); | 294 | rect->height + icd->y_skip_top + 43); |
293 | else | 295 | else |
294 | ret = reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, | 296 | ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, |
295 | rect->height + icd->y_skip_top + 43); | 297 | rect->height + icd->y_skip_top + 43); |
296 | } | 298 | } |
297 | /* Setup frame format: defaults apart from width and height */ | 299 | /* Setup frame format: defaults apart from width and height */ |
298 | if (!ret) | 300 | if (!ret) |
299 | ret = reg_write(icd, MT9V022_COLUMN_START, rect->left); | 301 | ret = reg_write(client, MT9V022_COLUMN_START, rect->left); |
300 | if (!ret) | 302 | if (!ret) |
301 | ret = reg_write(icd, MT9V022_ROW_START, rect->top); | 303 | ret = reg_write(client, MT9V022_ROW_START, rect->top); |
302 | if (!ret) | 304 | if (!ret) |
303 | /* Default 94, Phytec driver says: | 305 | /* Default 94, Phytec driver says: |
304 | * "width + horizontal blank >= 660" */ | 306 | * "width + horizontal blank >= 660" */ |
305 | ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING, | 307 | ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING, |
306 | rect->width > 660 - 43 ? 43 : | 308 | rect->width > 660 - 43 ? 43 : |
307 | 660 - rect->width); | 309 | 660 - rect->width); |
308 | if (!ret) | 310 | if (!ret) |
309 | ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45); | 311 | ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45); |
310 | if (!ret) | 312 | if (!ret) |
311 | ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width); | 313 | ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width); |
312 | if (!ret) | 314 | if (!ret) |
313 | ret = reg_write(icd, MT9V022_WINDOW_HEIGHT, | 315 | ret = reg_write(client, MT9V022_WINDOW_HEIGHT, |
314 | rect->height + icd->y_skip_top); | 316 | rect->height + icd->y_skip_top); |
315 | 317 | ||
316 | if (ret < 0) | 318 | if (ret < 0) |
@@ -396,16 +398,16 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd, | |||
396 | static int mt9v022_get_register(struct soc_camera_device *icd, | 398 | static int mt9v022_get_register(struct soc_camera_device *icd, |
397 | struct v4l2_dbg_register *reg) | 399 | struct v4l2_dbg_register *reg) |
398 | { | 400 | { |
399 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 401 | struct i2c_client *client = to_i2c_client(icd->control); |
400 | 402 | ||
401 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 403 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
402 | return -EINVAL; | 404 | return -EINVAL; |
403 | 405 | ||
404 | if (reg->match.addr != mt9v022->client->addr) | 406 | if (reg->match.addr != client->addr) |
405 | return -ENODEV; | 407 | return -ENODEV; |
406 | 408 | ||
407 | reg->size = 2; | 409 | reg->size = 2; |
408 | reg->val = reg_read(icd, reg->reg); | 410 | reg->val = reg_read(client, reg->reg); |
409 | 411 | ||
410 | if (reg->val > 0xffff) | 412 | if (reg->val > 0xffff) |
411 | return -EIO; | 413 | return -EIO; |
@@ -416,15 +418,15 @@ static int mt9v022_get_register(struct soc_camera_device *icd, | |||
416 | static int mt9v022_set_register(struct soc_camera_device *icd, | 418 | static int mt9v022_set_register(struct soc_camera_device *icd, |
417 | struct v4l2_dbg_register *reg) | 419 | struct v4l2_dbg_register *reg) |
418 | { | 420 | { |
419 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 421 | struct i2c_client *client = to_i2c_client(icd->control); |
420 | 422 | ||
421 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 423 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
422 | return -EINVAL; | 424 | return -EINVAL; |
423 | 425 | ||
424 | if (reg->match.addr != mt9v022->client->addr) | 426 | if (reg->match.addr != client->addr) |
425 | return -ENODEV; | 427 | return -ENODEV; |
426 | 428 | ||
427 | if (reg_write(icd, reg->reg, reg->val) < 0) | 429 | if (reg_write(client, reg->reg, reg->val) < 0) |
428 | return -EIO; | 430 | return -EIO; |
429 | 431 | ||
430 | return 0; | 432 | return 0; |
@@ -517,29 +519,30 @@ static struct soc_camera_ops mt9v022_ops = { | |||
517 | static int mt9v022_get_control(struct soc_camera_device *icd, | 519 | static int mt9v022_get_control(struct soc_camera_device *icd, |
518 | struct v4l2_control *ctrl) | 520 | struct v4l2_control *ctrl) |
519 | { | 521 | { |
522 | struct i2c_client *client = to_i2c_client(icd->control); | ||
520 | int data; | 523 | int data; |
521 | 524 | ||
522 | switch (ctrl->id) { | 525 | switch (ctrl->id) { |
523 | case V4L2_CID_VFLIP: | 526 | case V4L2_CID_VFLIP: |
524 | data = reg_read(icd, MT9V022_READ_MODE); | 527 | data = reg_read(client, MT9V022_READ_MODE); |
525 | if (data < 0) | 528 | if (data < 0) |
526 | return -EIO; | 529 | return -EIO; |
527 | ctrl->value = !!(data & 0x10); | 530 | ctrl->value = !!(data & 0x10); |
528 | break; | 531 | break; |
529 | case V4L2_CID_HFLIP: | 532 | case V4L2_CID_HFLIP: |
530 | data = reg_read(icd, MT9V022_READ_MODE); | 533 | data = reg_read(client, MT9V022_READ_MODE); |
531 | if (data < 0) | 534 | if (data < 0) |
532 | return -EIO; | 535 | return -EIO; |
533 | ctrl->value = !!(data & 0x20); | 536 | ctrl->value = !!(data & 0x20); |
534 | break; | 537 | break; |
535 | case V4L2_CID_EXPOSURE_AUTO: | 538 | case V4L2_CID_EXPOSURE_AUTO: |
536 | data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | 539 | data = reg_read(client, MT9V022_AEC_AGC_ENABLE); |
537 | if (data < 0) | 540 | if (data < 0) |
538 | return -EIO; | 541 | return -EIO; |
539 | ctrl->value = !!(data & 0x1); | 542 | ctrl->value = !!(data & 0x1); |
540 | break; | 543 | break; |
541 | case V4L2_CID_AUTOGAIN: | 544 | case V4L2_CID_AUTOGAIN: |
542 | data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | 545 | data = reg_read(client, MT9V022_AEC_AGC_ENABLE); |
543 | if (data < 0) | 546 | if (data < 0) |
544 | return -EIO; | 547 | return -EIO; |
545 | ctrl->value = !!(data & 0x2); | 548 | ctrl->value = !!(data & 0x2); |
@@ -552,6 +555,7 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
552 | struct v4l2_control *ctrl) | 555 | struct v4l2_control *ctrl) |
553 | { | 556 | { |
554 | int data; | 557 | int data; |
558 | struct i2c_client *client = to_i2c_client(icd->control); | ||
555 | const struct v4l2_queryctrl *qctrl; | 559 | const struct v4l2_queryctrl *qctrl; |
556 | 560 | ||
557 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); | 561 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); |
@@ -562,17 +566,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
562 | switch (ctrl->id) { | 566 | switch (ctrl->id) { |
563 | case V4L2_CID_VFLIP: | 567 | case V4L2_CID_VFLIP: |
564 | if (ctrl->value) | 568 | if (ctrl->value) |
565 | data = reg_set(icd, MT9V022_READ_MODE, 0x10); | 569 | data = reg_set(client, MT9V022_READ_MODE, 0x10); |
566 | else | 570 | else |
567 | data = reg_clear(icd, MT9V022_READ_MODE, 0x10); | 571 | data = reg_clear(client, MT9V022_READ_MODE, 0x10); |
568 | if (data < 0) | 572 | if (data < 0) |
569 | return -EIO; | 573 | return -EIO; |
570 | break; | 574 | break; |
571 | case V4L2_CID_HFLIP: | 575 | case V4L2_CID_HFLIP: |
572 | if (ctrl->value) | 576 | if (ctrl->value) |
573 | data = reg_set(icd, MT9V022_READ_MODE, 0x20); | 577 | data = reg_set(client, MT9V022_READ_MODE, 0x20); |
574 | else | 578 | else |
575 | data = reg_clear(icd, MT9V022_READ_MODE, 0x20); | 579 | data = reg_clear(client, MT9V022_READ_MODE, 0x20); |
576 | if (data < 0) | 580 | if (data < 0) |
577 | return -EIO; | 581 | return -EIO; |
578 | break; | 582 | break; |
@@ -593,12 +597,12 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
593 | /* The user wants to set gain manually, hope, she | 597 | /* The user wants to set gain manually, hope, she |
594 | * knows, what she's doing... Switch AGC off. */ | 598 | * knows, what she's doing... Switch AGC off. */ |
595 | 599 | ||
596 | if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) | 600 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) |
597 | return -EIO; | 601 | return -EIO; |
598 | 602 | ||
599 | dev_info(&icd->dev, "Setting gain from %d to %lu\n", | 603 | dev_info(&icd->dev, "Setting gain from %d to %lu\n", |
600 | reg_read(icd, MT9V022_ANALOG_GAIN), gain); | 604 | reg_read(client, MT9V022_ANALOG_GAIN), gain); |
601 | if (reg_write(icd, MT9V022_ANALOG_GAIN, gain) < 0) | 605 | if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) |
602 | return -EIO; | 606 | return -EIO; |
603 | icd->gain = ctrl->value; | 607 | icd->gain = ctrl->value; |
604 | } | 608 | } |
@@ -614,13 +618,13 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
614 | /* The user wants to set shutter width manually, hope, | 618 | /* The user wants to set shutter width manually, hope, |
615 | * she knows, what she's doing... Switch AEC off. */ | 619 | * she knows, what she's doing... Switch AEC off. */ |
616 | 620 | ||
617 | if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) | 621 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) |
618 | return -EIO; | 622 | return -EIO; |
619 | 623 | ||
620 | dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", | 624 | dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", |
621 | reg_read(icd, MT9V022_TOTAL_SHUTTER_WIDTH), | 625 | reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH), |
622 | shutter); | 626 | shutter); |
623 | if (reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, | 627 | if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, |
624 | shutter) < 0) | 628 | shutter) < 0) |
625 | return -EIO; | 629 | return -EIO; |
626 | icd->exposure = ctrl->value; | 630 | icd->exposure = ctrl->value; |
@@ -628,17 +632,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
628 | break; | 632 | break; |
629 | case V4L2_CID_AUTOGAIN: | 633 | case V4L2_CID_AUTOGAIN: |
630 | if (ctrl->value) | 634 | if (ctrl->value) |
631 | data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x2); | 635 | data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2); |
632 | else | 636 | else |
633 | data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2); | 637 | data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2); |
634 | if (data < 0) | 638 | if (data < 0) |
635 | return -EIO; | 639 | return -EIO; |
636 | break; | 640 | break; |
637 | case V4L2_CID_EXPOSURE_AUTO: | 641 | case V4L2_CID_EXPOSURE_AUTO: |
638 | if (ctrl->value) | 642 | if (ctrl->value) |
639 | data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x1); | 643 | data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1); |
640 | else | 644 | else |
641 | data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1); | 645 | data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1); |
642 | if (data < 0) | 646 | if (data < 0) |
643 | return -EIO; | 647 | return -EIO; |
644 | break; | 648 | break; |
@@ -650,8 +654,9 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
650 | * this wasn't our capture interface, so, we wait for the right one */ | 654 | * this wasn't our capture interface, so, we wait for the right one */ |
651 | static int mt9v022_video_probe(struct soc_camera_device *icd) | 655 | static int mt9v022_video_probe(struct soc_camera_device *icd) |
652 | { | 656 | { |
657 | struct i2c_client *client = to_i2c_client(icd->control); | ||
653 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 658 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
654 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | 659 | struct soc_camera_link *icl = client->dev.platform_data; |
655 | s32 data; | 660 | s32 data; |
656 | int ret; | 661 | int ret; |
657 | unsigned long flags; | 662 | unsigned long flags; |
@@ -661,7 +666,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) | |||
661 | return -ENODEV; | 666 | return -ENODEV; |
662 | 667 | ||
663 | /* Read out the chip version register */ | 668 | /* Read out the chip version register */ |
664 | data = reg_read(icd, MT9V022_CHIP_VERSION); | 669 | data = reg_read(client, MT9V022_CHIP_VERSION); |
665 | 670 | ||
666 | /* must be 0x1311 or 0x1313 */ | 671 | /* must be 0x1311 or 0x1313 */ |
667 | if (data != 0x1311 && data != 0x1313) { | 672 | if (data != 0x1311 && data != 0x1313) { |
@@ -672,12 +677,12 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) | |||
672 | } | 677 | } |
673 | 678 | ||
674 | /* Soft reset */ | 679 | /* Soft reset */ |
675 | ret = reg_write(icd, MT9V022_RESET, 1); | 680 | ret = reg_write(client, MT9V022_RESET, 1); |
676 | if (ret < 0) | 681 | if (ret < 0) |
677 | goto ei2c; | 682 | goto ei2c; |
678 | /* 15 clock cycles */ | 683 | /* 15 clock cycles */ |
679 | udelay(200); | 684 | udelay(200); |
680 | if (reg_read(icd, MT9V022_RESET)) { | 685 | if (reg_read(client, MT9V022_RESET)) { |
681 | dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); | 686 | dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); |
682 | goto ei2c; | 687 | goto ei2c; |
683 | } | 688 | } |
@@ -685,11 +690,11 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) | |||
685 | /* Set monochrome or colour sensor type */ | 690 | /* Set monochrome or colour sensor type */ |
686 | if (sensor_type && (!strcmp("colour", sensor_type) || | 691 | if (sensor_type && (!strcmp("colour", sensor_type) || |
687 | !strcmp("color", sensor_type))) { | 692 | !strcmp("color", sensor_type))) { |
688 | ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); | 693 | ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); |
689 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; | 694 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; |
690 | icd->formats = mt9v022_colour_formats; | 695 | icd->formats = mt9v022_colour_formats; |
691 | } else { | 696 | } else { |
692 | ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11); | 697 | ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11); |
693 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; | 698 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; |
694 | icd->formats = mt9v022_monochrome_formats; | 699 | icd->formats = mt9v022_monochrome_formats; |
695 | } | 700 | } |
@@ -735,10 +740,13 @@ ei2c: | |||
735 | static void mt9v022_video_remove(struct soc_camera_device *icd) | 740 | static void mt9v022_video_remove(struct soc_camera_device *icd) |
736 | { | 741 | { |
737 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 742 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
743 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | ||
738 | 744 | ||
739 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, | 745 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, |
740 | icd->dev.parent, icd->vdev); | 746 | icd->dev.parent, icd->vdev); |
741 | soc_camera_video_stop(icd); | 747 | soc_camera_video_stop(icd); |
748 | if (icl->free_bus) | ||
749 | icl->free_bus(icl); | ||
742 | } | 750 | } |
743 | 751 | ||
744 | static int mt9v022_probe(struct i2c_client *client, | 752 | static int mt9v022_probe(struct i2c_client *client, |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 86fab56c5a20..2d075205bdfe 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -102,10 +102,10 @@ struct mx1_buffer { | |||
102 | * Interface. If anyone ever builds hardware to enable more than | 102 | * Interface. If anyone ever builds hardware to enable more than |
103 | * one camera, they will have to modify this driver too */ | 103 | * one camera, they will have to modify this driver too */ |
104 | struct mx1_camera_dev { | 104 | struct mx1_camera_dev { |
105 | struct soc_camera_host soc_host; | ||
105 | struct soc_camera_device *icd; | 106 | struct soc_camera_device *icd; |
106 | struct mx1_camera_pdata *pdata; | 107 | struct mx1_camera_pdata *pdata; |
107 | struct mx1_buffer *active; | 108 | struct mx1_buffer *active; |
108 | struct device *dev; | ||
109 | struct resource *res; | 109 | struct resource *res; |
110 | struct clk *clk; | 110 | struct clk *clk; |
111 | struct list_head capture; | 111 | struct list_head capture; |
@@ -219,7 +219,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev) | |||
219 | int ret; | 219 | int ret; |
220 | 220 | ||
221 | if (unlikely(!pcdev->active)) { | 221 | if (unlikely(!pcdev->active)) { |
222 | dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n"); | 222 | dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n"); |
223 | return -EFAULT; | 223 | return -EFAULT; |
224 | } | 224 | } |
225 | 225 | ||
@@ -229,7 +229,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev) | |||
229 | vbuf->size, pcdev->res->start + | 229 | vbuf->size, pcdev->res->start + |
230 | CSIRXR, DMA_MODE_READ); | 230 | CSIRXR, DMA_MODE_READ); |
231 | if (unlikely(ret)) | 231 | if (unlikely(ret)) |
232 | dev_err(pcdev->dev, "Failed to setup DMA sg list\n"); | 232 | dev_err(pcdev->soc_host.dev, "Failed to setup DMA sg list\n"); |
233 | 233 | ||
234 | return ret; | 234 | return ret; |
235 | } | 235 | } |
@@ -338,14 +338,14 @@ static void mx1_camera_dma_irq(int channel, void *data) | |||
338 | imx_dma_disable(channel); | 338 | imx_dma_disable(channel); |
339 | 339 | ||
340 | if (unlikely(!pcdev->active)) { | 340 | if (unlikely(!pcdev->active)) { |
341 | dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n"); | 341 | dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n"); |
342 | goto out; | 342 | goto out; |
343 | } | 343 | } |
344 | 344 | ||
345 | vb = &pcdev->active->vb; | 345 | vb = &pcdev->active->vb; |
346 | buf = container_of(vb, struct mx1_buffer, vb); | 346 | buf = container_of(vb, struct mx1_buffer, vb); |
347 | WARN_ON(buf->inwork || list_empty(&vb->queue)); | 347 | WARN_ON(buf->inwork || list_empty(&vb->queue)); |
348 | dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 348 | dev_dbg(pcdev->soc_host.dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, |
349 | vb, vb->baddr, vb->bsize); | 349 | vb, vb->baddr, vb->bsize); |
350 | 350 | ||
351 | mx1_camera_wakeup(pcdev, vb, buf); | 351 | mx1_camera_wakeup(pcdev, vb, buf); |
@@ -366,7 +366,7 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q, | |||
366 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 366 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
367 | struct mx1_camera_dev *pcdev = ici->priv; | 367 | struct mx1_camera_dev *pcdev = ici->priv; |
368 | 368 | ||
369 | videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, pcdev->dev, | 369 | videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, ici->dev, |
370 | &pcdev->lock, | 370 | &pcdev->lock, |
371 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 371 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
372 | V4L2_FIELD_NONE, | 372 | V4L2_FIELD_NONE, |
@@ -385,7 +385,7 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev) | |||
385 | * they get a nice Oops */ | 385 | * they get a nice Oops */ |
386 | div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; | 386 | div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; |
387 | 387 | ||
388 | dev_dbg(pcdev->dev, "System clock %lukHz, target freq %dkHz, " | 388 | dev_dbg(pcdev->soc_host.dev, "System clock %lukHz, target freq %dkHz, " |
389 | "divisor %lu\n", lcdclk / 1000, mclk / 1000, div); | 389 | "divisor %lu\n", lcdclk / 1000, mclk / 1000, div); |
390 | 390 | ||
391 | return div; | 391 | return div; |
@@ -395,7 +395,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) | |||
395 | { | 395 | { |
396 | unsigned int csicr1 = CSICR1_EN; | 396 | unsigned int csicr1 = CSICR1_EN; |
397 | 397 | ||
398 | dev_dbg(pcdev->dev, "Activate device\n"); | 398 | dev_dbg(pcdev->soc_host.dev, "Activate device\n"); |
399 | 399 | ||
400 | clk_enable(pcdev->clk); | 400 | clk_enable(pcdev->clk); |
401 | 401 | ||
@@ -411,7 +411,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) | |||
411 | 411 | ||
412 | static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) | 412 | static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) |
413 | { | 413 | { |
414 | dev_dbg(pcdev->dev, "Deactivate device\n"); | 414 | dev_dbg(pcdev->soc_host.dev, "Deactivate device\n"); |
415 | 415 | ||
416 | /* Disable all CSI interface */ | 416 | /* Disable all CSI interface */ |
417 | __raw_writel(0x00, pcdev->base + CSICR1); | 417 | __raw_writel(0x00, pcdev->base + CSICR1); |
@@ -550,7 +550,7 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd, | |||
550 | 550 | ||
551 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 551 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
552 | if (!xlate) { | 552 | if (!xlate) { |
553 | dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); | 553 | dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); |
554 | return -EINVAL; | 554 | return -EINVAL; |
555 | } | 555 | } |
556 | 556 | ||
@@ -633,12 +633,6 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = { | |||
633 | .querycap = mx1_camera_querycap, | 633 | .querycap = mx1_camera_querycap, |
634 | }; | 634 | }; |
635 | 635 | ||
636 | /* Should be allocated dynamically too, but we have only one. */ | ||
637 | static struct soc_camera_host mx1_soc_camera_host = { | ||
638 | .drv_name = DRIVER_NAME, | ||
639 | .ops = &mx1_soc_camera_host_ops, | ||
640 | }; | ||
641 | |||
642 | static struct fiq_handler fh = { | 636 | static struct fiq_handler fh = { |
643 | .name = "csi_sof" | 637 | .name = "csi_sof" |
644 | }; | 638 | }; |
@@ -673,7 +667,6 @@ static int __init mx1_camera_probe(struct platform_device *pdev) | |||
673 | goto exit_put_clk; | 667 | goto exit_put_clk; |
674 | } | 668 | } |
675 | 669 | ||
676 | dev_set_drvdata(&pdev->dev, pcdev); | ||
677 | pcdev->res = res; | 670 | pcdev->res = res; |
678 | pcdev->clk = clk; | 671 | pcdev->clk = clk; |
679 | 672 | ||
@@ -707,16 +700,15 @@ static int __init mx1_camera_probe(struct platform_device *pdev) | |||
707 | } | 700 | } |
708 | pcdev->irq = irq; | 701 | pcdev->irq = irq; |
709 | pcdev->base = base; | 702 | pcdev->base = base; |
710 | pcdev->dev = &pdev->dev; | ||
711 | 703 | ||
712 | /* request dma */ | 704 | /* request dma */ |
713 | pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH); | 705 | pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH); |
714 | if (pcdev->dma_chan < 0) { | 706 | if (pcdev->dma_chan < 0) { |
715 | dev_err(pcdev->dev, "Can't request DMA for MX1 CSI\n"); | 707 | dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n"); |
716 | err = -EBUSY; | 708 | err = -EBUSY; |
717 | goto exit_iounmap; | 709 | goto exit_iounmap; |
718 | } | 710 | } |
719 | dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chan); | 711 | dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan); |
720 | 712 | ||
721 | imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL, | 713 | imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL, |
722 | pcdev); | 714 | pcdev); |
@@ -729,7 +721,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev) | |||
729 | /* request irq */ | 721 | /* request irq */ |
730 | err = claim_fiq(&fh); | 722 | err = claim_fiq(&fh); |
731 | if (err) { | 723 | if (err) { |
732 | dev_err(pcdev->dev, "Camera interrupt register failed \n"); | 724 | dev_err(&pdev->dev, "Camera interrupt register failed \n"); |
733 | goto exit_free_dma; | 725 | goto exit_free_dma; |
734 | } | 726 | } |
735 | 727 | ||
@@ -746,10 +738,12 @@ static int __init mx1_camera_probe(struct platform_device *pdev) | |||
746 | mxc_set_irq_fiq(irq, 1); | 738 | mxc_set_irq_fiq(irq, 1); |
747 | enable_fiq(irq); | 739 | enable_fiq(irq); |
748 | 740 | ||
749 | mx1_soc_camera_host.priv = pcdev; | 741 | pcdev->soc_host.drv_name = DRIVER_NAME; |
750 | mx1_soc_camera_host.dev.parent = &pdev->dev; | 742 | pcdev->soc_host.ops = &mx1_soc_camera_host_ops; |
751 | mx1_soc_camera_host.nr = pdev->id; | 743 | pcdev->soc_host.priv = pcdev; |
752 | err = soc_camera_host_register(&mx1_soc_camera_host); | 744 | pcdev->soc_host.dev = &pdev->dev; |
745 | pcdev->soc_host.nr = pdev->id; | ||
746 | err = soc_camera_host_register(&pcdev->soc_host); | ||
753 | if (err) | 747 | if (err) |
754 | goto exit_free_irq; | 748 | goto exit_free_irq; |
755 | 749 | ||
@@ -777,7 +771,9 @@ exit: | |||
777 | 771 | ||
778 | static int __exit mx1_camera_remove(struct platform_device *pdev) | 772 | static int __exit mx1_camera_remove(struct platform_device *pdev) |
779 | { | 773 | { |
780 | struct mx1_camera_dev *pcdev = platform_get_drvdata(pdev); | 774 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); |
775 | struct mx1_camera_dev *pcdev = container_of(soc_host, | ||
776 | struct mx1_camera_dev, soc_host); | ||
781 | struct resource *res; | 777 | struct resource *res; |
782 | 778 | ||
783 | imx_dma_free(pcdev->dma_chan); | 779 | imx_dma_free(pcdev->dma_chan); |
@@ -787,7 +783,7 @@ static int __exit mx1_camera_remove(struct platform_device *pdev) | |||
787 | 783 | ||
788 | clk_put(pcdev->clk); | 784 | clk_put(pcdev->clk); |
789 | 785 | ||
790 | soc_camera_host_unregister(&mx1_soc_camera_host); | 786 | soc_camera_host_unregister(soc_host); |
791 | 787 | ||
792 | iounmap(pcdev->base); | 788 | iounmap(pcdev->base); |
793 | 789 | ||
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index 2d0781118eb0..e605c076ed89 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -87,7 +87,6 @@ struct mx3_camera_buffer { | |||
87 | * @soc_host: embedded soc_host object | 87 | * @soc_host: embedded soc_host object |
88 | */ | 88 | */ |
89 | struct mx3_camera_dev { | 89 | struct mx3_camera_dev { |
90 | struct device *dev; | ||
91 | /* | 90 | /* |
92 | * i.MX3x is only supposed to handle one camera on its Camera Sensor | 91 | * i.MX3x is only supposed to handle one camera on its Camera Sensor |
93 | * Interface. If anyone ever builds hardware to enable more than one | 92 | * Interface. If anyone ever builds hardware to enable more than one |
@@ -431,7 +430,7 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q, | |||
431 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 430 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
432 | struct mx3_camera_dev *mx3_cam = ici->priv; | 431 | struct mx3_camera_dev *mx3_cam = ici->priv; |
433 | 432 | ||
434 | videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, mx3_cam->dev, | 433 | videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, ici->dev, |
435 | &mx3_cam->lock, | 434 | &mx3_cam->lock, |
436 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 435 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
437 | V4L2_FIELD_NONE, | 436 | V4L2_FIELD_NONE, |
@@ -599,7 +598,8 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam, | |||
599 | *flags |= SOCAM_DATAWIDTH_4; | 598 | *flags |= SOCAM_DATAWIDTH_4; |
600 | break; | 599 | break; |
601 | default: | 600 | default: |
602 | dev_info(mx3_cam->dev, "Unsupported bus width %d\n", buswidth); | 601 | dev_info(mx3_cam->soc_host.dev, "Unsupported bus width %d\n", |
602 | buswidth); | ||
603 | return -EINVAL; | 603 | return -EINVAL; |
604 | } | 604 | } |
605 | 605 | ||
@@ -614,7 +614,7 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd, | |||
614 | unsigned long bus_flags, camera_flags; | 614 | unsigned long bus_flags, camera_flags; |
615 | int ret = test_platform_param(mx3_cam, depth, &bus_flags); | 615 | int ret = test_platform_param(mx3_cam, depth, &bus_flags); |
616 | 616 | ||
617 | dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", depth, ret); | 617 | dev_dbg(ici->dev, "requested bus width %d bit: %d\n", depth, ret); |
618 | 618 | ||
619 | if (ret < 0) | 619 | if (ret < 0) |
620 | return ret; | 620 | return ret; |
@@ -637,7 +637,7 @@ static bool chan_filter(struct dma_chan *chan, void *arg) | |||
637 | if (!rq) | 637 | if (!rq) |
638 | return false; | 638 | return false; |
639 | 639 | ||
640 | pdata = rq->mx3_cam->dev->platform_data; | 640 | pdata = rq->mx3_cam->soc_host.dev->platform_data; |
641 | 641 | ||
642 | return rq->id == chan->chan_id && | 642 | return rq->id == chan->chan_id && |
643 | pdata->dma_dev == chan->device->dev; | 643 | pdata->dma_dev == chan->device->dev; |
@@ -697,7 +697,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
697 | xlate->cam_fmt = icd->formats + idx; | 697 | xlate->cam_fmt = icd->formats + idx; |
698 | xlate->buswidth = buswidth; | 698 | xlate->buswidth = buswidth; |
699 | xlate++; | 699 | xlate++; |
700 | dev_dbg(&ici->dev, "Providing format %s using %s\n", | 700 | dev_dbg(ici->dev, "Providing format %s using %s\n", |
701 | mx3_camera_formats[0].name, | 701 | mx3_camera_formats[0].name, |
702 | icd->formats[idx].name); | 702 | icd->formats[idx].name); |
703 | } | 703 | } |
@@ -709,7 +709,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
709 | xlate->cam_fmt = icd->formats + idx; | 709 | xlate->cam_fmt = icd->formats + idx; |
710 | xlate->buswidth = buswidth; | 710 | xlate->buswidth = buswidth; |
711 | xlate++; | 711 | xlate++; |
712 | dev_dbg(&ici->dev, "Providing format %s using %s\n", | 712 | dev_dbg(ici->dev, "Providing format %s using %s\n", |
713 | mx3_camera_formats[0].name, | 713 | mx3_camera_formats[0].name, |
714 | icd->formats[idx].name); | 714 | icd->formats[idx].name); |
715 | } | 715 | } |
@@ -722,7 +722,7 @@ passthrough: | |||
722 | xlate->cam_fmt = icd->formats + idx; | 722 | xlate->cam_fmt = icd->formats + idx; |
723 | xlate->buswidth = buswidth; | 723 | xlate->buswidth = buswidth; |
724 | xlate++; | 724 | xlate++; |
725 | dev_dbg(&ici->dev, | 725 | dev_dbg(ici->dev, |
726 | "Providing format %s in pass-through mode\n", | 726 | "Providing format %s in pass-through mode\n", |
727 | icd->formats[idx].name); | 727 | icd->formats[idx].name); |
728 | } | 728 | } |
@@ -829,7 +829,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd, | |||
829 | 829 | ||
830 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 830 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
831 | if (!xlate) { | 831 | if (!xlate) { |
832 | dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); | 832 | dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); |
833 | return -EINVAL; | 833 | return -EINVAL; |
834 | } | 834 | } |
835 | 835 | ||
@@ -866,7 +866,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd, | |||
866 | 866 | ||
867 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 867 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
868 | if (pixfmt && !xlate) { | 868 | if (pixfmt && !xlate) { |
869 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 869 | dev_warn(ici->dev, "Format %x not found\n", pixfmt); |
870 | return -EINVAL; | 870 | return -EINVAL; |
871 | } | 871 | } |
872 | 872 | ||
@@ -933,11 +933,11 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
933 | 933 | ||
934 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 934 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
935 | if (!xlate) { | 935 | if (!xlate) { |
936 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 936 | dev_warn(ici->dev, "Format %x not found\n", pixfmt); |
937 | return -EINVAL; | 937 | return -EINVAL; |
938 | } | 938 | } |
939 | 939 | ||
940 | dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", | 940 | dev_dbg(ici->dev, "requested bus width %d bit: %d\n", |
941 | icd->buswidth, ret); | 941 | icd->buswidth, ret); |
942 | 942 | ||
943 | if (ret < 0) | 943 | if (ret < 0) |
@@ -947,7 +947,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
947 | 947 | ||
948 | common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); | 948 | common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); |
949 | if (!common_flags) { | 949 | if (!common_flags) { |
950 | dev_dbg(&ici->dev, "no common flags: camera %lx, host %lx\n", | 950 | dev_dbg(ici->dev, "no common flags: camera %lx, host %lx\n", |
951 | camera_flags, bus_flags); | 951 | camera_flags, bus_flags); |
952 | return -EINVAL; | 952 | return -EINVAL; |
953 | } | 953 | } |
@@ -1054,7 +1054,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
1054 | 1054 | ||
1055 | csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF); | 1055 | csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF); |
1056 | 1056 | ||
1057 | dev_dbg(&ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw); | 1057 | dev_dbg(ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw); |
1058 | 1058 | ||
1059 | return 0; | 1059 | return 0; |
1060 | } | 1060 | } |
@@ -1074,7 +1074,7 @@ static struct soc_camera_host_ops mx3_soc_camera_host_ops = { | |||
1074 | .set_bus_param = mx3_camera_set_bus_param, | 1074 | .set_bus_param = mx3_camera_set_bus_param, |
1075 | }; | 1075 | }; |
1076 | 1076 | ||
1077 | static int mx3_camera_probe(struct platform_device *pdev) | 1077 | static int __devinit mx3_camera_probe(struct platform_device *pdev) |
1078 | { | 1078 | { |
1079 | struct mx3_camera_dev *mx3_cam; | 1079 | struct mx3_camera_dev *mx3_cam; |
1080 | struct resource *res; | 1080 | struct resource *res; |
@@ -1102,8 +1102,6 @@ static int mx3_camera_probe(struct platform_device *pdev) | |||
1102 | goto eclkget; | 1102 | goto eclkget; |
1103 | } | 1103 | } |
1104 | 1104 | ||
1105 | dev_set_drvdata(&pdev->dev, mx3_cam); | ||
1106 | |||
1107 | mx3_cam->pdata = pdev->dev.platform_data; | 1105 | mx3_cam->pdata = pdev->dev.platform_data; |
1108 | mx3_cam->platform_flags = mx3_cam->pdata->flags; | 1106 | mx3_cam->platform_flags = mx3_cam->pdata->flags; |
1109 | if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | | 1107 | if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | |
@@ -1135,14 +1133,14 @@ static int mx3_camera_probe(struct platform_device *pdev) | |||
1135 | } | 1133 | } |
1136 | 1134 | ||
1137 | mx3_cam->base = base; | 1135 | mx3_cam->base = base; |
1138 | mx3_cam->dev = &pdev->dev; | ||
1139 | 1136 | ||
1140 | soc_host = &mx3_cam->soc_host; | 1137 | soc_host = &mx3_cam->soc_host; |
1141 | soc_host->drv_name = MX3_CAM_DRV_NAME; | 1138 | soc_host->drv_name = MX3_CAM_DRV_NAME; |
1142 | soc_host->ops = &mx3_soc_camera_host_ops; | 1139 | soc_host->ops = &mx3_soc_camera_host_ops; |
1143 | soc_host->priv = mx3_cam; | 1140 | soc_host->priv = mx3_cam; |
1144 | soc_host->dev.parent = &pdev->dev; | 1141 | soc_host->dev = &pdev->dev; |
1145 | soc_host->nr = pdev->id; | 1142 | soc_host->nr = pdev->id; |
1143 | |||
1146 | err = soc_camera_host_register(soc_host); | 1144 | err = soc_camera_host_register(soc_host); |
1147 | if (err) | 1145 | if (err) |
1148 | goto ecamhostreg; | 1146 | goto ecamhostreg; |
@@ -1165,11 +1163,13 @@ egetres: | |||
1165 | 1163 | ||
1166 | static int __devexit mx3_camera_remove(struct platform_device *pdev) | 1164 | static int __devexit mx3_camera_remove(struct platform_device *pdev) |
1167 | { | 1165 | { |
1168 | struct mx3_camera_dev *mx3_cam = platform_get_drvdata(pdev); | 1166 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); |
1167 | struct mx3_camera_dev *mx3_cam = container_of(soc_host, | ||
1168 | struct mx3_camera_dev, soc_host); | ||
1169 | 1169 | ||
1170 | clk_put(mx3_cam->clk); | 1170 | clk_put(mx3_cam->clk); |
1171 | 1171 | ||
1172 | soc_camera_host_unregister(&mx3_cam->soc_host); | 1172 | soc_camera_host_unregister(soc_host); |
1173 | 1173 | ||
1174 | iounmap(mx3_cam->base); | 1174 | iounmap(mx3_cam->base); |
1175 | 1175 | ||
@@ -1194,11 +1194,11 @@ static struct platform_driver mx3_camera_driver = { | |||
1194 | .name = MX3_CAM_DRV_NAME, | 1194 | .name = MX3_CAM_DRV_NAME, |
1195 | }, | 1195 | }, |
1196 | .probe = mx3_camera_probe, | 1196 | .probe = mx3_camera_probe, |
1197 | .remove = __exit_p(mx3_camera_remove), | 1197 | .remove = __devexit_p(mx3_camera_remove), |
1198 | }; | 1198 | }; |
1199 | 1199 | ||
1200 | 1200 | ||
1201 | static int __devinit mx3_camera_init(void) | 1201 | static int __init mx3_camera_init(void) |
1202 | { | 1202 | { |
1203 | return platform_driver_register(&mx3_camera_driver); | 1203 | return platform_driver_register(&mx3_camera_driver); |
1204 | } | 1204 | } |
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 3be5a71bdac2..35890e8b2431 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
@@ -453,7 +453,7 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc) | |||
453 | static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) | 453 | static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) |
454 | { | 454 | { |
455 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); | 455 | DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); |
456 | if (i->index < 0 || i->index >= MXB_INPUTS) | 456 | if (i->index >= MXB_INPUTS) |
457 | return -EINVAL; | 457 | return -EINVAL; |
458 | memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); | 458 | memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); |
459 | return 0; | 459 | return 0; |
@@ -616,7 +616,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) | |||
616 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | 616 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
617 | struct mxb *mxb = (struct mxb *)dev->ext_priv; | 617 | struct mxb *mxb = (struct mxb *)dev->ext_priv; |
618 | 618 | ||
619 | if (a->index < 0 || a->index > MXB_INPUTS) { | 619 | if (a->index > MXB_INPUTS) { |
620 | DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index)); | 620 | DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index)); |
621 | return -EINVAL; | 621 | return -EINVAL; |
622 | } | 622 | } |
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 9af5532db142..08cfd3e4ae8a 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c | |||
@@ -112,6 +112,8 @@ static int framedrop = -1; | |||
112 | static int fastset; | 112 | static int fastset; |
113 | static int force_palette; | 113 | static int force_palette; |
114 | static int backlight; | 114 | static int backlight; |
115 | /* Bitmask marking allocated devices from 0 to OV511_MAX_UNIT_VIDEO */ | ||
116 | static unsigned long ov511_devused; | ||
115 | static int unit_video[OV511_MAX_UNIT_VIDEO]; | 117 | static int unit_video[OV511_MAX_UNIT_VIDEO]; |
116 | static int remove_zeros; | 118 | static int remove_zeros; |
117 | static int mirror; | 119 | static int mirror; |
@@ -5720,7 +5722,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
5720 | struct usb_device *dev = interface_to_usbdev(intf); | 5722 | struct usb_device *dev = interface_to_usbdev(intf); |
5721 | struct usb_interface_descriptor *idesc; | 5723 | struct usb_interface_descriptor *idesc; |
5722 | struct usb_ov511 *ov; | 5724 | struct usb_ov511 *ov; |
5723 | int i; | 5725 | int i, rc, nr; |
5724 | 5726 | ||
5725 | PDEBUG(1, "probing for device..."); | 5727 | PDEBUG(1, "probing for device..."); |
5726 | 5728 | ||
@@ -5845,33 +5847,41 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
5845 | ov->vdev->parent = &intf->dev; | 5847 | ov->vdev->parent = &intf->dev; |
5846 | video_set_drvdata(ov->vdev, ov); | 5848 | video_set_drvdata(ov->vdev, ov); |
5847 | 5849 | ||
5848 | for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { | 5850 | mutex_lock(&ov->lock); |
5849 | /* Minor 0 cannot be specified; assume user wants autodetect */ | ||
5850 | if (unit_video[i] == 0) | ||
5851 | break; | ||
5852 | 5851 | ||
5853 | if (video_register_device(ov->vdev, VFL_TYPE_GRABBER, | 5852 | /* Check to see next free device and mark as used */ |
5854 | unit_video[i]) >= 0) { | 5853 | nr = find_first_zero_bit(&ov511_devused, OV511_MAX_UNIT_VIDEO); |
5855 | break; | 5854 | |
5856 | } | 5855 | /* Registers device */ |
5857 | } | 5856 | if (unit_video[nr] != 0) |
5857 | rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER, | ||
5858 | unit_video[nr]); | ||
5859 | else | ||
5860 | rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1); | ||
5858 | 5861 | ||
5859 | /* Use the next available one */ | 5862 | if (rc < 0) { |
5860 | if ((ov->vdev->minor == -1) && | ||
5861 | video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) { | ||
5862 | err("video_register_device failed"); | 5863 | err("video_register_device failed"); |
5864 | mutex_unlock(&ov->lock); | ||
5863 | goto error; | 5865 | goto error; |
5864 | } | 5866 | } |
5865 | 5867 | ||
5868 | /* Mark device as used */ | ||
5869 | ov511_devused |= 1 << nr; | ||
5870 | ov->nr = nr; | ||
5871 | |||
5866 | dev_info(&intf->dev, "Device at %s registered to minor %d\n", | 5872 | dev_info(&intf->dev, "Device at %s registered to minor %d\n", |
5867 | ov->usb_path, ov->vdev->minor); | 5873 | ov->usb_path, ov->vdev->minor); |
5868 | 5874 | ||
5869 | usb_set_intfdata(intf, ov); | 5875 | usb_set_intfdata(intf, ov); |
5870 | if (ov_create_sysfs(ov->vdev)) { | 5876 | if (ov_create_sysfs(ov->vdev)) { |
5871 | err("ov_create_sysfs failed"); | 5877 | err("ov_create_sysfs failed"); |
5878 | ov511_devused &= ~(1 << nr); | ||
5879 | mutex_unlock(&ov->lock); | ||
5872 | goto error; | 5880 | goto error; |
5873 | } | 5881 | } |
5874 | 5882 | ||
5883 | mutex_lock(&ov->lock); | ||
5884 | |||
5875 | return 0; | 5885 | return 0; |
5876 | 5886 | ||
5877 | error: | 5887 | error: |
@@ -5906,10 +5916,16 @@ ov51x_disconnect(struct usb_interface *intf) | |||
5906 | 5916 | ||
5907 | PDEBUG(3, ""); | 5917 | PDEBUG(3, ""); |
5908 | 5918 | ||
5919 | mutex_lock(&ov->lock); | ||
5909 | usb_set_intfdata (intf, NULL); | 5920 | usb_set_intfdata (intf, NULL); |
5910 | 5921 | ||
5911 | if (!ov) | 5922 | if (!ov) { |
5923 | mutex_unlock(&ov->lock); | ||
5912 | return; | 5924 | return; |
5925 | } | ||
5926 | |||
5927 | /* Free device number */ | ||
5928 | ov511_devused &= ~(1 << ov->nr); | ||
5913 | 5929 | ||
5914 | if (ov->vdev) | 5930 | if (ov->vdev) |
5915 | video_unregister_device(ov->vdev); | 5931 | video_unregister_device(ov->vdev); |
@@ -5927,6 +5943,7 @@ ov51x_disconnect(struct usb_interface *intf) | |||
5927 | 5943 | ||
5928 | ov->streaming = 0; | 5944 | ov->streaming = 0; |
5929 | ov51x_unlink_isoc(ov); | 5945 | ov51x_unlink_isoc(ov); |
5946 | mutex_unlock(&ov->lock); | ||
5930 | 5947 | ||
5931 | ov->dev = NULL; | 5948 | ov->dev = NULL; |
5932 | 5949 | ||
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h index 70d99e52329d..c450c92468da 100644 --- a/drivers/media/video/ov511.h +++ b/drivers/media/video/ov511.h | |||
@@ -494,6 +494,9 @@ struct usb_ov511 { | |||
494 | int has_decoder; /* Device has a video decoder */ | 494 | int has_decoder; /* Device has a video decoder */ |
495 | int pal; /* Device is designed for PAL resolution */ | 495 | int pal; /* Device is designed for PAL resolution */ |
496 | 496 | ||
497 | /* ov511 device number ID */ | ||
498 | int nr; /* Stores a device number */ | ||
499 | |||
497 | /* I2C interface */ | 500 | /* I2C interface */ |
498 | struct mutex i2c_lock; /* Protect I2C controller regs */ | 501 | struct mutex i2c_lock; /* Protect I2C controller regs */ |
499 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ | 502 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index 1cb6a260e8b0..336a20eded0f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c | |||
@@ -71,6 +71,7 @@ static const struct pvr2_device_desc pvr2_device_29xxx = { | |||
71 | .flag_has_svideo = !0, | 71 | .flag_has_svideo = !0, |
72 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, | 72 | .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, |
73 | .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, | 73 | .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, |
74 | .ir_scheme = PVR2_IR_SCHEME_29XXX, | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | 77 | ||
@@ -284,6 +285,11 @@ static struct tda10048_config hauppauge_tda10048_config = { | |||
284 | .output_mode = TDA10048_PARALLEL_OUTPUT, | 285 | .output_mode = TDA10048_PARALLEL_OUTPUT, |
285 | .fwbulkwritelen = TDA10048_BULKWRITE_50, | 286 | .fwbulkwritelen = TDA10048_BULKWRITE_50, |
286 | .inversion = TDA10048_INVERSION_ON, | 287 | .inversion = TDA10048_INVERSION_ON, |
288 | .dtv6_if_freq_khz = TDA10048_IF_3300, | ||
289 | .dtv7_if_freq_khz = TDA10048_IF_3800, | ||
290 | .dtv8_if_freq_khz = TDA10048_IF_4300, | ||
291 | .clk_freq_khz = TDA10048_CLK_16000, | ||
292 | .disable_gate_access = 1, | ||
287 | }; | 293 | }; |
288 | 294 | ||
289 | static struct tda829x_config tda829x_no_probe = { | 295 | static struct tda829x_config tda829x_no_probe = { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h index 3e553389cbc3..ea04ecf8aa39 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h | |||
@@ -69,6 +69,7 @@ struct pvr2_string_table { | |||
69 | #define PVR2_ROUTING_SCHEME_HAUPPAUGE 0 | 69 | #define PVR2_ROUTING_SCHEME_HAUPPAUGE 0 |
70 | #define PVR2_ROUTING_SCHEME_GOTVIEW 1 | 70 | #define PVR2_ROUTING_SCHEME_GOTVIEW 1 |
71 | #define PVR2_ROUTING_SCHEME_ONAIR 2 | 71 | #define PVR2_ROUTING_SCHEME_ONAIR 2 |
72 | #define PVR2_ROUTING_SCHEME_AV400 3 | ||
72 | 73 | ||
73 | #define PVR2_DIGITAL_SCHEME_NONE 0 | 74 | #define PVR2_DIGITAL_SCHEME_NONE 0 |
74 | #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1 | 75 | #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1 |
@@ -78,8 +79,10 @@ struct pvr2_string_table { | |||
78 | #define PVR2_LED_SCHEME_HAUPPAUGE 1 | 79 | #define PVR2_LED_SCHEME_HAUPPAUGE 1 |
79 | 80 | ||
80 | #define PVR2_IR_SCHEME_NONE 0 | 81 | #define PVR2_IR_SCHEME_NONE 0 |
81 | #define PVR2_IR_SCHEME_24XXX 1 | 82 | #define PVR2_IR_SCHEME_24XXX 1 /* FX2-controlled IR */ |
82 | #define PVR2_IR_SCHEME_ZILOG 2 | 83 | #define PVR2_IR_SCHEME_ZILOG 2 /* HVR-1950 style (must be taken out of reset) */ |
84 | #define PVR2_IR_SCHEME_24XXX_MCE 3 /* 24xxx MCE device */ | ||
85 | #define PVR2_IR_SCHEME_29XXX 4 /* Original 29xxx device */ | ||
83 | 86 | ||
84 | /* This describes a particular hardware type (except for the USB device ID | 87 | /* This describes a particular hardware type (except for the USB device ID |
85 | which must live in a separate structure due to environmental | 88 | which must live in a separate structure due to environmental |
@@ -162,19 +165,9 @@ struct pvr2_device_desc { | |||
162 | ensure that it is found. */ | 165 | ensure that it is found. */ |
163 | unsigned int flag_has_wm8775:1; | 166 | unsigned int flag_has_wm8775:1; |
164 | 167 | ||
165 | /* Indicate any specialized IR scheme that might need to be | 168 | /* Indicate IR scheme of hardware. If not set, then it is assumed |
166 | supported by this driver. If not set, then it is assumed that | 169 | that IR can work without any help from the driver. */ |
167 | IR can work without help from the driver (which is frequently | 170 | unsigned int ir_scheme:3; |
168 | the case). This is otherwise set to one of | ||
169 | PVR2_IR_SCHEME_xxxx. For "xxxx", the value "24XXX" indicates a | ||
170 | Hauppauge 24xxx class device which has an FPGA-hosted IR | ||
171 | receiver that can only be reached via FX2 command codes. In | ||
172 | that case the pvrusb2 driver will emulate the behavior of the | ||
173 | older 29xxx device's IR receiver (a "virtual" I2C chip) in terms | ||
174 | of those command codes. For the value "ZILOG", we're dealing | ||
175 | with an IR chip that must be taken out of reset via another FX2 | ||
176 | command code (which is the case for HVR-1950 devices). */ | ||
177 | unsigned int ir_scheme:2; | ||
178 | 171 | ||
179 | /* These bits define which kinds of sources the device can handle. | 172 | /* These bits define which kinds of sources the device can handle. |
180 | Note: Digital tuner presence is inferred by the | 173 | Note: Digital tuner presence is inferred by the |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index 5d75eb5211b1..5b152ff20bd0 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | |||
@@ -200,6 +200,9 @@ struct pvr2_hdw { | |||
200 | int i2c_cx25840_hack_state; | 200 | int i2c_cx25840_hack_state; |
201 | int i2c_linked; | 201 | int i2c_linked; |
202 | 202 | ||
203 | /* IR related */ | ||
204 | unsigned int ir_scheme_active; /* IR scheme as seen from the outside */ | ||
205 | |||
203 | /* Frequency table */ | 206 | /* Frequency table */ |
204 | unsigned int freqTable[FREQTABLE_SIZE]; | 207 | unsigned int freqTable[FREQTABLE_SIZE]; |
205 | unsigned int freqProgSlot; | 208 | unsigned int freqProgSlot; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index add3395d3248..0c745b142fb7 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -142,6 +142,15 @@ static const unsigned char *module_i2c_addresses[] = { | |||
142 | }; | 142 | }; |
143 | 143 | ||
144 | 144 | ||
145 | static const char *ir_scheme_names[] = { | ||
146 | [PVR2_IR_SCHEME_NONE] = "none", | ||
147 | [PVR2_IR_SCHEME_29XXX] = "29xxx", | ||
148 | [PVR2_IR_SCHEME_24XXX] = "24xxx (29xxx emulation)", | ||
149 | [PVR2_IR_SCHEME_24XXX_MCE] = "24xxx (MCE device)", | ||
150 | [PVR2_IR_SCHEME_ZILOG] = "Zilog", | ||
151 | }; | ||
152 | |||
153 | |||
145 | /* Define the list of additional controls we'll dynamically construct based | 154 | /* Define the list of additional controls we'll dynamically construct based |
146 | on query of the cx2341x module. */ | 155 | on query of the cx2341x module. */ |
147 | struct pvr2_mpeg_ids { | 156 | struct pvr2_mpeg_ids { |
@@ -2170,7 +2179,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) | |||
2170 | } | 2179 | } |
2171 | 2180 | ||
2172 | /* Take the IR chip out of reset, if appropriate */ | 2181 | /* Take the IR chip out of reset, if appropriate */ |
2173 | if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_ZILOG) { | 2182 | if (hdw->ir_scheme_active == PVR2_IR_SCHEME_ZILOG) { |
2174 | pvr2_issue_simple_cmd(hdw, | 2183 | pvr2_issue_simple_cmd(hdw, |
2175 | FX2CMD_HCW_ZILOG_RESET | | 2184 | FX2CMD_HCW_ZILOG_RESET | |
2176 | (1 << 8) | | 2185 | (1 << 8) | |
@@ -2451,6 +2460,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2451 | GFP_KERNEL); | 2460 | GFP_KERNEL); |
2452 | if (!hdw->controls) goto fail; | 2461 | if (!hdw->controls) goto fail; |
2453 | hdw->hdw_desc = hdw_desc; | 2462 | hdw->hdw_desc = hdw_desc; |
2463 | hdw->ir_scheme_active = hdw->hdw_desc->ir_scheme; | ||
2454 | for (idx = 0; idx < hdw->control_cnt; idx++) { | 2464 | for (idx = 0; idx < hdw->control_cnt; idx++) { |
2455 | cptr = hdw->controls + idx; | 2465 | cptr = hdw->controls + idx; |
2456 | cptr->hdw = hdw; | 2466 | cptr->hdw = hdw; |
@@ -4809,6 +4819,12 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, | |||
4809 | stats.buffers_processed, | 4819 | stats.buffers_processed, |
4810 | stats.buffers_failed); | 4820 | stats.buffers_failed); |
4811 | } | 4821 | } |
4822 | case 6: { | ||
4823 | unsigned int id = hdw->ir_scheme_active; | ||
4824 | return scnprintf(buf, acnt, "ir scheme: id=%d %s", id, | ||
4825 | (id >= ARRAY_SIZE(ir_scheme_names) ? | ||
4826 | "?" : ir_scheme_names[id])); | ||
4827 | } | ||
4812 | default: break; | 4828 | default: break; |
4813 | } | 4829 | } |
4814 | return 0; | 4830 | return 0; |
@@ -4825,65 +4841,35 @@ static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw, | |||
4825 | unsigned int tcnt = 0; | 4841 | unsigned int tcnt = 0; |
4826 | unsigned int ccnt; | 4842 | unsigned int ccnt; |
4827 | struct i2c_client *client; | 4843 | struct i2c_client *client; |
4828 | struct list_head *item; | ||
4829 | void *cd; | ||
4830 | const char *p; | 4844 | const char *p; |
4831 | unsigned int id; | 4845 | unsigned int id; |
4832 | 4846 | ||
4833 | ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers:"); | 4847 | ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers and I2C clients:\n"); |
4834 | tcnt += ccnt; | 4848 | tcnt += ccnt; |
4835 | v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { | 4849 | v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { |
4836 | id = sd->grp_id; | 4850 | id = sd->grp_id; |
4837 | p = NULL; | 4851 | p = NULL; |
4838 | if (id < ARRAY_SIZE(module_names)) p = module_names[id]; | 4852 | if (id < ARRAY_SIZE(module_names)) p = module_names[id]; |
4839 | if (p) { | 4853 | if (p) { |
4840 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s", p); | 4854 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s:", p); |
4841 | tcnt += ccnt; | 4855 | tcnt += ccnt; |
4842 | } else { | 4856 | } else { |
4843 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, | 4857 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, |
4844 | " (unknown id=%u)", id); | 4858 | " (unknown id=%u):", id); |
4845 | tcnt += ccnt; | 4859 | tcnt += ccnt; |
4846 | } | 4860 | } |
4847 | } | 4861 | client = v4l2_get_subdevdata(sd); |
4848 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n"); | 4862 | if (client) { |
4849 | tcnt += ccnt; | 4863 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, |
4850 | 4864 | " %s @ %02x\n", client->name, | |
4851 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n"); | 4865 | client->addr); |
4852 | tcnt += ccnt; | 4866 | tcnt += ccnt; |
4853 | 4867 | } else { | |
4854 | mutex_lock(&hdw->i2c_adap.clist_lock); | 4868 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, |
4855 | list_for_each(item, &hdw->i2c_adap.clients) { | 4869 | " no i2c client\n"); |
4856 | client = list_entry(item, struct i2c_client, list); | 4870 | tcnt += ccnt; |
4857 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, | ||
4858 | " %s: i2c=%02x", client->name, client->addr); | ||
4859 | tcnt += ccnt; | ||
4860 | cd = i2c_get_clientdata(client); | ||
4861 | v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { | ||
4862 | if (cd == sd) { | ||
4863 | id = sd->grp_id; | ||
4864 | p = NULL; | ||
4865 | if (id < ARRAY_SIZE(module_names)) { | ||
4866 | p = module_names[id]; | ||
4867 | } | ||
4868 | if (p) { | ||
4869 | ccnt = scnprintf(buf + tcnt, | ||
4870 | acnt - tcnt, | ||
4871 | " subdev=%s", p); | ||
4872 | tcnt += ccnt; | ||
4873 | } else { | ||
4874 | ccnt = scnprintf(buf + tcnt, | ||
4875 | acnt - tcnt, | ||
4876 | " subdev= id %u)", | ||
4877 | id); | ||
4878 | tcnt += ccnt; | ||
4879 | } | ||
4880 | break; | ||
4881 | } | ||
4882 | } | 4871 | } |
4883 | ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n"); | ||
4884 | tcnt += ccnt; | ||
4885 | } | 4872 | } |
4886 | mutex_unlock(&hdw->i2c_adap.clist_lock); | ||
4887 | return tcnt; | 4873 | return tcnt; |
4888 | } | 4874 | } |
4889 | 4875 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 9af282f9e765..610bd848df24 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | |||
@@ -42,6 +42,18 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 }; | |||
42 | module_param_array(ir_mode, int, NULL, 0444); | 42 | module_param_array(ir_mode, int, NULL, 0444); |
43 | MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR"); | 43 | MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR"); |
44 | 44 | ||
45 | static int pvr2_disable_ir_video; | ||
46 | module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video, | ||
47 | int, S_IRUGO|S_IWUSR); | ||
48 | MODULE_PARM_DESC(disable_autoload_ir_video, | ||
49 | "1=do not try to autoload ir_video IR receiver"); | ||
50 | |||
51 | /* Mapping of IR schemes to known I2C addresses - if any */ | ||
52 | static const unsigned char ir_video_addresses[] = { | ||
53 | [PVR2_IR_SCHEME_29XXX] = 0x18, | ||
54 | [PVR2_IR_SCHEME_24XXX] = 0x18, | ||
55 | }; | ||
56 | |||
45 | static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ | 57 | static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ |
46 | u8 i2c_addr, /* I2C address we're talking to */ | 58 | u8 i2c_addr, /* I2C address we're talking to */ |
47 | u8 *data, /* Data to write */ | 59 | u8 *data, /* Data to write */ |
@@ -559,6 +571,31 @@ static void do_i2c_scan(struct pvr2_hdw *hdw) | |||
559 | printk(KERN_INFO "%s: i2c scan done.\n", hdw->name); | 571 | printk(KERN_INFO "%s: i2c scan done.\n", hdw->name); |
560 | } | 572 | } |
561 | 573 | ||
574 | static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw) | ||
575 | { | ||
576 | struct i2c_board_info info; | ||
577 | unsigned char addr = 0; | ||
578 | if (pvr2_disable_ir_video) { | ||
579 | pvr2_trace(PVR2_TRACE_INFO, | ||
580 | "Automatic binding of ir_video has been disabled."); | ||
581 | return; | ||
582 | } | ||
583 | if (hdw->ir_scheme_active < ARRAY_SIZE(ir_video_addresses)) { | ||
584 | addr = ir_video_addresses[hdw->ir_scheme_active]; | ||
585 | } | ||
586 | if (!addr) { | ||
587 | /* The device either doesn't support I2C-based IR or we | ||
588 | don't know (yet) how to operate IR on the device. */ | ||
589 | return; | ||
590 | } | ||
591 | pvr2_trace(PVR2_TRACE_INFO, | ||
592 | "Binding ir_video to i2c address 0x%02x.", addr); | ||
593 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
594 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
595 | info.addr = addr; | ||
596 | i2c_new_device(&hdw->i2c_adap, &info); | ||
597 | } | ||
598 | |||
562 | void pvr2_i2c_core_init(struct pvr2_hdw *hdw) | 599 | void pvr2_i2c_core_init(struct pvr2_hdw *hdw) |
563 | { | 600 | { |
564 | unsigned int idx; | 601 | unsigned int idx; |
@@ -574,7 +611,9 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) | |||
574 | printk(KERN_INFO "%s: IR disabled\n",hdw->name); | 611 | printk(KERN_INFO "%s: IR disabled\n",hdw->name); |
575 | hdw->i2c_func[0x18] = i2c_black_hole; | 612 | hdw->i2c_func[0x18] = i2c_black_hole; |
576 | } else if (ir_mode[hdw->unit_number] == 1) { | 613 | } else if (ir_mode[hdw->unit_number] == 1) { |
577 | if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) { | 614 | if (hdw->ir_scheme_active == PVR2_IR_SCHEME_24XXX) { |
615 | /* Set up translation so that our IR looks like a | ||
616 | 29xxx device */ | ||
578 | hdw->i2c_func[0x18] = i2c_24xxx_ir; | 617 | hdw->i2c_func[0x18] = i2c_24xxx_ir; |
579 | } | 618 | } |
580 | } | 619 | } |
@@ -597,15 +636,23 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) | |||
597 | i2c_add_adapter(&hdw->i2c_adap); | 636 | i2c_add_adapter(&hdw->i2c_adap); |
598 | if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { | 637 | if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { |
599 | /* Probe for a different type of IR receiver on this | 638 | /* Probe for a different type of IR receiver on this |
600 | device. If present, disable the emulated IR receiver. */ | 639 | device. This is really the only way to differentiate |
640 | older 24xxx devices from 24xxx variants that include an | ||
641 | IR blaster. If the IR blaster is present, the IR | ||
642 | receiver is part of that chip and thus we must disable | ||
643 | the emulated IR receiver. */ | ||
601 | if (do_i2c_probe(hdw, 0x71)) { | 644 | if (do_i2c_probe(hdw, 0x71)) { |
602 | pvr2_trace(PVR2_TRACE_INFO, | 645 | pvr2_trace(PVR2_TRACE_INFO, |
603 | "Device has newer IR hardware;" | 646 | "Device has newer IR hardware;" |
604 | " disabling unneeded virtual IR device"); | 647 | " disabling unneeded virtual IR device"); |
605 | hdw->i2c_func[0x18] = NULL; | 648 | hdw->i2c_func[0x18] = NULL; |
649 | /* Remember that this is a different device... */ | ||
650 | hdw->ir_scheme_active = PVR2_IR_SCHEME_24XXX_MCE; | ||
606 | } | 651 | } |
607 | } | 652 | } |
608 | if (i2c_scan) do_i2c_scan(hdw); | 653 | if (i2c_scan) do_i2c_scan(hdw); |
654 | |||
655 | pvr2_i2c_register_ir(hdw); | ||
609 | } | 656 | } |
610 | 657 | ||
611 | void pvr2_i2c_core_done(struct pvr2_hdw *hdw) | 658 | void pvr2_i2c_core_done(struct pvr2_hdw *hdw) |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 9e0f2b07b93b..2d8825e5b1be 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -90,7 +90,7 @@ static struct v4l2_capability pvr_capability ={ | |||
90 | .driver = "pvrusb2", | 90 | .driver = "pvrusb2", |
91 | .card = "Hauppauge WinTV pvr-usb2", | 91 | .card = "Hauppauge WinTV pvr-usb2", |
92 | .bus_info = "usb", | 92 | .bus_info = "usb", |
93 | .version = KERNEL_VERSION(0,8,0), | 93 | .version = KERNEL_VERSION(0, 9, 0), |
94 | .capabilities = (V4L2_CAP_VIDEO_CAPTURE | | 94 | .capabilities = (V4L2_CAP_VIDEO_CAPTURE | |
95 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | | 95 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | |
96 | V4L2_CAP_READWRITE), | 96 | V4L2_CAP_READWRITE), |
@@ -267,7 +267,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
267 | memset(&tmp,0,sizeof(tmp)); | 267 | memset(&tmp,0,sizeof(tmp)); |
268 | tmp.index = vi->index; | 268 | tmp.index = vi->index; |
269 | ret = 0; | 269 | ret = 0; |
270 | if ((vi->index < 0) || (vi->index >= fh->input_cnt)) { | 270 | if (vi->index >= fh->input_cnt) { |
271 | ret = -EINVAL; | 271 | ret = -EINVAL; |
272 | break; | 272 | break; |
273 | } | 273 | } |
@@ -331,7 +331,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
331 | case VIDIOC_S_INPUT: | 331 | case VIDIOC_S_INPUT: |
332 | { | 332 | { |
333 | struct v4l2_input *vi = (struct v4l2_input *)arg; | 333 | struct v4l2_input *vi = (struct v4l2_input *)arg; |
334 | if ((vi->index < 0) || (vi->index >= fh->input_cnt)) { | 334 | if (vi->index >= fh->input_cnt) { |
335 | ret = -ERANGE; | 335 | ret = -ERANGE; |
336 | break; | 336 | break; |
337 | } | 337 | } |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 7c542caf248e..db25c3034c11 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -601,7 +601,7 @@ static void pwc_snapshot_button(struct pwc_device *pdev, int down) | |||
601 | 601 | ||
602 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 602 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
603 | if (pdev->button_dev) { | 603 | if (pdev->button_dev) { |
604 | input_report_key(pdev->button_dev, BTN_0, down); | 604 | input_report_key(pdev->button_dev, KEY_CAMERA, down); |
605 | input_sync(pdev->button_dev); | 605 | input_sync(pdev->button_dev); |
606 | } | 606 | } |
607 | #endif | 607 | #endif |
@@ -1783,7 +1783,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1783 | return -ENOMEM; | 1783 | return -ENOMEM; |
1784 | } | 1784 | } |
1785 | memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); | 1785 | memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); |
1786 | pdev->vdev->parent = &(udev->dev); | 1786 | pdev->vdev->parent = &intf->dev; |
1787 | strcpy(pdev->vdev->name, name); | 1787 | strcpy(pdev->vdev->name, name); |
1788 | video_set_drvdata(pdev->vdev, pdev); | 1788 | video_set_drvdata(pdev->vdev, pdev); |
1789 | 1789 | ||
@@ -1847,7 +1847,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1847 | usb_to_input_id(pdev->udev, &pdev->button_dev->id); | 1847 | usb_to_input_id(pdev->udev, &pdev->button_dev->id); |
1848 | pdev->button_dev->dev.parent = &pdev->udev->dev; | 1848 | pdev->button_dev->dev.parent = &pdev->udev->dev; |
1849 | pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY); | 1849 | pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY); |
1850 | pdev->button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); | 1850 | pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); |
1851 | 1851 | ||
1852 | rc = input_register_device(pdev->button_dev); | 1852 | rc = input_register_device(pdev->button_dev); |
1853 | if (rc) { | 1853 | if (rc) { |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index bc0a464295c5..2876ce084510 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -1107,7 +1107,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1107 | return -EINVAL; | 1107 | return -EINVAL; |
1108 | if (buf->memory != V4L2_MEMORY_MMAP) | 1108 | if (buf->memory != V4L2_MEMORY_MMAP) |
1109 | return -EINVAL; | 1109 | return -EINVAL; |
1110 | if (buf->index < 0 || buf->index >= pwc_mbufs) | 1110 | if (buf->index >= pwc_mbufs) |
1111 | return -EINVAL; | 1111 | return -EINVAL; |
1112 | 1112 | ||
1113 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | 1113 | buf->flags |= V4L2_BUF_FLAG_QUEUED; |
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index c639845460ff..f60de40fd21f 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
@@ -202,7 +202,7 @@ struct pxa_buffer { | |||
202 | }; | 202 | }; |
203 | 203 | ||
204 | struct pxa_camera_dev { | 204 | struct pxa_camera_dev { |
205 | struct device *dev; | 205 | struct soc_camera_host soc_host; |
206 | /* PXA27x is only supposed to handle one camera on its Quick Capture | 206 | /* PXA27x is only supposed to handle one camera on its Quick Capture |
207 | * interface. If anyone ever builds hardware to enable more than | 207 | * interface. If anyone ever builds hardware to enable more than |
208 | * one camera, they will have to modify this driver too */ | 208 | * one camera, they will have to modify this driver too */ |
@@ -261,7 +261,6 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) | |||
261 | { | 261 | { |
262 | struct soc_camera_device *icd = vq->priv_data; | 262 | struct soc_camera_device *icd = vq->priv_data; |
263 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 263 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
264 | struct pxa_camera_dev *pcdev = ici->priv; | ||
265 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | 264 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); |
266 | int i; | 265 | int i; |
267 | 266 | ||
@@ -278,7 +277,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) | |||
278 | 277 | ||
279 | for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) { | 278 | for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) { |
280 | if (buf->dmas[i].sg_cpu) | 279 | if (buf->dmas[i].sg_cpu) |
281 | dma_free_coherent(pcdev->dev, buf->dmas[i].sg_size, | 280 | dma_free_coherent(ici->dev, buf->dmas[i].sg_size, |
282 | buf->dmas[i].sg_cpu, | 281 | buf->dmas[i].sg_cpu, |
283 | buf->dmas[i].sg_dma); | 282 | buf->dmas[i].sg_dma); |
284 | buf->dmas[i].sg_cpu = NULL; | 283 | buf->dmas[i].sg_cpu = NULL; |
@@ -338,14 +337,14 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev, | |||
338 | int dma_len = 0, xfer_len = 0; | 337 | int dma_len = 0, xfer_len = 0; |
339 | 338 | ||
340 | if (pxa_dma->sg_cpu) | 339 | if (pxa_dma->sg_cpu) |
341 | dma_free_coherent(pcdev->dev, pxa_dma->sg_size, | 340 | dma_free_coherent(pcdev->soc_host.dev, pxa_dma->sg_size, |
342 | pxa_dma->sg_cpu, pxa_dma->sg_dma); | 341 | pxa_dma->sg_cpu, pxa_dma->sg_dma); |
343 | 342 | ||
344 | sglen = calculate_dma_sglen(*sg_first, dma->sglen, | 343 | sglen = calculate_dma_sglen(*sg_first, dma->sglen, |
345 | *sg_first_ofs, size); | 344 | *sg_first_ofs, size); |
346 | 345 | ||
347 | pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc); | 346 | pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc); |
348 | pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->dev, pxa_dma->sg_size, | 347 | pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->soc_host.dev, pxa_dma->sg_size, |
349 | &pxa_dma->sg_dma, GFP_KERNEL); | 348 | &pxa_dma->sg_dma, GFP_KERNEL); |
350 | if (!pxa_dma->sg_cpu) | 349 | if (!pxa_dma->sg_cpu) |
351 | return -ENOMEM; | 350 | return -ENOMEM; |
@@ -353,7 +352,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev, | |||
353 | pxa_dma->sglen = sglen; | 352 | pxa_dma->sglen = sglen; |
354 | offset = *sg_first_ofs; | 353 | offset = *sg_first_ofs; |
355 | 354 | ||
356 | dev_dbg(pcdev->dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n", | 355 | dev_dbg(pcdev->soc_host.dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n", |
357 | *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma); | 356 | *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma); |
358 | 357 | ||
359 | 358 | ||
@@ -376,7 +375,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev, | |||
376 | pxa_dma->sg_cpu[i].ddadr = | 375 | pxa_dma->sg_cpu[i].ddadr = |
377 | pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc); | 376 | pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc); |
378 | 377 | ||
379 | dev_vdbg(pcdev->dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n", | 378 | dev_vdbg(pcdev->soc_host.dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n", |
380 | pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc), | 379 | pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc), |
381 | sg_dma_address(sg) + offset, xfer_len); | 380 | sg_dma_address(sg) + offset, xfer_len); |
382 | offset = 0; | 381 | offset = 0; |
@@ -488,7 +487,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, | |||
488 | ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y, | 487 | ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y, |
489 | &sg, &next_ofs); | 488 | &sg, &next_ofs); |
490 | if (ret) { | 489 | if (ret) { |
491 | dev_err(pcdev->dev, | 490 | dev_err(pcdev->soc_host.dev, |
492 | "DMA initialization for Y/RGB failed\n"); | 491 | "DMA initialization for Y/RGB failed\n"); |
493 | goto fail; | 492 | goto fail; |
494 | } | 493 | } |
@@ -498,7 +497,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, | |||
498 | ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1, | 497 | ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1, |
499 | size_u, &sg, &next_ofs); | 498 | size_u, &sg, &next_ofs); |
500 | if (ret) { | 499 | if (ret) { |
501 | dev_err(pcdev->dev, | 500 | dev_err(pcdev->soc_host.dev, |
502 | "DMA initialization for U failed\n"); | 501 | "DMA initialization for U failed\n"); |
503 | goto fail_u; | 502 | goto fail_u; |
504 | } | 503 | } |
@@ -508,7 +507,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, | |||
508 | ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2, | 507 | ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2, |
509 | size_v, &sg, &next_ofs); | 508 | size_v, &sg, &next_ofs); |
510 | if (ret) { | 509 | if (ret) { |
511 | dev_err(pcdev->dev, | 510 | dev_err(pcdev->soc_host.dev, |
512 | "DMA initialization for V failed\n"); | 511 | "DMA initialization for V failed\n"); |
513 | goto fail_v; | 512 | goto fail_v; |
514 | } | 513 | } |
@@ -522,10 +521,10 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, | |||
522 | return 0; | 521 | return 0; |
523 | 522 | ||
524 | fail_v: | 523 | fail_v: |
525 | dma_free_coherent(pcdev->dev, buf->dmas[1].sg_size, | 524 | dma_free_coherent(pcdev->soc_host.dev, buf->dmas[1].sg_size, |
526 | buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma); | 525 | buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma); |
527 | fail_u: | 526 | fail_u: |
528 | dma_free_coherent(pcdev->dev, buf->dmas[0].sg_size, | 527 | dma_free_coherent(pcdev->soc_host.dev, buf->dmas[0].sg_size, |
529 | buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma); | 528 | buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma); |
530 | fail: | 529 | fail: |
531 | free_buffer(vq, buf); | 530 | free_buffer(vq, buf); |
@@ -549,7 +548,7 @@ static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev) | |||
549 | active = pcdev->active; | 548 | active = pcdev->active; |
550 | 549 | ||
551 | for (i = 0; i < pcdev->channels; i++) { | 550 | for (i = 0; i < pcdev->channels; i++) { |
552 | dev_dbg(pcdev->dev, "%s (channel=%d) ddadr=%08x\n", __func__, | 551 | dev_dbg(pcdev->soc_host.dev, "%s (channel=%d) ddadr=%08x\n", __func__, |
553 | i, active->dmas[i].sg_dma); | 552 | i, active->dmas[i].sg_dma); |
554 | DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma; | 553 | DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma; |
555 | DCSR(pcdev->dma_chans[i]) = DCSR_RUN; | 554 | DCSR(pcdev->dma_chans[i]) = DCSR_RUN; |
@@ -561,7 +560,7 @@ static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev) | |||
561 | int i; | 560 | int i; |
562 | 561 | ||
563 | for (i = 0; i < pcdev->channels; i++) { | 562 | for (i = 0; i < pcdev->channels; i++) { |
564 | dev_dbg(pcdev->dev, "%s (channel=%d)\n", __func__, i); | 563 | dev_dbg(pcdev->soc_host.dev, "%s (channel=%d)\n", __func__, i); |
565 | DCSR(pcdev->dma_chans[i]) = 0; | 564 | DCSR(pcdev->dma_chans[i]) = 0; |
566 | } | 565 | } |
567 | } | 566 | } |
@@ -597,7 +596,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev) | |||
597 | { | 596 | { |
598 | unsigned long cicr0, cifr; | 597 | unsigned long cicr0, cifr; |
599 | 598 | ||
600 | dev_dbg(pcdev->dev, "%s\n", __func__); | 599 | dev_dbg(pcdev->soc_host.dev, "%s\n", __func__); |
601 | /* Reset the FIFOs */ | 600 | /* Reset the FIFOs */ |
602 | cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F; | 601 | cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F; |
603 | __raw_writel(cifr, pcdev->base + CIFR); | 602 | __raw_writel(cifr, pcdev->base + CIFR); |
@@ -617,7 +616,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev) | |||
617 | __raw_writel(cicr0, pcdev->base + CICR0); | 616 | __raw_writel(cicr0, pcdev->base + CICR0); |
618 | 617 | ||
619 | pcdev->active = NULL; | 618 | pcdev->active = NULL; |
620 | dev_dbg(pcdev->dev, "%s\n", __func__); | 619 | dev_dbg(pcdev->soc_host.dev, "%s\n", __func__); |
621 | } | 620 | } |
622 | 621 | ||
623 | static void pxa_videobuf_queue(struct videobuf_queue *vq, | 622 | static void pxa_videobuf_queue(struct videobuf_queue *vq, |
@@ -686,7 +685,7 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev, | |||
686 | do_gettimeofday(&vb->ts); | 685 | do_gettimeofday(&vb->ts); |
687 | vb->field_count++; | 686 | vb->field_count++; |
688 | wake_up(&vb->done); | 687 | wake_up(&vb->done); |
689 | dev_dbg(pcdev->dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb); | 688 | dev_dbg(pcdev->soc_host.dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb); |
690 | 689 | ||
691 | if (list_empty(&pcdev->capture)) { | 690 | if (list_empty(&pcdev->capture)) { |
692 | pxa_camera_stop_capture(pcdev); | 691 | pxa_camera_stop_capture(pcdev); |
@@ -722,7 +721,7 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev) | |||
722 | for (i = 0; i < pcdev->channels; i++) | 721 | for (i = 0; i < pcdev->channels; i++) |
723 | if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP) | 722 | if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP) |
724 | is_dma_stopped = 0; | 723 | is_dma_stopped = 0; |
725 | dev_dbg(pcdev->dev, "%s : top queued buffer=%p, dma_stopped=%d\n", | 724 | dev_dbg(pcdev->soc_host.dev, "%s : top queued buffer=%p, dma_stopped=%d\n", |
726 | __func__, pcdev->active, is_dma_stopped); | 725 | __func__, pcdev->active, is_dma_stopped); |
727 | if (pcdev->active && is_dma_stopped) | 726 | if (pcdev->active && is_dma_stopped) |
728 | pxa_camera_start_capture(pcdev); | 727 | pxa_camera_start_capture(pcdev); |
@@ -747,12 +746,12 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, | |||
747 | overrun |= CISR_IFO_1 | CISR_IFO_2; | 746 | overrun |= CISR_IFO_1 | CISR_IFO_2; |
748 | 747 | ||
749 | if (status & DCSR_BUSERR) { | 748 | if (status & DCSR_BUSERR) { |
750 | dev_err(pcdev->dev, "DMA Bus Error IRQ!\n"); | 749 | dev_err(pcdev->soc_host.dev, "DMA Bus Error IRQ!\n"); |
751 | goto out; | 750 | goto out; |
752 | } | 751 | } |
753 | 752 | ||
754 | if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) { | 753 | if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) { |
755 | dev_err(pcdev->dev, "Unknown DMA IRQ source, " | 754 | dev_err(pcdev->soc_host.dev, "Unknown DMA IRQ source, " |
756 | "status: 0x%08x\n", status); | 755 | "status: 0x%08x\n", status); |
757 | goto out; | 756 | goto out; |
758 | } | 757 | } |
@@ -776,7 +775,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, | |||
776 | buf = container_of(vb, struct pxa_buffer, vb); | 775 | buf = container_of(vb, struct pxa_buffer, vb); |
777 | WARN_ON(buf->inwork || list_empty(&vb->queue)); | 776 | WARN_ON(buf->inwork || list_empty(&vb->queue)); |
778 | 777 | ||
779 | dev_dbg(pcdev->dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n", | 778 | dev_dbg(pcdev->soc_host.dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n", |
780 | __func__, channel, status & DCSR_STARTINTR ? "SOF " : "", | 779 | __func__, channel, status & DCSR_STARTINTR ? "SOF " : "", |
781 | status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel)); | 780 | status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel)); |
782 | 781 | ||
@@ -787,7 +786,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, | |||
787 | */ | 786 | */ |
788 | if (camera_status & overrun && | 787 | if (camera_status & overrun && |
789 | !list_is_last(pcdev->capture.next, &pcdev->capture)) { | 788 | !list_is_last(pcdev->capture.next, &pcdev->capture)) { |
790 | dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", | 789 | dev_dbg(pcdev->soc_host.dev, "FIFO overrun! CISR: %x\n", |
791 | camera_status); | 790 | camera_status); |
792 | pxa_camera_stop_capture(pcdev); | 791 | pxa_camera_stop_capture(pcdev); |
793 | pxa_camera_start_capture(pcdev); | 792 | pxa_camera_start_capture(pcdev); |
@@ -854,7 +853,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev) | |||
854 | /* mclk <= ciclk / 4 (27.4.2) */ | 853 | /* mclk <= ciclk / 4 (27.4.2) */ |
855 | if (mclk > lcdclk / 4) { | 854 | if (mclk > lcdclk / 4) { |
856 | mclk = lcdclk / 4; | 855 | mclk = lcdclk / 4; |
857 | dev_warn(pcdev->dev, "Limiting master clock to %lu\n", mclk); | 856 | dev_warn(pcdev->soc_host.dev, "Limiting master clock to %lu\n", mclk); |
858 | } | 857 | } |
859 | 858 | ||
860 | /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */ | 859 | /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */ |
@@ -864,7 +863,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev) | |||
864 | if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) | 863 | if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) |
865 | pcdev->mclk = lcdclk / (2 * (div + 1)); | 864 | pcdev->mclk = lcdclk / (2 * (div + 1)); |
866 | 865 | ||
867 | dev_dbg(pcdev->dev, "LCD clock %luHz, target freq %luHz, " | 866 | dev_dbg(pcdev->soc_host.dev, "LCD clock %luHz, target freq %luHz, " |
868 | "divisor %u\n", lcdclk, mclk, div); | 867 | "divisor %u\n", lcdclk, mclk, div); |
869 | 868 | ||
870 | return div; | 869 | return div; |
@@ -884,12 +883,12 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) | |||
884 | struct pxacamera_platform_data *pdata = pcdev->pdata; | 883 | struct pxacamera_platform_data *pdata = pcdev->pdata; |
885 | u32 cicr4 = 0; | 884 | u32 cicr4 = 0; |
886 | 885 | ||
887 | dev_dbg(pcdev->dev, "Registered platform device at %p data %p\n", | 886 | dev_dbg(pcdev->soc_host.dev, "Registered platform device at %p data %p\n", |
888 | pcdev, pdata); | 887 | pcdev, pdata); |
889 | 888 | ||
890 | if (pdata && pdata->init) { | 889 | if (pdata && pdata->init) { |
891 | dev_dbg(pcdev->dev, "%s: Init gpios\n", __func__); | 890 | dev_dbg(pcdev->soc_host.dev, "%s: Init gpios\n", __func__); |
892 | pdata->init(pcdev->dev); | 891 | pdata->init(pcdev->soc_host.dev); |
893 | } | 892 | } |
894 | 893 | ||
895 | /* disable all interrupts */ | 894 | /* disable all interrupts */ |
@@ -931,7 +930,7 @@ static irqreturn_t pxa_camera_irq(int irq, void *data) | |||
931 | struct videobuf_buffer *vb; | 930 | struct videobuf_buffer *vb; |
932 | 931 | ||
933 | status = __raw_readl(pcdev->base + CISR); | 932 | status = __raw_readl(pcdev->base + CISR); |
934 | dev_dbg(pcdev->dev, "Camera interrupt status 0x%lx\n", status); | 933 | dev_dbg(pcdev->soc_host.dev, "Camera interrupt status 0x%lx\n", status); |
935 | 934 | ||
936 | if (!status) | 935 | if (!status) |
937 | return IRQ_NONE; | 936 | return IRQ_NONE; |
@@ -1259,7 +1258,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
1259 | xlate->cam_fmt = icd->formats + idx; | 1258 | xlate->cam_fmt = icd->formats + idx; |
1260 | xlate->buswidth = buswidth; | 1259 | xlate->buswidth = buswidth; |
1261 | xlate++; | 1260 | xlate++; |
1262 | dev_dbg(&ici->dev, "Providing format %s using %s\n", | 1261 | dev_dbg(ici->dev, "Providing format %s using %s\n", |
1263 | pxa_camera_formats[0].name, | 1262 | pxa_camera_formats[0].name, |
1264 | icd->formats[idx].name); | 1263 | icd->formats[idx].name); |
1265 | } | 1264 | } |
@@ -1274,7 +1273,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
1274 | xlate->cam_fmt = icd->formats + idx; | 1273 | xlate->cam_fmt = icd->formats + idx; |
1275 | xlate->buswidth = buswidth; | 1274 | xlate->buswidth = buswidth; |
1276 | xlate++; | 1275 | xlate++; |
1277 | dev_dbg(&ici->dev, "Providing format %s packed\n", | 1276 | dev_dbg(ici->dev, "Providing format %s packed\n", |
1278 | icd->formats[idx].name); | 1277 | icd->formats[idx].name); |
1279 | } | 1278 | } |
1280 | break; | 1279 | break; |
@@ -1286,7 +1285,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
1286 | xlate->cam_fmt = icd->formats + idx; | 1285 | xlate->cam_fmt = icd->formats + idx; |
1287 | xlate->buswidth = icd->formats[idx].depth; | 1286 | xlate->buswidth = icd->formats[idx].depth; |
1288 | xlate++; | 1287 | xlate++; |
1289 | dev_dbg(&ici->dev, | 1288 | dev_dbg(ici->dev, |
1290 | "Providing format %s in pass-through mode\n", | 1289 | "Providing format %s in pass-through mode\n", |
1291 | icd->formats[idx].name); | 1290 | icd->formats[idx].name); |
1292 | } | 1291 | } |
@@ -1315,11 +1314,11 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, | |||
1315 | icd->sense = NULL; | 1314 | icd->sense = NULL; |
1316 | 1315 | ||
1317 | if (ret < 0) { | 1316 | if (ret < 0) { |
1318 | dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n", | 1317 | dev_warn(ici->dev, "Failed to crop to %ux%u@%u:%u\n", |
1319 | rect->width, rect->height, rect->left, rect->top); | 1318 | rect->width, rect->height, rect->left, rect->top); |
1320 | } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { | 1319 | } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { |
1321 | if (sense.pixel_clock > sense.pixel_clock_max) { | 1320 | if (sense.pixel_clock > sense.pixel_clock_max) { |
1322 | dev_err(&ici->dev, | 1321 | dev_err(ici->dev, |
1323 | "pixel clock %lu set by the camera too high!", | 1322 | "pixel clock %lu set by the camera too high!", |
1324 | sense.pixel_clock); | 1323 | sense.pixel_clock); |
1325 | return -EIO; | 1324 | return -EIO; |
@@ -1347,7 +1346,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, | |||
1347 | 1346 | ||
1348 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 1347 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
1349 | if (!xlate) { | 1348 | if (!xlate) { |
1350 | dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); | 1349 | dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); |
1351 | return -EINVAL; | 1350 | return -EINVAL; |
1352 | } | 1351 | } |
1353 | 1352 | ||
@@ -1363,11 +1362,11 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, | |||
1363 | icd->sense = NULL; | 1362 | icd->sense = NULL; |
1364 | 1363 | ||
1365 | if (ret < 0) { | 1364 | if (ret < 0) { |
1366 | dev_warn(&ici->dev, "Failed to configure for format %x\n", | 1365 | dev_warn(ici->dev, "Failed to configure for format %x\n", |
1367 | pix->pixelformat); | 1366 | pix->pixelformat); |
1368 | } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { | 1367 | } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { |
1369 | if (sense.pixel_clock > sense.pixel_clock_max) { | 1368 | if (sense.pixel_clock > sense.pixel_clock_max) { |
1370 | dev_err(&ici->dev, | 1369 | dev_err(ici->dev, |
1371 | "pixel clock %lu set by the camera too high!", | 1370 | "pixel clock %lu set by the camera too high!", |
1372 | sense.pixel_clock); | 1371 | sense.pixel_clock); |
1373 | return -EIO; | 1372 | return -EIO; |
@@ -1395,7 +1394,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, | |||
1395 | 1394 | ||
1396 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 1395 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
1397 | if (!xlate) { | 1396 | if (!xlate) { |
1398 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 1397 | dev_warn(ici->dev, "Format %x not found\n", pixfmt); |
1399 | return -EINVAL; | 1398 | return -EINVAL; |
1400 | } | 1399 | } |
1401 | 1400 | ||
@@ -1552,13 +1551,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = { | |||
1552 | .set_bus_param = pxa_camera_set_bus_param, | 1551 | .set_bus_param = pxa_camera_set_bus_param, |
1553 | }; | 1552 | }; |
1554 | 1553 | ||
1555 | /* Should be allocated dynamically too, but we have only one. */ | 1554 | static int __devinit pxa_camera_probe(struct platform_device *pdev) |
1556 | static struct soc_camera_host pxa_soc_camera_host = { | ||
1557 | .drv_name = PXA_CAM_DRV_NAME, | ||
1558 | .ops = &pxa_soc_camera_host_ops, | ||
1559 | }; | ||
1560 | |||
1561 | static int pxa_camera_probe(struct platform_device *pdev) | ||
1562 | { | 1555 | { |
1563 | struct pxa_camera_dev *pcdev; | 1556 | struct pxa_camera_dev *pcdev; |
1564 | struct resource *res; | 1557 | struct resource *res; |
@@ -1586,7 +1579,6 @@ static int pxa_camera_probe(struct platform_device *pdev) | |||
1586 | goto exit_kfree; | 1579 | goto exit_kfree; |
1587 | } | 1580 | } |
1588 | 1581 | ||
1589 | dev_set_drvdata(&pdev->dev, pcdev); | ||
1590 | pcdev->res = res; | 1582 | pcdev->res = res; |
1591 | 1583 | ||
1592 | pcdev->pdata = pdev->dev.platform_data; | 1584 | pcdev->pdata = pdev->dev.platform_data; |
@@ -1607,7 +1599,6 @@ static int pxa_camera_probe(struct platform_device *pdev) | |||
1607 | pcdev->mclk = 20000000; | 1599 | pcdev->mclk = 20000000; |
1608 | } | 1600 | } |
1609 | 1601 | ||
1610 | pcdev->dev = &pdev->dev; | ||
1611 | pcdev->mclk_divisor = mclk_get_divisor(pcdev); | 1602 | pcdev->mclk_divisor = mclk_get_divisor(pcdev); |
1612 | 1603 | ||
1613 | INIT_LIST_HEAD(&pcdev->capture); | 1604 | INIT_LIST_HEAD(&pcdev->capture); |
@@ -1616,13 +1607,13 @@ static int pxa_camera_probe(struct platform_device *pdev) | |||
1616 | /* | 1607 | /* |
1617 | * Request the regions. | 1608 | * Request the regions. |
1618 | */ | 1609 | */ |
1619 | if (!request_mem_region(res->start, res->end - res->start + 1, | 1610 | if (!request_mem_region(res->start, resource_size(res), |
1620 | PXA_CAM_DRV_NAME)) { | 1611 | PXA_CAM_DRV_NAME)) { |
1621 | err = -EBUSY; | 1612 | err = -EBUSY; |
1622 | goto exit_clk; | 1613 | goto exit_clk; |
1623 | } | 1614 | } |
1624 | 1615 | ||
1625 | base = ioremap(res->start, res->end - res->start + 1); | 1616 | base = ioremap(res->start, resource_size(res)); |
1626 | if (!base) { | 1617 | if (!base) { |
1627 | err = -ENOMEM; | 1618 | err = -ENOMEM; |
1628 | goto exit_release; | 1619 | goto exit_release; |
@@ -1634,29 +1625,29 @@ static int pxa_camera_probe(struct platform_device *pdev) | |||
1634 | err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, | 1625 | err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, |
1635 | pxa_camera_dma_irq_y, pcdev); | 1626 | pxa_camera_dma_irq_y, pcdev); |
1636 | if (err < 0) { | 1627 | if (err < 0) { |
1637 | dev_err(pcdev->dev, "Can't request DMA for Y\n"); | 1628 | dev_err(&pdev->dev, "Can't request DMA for Y\n"); |
1638 | goto exit_iounmap; | 1629 | goto exit_iounmap; |
1639 | } | 1630 | } |
1640 | pcdev->dma_chans[0] = err; | 1631 | pcdev->dma_chans[0] = err; |
1641 | dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]); | 1632 | dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]); |
1642 | 1633 | ||
1643 | err = pxa_request_dma("CI_U", DMA_PRIO_HIGH, | 1634 | err = pxa_request_dma("CI_U", DMA_PRIO_HIGH, |
1644 | pxa_camera_dma_irq_u, pcdev); | 1635 | pxa_camera_dma_irq_u, pcdev); |
1645 | if (err < 0) { | 1636 | if (err < 0) { |
1646 | dev_err(pcdev->dev, "Can't request DMA for U\n"); | 1637 | dev_err(&pdev->dev, "Can't request DMA for U\n"); |
1647 | goto exit_free_dma_y; | 1638 | goto exit_free_dma_y; |
1648 | } | 1639 | } |
1649 | pcdev->dma_chans[1] = err; | 1640 | pcdev->dma_chans[1] = err; |
1650 | dev_dbg(pcdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]); | 1641 | dev_dbg(&pdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]); |
1651 | 1642 | ||
1652 | err = pxa_request_dma("CI_V", DMA_PRIO_HIGH, | 1643 | err = pxa_request_dma("CI_V", DMA_PRIO_HIGH, |
1653 | pxa_camera_dma_irq_v, pcdev); | 1644 | pxa_camera_dma_irq_v, pcdev); |
1654 | if (err < 0) { | 1645 | if (err < 0) { |
1655 | dev_err(pcdev->dev, "Can't request DMA for V\n"); | 1646 | dev_err(&pdev->dev, "Can't request DMA for V\n"); |
1656 | goto exit_free_dma_u; | 1647 | goto exit_free_dma_u; |
1657 | } | 1648 | } |
1658 | pcdev->dma_chans[2] = err; | 1649 | pcdev->dma_chans[2] = err; |
1659 | dev_dbg(pcdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]); | 1650 | dev_dbg(&pdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]); |
1660 | 1651 | ||
1661 | DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD; | 1652 | DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD; |
1662 | DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD; | 1653 | DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD; |
@@ -1666,14 +1657,17 @@ static int pxa_camera_probe(struct platform_device *pdev) | |||
1666 | err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME, | 1657 | err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME, |
1667 | pcdev); | 1658 | pcdev); |
1668 | if (err) { | 1659 | if (err) { |
1669 | dev_err(pcdev->dev, "Camera interrupt register failed \n"); | 1660 | dev_err(&pdev->dev, "Camera interrupt register failed \n"); |
1670 | goto exit_free_dma; | 1661 | goto exit_free_dma; |
1671 | } | 1662 | } |
1672 | 1663 | ||
1673 | pxa_soc_camera_host.priv = pcdev; | 1664 | pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME; |
1674 | pxa_soc_camera_host.dev.parent = &pdev->dev; | 1665 | pcdev->soc_host.ops = &pxa_soc_camera_host_ops; |
1675 | pxa_soc_camera_host.nr = pdev->id; | 1666 | pcdev->soc_host.priv = pcdev; |
1676 | err = soc_camera_host_register(&pxa_soc_camera_host); | 1667 | pcdev->soc_host.dev = &pdev->dev; |
1668 | pcdev->soc_host.nr = pdev->id; | ||
1669 | |||
1670 | err = soc_camera_host_register(&pcdev->soc_host); | ||
1677 | if (err) | 1671 | if (err) |
1678 | goto exit_free_irq; | 1672 | goto exit_free_irq; |
1679 | 1673 | ||
@@ -1690,7 +1684,7 @@ exit_free_dma_y: | |||
1690 | exit_iounmap: | 1684 | exit_iounmap: |
1691 | iounmap(base); | 1685 | iounmap(base); |
1692 | exit_release: | 1686 | exit_release: |
1693 | release_mem_region(res->start, res->end - res->start + 1); | 1687 | release_mem_region(res->start, resource_size(res)); |
1694 | exit_clk: | 1688 | exit_clk: |
1695 | clk_put(pcdev->clk); | 1689 | clk_put(pcdev->clk); |
1696 | exit_kfree: | 1690 | exit_kfree: |
@@ -1701,7 +1695,9 @@ exit: | |||
1701 | 1695 | ||
1702 | static int __devexit pxa_camera_remove(struct platform_device *pdev) | 1696 | static int __devexit pxa_camera_remove(struct platform_device *pdev) |
1703 | { | 1697 | { |
1704 | struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev); | 1698 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); |
1699 | struct pxa_camera_dev *pcdev = container_of(soc_host, | ||
1700 | struct pxa_camera_dev, soc_host); | ||
1705 | struct resource *res; | 1701 | struct resource *res; |
1706 | 1702 | ||
1707 | clk_put(pcdev->clk); | 1703 | clk_put(pcdev->clk); |
@@ -1711,12 +1707,12 @@ static int __devexit pxa_camera_remove(struct platform_device *pdev) | |||
1711 | pxa_free_dma(pcdev->dma_chans[2]); | 1707 | pxa_free_dma(pcdev->dma_chans[2]); |
1712 | free_irq(pcdev->irq, pcdev); | 1708 | free_irq(pcdev->irq, pcdev); |
1713 | 1709 | ||
1714 | soc_camera_host_unregister(&pxa_soc_camera_host); | 1710 | soc_camera_host_unregister(soc_host); |
1715 | 1711 | ||
1716 | iounmap(pcdev->base); | 1712 | iounmap(pcdev->base); |
1717 | 1713 | ||
1718 | res = pcdev->res; | 1714 | res = pcdev->res; |
1719 | release_mem_region(res->start, res->end - res->start + 1); | 1715 | release_mem_region(res->start, resource_size(res)); |
1720 | 1716 | ||
1721 | kfree(pcdev); | 1717 | kfree(pcdev); |
1722 | 1718 | ||
@@ -1730,11 +1726,11 @@ static struct platform_driver pxa_camera_driver = { | |||
1730 | .name = PXA_CAM_DRV_NAME, | 1726 | .name = PXA_CAM_DRV_NAME, |
1731 | }, | 1727 | }, |
1732 | .probe = pxa_camera_probe, | 1728 | .probe = pxa_camera_probe, |
1733 | .remove = __exit_p(pxa_camera_remove), | 1729 | .remove = __devexit_p(pxa_camera_remove), |
1734 | }; | 1730 | }; |
1735 | 1731 | ||
1736 | 1732 | ||
1737 | static int __devinit pxa_camera_init(void) | 1733 | static int __init pxa_camera_init(void) |
1738 | { | 1734 | { |
1739 | return platform_driver_register(&pxa_camera_driver); | 1735 | return platform_driver_register(&pxa_camera_driver); |
1740 | } | 1736 | } |
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 30f4698be90a..6be845ccc7d7 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -77,6 +77,8 @@ | |||
77 | #define MAX_CHANNELS 4 | 77 | #define MAX_CHANNELS 4 |
78 | #define S2255_MARKER_FRAME 0x2255DA4AL | 78 | #define S2255_MARKER_FRAME 0x2255DA4AL |
79 | #define S2255_MARKER_RESPONSE 0x2255ACACL | 79 | #define S2255_MARKER_RESPONSE 0x2255ACACL |
80 | #define S2255_RESPONSE_SETMODE 0x01 | ||
81 | #define S2255_RESPONSE_FW 0x10 | ||
80 | #define S2255_USB_XFER_SIZE (16 * 1024) | 82 | #define S2255_USB_XFER_SIZE (16 * 1024) |
81 | #define MAX_CHANNELS 4 | 83 | #define MAX_CHANNELS 4 |
82 | #define MAX_PIPE_BUFFERS 1 | 84 | #define MAX_PIPE_BUFFERS 1 |
@@ -107,6 +109,8 @@ | |||
107 | #define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */ | 109 | #define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */ |
108 | #define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */ | 110 | #define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */ |
109 | #define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */ | 111 | #define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */ |
112 | /* SCALE_4CIFSI is the 2 fields interpolated into one */ | ||
113 | #define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */ | ||
110 | 114 | ||
111 | #define COLOR_YUVPL 1 /* YUV planar */ | 115 | #define COLOR_YUVPL 1 /* YUV planar */ |
112 | #define COLOR_YUVPK 2 /* YUV packed */ | 116 | #define COLOR_YUVPK 2 /* YUV packed */ |
@@ -178,9 +182,6 @@ struct s2255_bufferi { | |||
178 | 182 | ||
179 | struct s2255_dmaqueue { | 183 | struct s2255_dmaqueue { |
180 | struct list_head active; | 184 | struct list_head active; |
181 | /* thread for acquisition */ | ||
182 | struct task_struct *kthread; | ||
183 | int frame; | ||
184 | struct s2255_dev *dev; | 185 | struct s2255_dev *dev; |
185 | int channel; | 186 | int channel; |
186 | }; | 187 | }; |
@@ -210,16 +211,11 @@ struct s2255_pipeinfo { | |||
210 | u32 max_transfer_size; | 211 | u32 max_transfer_size; |
211 | u32 cur_transfer_size; | 212 | u32 cur_transfer_size; |
212 | u8 *transfer_buffer; | 213 | u8 *transfer_buffer; |
213 | u32 transfer_flags;; | ||
214 | u32 state; | 214 | u32 state; |
215 | u32 prev_state; | ||
216 | u32 urb_size; | ||
217 | void *stream_urb; | 215 | void *stream_urb; |
218 | void *dev; /* back pointer to s2255_dev struct*/ | 216 | void *dev; /* back pointer to s2255_dev struct*/ |
219 | u32 err_count; | 217 | u32 err_count; |
220 | u32 buf_index; | ||
221 | u32 idx; | 218 | u32 idx; |
222 | u32 priority_set; | ||
223 | }; | 219 | }; |
224 | 220 | ||
225 | struct s2255_fmt; /*forward declaration */ | 221 | struct s2255_fmt; /*forward declaration */ |
@@ -239,13 +235,13 @@ struct s2255_dev { | |||
239 | struct list_head s2255_devlist; | 235 | struct list_head s2255_devlist; |
240 | struct timer_list timer; | 236 | struct timer_list timer; |
241 | struct s2255_fw *fw_data; | 237 | struct s2255_fw *fw_data; |
242 | int board_num; | ||
243 | int is_open; | ||
244 | struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; | 238 | struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; |
245 | struct s2255_bufferi buffer[MAX_CHANNELS]; | 239 | struct s2255_bufferi buffer[MAX_CHANNELS]; |
246 | struct s2255_mode mode[MAX_CHANNELS]; | 240 | struct s2255_mode mode[MAX_CHANNELS]; |
247 | /* jpeg compression */ | 241 | /* jpeg compression */ |
248 | struct v4l2_jpegcompression jc[MAX_CHANNELS]; | 242 | struct v4l2_jpegcompression jc[MAX_CHANNELS]; |
243 | /* capture parameters (for high quality mode full size) */ | ||
244 | struct v4l2_captureparm cap_parm[MAX_CHANNELS]; | ||
249 | const struct s2255_fmt *cur_fmt[MAX_CHANNELS]; | 245 | const struct s2255_fmt *cur_fmt[MAX_CHANNELS]; |
250 | int cur_frame[MAX_CHANNELS]; | 246 | int cur_frame[MAX_CHANNELS]; |
251 | int last_frame[MAX_CHANNELS]; | 247 | int last_frame[MAX_CHANNELS]; |
@@ -297,9 +293,10 @@ struct s2255_fh { | |||
297 | int resources[MAX_CHANNELS]; | 293 | int resources[MAX_CHANNELS]; |
298 | }; | 294 | }; |
299 | 295 | ||
300 | #define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */ | 296 | /* current cypress EEPROM firmware version */ |
297 | #define S2255_CUR_USB_FWVER ((3 << 8) | 6) | ||
301 | #define S2255_MAJOR_VERSION 1 | 298 | #define S2255_MAJOR_VERSION 1 |
302 | #define S2255_MINOR_VERSION 13 | 299 | #define S2255_MINOR_VERSION 14 |
303 | #define S2255_RELEASE 0 | 300 | #define S2255_RELEASE 0 |
304 | #define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ | 301 | #define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ |
305 | S2255_MINOR_VERSION, \ | 302 | S2255_MINOR_VERSION, \ |
@@ -1027,9 +1024,16 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1027 | fh->type = f->type; | 1024 | fh->type = f->type; |
1028 | norm = norm_minw(fh->dev->vdev[fh->channel]); | 1025 | norm = norm_minw(fh->dev->vdev[fh->channel]); |
1029 | if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) { | 1026 | if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) { |
1030 | if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) | 1027 | if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) { |
1031 | fh->mode.scale = SCALE_4CIFS; | 1028 | if (fh->dev->cap_parm[fh->channel].capturemode & |
1032 | else | 1029 | V4L2_MODE_HIGHQUALITY) { |
1030 | fh->mode.scale = SCALE_4CIFSI; | ||
1031 | dprintk(2, "scale 4CIFSI\n"); | ||
1032 | } else { | ||
1033 | fh->mode.scale = SCALE_4CIFS; | ||
1034 | dprintk(2, "scale 4CIFS\n"); | ||
1035 | } | ||
1036 | } else | ||
1033 | fh->mode.scale = SCALE_2CIFS; | 1037 | fh->mode.scale = SCALE_2CIFS; |
1034 | 1038 | ||
1035 | } else { | 1039 | } else { |
@@ -1130,6 +1134,7 @@ static u32 get_transfer_size(struct s2255_mode *mode) | |||
1130 | if (mode->format == FORMAT_NTSC) { | 1134 | if (mode->format == FORMAT_NTSC) { |
1131 | switch (mode->scale) { | 1135 | switch (mode->scale) { |
1132 | case SCALE_4CIFS: | 1136 | case SCALE_4CIFS: |
1137 | case SCALE_4CIFSI: | ||
1133 | linesPerFrame = NUM_LINES_4CIFS_NTSC * 2; | 1138 | linesPerFrame = NUM_LINES_4CIFS_NTSC * 2; |
1134 | pixelsPerLine = LINE_SZ_4CIFS_NTSC; | 1139 | pixelsPerLine = LINE_SZ_4CIFS_NTSC; |
1135 | break; | 1140 | break; |
@@ -1147,6 +1152,7 @@ static u32 get_transfer_size(struct s2255_mode *mode) | |||
1147 | } else if (mode->format == FORMAT_PAL) { | 1152 | } else if (mode->format == FORMAT_PAL) { |
1148 | switch (mode->scale) { | 1153 | switch (mode->scale) { |
1149 | case SCALE_4CIFS: | 1154 | case SCALE_4CIFS: |
1155 | case SCALE_4CIFSI: | ||
1150 | linesPerFrame = NUM_LINES_4CIFS_PAL * 2; | 1156 | linesPerFrame = NUM_LINES_4CIFS_PAL * 2; |
1151 | pixelsPerLine = LINE_SZ_4CIFS_PAL; | 1157 | pixelsPerLine = LINE_SZ_4CIFS_PAL; |
1152 | break; | 1158 | break; |
@@ -1502,6 +1508,33 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, | |||
1502 | dprintk(2, "setting jpeg quality %d\n", jc->quality); | 1508 | dprintk(2, "setting jpeg quality %d\n", jc->quality); |
1503 | return 0; | 1509 | return 0; |
1504 | } | 1510 | } |
1511 | |||
1512 | static int vidioc_g_parm(struct file *file, void *priv, | ||
1513 | struct v4l2_streamparm *sp) | ||
1514 | { | ||
1515 | struct s2255_fh *fh = priv; | ||
1516 | struct s2255_dev *dev = fh->dev; | ||
1517 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1518 | return -EINVAL; | ||
1519 | sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode; | ||
1520 | dprintk(2, "getting parm %d\n", sp->parm.capture.capturemode); | ||
1521 | return 0; | ||
1522 | } | ||
1523 | |||
1524 | static int vidioc_s_parm(struct file *file, void *priv, | ||
1525 | struct v4l2_streamparm *sp) | ||
1526 | { | ||
1527 | struct s2255_fh *fh = priv; | ||
1528 | struct s2255_dev *dev = fh->dev; | ||
1529 | |||
1530 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1531 | return -EINVAL; | ||
1532 | |||
1533 | dev->cap_parm[fh->channel].capturemode = sp->parm.capture.capturemode; | ||
1534 | dprintk(2, "setting param capture mode %d\n", | ||
1535 | sp->parm.capture.capturemode); | ||
1536 | return 0; | ||
1537 | } | ||
1505 | static int s2255_open(struct file *file) | 1538 | static int s2255_open(struct file *file) |
1506 | { | 1539 | { |
1507 | int minor = video_devdata(file)->minor; | 1540 | int minor = video_devdata(file)->minor; |
@@ -1793,6 +1826,8 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | |||
1793 | #endif | 1826 | #endif |
1794 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, | 1827 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, |
1795 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, | 1828 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, |
1829 | .vidioc_s_parm = vidioc_s_parm, | ||
1830 | .vidioc_g_parm = vidioc_g_parm, | ||
1796 | }; | 1831 | }; |
1797 | 1832 | ||
1798 | static struct video_device template = { | 1833 | static struct video_device template = { |
@@ -1818,7 +1853,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1818 | INIT_LIST_HEAD(&dev->vidq[i].active); | 1853 | INIT_LIST_HEAD(&dev->vidq[i].active); |
1819 | dev->vidq[i].dev = dev; | 1854 | dev->vidq[i].dev = dev; |
1820 | dev->vidq[i].channel = i; | 1855 | dev->vidq[i].channel = i; |
1821 | dev->vidq[i].kthread = NULL; | ||
1822 | /* register 4 video devices */ | 1856 | /* register 4 video devices */ |
1823 | dev->vdev[i] = video_device_alloc(); | 1857 | dev->vdev[i] = video_device_alloc(); |
1824 | memcpy(dev->vdev[i], &template, sizeof(struct video_device)); | 1858 | memcpy(dev->vdev[i], &template, sizeof(struct video_device)); |
@@ -1839,7 +1873,9 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1839 | return ret; | 1873 | return ret; |
1840 | } | 1874 | } |
1841 | } | 1875 | } |
1842 | printk(KERN_INFO "Sensoray 2255 V4L driver\n"); | 1876 | printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n", |
1877 | S2255_MAJOR_VERSION, | ||
1878 | S2255_MINOR_VERSION); | ||
1843 | return ret; | 1879 | return ret; |
1844 | } | 1880 | } |
1845 | 1881 | ||
@@ -1929,14 +1965,14 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) | |||
1929 | if (!(cc >= 0 && cc < MAX_CHANNELS)) | 1965 | if (!(cc >= 0 && cc < MAX_CHANNELS)) |
1930 | break; | 1966 | break; |
1931 | switch (pdword[2]) { | 1967 | switch (pdword[2]) { |
1932 | case 0x01: | 1968 | case S2255_RESPONSE_SETMODE: |
1933 | /* check if channel valid */ | 1969 | /* check if channel valid */ |
1934 | /* set mode ready */ | 1970 | /* set mode ready */ |
1935 | dev->setmode_ready[cc] = 1; | 1971 | dev->setmode_ready[cc] = 1; |
1936 | wake_up(&dev->wait_setmode[cc]); | 1972 | wake_up(&dev->wait_setmode[cc]); |
1937 | dprintk(5, "setmode ready %d\n", cc); | 1973 | dprintk(5, "setmode ready %d\n", cc); |
1938 | break; | 1974 | break; |
1939 | case 0x10: | 1975 | case S2255_RESPONSE_FW: |
1940 | 1976 | ||
1941 | dev->chn_ready |= (1 << cc); | 1977 | dev->chn_ready |= (1 << cc); |
1942 | if ((dev->chn_ready & 0x0f) != 0x0f) | 1978 | if ((dev->chn_ready & 0x0f) != 0x0f) |
@@ -2172,10 +2208,15 @@ static int s2255_board_init(struct s2255_dev *dev) | |||
2172 | /* query the firmware */ | 2208 | /* query the firmware */ |
2173 | fw_ver = s2255_get_fx2fw(dev); | 2209 | fw_ver = s2255_get_fx2fw(dev); |
2174 | 2210 | ||
2175 | printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver); | 2211 | printk(KERN_INFO "2255 usb firmware version %d.%d\n", |
2176 | if (fw_ver < CUR_USB_FWVER) | 2212 | (fw_ver >> 8) & 0xff, |
2213 | fw_ver & 0xff); | ||
2214 | |||
2215 | if (fw_ver < S2255_CUR_USB_FWVER) | ||
2177 | dev_err(&dev->udev->dev, | 2216 | dev_err(&dev->udev->dev, |
2178 | "usb firmware not up to date %d\n", fw_ver); | 2217 | "usb firmware not up to date %d.%d\n", |
2218 | (fw_ver >> 8) & 0xff, | ||
2219 | fw_ver & 0xff); | ||
2179 | 2220 | ||
2180 | for (j = 0; j < MAX_CHANNELS; j++) { | 2221 | for (j = 0; j < MAX_CHANNELS; j++) { |
2181 | dev->b_acquire[j] = 0; | 2222 | dev->b_acquire[j] = 0; |
@@ -2240,8 +2281,10 @@ static void read_pipe_completion(struct urb *purb) | |||
2240 | return; | 2281 | return; |
2241 | } | 2282 | } |
2242 | status = purb->status; | 2283 | status = purb->status; |
2243 | if (status != 0) { | 2284 | /* if shutting down, do not resubmit, exit immediately */ |
2244 | dprintk(2, "read_pipe_completion: err\n"); | 2285 | if (status == -ESHUTDOWN) { |
2286 | dprintk(2, "read_pipe_completion: err shutdown\n"); | ||
2287 | pipe_info->err_count++; | ||
2245 | return; | 2288 | return; |
2246 | } | 2289 | } |
2247 | 2290 | ||
@@ -2250,9 +2293,13 @@ static void read_pipe_completion(struct urb *purb) | |||
2250 | return; | 2293 | return; |
2251 | } | 2294 | } |
2252 | 2295 | ||
2253 | s2255_read_video_callback(dev, pipe_info); | 2296 | if (status == 0) |
2297 | s2255_read_video_callback(dev, pipe_info); | ||
2298 | else { | ||
2299 | pipe_info->err_count++; | ||
2300 | dprintk(1, "s2255drv: failed URB %d\n", status); | ||
2301 | } | ||
2254 | 2302 | ||
2255 | pipe_info->err_count = 0; | ||
2256 | pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); | 2303 | pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); |
2257 | /* reuse urb */ | 2304 | /* reuse urb */ |
2258 | usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, | 2305 | usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, |
@@ -2264,7 +2311,6 @@ static void read_pipe_completion(struct urb *purb) | |||
2264 | if (pipe_info->state != 0) { | 2311 | if (pipe_info->state != 0) { |
2265 | if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) { | 2312 | if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) { |
2266 | dev_err(&dev->udev->dev, "error submitting urb\n"); | 2313 | dev_err(&dev->udev->dev, "error submitting urb\n"); |
2267 | usb_free_urb(pipe_info->stream_urb); | ||
2268 | } | 2314 | } |
2269 | } else { | 2315 | } else { |
2270 | dprintk(2, "read pipe complete state 0\n"); | 2316 | dprintk(2, "read pipe complete state 0\n"); |
@@ -2283,8 +2329,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev) | |||
2283 | 2329 | ||
2284 | for (i = 0; i < MAX_PIPE_BUFFERS; i++) { | 2330 | for (i = 0; i < MAX_PIPE_BUFFERS; i++) { |
2285 | pipe_info->state = 1; | 2331 | pipe_info->state = 1; |
2286 | pipe_info->buf_index = (u32) i; | 2332 | pipe_info->err_count = 0; |
2287 | pipe_info->priority_set = 0; | ||
2288 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); | 2333 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); |
2289 | if (!pipe_info->stream_urb) { | 2334 | if (!pipe_info->stream_urb) { |
2290 | dev_err(&dev->udev->dev, | 2335 | dev_err(&dev->udev->dev, |
@@ -2298,7 +2343,6 @@ static int s2255_start_readpipe(struct s2255_dev *dev) | |||
2298 | pipe_info->cur_transfer_size, | 2343 | pipe_info->cur_transfer_size, |
2299 | read_pipe_completion, pipe_info); | 2344 | read_pipe_completion, pipe_info); |
2300 | 2345 | ||
2301 | pipe_info->urb_size = sizeof(pipe_info->stream_urb); | ||
2302 | dprintk(4, "submitting URB %p\n", pipe_info->stream_urb); | 2346 | dprintk(4, "submitting URB %p\n", pipe_info->stream_urb); |
2303 | retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); | 2347 | retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); |
2304 | if (retval) { | 2348 | if (retval) { |
@@ -2403,8 +2447,6 @@ static void s2255_stop_readpipe(struct s2255_dev *dev) | |||
2403 | if (pipe_info->state == 0) | 2447 | if (pipe_info->state == 0) |
2404 | continue; | 2448 | continue; |
2405 | pipe_info->state = 0; | 2449 | pipe_info->state = 0; |
2406 | pipe_info->prev_state = 1; | ||
2407 | |||
2408 | } | 2450 | } |
2409 | } | 2451 | } |
2410 | 2452 | ||
@@ -2542,7 +2584,9 @@ static int s2255_probe(struct usb_interface *interface, | |||
2542 | s2255_probe_v4l(dev); | 2584 | s2255_probe_v4l(dev); |
2543 | usb_reset_device(dev->udev); | 2585 | usb_reset_device(dev->udev); |
2544 | /* load 2255 board specific */ | 2586 | /* load 2255 board specific */ |
2545 | s2255_board_init(dev); | 2587 | retval = s2255_board_init(dev); |
2588 | if (retval) | ||
2589 | goto error; | ||
2546 | 2590 | ||
2547 | dprintk(4, "before probe done %p\n", dev); | 2591 | dprintk(4, "before probe done %p\n", dev); |
2548 | spin_lock_init(&dev->slock); | 2592 | spin_lock_init(&dev->slock); |
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index 0ba68987bfce..5bcce092e804 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig | |||
@@ -44,6 +44,7 @@ config VIDEO_SAA7134_DVB | |||
44 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | 44 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE |
45 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | 45 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE |
46 | select DVB_LGDT3305 if !DVB_FE_CUSTOMISE | 46 | select DVB_LGDT3305 if !DVB_FE_CUSTOMISE |
47 | select DVB_TDA10048 if !DVB_FE_CUSTOMISE | ||
47 | select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE | 48 | select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE |
48 | select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE | 49 | select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE |
49 | ---help--- | 50 | ---help--- |
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index 3dbaa19a6d00..604158a8c235 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile | |||
@@ -3,8 +3,7 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \ | |||
3 | saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \ | 3 | saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \ |
4 | saa7134-video.o saa7134-input.o | 4 | saa7134-video.o saa7134-input.o |
5 | 5 | ||
6 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \ | 6 | obj-$(CONFIG_VIDEO_SAA7134) += saa6752hs.o saa7134.o saa7134-empress.o |
7 | saa6752hs.o | ||
8 | 7 | ||
9 | obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o | 8 | obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o |
10 | 9 | ||
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index fdb19449d269..06861b782b95 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -1669,6 +1669,39 @@ struct saa7134_board saa7134_boards[] = { | |||
1669 | .amux = LINE1, | 1669 | .amux = LINE1, |
1670 | }, | 1670 | }, |
1671 | }, | 1671 | }, |
1672 | [SAA7134_BOARD_AVERMEDIA_CARDBUS_501] = { | ||
1673 | /* Oldrich Jedlicka <oldium.pro@seznam.cz> */ | ||
1674 | .name = "AVerMedia Cardbus TV/Radio (E501R)", | ||
1675 | .audio_clock = 0x187de7, | ||
1676 | .tuner_type = TUNER_ALPS_TSBE5_PAL, | ||
1677 | .radio_type = TUNER_TEA5767, | ||
1678 | .tuner_addr = 0x61, | ||
1679 | .radio_addr = 0x60, | ||
1680 | .tda9887_conf = TDA9887_PRESENT, | ||
1681 | .gpiomask = 0x08000000, | ||
1682 | .inputs = { { | ||
1683 | .name = name_tv, | ||
1684 | .vmux = 1, | ||
1685 | .amux = TV, | ||
1686 | .tv = 1, | ||
1687 | .gpio = 0x08000000, | ||
1688 | }, { | ||
1689 | .name = name_comp1, | ||
1690 | .vmux = 3, | ||
1691 | .amux = LINE1, | ||
1692 | .gpio = 0x08000000, | ||
1693 | }, { | ||
1694 | .name = name_svideo, | ||
1695 | .vmux = 8, | ||
1696 | .amux = LINE1, | ||
1697 | .gpio = 0x08000000, | ||
1698 | } }, | ||
1699 | .radio = { | ||
1700 | .name = name_radio, | ||
1701 | .amux = LINE2, | ||
1702 | .gpio = 0x00000000, | ||
1703 | }, | ||
1704 | }, | ||
1672 | [SAA7134_BOARD_CINERGY400_CARDBUS] = { | 1705 | [SAA7134_BOARD_CINERGY400_CARDBUS] = { |
1673 | .name = "Terratec Cinergy 400 mobile", | 1706 | .name = "Terratec Cinergy 400 mobile", |
1674 | .audio_clock = 0x187de7, | 1707 | .audio_clock = 0x187de7, |
@@ -3331,13 +3364,15 @@ struct saa7134_board saa7134_boards[] = { | |||
3331 | }, | 3364 | }, |
3332 | }, | 3365 | }, |
3333 | [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = { | 3366 | [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = { |
3334 | .name = "Hauppauge WinTV-HVR1110r3", | 3367 | .name = "Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid", |
3335 | .audio_clock = 0x00187de7, | 3368 | .audio_clock = 0x00187de7, |
3336 | .tuner_type = TUNER_PHILIPS_TDA8290, | 3369 | .tuner_type = TUNER_PHILIPS_TDA8290, |
3337 | .radio_type = UNSET, | 3370 | .radio_type = UNSET, |
3338 | .tuner_addr = ADDR_UNSET, | 3371 | .tuner_addr = ADDR_UNSET, |
3339 | .radio_addr = ADDR_UNSET, | 3372 | .radio_addr = ADDR_UNSET, |
3340 | .tuner_config = 3, | 3373 | .tuner_config = 3, |
3374 | .mpeg = SAA7134_MPEG_DVB, | ||
3375 | .ts_type = SAA7134_MPEG_TS_SERIAL, | ||
3341 | .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */ | 3376 | .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */ |
3342 | .inputs = {{ | 3377 | .inputs = {{ |
3343 | .name = name_tv, | 3378 | .name = name_tv, |
@@ -4006,7 +4041,7 @@ struct saa7134_board saa7134_boards[] = { | |||
4006 | [SAA7134_BOARD_BEHOLD_505FM] = { | 4041 | [SAA7134_BOARD_BEHOLD_505FM] = { |
4007 | /* Beholder Intl. Ltd. 2008 */ | 4042 | /* Beholder Intl. Ltd. 2008 */ |
4008 | /*Dmitry Belimov <d.belimov@gmail.com> */ | 4043 | /*Dmitry Belimov <d.belimov@gmail.com> */ |
4009 | .name = "Beholder BeholdTV 505 FM/RDS", | 4044 | .name = "Beholder BeholdTV 505 FM", |
4010 | .audio_clock = 0x00200000, | 4045 | .audio_clock = 0x00200000, |
4011 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 4046 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
4012 | .radio_type = UNSET, | 4047 | .radio_type = UNSET, |
@@ -4019,6 +4054,40 @@ struct saa7134_board saa7134_boards[] = { | |||
4019 | .vmux = 3, | 4054 | .vmux = 3, |
4020 | .amux = LINE2, | 4055 | .amux = LINE2, |
4021 | .tv = 1, | 4056 | .tv = 1, |
4057 | }, { | ||
4058 | .name = name_comp1, | ||
4059 | .vmux = 1, | ||
4060 | .amux = LINE1, | ||
4061 | }, { | ||
4062 | .name = name_svideo, | ||
4063 | .vmux = 8, | ||
4064 | .amux = LINE1, | ||
4065 | } }, | ||
4066 | .mute = { | ||
4067 | .name = name_mute, | ||
4068 | .amux = LINE1, | ||
4069 | }, | ||
4070 | .radio = { | ||
4071 | .name = name_radio, | ||
4072 | .amux = LINE2, | ||
4073 | }, | ||
4074 | }, | ||
4075 | [SAA7134_BOARD_BEHOLD_505RDS] = { | ||
4076 | /* Beholder Intl. Ltd. 2008 */ | ||
4077 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
4078 | .name = "Beholder BeholdTV 505 RDS", | ||
4079 | .audio_clock = 0x00200000, | ||
4080 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4081 | .radio_type = UNSET, | ||
4082 | .tuner_addr = ADDR_UNSET, | ||
4083 | .radio_addr = ADDR_UNSET, | ||
4084 | .tda9887_conf = TDA9887_PRESENT, | ||
4085 | .gpiomask = 0x00008000, | ||
4086 | .inputs = {{ | ||
4087 | .name = name_tv, | ||
4088 | .vmux = 3, | ||
4089 | .amux = LINE2, | ||
4090 | .tv = 1, | ||
4022 | },{ | 4091 | },{ |
4023 | .name = name_comp1, | 4092 | .name = name_comp1, |
4024 | .vmux = 1, | 4093 | .vmux = 1, |
@@ -4040,7 +4109,7 @@ struct saa7134_board saa7134_boards[] = { | |||
4040 | [SAA7134_BOARD_BEHOLD_507_9FM] = { | 4109 | [SAA7134_BOARD_BEHOLD_507_9FM] = { |
4041 | /* Beholder Intl. Ltd. 2008 */ | 4110 | /* Beholder Intl. Ltd. 2008 */ |
4042 | /*Dmitry Belimov <d.belimov@gmail.com> */ | 4111 | /*Dmitry Belimov <d.belimov@gmail.com> */ |
4043 | .name = "Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM", | 4112 | .name = "Beholder BeholdTV 507 FM / BeholdTV 509 FM", |
4044 | .audio_clock = 0x00187de7, | 4113 | .audio_clock = 0x00187de7, |
4045 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 4114 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
4046 | .radio_type = UNSET, | 4115 | .radio_type = UNSET, |
@@ -4067,6 +4136,66 @@ struct saa7134_board saa7134_boards[] = { | |||
4067 | .amux = LINE2, | 4136 | .amux = LINE2, |
4068 | }, | 4137 | }, |
4069 | }, | 4138 | }, |
4139 | [SAA7134_BOARD_BEHOLD_507RDS_MK5] = { | ||
4140 | /* Beholder Intl. Ltd. 2008 */ | ||
4141 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
4142 | .name = "Beholder BeholdTV 507 RDS", | ||
4143 | .audio_clock = 0x00187de7, | ||
4144 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4145 | .radio_type = UNSET, | ||
4146 | .tuner_addr = ADDR_UNSET, | ||
4147 | .radio_addr = ADDR_UNSET, | ||
4148 | .tda9887_conf = TDA9887_PRESENT, | ||
4149 | .gpiomask = 0x00008000, | ||
4150 | .inputs = {{ | ||
4151 | .name = name_tv, | ||
4152 | .vmux = 3, | ||
4153 | .amux = TV, | ||
4154 | .tv = 1, | ||
4155 | }, { | ||
4156 | .name = name_comp1, | ||
4157 | .vmux = 1, | ||
4158 | .amux = LINE1, | ||
4159 | }, { | ||
4160 | .name = name_svideo, | ||
4161 | .vmux = 8, | ||
4162 | .amux = LINE1, | ||
4163 | } }, | ||
4164 | .radio = { | ||
4165 | .name = name_radio, | ||
4166 | .amux = LINE2, | ||
4167 | }, | ||
4168 | }, | ||
4169 | [SAA7134_BOARD_BEHOLD_507RDS_MK3] = { | ||
4170 | /* Beholder Intl. Ltd. 2008 */ | ||
4171 | /*Dmitry Belimov <d.belimov@gmail.com> */ | ||
4172 | .name = "Beholder BeholdTV 507 RDS", | ||
4173 | .audio_clock = 0x00187de7, | ||
4174 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
4175 | .radio_type = UNSET, | ||
4176 | .tuner_addr = ADDR_UNSET, | ||
4177 | .radio_addr = ADDR_UNSET, | ||
4178 | .tda9887_conf = TDA9887_PRESENT, | ||
4179 | .gpiomask = 0x00008000, | ||
4180 | .inputs = {{ | ||
4181 | .name = name_tv, | ||
4182 | .vmux = 3, | ||
4183 | .amux = TV, | ||
4184 | .tv = 1, | ||
4185 | }, { | ||
4186 | .name = name_comp1, | ||
4187 | .vmux = 1, | ||
4188 | .amux = LINE1, | ||
4189 | }, { | ||
4190 | .name = name_svideo, | ||
4191 | .vmux = 8, | ||
4192 | .amux = LINE1, | ||
4193 | } }, | ||
4194 | .radio = { | ||
4195 | .name = name_radio, | ||
4196 | .amux = LINE2, | ||
4197 | }, | ||
4198 | }, | ||
4070 | [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { | 4199 | [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { |
4071 | /* Beholder Intl. Ltd. 2008 */ | 4200 | /* Beholder Intl. Ltd. 2008 */ |
4072 | /*Dmitry Belimov <d.belimov@gmail.com> */ | 4201 | /*Dmitry Belimov <d.belimov@gmail.com> */ |
@@ -4101,9 +4230,121 @@ struct saa7134_board saa7134_boards[] = { | |||
4101 | .gpio = 0x000A8000, | 4230 | .gpio = 0x000A8000, |
4102 | }, | 4231 | }, |
4103 | }, | 4232 | }, |
4104 | [SAA7134_BOARD_BEHOLD_607_9FM] = { | 4233 | [SAA7134_BOARD_BEHOLD_607FM_MK3] = { |
4234 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4235 | .name = "Beholder BeholdTV 607 FM", | ||
4236 | .audio_clock = 0x00187de7, | ||
4237 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
4238 | .radio_type = UNSET, | ||
4239 | .tuner_addr = ADDR_UNSET, | ||
4240 | .radio_addr = ADDR_UNSET, | ||
4241 | .tda9887_conf = TDA9887_PRESENT, | ||
4242 | .inputs = {{ | ||
4243 | .name = name_tv, | ||
4244 | .vmux = 3, | ||
4245 | .amux = TV, | ||
4246 | .tv = 1, | ||
4247 | }, { | ||
4248 | .name = name_comp1, | ||
4249 | .vmux = 1, | ||
4250 | .amux = LINE1, | ||
4251 | }, { | ||
4252 | .name = name_svideo, | ||
4253 | .vmux = 8, | ||
4254 | .amux = LINE1, | ||
4255 | } }, | ||
4256 | .radio = { | ||
4257 | .name = name_radio, | ||
4258 | .amux = LINE2, | ||
4259 | }, | ||
4260 | }, | ||
4261 | [SAA7134_BOARD_BEHOLD_609FM_MK3] = { | ||
4262 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4263 | .name = "Beholder BeholdTV 609 FM", | ||
4264 | .audio_clock = 0x00187de7, | ||
4265 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
4266 | .radio_type = UNSET, | ||
4267 | .tuner_addr = ADDR_UNSET, | ||
4268 | .radio_addr = ADDR_UNSET, | ||
4269 | .tda9887_conf = TDA9887_PRESENT, | ||
4270 | .inputs = {{ | ||
4271 | .name = name_tv, | ||
4272 | .vmux = 3, | ||
4273 | .amux = TV, | ||
4274 | .tv = 1, | ||
4275 | }, { | ||
4276 | .name = name_comp1, | ||
4277 | .vmux = 1, | ||
4278 | .amux = LINE1, | ||
4279 | }, { | ||
4280 | .name = name_svideo, | ||
4281 | .vmux = 8, | ||
4282 | .amux = LINE1, | ||
4283 | } }, | ||
4284 | .radio = { | ||
4285 | .name = name_radio, | ||
4286 | .amux = LINE2, | ||
4287 | }, | ||
4288 | }, | ||
4289 | [SAA7134_BOARD_BEHOLD_607FM_MK5] = { | ||
4290 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4291 | .name = "Beholder BeholdTV 607 FM", | ||
4292 | .audio_clock = 0x00187de7, | ||
4293 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4294 | .radio_type = UNSET, | ||
4295 | .tuner_addr = ADDR_UNSET, | ||
4296 | .radio_addr = ADDR_UNSET, | ||
4297 | .tda9887_conf = TDA9887_PRESENT, | ||
4298 | .inputs = {{ | ||
4299 | .name = name_tv, | ||
4300 | .vmux = 3, | ||
4301 | .amux = TV, | ||
4302 | .tv = 1, | ||
4303 | }, { | ||
4304 | .name = name_comp1, | ||
4305 | .vmux = 1, | ||
4306 | .amux = LINE1, | ||
4307 | }, { | ||
4308 | .name = name_svideo, | ||
4309 | .vmux = 8, | ||
4310 | .amux = LINE1, | ||
4311 | } }, | ||
4312 | .radio = { | ||
4313 | .name = name_radio, | ||
4314 | .amux = LINE2, | ||
4315 | }, | ||
4316 | }, | ||
4317 | [SAA7134_BOARD_BEHOLD_609FM_MK5] = { | ||
4105 | /* Andrey Melnikoff <temnota@kmv.ru> */ | 4318 | /* Andrey Melnikoff <temnota@kmv.ru> */ |
4106 | .name = "Beholder BeholdTV 607 / BeholdTV 609", | 4319 | .name = "Beholder BeholdTV 609 FM", |
4320 | .audio_clock = 0x00187de7, | ||
4321 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4322 | .radio_type = UNSET, | ||
4323 | .tuner_addr = ADDR_UNSET, | ||
4324 | .radio_addr = ADDR_UNSET, | ||
4325 | .tda9887_conf = TDA9887_PRESENT, | ||
4326 | .inputs = {{ | ||
4327 | .name = name_tv, | ||
4328 | .vmux = 3, | ||
4329 | .amux = TV, | ||
4330 | .tv = 1, | ||
4331 | }, { | ||
4332 | .name = name_comp1, | ||
4333 | .vmux = 1, | ||
4334 | .amux = LINE1, | ||
4335 | }, { | ||
4336 | .name = name_svideo, | ||
4337 | .vmux = 8, | ||
4338 | .amux = LINE1, | ||
4339 | } }, | ||
4340 | .radio = { | ||
4341 | .name = name_radio, | ||
4342 | .amux = LINE2, | ||
4343 | }, | ||
4344 | }, | ||
4345 | [SAA7134_BOARD_BEHOLD_607RDS_MK3] = { | ||
4346 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4347 | .name = "Beholder BeholdTV 607 RDS", | ||
4107 | .audio_clock = 0x00187de7, | 4348 | .audio_clock = 0x00187de7, |
4108 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 4349 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
4109 | .radio_type = UNSET, | 4350 | .radio_type = UNSET, |
@@ -4115,6 +4356,90 @@ struct saa7134_board saa7134_boards[] = { | |||
4115 | .vmux = 3, | 4356 | .vmux = 3, |
4116 | .amux = TV, | 4357 | .amux = TV, |
4117 | .tv = 1, | 4358 | .tv = 1, |
4359 | }, { | ||
4360 | .name = name_comp1, | ||
4361 | .vmux = 1, | ||
4362 | .amux = LINE1, | ||
4363 | }, { | ||
4364 | .name = name_svideo, | ||
4365 | .vmux = 8, | ||
4366 | .amux = LINE1, | ||
4367 | } }, | ||
4368 | .radio = { | ||
4369 | .name = name_radio, | ||
4370 | .amux = LINE2, | ||
4371 | }, | ||
4372 | }, | ||
4373 | [SAA7134_BOARD_BEHOLD_609RDS_MK3] = { | ||
4374 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4375 | .name = "Beholder BeholdTV 609 RDS", | ||
4376 | .audio_clock = 0x00187de7, | ||
4377 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
4378 | .radio_type = UNSET, | ||
4379 | .tuner_addr = ADDR_UNSET, | ||
4380 | .radio_addr = ADDR_UNSET, | ||
4381 | .tda9887_conf = TDA9887_PRESENT, | ||
4382 | .inputs = {{ | ||
4383 | .name = name_tv, | ||
4384 | .vmux = 3, | ||
4385 | .amux = TV, | ||
4386 | .tv = 1, | ||
4387 | }, { | ||
4388 | .name = name_comp1, | ||
4389 | .vmux = 1, | ||
4390 | .amux = LINE1, | ||
4391 | }, { | ||
4392 | .name = name_svideo, | ||
4393 | .vmux = 8, | ||
4394 | .amux = LINE1, | ||
4395 | } }, | ||
4396 | .radio = { | ||
4397 | .name = name_radio, | ||
4398 | .amux = LINE2, | ||
4399 | }, | ||
4400 | }, | ||
4401 | [SAA7134_BOARD_BEHOLD_607RDS_MK5] = { | ||
4402 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4403 | .name = "Beholder BeholdTV 607 RDS", | ||
4404 | .audio_clock = 0x00187de7, | ||
4405 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4406 | .radio_type = UNSET, | ||
4407 | .tuner_addr = ADDR_UNSET, | ||
4408 | .radio_addr = ADDR_UNSET, | ||
4409 | .tda9887_conf = TDA9887_PRESENT, | ||
4410 | .inputs = {{ | ||
4411 | .name = name_tv, | ||
4412 | .vmux = 3, | ||
4413 | .amux = TV, | ||
4414 | .tv = 1, | ||
4415 | }, { | ||
4416 | .name = name_comp1, | ||
4417 | .vmux = 1, | ||
4418 | .amux = LINE1, | ||
4419 | }, { | ||
4420 | .name = name_svideo, | ||
4421 | .vmux = 8, | ||
4422 | .amux = LINE1, | ||
4423 | } }, | ||
4424 | .radio = { | ||
4425 | .name = name_radio, | ||
4426 | .amux = LINE2, | ||
4427 | }, | ||
4428 | }, | ||
4429 | [SAA7134_BOARD_BEHOLD_609RDS_MK5] = { | ||
4430 | /* Andrey Melnikoff <temnota@kmv.ru> */ | ||
4431 | .name = "Beholder BeholdTV 609 RDS", | ||
4432 | .audio_clock = 0x00187de7, | ||
4433 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ | ||
4434 | .radio_type = UNSET, | ||
4435 | .tuner_addr = ADDR_UNSET, | ||
4436 | .radio_addr = ADDR_UNSET, | ||
4437 | .tda9887_conf = TDA9887_PRESENT, | ||
4438 | .inputs = {{ | ||
4439 | .name = name_tv, | ||
4440 | .vmux = 3, | ||
4441 | .amux = TV, | ||
4442 | .tv = 1, | ||
4118 | },{ | 4443 | },{ |
4119 | .name = name_comp1, | 4444 | .name = name_comp1, |
4120 | .vmux = 1, | 4445 | .vmux = 1, |
@@ -4133,6 +4458,7 @@ struct saa7134_board saa7134_boards[] = { | |||
4133 | /* Igor Kuznetsov <igk@igk.ru> */ | 4458 | /* Igor Kuznetsov <igk@igk.ru> */ |
4134 | /* Andrey Melnikoff <temnota@kmv.ru> */ | 4459 | /* Andrey Melnikoff <temnota@kmv.ru> */ |
4135 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ | 4460 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ |
4461 | /* Alexey Osipov <lion-simba@pridelands.ru> */ | ||
4136 | .name = "Beholder BeholdTV M6", | 4462 | .name = "Beholder BeholdTV M6", |
4137 | .audio_clock = 0x00187de7, | 4463 | .audio_clock = 0x00187de7, |
4138 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 4464 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
@@ -4207,10 +4533,10 @@ struct saa7134_board saa7134_boards[] = { | |||
4207 | /* Igor Kuznetsov <igk@igk.ru> */ | 4533 | /* Igor Kuznetsov <igk@igk.ru> */ |
4208 | /* Andrey Melnikoff <temnota@kmv.ru> */ | 4534 | /* Andrey Melnikoff <temnota@kmv.ru> */ |
4209 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ | 4535 | /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ |
4536 | /* Alexey Osipov <lion-simba@pridelands.ru> */ | ||
4210 | .name = "Beholder BeholdTV M6 Extra", | 4537 | .name = "Beholder BeholdTV M6 Extra", |
4211 | .audio_clock = 0x00187de7, | 4538 | .audio_clock = 0x00187de7, |
4212 | /* FIXME: Must be PHILIPS_FM1216ME_MK5*/ | 4539 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ |
4213 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
4214 | .radio_type = UNSET, | 4540 | .radio_type = UNSET, |
4215 | .tuner_addr = ADDR_UNSET, | 4541 | .tuner_addr = ADDR_UNSET, |
4216 | .radio_addr = ADDR_UNSET, | 4542 | .radio_addr = ADDR_UNSET, |
@@ -4465,7 +4791,6 @@ struct saa7134_board saa7134_boards[] = { | |||
4465 | .radio_type = UNSET, | 4791 | .radio_type = UNSET, |
4466 | .tuner_addr = ADDR_UNSET, | 4792 | .tuner_addr = ADDR_UNSET, |
4467 | .radio_addr = ADDR_UNSET, | 4793 | .radio_addr = ADDR_UNSET, |
4468 | .mpeg = SAA7134_MPEG_DVB, | ||
4469 | .inputs = {{ | 4794 | .inputs = {{ |
4470 | .name = name_tv, | 4795 | .name = name_tv, |
4471 | .vmux = 3, | 4796 | .vmux = 3, |
@@ -4753,6 +5078,44 @@ struct saa7134_board saa7134_boards[] = { | |||
4753 | .gpio = 0x01, | 5078 | .gpio = 0x01, |
4754 | }, | 5079 | }, |
4755 | }, | 5080 | }, |
5081 | [SAA7134_BOARD_AVERMEDIA_STUDIO_507UA] = { | ||
5082 | /* Andy Shevchenko <andy@smile.org.ua> */ | ||
5083 | .name = "Avermedia AVerTV Studio 507UA", | ||
5084 | .audio_clock = 0x00187de7, | ||
5085 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* Should be MK5 */ | ||
5086 | .radio_type = UNSET, | ||
5087 | .tuner_addr = ADDR_UNSET, | ||
5088 | .radio_addr = ADDR_UNSET, | ||
5089 | .tda9887_conf = TDA9887_PRESENT, | ||
5090 | .gpiomask = 0x03, | ||
5091 | .inputs = { { | ||
5092 | .name = name_tv, | ||
5093 | .vmux = 1, | ||
5094 | .amux = TV, | ||
5095 | .tv = 1, | ||
5096 | .gpio = 0x00, | ||
5097 | }, { | ||
5098 | .name = name_comp1, | ||
5099 | .vmux = 3, | ||
5100 | .amux = LINE1, | ||
5101 | .gpio = 0x00, | ||
5102 | }, { | ||
5103 | .name = name_svideo, | ||
5104 | .vmux = 8, | ||
5105 | .amux = LINE1, | ||
5106 | .gpio = 0x00, | ||
5107 | } }, | ||
5108 | .radio = { | ||
5109 | .name = name_radio, | ||
5110 | .amux = LINE2, | ||
5111 | .gpio = 0x01, | ||
5112 | }, | ||
5113 | .mute = { | ||
5114 | .name = name_mute, | ||
5115 | .amux = LINE1, | ||
5116 | .gpio = 0x00, | ||
5117 | }, | ||
5118 | }, | ||
4756 | }; | 5119 | }; |
4757 | 5120 | ||
4758 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 5121 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); |
@@ -5027,6 +5390,13 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5027 | .subdevice = 0xd6ee, | 5390 | .subdevice = 0xd6ee, |
5028 | .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS, | 5391 | .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS, |
5029 | },{ | 5392 | },{ |
5393 | /* AVerMedia CardBus */ | ||
5394 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5395 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
5396 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
5397 | .subdevice = 0xb7e9, | ||
5398 | .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_501, | ||
5399 | }, { | ||
5030 | /* TransGear 3000TV */ | 5400 | /* TransGear 3000TV */ |
5031 | .vendor = PCI_VENDOR_ID_PHILIPS, | 5401 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5032 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | 5402 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, |
@@ -5441,6 +5811,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5441 | .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507, | 5811 | .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507, |
5442 | },{ | 5812 | },{ |
5443 | .vendor = PCI_VENDOR_ID_PHILIPS, | 5813 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5814 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
5815 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
5816 | .subdevice = 0xa11b, | ||
5817 | .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507UA, | ||
5818 | }, { | ||
5819 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5444 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 5820 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5445 | .subvendor = 0x1043, | 5821 | .subvendor = 0x1043, |
5446 | .subdevice = 0x4876, | 5822 | .subdevice = 0x4876, |
@@ -5647,14 +6023,8 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5647 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6023 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5648 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | 6024 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, |
5649 | .subvendor = 0x0000, | 6025 | .subvendor = 0x0000, |
5650 | .subdevice = 0x5051, | ||
5651 | .driver_data = SAA7134_BOARD_BEHOLD_505FM, | ||
5652 | },{ | ||
5653 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
5654 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | ||
5655 | .subvendor = 0x0000, | ||
5656 | .subdevice = 0x505B, | 6026 | .subdevice = 0x505B, |
5657 | .driver_data = SAA7134_BOARD_BEHOLD_505FM, | 6027 | .driver_data = SAA7134_BOARD_BEHOLD_505RDS, |
5658 | },{ | 6028 | },{ |
5659 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6029 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5660 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | 6030 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, |
@@ -5666,13 +6036,13 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5666 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6036 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5667 | .subvendor = 0x0000, | 6037 | .subvendor = 0x0000, |
5668 | .subdevice = 0x5071, | 6038 | .subdevice = 0x5071, |
5669 | .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, | 6039 | .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK3, |
5670 | },{ | 6040 | },{ |
5671 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6041 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5672 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6042 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5673 | .subvendor = 0x0000, | 6043 | .subvendor = 0x0000, |
5674 | .subdevice = 0x507B, | 6044 | .subdevice = 0x507B, |
5675 | .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, | 6045 | .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK5, |
5676 | },{ | 6046 | },{ |
5677 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6047 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5678 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6048 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
@@ -5696,49 +6066,49 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5696 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6066 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
5697 | .subvendor = 0x5ace, | 6067 | .subvendor = 0x5ace, |
5698 | .subdevice = 0x6070, | 6068 | .subdevice = 0x6070, |
5699 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6069 | .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK3, |
5700 | },{ | 6070 | },{ |
5701 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6071 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5702 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6072 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
5703 | .subvendor = 0x5ace, | 6073 | .subvendor = 0x5ace, |
5704 | .subdevice = 0x6071, | 6074 | .subdevice = 0x6071, |
5705 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6075 | .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK5, |
5706 | },{ | 6076 | },{ |
5707 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6077 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5708 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6078 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
5709 | .subvendor = 0x5ace, | 6079 | .subvendor = 0x5ace, |
5710 | .subdevice = 0x6072, | 6080 | .subdevice = 0x6072, |
5711 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6081 | .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK3, |
5712 | },{ | 6082 | },{ |
5713 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6083 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5714 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 6084 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
5715 | .subvendor = 0x5ace, | 6085 | .subvendor = 0x5ace, |
5716 | .subdevice = 0x6073, | 6086 | .subdevice = 0x6073, |
5717 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6087 | .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK5, |
5718 | },{ | 6088 | },{ |
5719 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6089 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5720 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6090 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5721 | .subvendor = 0x5ace, | 6091 | .subvendor = 0x5ace, |
5722 | .subdevice = 0x6090, | 6092 | .subdevice = 0x6090, |
5723 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6093 | .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK3, |
5724 | },{ | 6094 | },{ |
5725 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6095 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5726 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6096 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5727 | .subvendor = 0x5ace, | 6097 | .subvendor = 0x5ace, |
5728 | .subdevice = 0x6091, | 6098 | .subdevice = 0x6091, |
5729 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6099 | .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK5, |
5730 | },{ | 6100 | },{ |
5731 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6101 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5732 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6102 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5733 | .subvendor = 0x5ace, | 6103 | .subvendor = 0x5ace, |
5734 | .subdevice = 0x6092, | 6104 | .subdevice = 0x6092, |
5735 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6105 | .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK3, |
5736 | },{ | 6106 | },{ |
5737 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6107 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5738 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6108 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
5739 | .subvendor = 0x5ace, | 6109 | .subvendor = 0x5ace, |
5740 | .subdevice = 0x6093, | 6110 | .subdevice = 0x6093, |
5741 | .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, | 6111 | .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK5, |
5742 | },{ | 6112 | },{ |
5743 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6113 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5744 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6114 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
@@ -5832,6 +6202,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
5832 | }, { | 6202 | }, { |
5833 | .vendor = PCI_VENDOR_ID_PHILIPS, | 6203 | .vendor = PCI_VENDOR_ID_PHILIPS, |
5834 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 6204 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
6205 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ | ||
6206 | .subdevice = 0xf736, | ||
6207 | .driver_data = SAA7134_BOARD_AVERMEDIA_M103, | ||
6208 | }, { | ||
6209 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
6210 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
5835 | .subvendor = 0x1043, | 6211 | .subvendor = 0x1043, |
5836 | .subdevice = 0x4878, /* REV:1.02G */ | 6212 | .subdevice = 0x4878, /* REV:1.02G */ |
5837 | .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1, | 6213 | .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1, |
@@ -6114,7 +6490,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
6114 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | 6490 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: |
6115 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | 6491 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: |
6116 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: | 6492 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: |
6117 | case SAA7134_BOARD_VIDEOMATE_T750: | ||
6118 | case SAA7134_BOARD_MANLI_MTV001: | 6493 | case SAA7134_BOARD_MANLI_MTV001: |
6119 | case SAA7134_BOARD_MANLI_MTV002: | 6494 | case SAA7134_BOARD_MANLI_MTV002: |
6120 | case SAA7134_BOARD_BEHOLD_409FM: | 6495 | case SAA7134_BOARD_BEHOLD_409FM: |
@@ -6142,7 +6517,10 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
6142 | case SAA7134_BOARD_BEHOLD_407FM: | 6517 | case SAA7134_BOARD_BEHOLD_407FM: |
6143 | case SAA7134_BOARD_BEHOLD_409: | 6518 | case SAA7134_BOARD_BEHOLD_409: |
6144 | case SAA7134_BOARD_BEHOLD_505FM: | 6519 | case SAA7134_BOARD_BEHOLD_505FM: |
6520 | case SAA7134_BOARD_BEHOLD_505RDS: | ||
6145 | case SAA7134_BOARD_BEHOLD_507_9FM: | 6521 | case SAA7134_BOARD_BEHOLD_507_9FM: |
6522 | case SAA7134_BOARD_BEHOLD_507RDS_MK3: | ||
6523 | case SAA7134_BOARD_BEHOLD_507RDS_MK5: | ||
6146 | case SAA7134_BOARD_GENIUS_TVGO_A11MCE: | 6524 | case SAA7134_BOARD_GENIUS_TVGO_A11MCE: |
6147 | case SAA7134_BOARD_REAL_ANGEL_220: | 6525 | case SAA7134_BOARD_REAL_ANGEL_220: |
6148 | case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: | 6526 | case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: |
@@ -6196,6 +6574,16 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
6196 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); | 6574 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); |
6197 | msleep(10); | 6575 | msleep(10); |
6198 | break; | 6576 | break; |
6577 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: | ||
6578 | /* power-down tuner chip */ | ||
6579 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08400000, 0x08400000); | ||
6580 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0); | ||
6581 | msleep(10); | ||
6582 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08400000, 0x08400000); | ||
6583 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0x08400000); | ||
6584 | msleep(10); | ||
6585 | dev->has_remote = SAA7134_REMOTE_I2C; | ||
6586 | break; | ||
6199 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: | 6587 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: |
6200 | saa7134_set_gpio(dev, 23, 0); | 6588 | saa7134_set_gpio(dev, 23, 0); |
6201 | msleep(10); | 6589 | msleep(10); |
@@ -6253,7 +6641,14 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
6253 | case SAA7134_BOARD_UPMOST_PURPLE_TV: | 6641 | case SAA7134_BOARD_UPMOST_PURPLE_TV: |
6254 | case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: | 6642 | case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: |
6255 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: | 6643 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: |
6256 | case SAA7134_BOARD_BEHOLD_607_9FM: | 6644 | case SAA7134_BOARD_BEHOLD_607FM_MK3: |
6645 | case SAA7134_BOARD_BEHOLD_607FM_MK5: | ||
6646 | case SAA7134_BOARD_BEHOLD_609FM_MK3: | ||
6647 | case SAA7134_BOARD_BEHOLD_609FM_MK5: | ||
6648 | case SAA7134_BOARD_BEHOLD_607RDS_MK3: | ||
6649 | case SAA7134_BOARD_BEHOLD_607RDS_MK5: | ||
6650 | case SAA7134_BOARD_BEHOLD_609RDS_MK3: | ||
6651 | case SAA7134_BOARD_BEHOLD_609RDS_MK5: | ||
6257 | case SAA7134_BOARD_BEHOLD_M6: | 6652 | case SAA7134_BOARD_BEHOLD_M6: |
6258 | case SAA7134_BOARD_BEHOLD_M63: | 6653 | case SAA7134_BOARD_BEHOLD_M63: |
6259 | case SAA7134_BOARD_BEHOLD_M6_EXTRA: | 6654 | case SAA7134_BOARD_BEHOLD_M6_EXTRA: |
@@ -6635,6 +7030,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
6635 | 7030 | ||
6636 | switch (dev->board) { | 7031 | switch (dev->board) { |
6637 | case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: | 7032 | case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: |
7033 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: | ||
6638 | { | 7034 | { |
6639 | struct v4l2_priv_tun_config tea5767_cfg; | 7035 | struct v4l2_priv_tun_config tea5767_cfg; |
6640 | struct tea5767_ctrl ctl; | 7036 | struct tea5767_ctrl ctl; |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 2def6fec814b..94a023a14bbc 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -331,6 +331,10 @@ void saa7134_buffer_next(struct saa7134_dev *dev, | |||
331 | dprintk("buffer_next %p\n",NULL); | 331 | dprintk("buffer_next %p\n",NULL); |
332 | saa7134_set_dmabits(dev); | 332 | saa7134_set_dmabits(dev); |
333 | del_timer(&q->timeout); | 333 | del_timer(&q->timeout); |
334 | |||
335 | if (card_has_mpeg(dev)) | ||
336 | if (dev->ts_started) | ||
337 | saa7134_ts_stop(dev); | ||
334 | } | 338 | } |
335 | } | 339 | } |
336 | 340 | ||
@@ -416,6 +420,19 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) | |||
416 | ctrl |= SAA7134_MAIN_CTRL_TE5; | 420 | ctrl |= SAA7134_MAIN_CTRL_TE5; |
417 | irq |= SAA7134_IRQ1_INTE_RA2_1 | | 421 | irq |= SAA7134_IRQ1_INTE_RA2_1 | |
418 | SAA7134_IRQ1_INTE_RA2_0; | 422 | SAA7134_IRQ1_INTE_RA2_0; |
423 | |||
424 | /* dma: setup channel 5 (= TS) */ | ||
425 | |||
426 | saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); | ||
427 | saa_writeb(SAA7134_TS_DMA1, | ||
428 | ((dev->ts.nr_packets - 1) >> 8) & 0xff); | ||
429 | /* TSNOPIT=0, TSCOLAP=0 */ | ||
430 | saa_writeb(SAA7134_TS_DMA2, | ||
431 | (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00); | ||
432 | saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); | ||
433 | saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | | ||
434 | SAA7134_RS_CONTROL_ME | | ||
435 | (dev->ts.pt_ts.dma >> 12)); | ||
419 | } | 436 | } |
420 | 437 | ||
421 | /* set task conditions + field handling */ | 438 | /* set task conditions + field handling */ |
@@ -775,7 +792,6 @@ static struct video_device *vdev_init(struct saa7134_dev *dev, | |||
775 | if (NULL == vfd) | 792 | if (NULL == vfd) |
776 | return NULL; | 793 | return NULL; |
777 | *vfd = *template; | 794 | *vfd = *template; |
778 | vfd->minor = -1; | ||
779 | vfd->v4l2_dev = &dev->v4l2_dev; | 795 | vfd->v4l2_dev = &dev->v4l2_dev; |
780 | vfd->release = video_device_release; | 796 | vfd->release = video_device_release; |
781 | vfd->debug = video_debug; | 797 | vfd->debug = video_debug; |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 4eff1ca8593c..31930f26ffc7 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include "isl6405.h" | 48 | #include "isl6405.h" |
49 | #include "lnbp21.h" | 49 | #include "lnbp21.h" |
50 | #include "tuner-simple.h" | 50 | #include "tuner-simple.h" |
51 | #include "tda10048.h" | ||
51 | #include "tda18271.h" | 52 | #include "tda18271.h" |
52 | #include "lgdt3305.h" | 53 | #include "lgdt3305.h" |
53 | #include "tda8290.h" | 54 | #include "tda8290.h" |
@@ -978,6 +979,18 @@ static struct lgdt3305_config hcw_lgdt3305_config = { | |||
978 | .vsb_if_khz = 3250, | 979 | .vsb_if_khz = 3250, |
979 | }; | 980 | }; |
980 | 981 | ||
982 | static struct tda10048_config hcw_tda10048_config = { | ||
983 | .demod_address = 0x10 >> 1, | ||
984 | .output_mode = TDA10048_SERIAL_OUTPUT, | ||
985 | .fwbulkwritelen = TDA10048_BULKWRITE_200, | ||
986 | .inversion = TDA10048_INVERSION_ON, | ||
987 | .dtv6_if_freq_khz = TDA10048_IF_3300, | ||
988 | .dtv7_if_freq_khz = TDA10048_IF_3500, | ||
989 | .dtv8_if_freq_khz = TDA10048_IF_4000, | ||
990 | .clk_freq_khz = TDA10048_CLK_16000, | ||
991 | .disable_gate_access = 1, | ||
992 | }; | ||
993 | |||
981 | static struct tda18271_std_map hauppauge_tda18271_std_map = { | 994 | static struct tda18271_std_map hauppauge_tda18271_std_map = { |
982 | .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, | 995 | .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, |
983 | .if_lvl = 1, .rfagc_top = 0x58, }, | 996 | .if_lvl = 1, .rfagc_top = 0x58, }, |
@@ -1106,6 +1119,19 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1106 | &tda827x_cfg_2) < 0) | 1119 | &tda827x_cfg_2) < 0) |
1107 | goto dettach_frontend; | 1120 | goto dettach_frontend; |
1108 | break; | 1121 | break; |
1122 | case SAA7134_BOARD_HAUPPAUGE_HVR1110R3: | ||
1123 | fe0->dvb.frontend = dvb_attach(tda10048_attach, | ||
1124 | &hcw_tda10048_config, | ||
1125 | &dev->i2c_adap); | ||
1126 | if (fe0->dvb.frontend != NULL) { | ||
1127 | dvb_attach(tda829x_attach, fe0->dvb.frontend, | ||
1128 | &dev->i2c_adap, 0x4b, | ||
1129 | &tda829x_no_probe); | ||
1130 | dvb_attach(tda18271_attach, fe0->dvb.frontend, | ||
1131 | 0x60, &dev->i2c_adap, | ||
1132 | &hcw_tda18271_config); | ||
1133 | } | ||
1134 | break; | ||
1109 | case SAA7134_BOARD_PHILIPS_TIGER: | 1135 | case SAA7134_BOARD_PHILIPS_TIGER: |
1110 | if (configure_tda827x_fe(dev, &philips_tiger_config, | 1136 | if (configure_tda827x_fe(dev, &philips_tiger_config, |
1111 | &tda827x_cfg_0) < 0) | 1137 | &tda827x_cfg_0) < 0) |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 9db3472667e5..add1757f8930 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -255,6 +255,16 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv, | |||
255 | return 0; | 255 | return 0; |
256 | } | 256 | } |
257 | 257 | ||
258 | static int empress_try_fmt_vid_cap(struct file *file, void *priv, | ||
259 | struct v4l2_format *f) | ||
260 | { | ||
261 | struct saa7134_dev *dev = file->private_data; | ||
262 | |||
263 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
264 | f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; | ||
265 | |||
266 | return 0; | ||
267 | } | ||
258 | 268 | ||
259 | static int empress_reqbufs(struct file *file, void *priv, | 269 | static int empress_reqbufs(struct file *file, void *priv, |
260 | struct v4l2_requestbuffers *p) | 270 | struct v4l2_requestbuffers *p) |
@@ -450,6 +460,7 @@ static const struct v4l2_file_operations ts_fops = | |||
450 | static const struct v4l2_ioctl_ops ts_ioctl_ops = { | 460 | static const struct v4l2_ioctl_ops ts_ioctl_ops = { |
451 | .vidioc_querycap = empress_querycap, | 461 | .vidioc_querycap = empress_querycap, |
452 | .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, | 462 | .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, |
463 | .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap, | ||
453 | .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, | 464 | .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, |
454 | .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, | 465 | .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, |
455 | .vidioc_reqbufs = empress_reqbufs, | 466 | .vidioc_reqbufs = empress_reqbufs, |
@@ -491,11 +502,8 @@ static void empress_signal_update(struct work_struct *work) | |||
491 | 502 | ||
492 | if (dev->nosignal) { | 503 | if (dev->nosignal) { |
493 | dprintk("no video signal\n"); | 504 | dprintk("no video signal\n"); |
494 | ts_reset_encoder(dev); | ||
495 | } else { | 505 | } else { |
496 | dprintk("video signal acquired\n"); | 506 | dprintk("video signal acquired\n"); |
497 | if (atomic_read(&dev->empress_users)) | ||
498 | ts_init_encoder(dev); | ||
499 | } | 507 | } |
500 | } | 508 | } |
501 | 509 | ||
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index f3e285aa2fb4..8096dace5f6c 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c | |||
@@ -259,7 +259,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
259 | /* workaround for a saa7134 i2c bug | 259 | /* workaround for a saa7134 i2c bug |
260 | * needed to talk to the mt352 demux | 260 | * needed to talk to the mt352 demux |
261 | * thanks to pinnacle for the hint */ | 261 | * thanks to pinnacle for the hint */ |
262 | int quirk = 0xfd; | 262 | int quirk = 0xfe; |
263 | d1printk(" [%02x quirk]",quirk); | 263 | d1printk(" [%02x quirk]",quirk); |
264 | i2c_send_byte(dev,START,quirk); | 264 | i2c_send_byte(dev,START,quirk); |
265 | i2c_recv_byte(dev); | 265 | i2c_recv_byte(dev); |
@@ -321,33 +321,6 @@ static u32 functionality(struct i2c_adapter *adap) | |||
321 | return I2C_FUNC_SMBUS_EMUL; | 321 | return I2C_FUNC_SMBUS_EMUL; |
322 | } | 322 | } |
323 | 323 | ||
324 | static int attach_inform(struct i2c_client *client) | ||
325 | { | ||
326 | struct saa7134_dev *dev = client->adapter->algo_data; | ||
327 | |||
328 | d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", | ||
329 | client->driver->driver.name, client->addr, client->name); | ||
330 | |||
331 | /* Am I an i2c remote control? */ | ||
332 | |||
333 | switch (client->addr) { | ||
334 | case 0x7a: | ||
335 | case 0x47: | ||
336 | case 0x71: | ||
337 | case 0x2d: | ||
338 | case 0x30: | ||
339 | { | ||
340 | struct IR_i2c *ir = i2c_get_clientdata(client); | ||
341 | d1printk("%s i2c IR detected (%s).\n", | ||
342 | client->driver->driver.name, ir->phys); | ||
343 | saa7134_set_i2c_ir(dev,ir); | ||
344 | break; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static struct i2c_algorithm saa7134_algo = { | 324 | static struct i2c_algorithm saa7134_algo = { |
352 | .master_xfer = saa7134_i2c_xfer, | 325 | .master_xfer = saa7134_i2c_xfer, |
353 | .functionality = functionality, | 326 | .functionality = functionality, |
@@ -358,7 +331,6 @@ static struct i2c_adapter saa7134_adap_template = { | |||
358 | .name = "saa7134", | 331 | .name = "saa7134", |
359 | .id = I2C_HW_SAA7134, | 332 | .id = I2C_HW_SAA7134, |
360 | .algo = &saa7134_algo, | 333 | .algo = &saa7134_algo, |
361 | .client_register = attach_inform, | ||
362 | }; | 334 | }; |
363 | 335 | ||
364 | static struct i2c_client saa7134_client_template = { | 336 | static struct i2c_client saa7134_client_template = { |
@@ -433,6 +405,9 @@ int saa7134_i2c_register(struct saa7134_dev *dev) | |||
433 | saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata)); | 405 | saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata)); |
434 | if (i2c_scan) | 406 | if (i2c_scan) |
435 | do_i2c_scan(dev->name,&dev->i2c_client); | 407 | do_i2c_scan(dev->name,&dev->i2c_client); |
408 | |||
409 | /* Instantiate the IR receiver device, if present */ | ||
410 | saa7134_probe_i2c_ir(dev); | ||
436 | return 0; | 411 | return 0; |
437 | } | 412 | } |
438 | 413 | ||
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 8a106d36e723..6e219c2db841 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of " | |||
60 | #define dprintk(fmt, arg...) if (ir_debug) \ | 60 | #define dprintk(fmt, arg...) if (ir_debug) \ |
61 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) | 61 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) |
62 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ | 62 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ |
63 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) | 63 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg) |
64 | 64 | ||
65 | /* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ | 65 | /* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ |
66 | static int saa7134_rc5_irq(struct saa7134_dev *dev); | 66 | static int saa7134_rc5_irq(struct saa7134_dev *dev); |
@@ -134,10 +134,10 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, | |||
134 | int gpio; | 134 | int gpio; |
135 | 135 | ||
136 | /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ | 136 | /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ |
137 | struct saa7134_dev *dev = ir->c.adapter->algo_data; | 137 | struct saa7134_dev *dev = ir->c->adapter->algo_data; |
138 | if (dev == NULL) { | 138 | if (dev == NULL) { |
139 | dprintk("get_key_msi_tvanywhere_plus: " | 139 | dprintk("get_key_msi_tvanywhere_plus: " |
140 | "gir->c.adapter->algo_data is NULL!\n"); | 140 | "gir->c->adapter->algo_data is NULL!\n"); |
141 | return -EIO; | 141 | return -EIO; |
142 | } | 142 | } |
143 | 143 | ||
@@ -156,7 +156,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, | |||
156 | 156 | ||
157 | /* GPIO says there is a button press. Get it. */ | 157 | /* GPIO says there is a button press. Get it. */ |
158 | 158 | ||
159 | if (1 != i2c_master_recv(&ir->c, &b, 1)) { | 159 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
160 | i2cdprintk("read error\n"); | 160 | i2cdprintk("read error\n"); |
161 | return -EIO; | 161 | return -EIO; |
162 | } | 162 | } |
@@ -179,7 +179,7 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
179 | unsigned char b; | 179 | unsigned char b; |
180 | 180 | ||
181 | /* poll IR chip */ | 181 | /* poll IR chip */ |
182 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 182 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
183 | i2cdprintk("read error\n"); | 183 | i2cdprintk("read error\n"); |
184 | return -EIO; | 184 | return -EIO; |
185 | } | 185 | } |
@@ -202,7 +202,7 @@ static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
202 | unsigned char buf[5], cod4, code3, code4; | 202 | unsigned char buf[5], cod4, code3, code4; |
203 | 203 | ||
204 | /* poll IR chip */ | 204 | /* poll IR chip */ |
205 | if (5 != i2c_master_recv(&ir->c,buf,5)) | 205 | if (5 != i2c_master_recv(ir->c, buf, 5)) |
206 | return -EIO; | 206 | return -EIO; |
207 | 207 | ||
208 | cod4 = buf[4]; | 208 | cod4 = buf[4]; |
@@ -224,7 +224,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
224 | unsigned char data[12]; | 224 | unsigned char data[12]; |
225 | u32 gpio; | 225 | u32 gpio; |
226 | 226 | ||
227 | struct saa7134_dev *dev = ir->c.adapter->algo_data; | 227 | struct saa7134_dev *dev = ir->c->adapter->algo_data; |
228 | 228 | ||
229 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ | 229 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ |
230 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | 230 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); |
@@ -235,9 +235,9 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
235 | if (0x400000 & ~gpio) | 235 | if (0x400000 & ~gpio) |
236 | return 0; /* No button press */ | 236 | return 0; /* No button press */ |
237 | 237 | ||
238 | ir->c.addr = 0x5a >> 1; | 238 | ir->c->addr = 0x5a >> 1; |
239 | 239 | ||
240 | if (12 != i2c_master_recv(&ir->c, data, 12)) { | 240 | if (12 != i2c_master_recv(ir->c, data, 12)) { |
241 | i2cdprintk("read error\n"); | 241 | i2cdprintk("read error\n"); |
242 | return -EIO; | 242 | return -EIO; |
243 | } | 243 | } |
@@ -267,7 +267,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, | |||
267 | unsigned int start = 0,parity = 0,code = 0; | 267 | unsigned int start = 0,parity = 0,code = 0; |
268 | 268 | ||
269 | /* poll IR chip */ | 269 | /* poll IR chip */ |
270 | if (4 != i2c_master_recv(&ir->c, b, 4)) { | 270 | if (4 != i2c_master_recv(ir->c, b, 4)) { |
271 | i2cdprintk("read error\n"); | 271 | i2cdprintk("read error\n"); |
272 | return -EIO; | 272 | return -EIO; |
273 | } | 273 | } |
@@ -447,6 +447,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
447 | case SAA7134_BOARD_AVERMEDIA_STUDIO_305: | 447 | case SAA7134_BOARD_AVERMEDIA_STUDIO_305: |
448 | case SAA7134_BOARD_AVERMEDIA_STUDIO_307: | 448 | case SAA7134_BOARD_AVERMEDIA_STUDIO_307: |
449 | case SAA7134_BOARD_AVERMEDIA_STUDIO_507: | 449 | case SAA7134_BOARD_AVERMEDIA_STUDIO_507: |
450 | case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA: | ||
450 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: | 451 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: |
451 | case SAA7134_BOARD_AVERMEDIA_M102: | 452 | case SAA7134_BOARD_AVERMEDIA_M102: |
452 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: | 453 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: |
@@ -506,7 +507,10 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
506 | case SAA7134_BOARD_BEHOLD_407FM: | 507 | case SAA7134_BOARD_BEHOLD_407FM: |
507 | case SAA7134_BOARD_BEHOLD_409: | 508 | case SAA7134_BOARD_BEHOLD_409: |
508 | case SAA7134_BOARD_BEHOLD_505FM: | 509 | case SAA7134_BOARD_BEHOLD_505FM: |
510 | case SAA7134_BOARD_BEHOLD_505RDS: | ||
509 | case SAA7134_BOARD_BEHOLD_507_9FM: | 511 | case SAA7134_BOARD_BEHOLD_507_9FM: |
512 | case SAA7134_BOARD_BEHOLD_507RDS_MK3: | ||
513 | case SAA7134_BOARD_BEHOLD_507RDS_MK5: | ||
510 | ir_codes = ir_codes_manli; | 514 | ir_codes = ir_codes_manli; |
511 | mask_keycode = 0x003f00; | 515 | mask_keycode = 0x003f00; |
512 | mask_keyup = 0x004000; | 516 | mask_keyup = 0x004000; |
@@ -678,55 +682,101 @@ void saa7134_input_fini(struct saa7134_dev *dev) | |||
678 | dev->remote = NULL; | 682 | dev->remote = NULL; |
679 | } | 683 | } |
680 | 684 | ||
681 | void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) | 685 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev) |
682 | { | 686 | { |
687 | struct i2c_board_info info; | ||
688 | struct IR_i2c_init_data init_data; | ||
689 | const unsigned short addr_list[] = { | ||
690 | 0x7a, 0x47, 0x71, 0x2d, | ||
691 | I2C_CLIENT_END | ||
692 | }; | ||
693 | |||
694 | struct i2c_msg msg_msi = { | ||
695 | .addr = 0x50, | ||
696 | .flags = I2C_M_RD, | ||
697 | .len = 0, | ||
698 | .buf = NULL, | ||
699 | }; | ||
700 | |||
701 | int rc; | ||
702 | |||
683 | if (disable_ir) { | 703 | if (disable_ir) { |
684 | dprintk("Found supported i2c remote, but IR has been disabled\n"); | 704 | dprintk("IR has been disabled, not probing for i2c remote\n"); |
685 | ir->get_key=NULL; | ||
686 | return; | 705 | return; |
687 | } | 706 | } |
688 | 707 | ||
708 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
709 | memset(&init_data, 0, sizeof(struct IR_i2c_init_data)); | ||
710 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
711 | |||
689 | switch (dev->board) { | 712 | switch (dev->board) { |
690 | case SAA7134_BOARD_PINNACLE_PCTV_110i: | 713 | case SAA7134_BOARD_PINNACLE_PCTV_110i: |
691 | case SAA7134_BOARD_PINNACLE_PCTV_310i: | 714 | case SAA7134_BOARD_PINNACLE_PCTV_310i: |
692 | snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); | 715 | init_data.name = "Pinnacle PCTV"; |
693 | if (pinnacle_remote == 0) { | 716 | if (pinnacle_remote == 0) { |
694 | ir->get_key = get_key_pinnacle_color; | 717 | init_data.get_key = get_key_pinnacle_color; |
695 | ir->ir_codes = ir_codes_pinnacle_color; | 718 | init_data.ir_codes = ir_codes_pinnacle_color; |
696 | } else { | 719 | } else { |
697 | ir->get_key = get_key_pinnacle_grey; | 720 | init_data.get_key = get_key_pinnacle_grey; |
698 | ir->ir_codes = ir_codes_pinnacle_grey; | 721 | init_data.ir_codes = ir_codes_pinnacle_grey; |
699 | } | 722 | } |
700 | break; | 723 | break; |
701 | case SAA7134_BOARD_UPMOST_PURPLE_TV: | 724 | case SAA7134_BOARD_UPMOST_PURPLE_TV: |
702 | snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); | 725 | init_data.name = "Purple TV"; |
703 | ir->get_key = get_key_purpletv; | 726 | init_data.get_key = get_key_purpletv; |
704 | ir->ir_codes = ir_codes_purpletv; | 727 | init_data.ir_codes = ir_codes_purpletv; |
705 | break; | 728 | break; |
706 | case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: | 729 | case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: |
707 | snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus"); | 730 | init_data.name = "MSI TV@nywhere Plus"; |
708 | ir->get_key = get_key_msi_tvanywhere_plus; | 731 | init_data.get_key = get_key_msi_tvanywhere_plus; |
709 | ir->ir_codes = ir_codes_msi_tvanywhere_plus; | 732 | init_data.ir_codes = ir_codes_msi_tvanywhere_plus; |
733 | info.addr = 0x30; | ||
734 | /* MSI TV@nywhere Plus controller doesn't seem to | ||
735 | respond to probes unless we read something from | ||
736 | an existing device. Weird... | ||
737 | REVISIT: might no longer be needed */ | ||
738 | rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1); | ||
739 | dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n", | ||
740 | msg_msi.addr, dev->i2c_adap.name, | ||
741 | (1 == rc) ? "yes" : "no"); | ||
710 | break; | 742 | break; |
711 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: | 743 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: |
712 | snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110"); | 744 | init_data.name = "HVR 1110"; |
713 | ir->get_key = get_key_hvr1110; | 745 | init_data.get_key = get_key_hvr1110; |
714 | ir->ir_codes = ir_codes_hauppauge_new; | 746 | init_data.ir_codes = ir_codes_hauppauge_new; |
715 | break; | 747 | break; |
716 | case SAA7134_BOARD_BEHOLD_607_9FM: | 748 | case SAA7134_BOARD_BEHOLD_607FM_MK3: |
749 | case SAA7134_BOARD_BEHOLD_607FM_MK5: | ||
750 | case SAA7134_BOARD_BEHOLD_609FM_MK3: | ||
751 | case SAA7134_BOARD_BEHOLD_609FM_MK5: | ||
752 | case SAA7134_BOARD_BEHOLD_607RDS_MK3: | ||
753 | case SAA7134_BOARD_BEHOLD_607RDS_MK5: | ||
754 | case SAA7134_BOARD_BEHOLD_609RDS_MK3: | ||
755 | case SAA7134_BOARD_BEHOLD_609RDS_MK5: | ||
717 | case SAA7134_BOARD_BEHOLD_M6: | 756 | case SAA7134_BOARD_BEHOLD_M6: |
718 | case SAA7134_BOARD_BEHOLD_M63: | 757 | case SAA7134_BOARD_BEHOLD_M63: |
719 | case SAA7134_BOARD_BEHOLD_M6_EXTRA: | 758 | case SAA7134_BOARD_BEHOLD_M6_EXTRA: |
720 | case SAA7134_BOARD_BEHOLD_H6: | 759 | case SAA7134_BOARD_BEHOLD_H6: |
721 | snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV"); | 760 | init_data.name = "BeholdTV"; |
722 | ir->get_key = get_key_beholdm6xx; | 761 | init_data.get_key = get_key_beholdm6xx; |
723 | ir->ir_codes = ir_codes_behold; | 762 | init_data.ir_codes = ir_codes_behold; |
724 | break; | 763 | break; |
725 | default: | 764 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: |
726 | dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); | 765 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: |
766 | info.addr = 0x40; | ||
727 | break; | 767 | break; |
728 | } | 768 | } |
729 | 769 | ||
770 | if (init_data.name) | ||
771 | info.platform_data = &init_data; | ||
772 | /* No need to probe if address is known */ | ||
773 | if (info.addr) { | ||
774 | i2c_new_device(&dev->i2c_adap, &info); | ||
775 | return; | ||
776 | } | ||
777 | |||
778 | /* Address not known, fallback to probing */ | ||
779 | i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); | ||
730 | } | 780 | } |
731 | 781 | ||
732 | static int saa7134_rc5_irq(struct saa7134_dev *dev) | 782 | static int saa7134_rc5_irq(struct saa7134_dev *dev) |
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index cc8b923afbc0..3fa652279ac0 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c | |||
@@ -65,35 +65,10 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
65 | /* start DMA */ | 65 | /* start DMA */ |
66 | saa7134_set_dmabits(dev); | 66 | saa7134_set_dmabits(dev); |
67 | 67 | ||
68 | mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT); | 68 | mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT); |
69 | |||
70 | if (dev->ts_state == SAA7134_TS_BUFF_DONE) { | ||
71 | /* Clear TS cache */ | ||
72 | dev->buff_cnt = 0; | ||
73 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
74 | saa_writeb(SAA7134_TS_SERIAL1, 0x03); | ||
75 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
76 | saa_writeb(SAA7134_TS_SERIAL1, 0x01); | ||
77 | |||
78 | /* TS clock non-inverted */ | ||
79 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
80 | |||
81 | /* Start TS stream */ | ||
82 | switch (saa7134_boards[dev->board].ts_type) { | ||
83 | case SAA7134_MPEG_TS_PARALLEL: | ||
84 | saa_writeb(SAA7134_TS_SERIAL0, 0x40); | ||
85 | saa_writeb(SAA7134_TS_PARALLEL, 0xec); | ||
86 | break; | ||
87 | case SAA7134_MPEG_TS_SERIAL: | ||
88 | saa_writeb(SAA7134_TS_SERIAL0, 0xd8); | ||
89 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | ||
90 | saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); | ||
91 | saa_writeb(SAA7134_TS_SERIAL1, 0x02); | ||
92 | break; | ||
93 | } | ||
94 | 69 | ||
95 | dev->ts_state = SAA7134_TS_STARTED; | 70 | if (!dev->ts_started) |
96 | } | 71 | saa7134_ts_start(dev); |
97 | 72 | ||
98 | return 0; | 73 | return 0; |
99 | } | 74 | } |
@@ -104,7 +79,6 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
104 | struct saa7134_dev *dev = q->priv_data; | 79 | struct saa7134_dev *dev = q->priv_data; |
105 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 80 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); |
106 | unsigned int lines, llength, size; | 81 | unsigned int lines, llength, size; |
107 | u32 control; | ||
108 | int err; | 82 | int err; |
109 | 83 | ||
110 | dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); | 84 | dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); |
@@ -121,8 +95,11 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
121 | } | 95 | } |
122 | 96 | ||
123 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 97 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
98 | |||
124 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 99 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); |
125 | 100 | ||
101 | dprintk("buffer_prepare: needs_init\n"); | ||
102 | |||
126 | buf->vb.width = llength; | 103 | buf->vb.width = llength; |
127 | buf->vb.height = lines; | 104 | buf->vb.height = lines; |
128 | buf->vb.size = size; | 105 | buf->vb.size = size; |
@@ -139,23 +116,6 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
139 | goto oops; | 116 | goto oops; |
140 | } | 117 | } |
141 | 118 | ||
142 | dev->buff_cnt++; | ||
143 | |||
144 | if (dev->buff_cnt == dev->ts.nr_bufs) { | ||
145 | dev->ts_state = SAA7134_TS_BUFF_DONE; | ||
146 | /* dma: setup channel 5 (= TS) */ | ||
147 | control = SAA7134_RS_CONTROL_BURST_16 | | ||
148 | SAA7134_RS_CONTROL_ME | | ||
149 | (buf->pt->dma >> 12); | ||
150 | |||
151 | saa_writeb(SAA7134_TS_DMA0, (lines - 1) & 0xff); | ||
152 | saa_writeb(SAA7134_TS_DMA1, ((lines - 1) >> 8) & 0xff); | ||
153 | /* TSNOPIT=0, TSCOLAP=0 */ | ||
154 | saa_writeb(SAA7134_TS_DMA2, (((lines - 1) >> 16) & 0x3f) | 0x00); | ||
155 | saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); | ||
156 | saa_writel(SAA7134_RS_CONTROL(5), control); | ||
157 | } | ||
158 | |||
159 | buf->vb.state = VIDEOBUF_PREPARED; | 119 | buf->vb.state = VIDEOBUF_PREPARED; |
160 | buf->activate = buffer_activate; | 120 | buf->activate = buffer_activate; |
161 | buf->vb.field = field; | 121 | buf->vb.field = field; |
@@ -175,8 +135,7 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | |||
175 | if (0 == *count) | 135 | if (0 == *count) |
176 | *count = dev->ts.nr_bufs; | 136 | *count = dev->ts.nr_bufs; |
177 | *count = saa7134_buffer_count(*size,*count); | 137 | *count = saa7134_buffer_count(*size,*count); |
178 | dev->buff_cnt = 0; | 138 | |
179 | dev->ts_state = SAA7134_TS_STOPPED; | ||
180 | return 0; | 139 | return 0; |
181 | } | 140 | } |
182 | 141 | ||
@@ -193,11 +152,9 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | |||
193 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 152 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); |
194 | struct saa7134_dev *dev = q->priv_data; | 153 | struct saa7134_dev *dev = q->priv_data; |
195 | 154 | ||
196 | if (dev->ts_state == SAA7134_TS_STARTED) { | 155 | if (dev->ts_started) |
197 | /* Stop TS transport */ | 156 | saa7134_ts_stop(dev); |
198 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | 157 | |
199 | dev->ts_state = SAA7134_TS_STOPPED; | ||
200 | } | ||
201 | saa7134_dma_free(q,buf); | 158 | saa7134_dma_free(q,buf); |
202 | } | 159 | } |
203 | 160 | ||
@@ -214,7 +171,7 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops); | |||
214 | 171 | ||
215 | static unsigned int tsbufs = 8; | 172 | static unsigned int tsbufs = 8; |
216 | module_param(tsbufs, int, 0444); | 173 | module_param(tsbufs, int, 0444); |
217 | MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); | 174 | MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32"); |
218 | 175 | ||
219 | static unsigned int ts_nr_packets = 64; | 176 | static unsigned int ts_nr_packets = 64; |
220 | module_param(ts_nr_packets, int, 0444); | 177 | module_param(ts_nr_packets, int, 0444); |
@@ -256,6 +213,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev) | |||
256 | dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); | 213 | dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); |
257 | dev->ts_q.dev = dev; | 214 | dev->ts_q.dev = dev; |
258 | dev->ts_q.need_two = 1; | 215 | dev->ts_q.need_two = 1; |
216 | dev->ts_started = 0; | ||
259 | saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); | 217 | saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); |
260 | 218 | ||
261 | /* init TS hw */ | 219 | /* init TS hw */ |
@@ -264,13 +222,67 @@ int saa7134_ts_init1(struct saa7134_dev *dev) | |||
264 | return 0; | 222 | return 0; |
265 | } | 223 | } |
266 | 224 | ||
225 | /* Function for stop TS */ | ||
226 | int saa7134_ts_stop(struct saa7134_dev *dev) | ||
227 | { | ||
228 | dprintk("TS stop\n"); | ||
229 | |||
230 | BUG_ON(!dev->ts_started); | ||
231 | |||
232 | /* Stop TS stream */ | ||
233 | switch (saa7134_boards[dev->board].ts_type) { | ||
234 | case SAA7134_MPEG_TS_PARALLEL: | ||
235 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | ||
236 | dev->ts_started = 0; | ||
237 | break; | ||
238 | case SAA7134_MPEG_TS_SERIAL: | ||
239 | saa_writeb(SAA7134_TS_SERIAL0, 0x40); | ||
240 | dev->ts_started = 0; | ||
241 | break; | ||
242 | } | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | /* Function for start TS */ | ||
247 | int saa7134_ts_start(struct saa7134_dev *dev) | ||
248 | { | ||
249 | dprintk("TS start\n"); | ||
250 | |||
251 | BUG_ON(dev->ts_started); | ||
252 | |||
253 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
254 | saa_writeb(SAA7134_TS_SERIAL1, 0x03); | ||
255 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
256 | saa_writeb(SAA7134_TS_SERIAL1, 0x01); | ||
257 | |||
258 | /* TS clock non-inverted */ | ||
259 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | ||
260 | |||
261 | /* Start TS stream */ | ||
262 | switch (saa7134_boards[dev->board].ts_type) { | ||
263 | case SAA7134_MPEG_TS_PARALLEL: | ||
264 | saa_writeb(SAA7134_TS_SERIAL0, 0x40); | ||
265 | saa_writeb(SAA7134_TS_PARALLEL, 0xec); | ||
266 | break; | ||
267 | case SAA7134_MPEG_TS_SERIAL: | ||
268 | saa_writeb(SAA7134_TS_SERIAL0, 0xd8); | ||
269 | saa_writeb(SAA7134_TS_PARALLEL, 0x6c); | ||
270 | saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); | ||
271 | saa_writeb(SAA7134_TS_SERIAL1, 0x02); | ||
272 | break; | ||
273 | } | ||
274 | |||
275 | dev->ts_started = 1; | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
267 | int saa7134_ts_fini(struct saa7134_dev *dev) | 280 | int saa7134_ts_fini(struct saa7134_dev *dev) |
268 | { | 281 | { |
269 | saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); | 282 | saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); |
270 | return 0; | 283 | return 0; |
271 | } | 284 | } |
272 | 285 | ||
273 | |||
274 | void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) | 286 | void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) |
275 | { | 287 | { |
276 | enum v4l2_field field; | 288 | enum v4l2_field field; |
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 493cad941460..e305c1674cee 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -1057,6 +1057,7 @@ static int buffer_prepare(struct videobuf_queue *q, | |||
1057 | buf->vb.field = field; | 1057 | buf->vb.field = field; |
1058 | buf->fmt = fh->fmt; | 1058 | buf->fmt = fh->fmt; |
1059 | buf->pt = &fh->pt_cap; | 1059 | buf->pt = &fh->pt_cap; |
1060 | dev->video_q.curr = NULL; | ||
1060 | 1061 | ||
1061 | err = videobuf_iolock(q,&buf->vb,&dev->ovbuf); | 1062 | err = videobuf_iolock(q,&buf->vb,&dev->ovbuf); |
1062 | if (err) | 1063 | if (err) |
@@ -1423,11 +1424,13 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
1423 | { | 1424 | { |
1424 | struct saa7134_fh *fh = file->private_data; | 1425 | struct saa7134_fh *fh = file->private_data; |
1425 | struct videobuf_buffer *buf = NULL; | 1426 | struct videobuf_buffer *buf = NULL; |
1427 | unsigned int rc = 0; | ||
1426 | 1428 | ||
1427 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) | 1429 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) |
1428 | return videobuf_poll_stream(file, &fh->vbi, wait); | 1430 | return videobuf_poll_stream(file, &fh->vbi, wait); |
1429 | 1431 | ||
1430 | if (res_check(fh,RESOURCE_VIDEO)) { | 1432 | if (res_check(fh,RESOURCE_VIDEO)) { |
1433 | mutex_lock(&fh->cap.vb_lock); | ||
1431 | if (!list_empty(&fh->cap.stream)) | 1434 | if (!list_empty(&fh->cap.stream)) |
1432 | buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); | 1435 | buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); |
1433 | } else { | 1436 | } else { |
@@ -1446,13 +1449,14 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
1446 | } | 1449 | } |
1447 | 1450 | ||
1448 | if (!buf) | 1451 | if (!buf) |
1449 | return POLLERR; | 1452 | goto err; |
1450 | 1453 | ||
1451 | poll_wait(file, &buf->done, wait); | 1454 | poll_wait(file, &buf->done, wait); |
1452 | if (buf->state == VIDEOBUF_DONE || | 1455 | if (buf->state == VIDEOBUF_DONE || |
1453 | buf->state == VIDEOBUF_ERROR) | 1456 | buf->state == VIDEOBUF_ERROR) |
1454 | return POLLIN|POLLRDNORM; | 1457 | rc = POLLIN|POLLRDNORM; |
1455 | return 0; | 1458 | mutex_unlock(&fh->cap.vb_lock); |
1459 | return rc; | ||
1456 | 1460 | ||
1457 | err: | 1461 | err: |
1458 | mutex_unlock(&fh->cap.vb_lock); | 1462 | mutex_unlock(&fh->cap.vb_lock); |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 0cbaf90d4874..82268848f26a 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -252,7 +252,7 @@ struct saa7134_format { | |||
252 | #define SAA7134_BOARD_BEHOLD_505FM 126 | 252 | #define SAA7134_BOARD_BEHOLD_505FM 126 |
253 | #define SAA7134_BOARD_BEHOLD_507_9FM 127 | 253 | #define SAA7134_BOARD_BEHOLD_507_9FM 127 |
254 | #define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128 | 254 | #define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128 |
255 | #define SAA7134_BOARD_BEHOLD_607_9FM 129 | 255 | #define SAA7134_BOARD_BEHOLD_607FM_MK3 129 |
256 | #define SAA7134_BOARD_BEHOLD_M6 130 | 256 | #define SAA7134_BOARD_BEHOLD_M6 130 |
257 | #define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 | 257 | #define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 |
258 | #define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132 | 258 | #define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132 |
@@ -280,6 +280,18 @@ struct saa7134_format { | |||
280 | #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154 | 280 | #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154 |
281 | #define SAA7134_BOARD_HAUPPAUGE_HVR1120 155 | 281 | #define SAA7134_BOARD_HAUPPAUGE_HVR1120 155 |
282 | #define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156 | 282 | #define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156 |
283 | #define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157 | ||
284 | #define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158 | ||
285 | #define SAA7134_BOARD_BEHOLD_505RDS 159 | ||
286 | #define SAA7134_BOARD_BEHOLD_507RDS_MK3 160 | ||
287 | #define SAA7134_BOARD_BEHOLD_507RDS_MK5 161 | ||
288 | #define SAA7134_BOARD_BEHOLD_607FM_MK5 162 | ||
289 | #define SAA7134_BOARD_BEHOLD_609FM_MK3 163 | ||
290 | #define SAA7134_BOARD_BEHOLD_609FM_MK5 164 | ||
291 | #define SAA7134_BOARD_BEHOLD_607RDS_MK3 165 | ||
292 | #define SAA7134_BOARD_BEHOLD_607RDS_MK5 166 | ||
293 | #define SAA7134_BOARD_BEHOLD_609RDS_MK3 167 | ||
294 | #define SAA7134_BOARD_BEHOLD_609RDS_MK5 168 | ||
283 | 295 | ||
284 | #define SAA7134_MAXBOARDS 32 | 296 | #define SAA7134_MAXBOARDS 32 |
285 | #define SAA7134_INPUT_MAX 8 | 297 | #define SAA7134_INPUT_MAX 8 |
@@ -364,6 +376,7 @@ struct saa7134_board { | |||
364 | #define INTERLACE_OFF 2 | 376 | #define INTERLACE_OFF 2 |
365 | 377 | ||
366 | #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ | 378 | #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ |
379 | #define TS_BUFFER_TIMEOUT msecs_to_jiffies(1000) /* 1 second */ | ||
367 | 380 | ||
368 | struct saa7134_dev; | 381 | struct saa7134_dev; |
369 | struct saa7134_dma; | 382 | struct saa7134_dma; |
@@ -480,12 +493,6 @@ struct saa7134_mpeg_ops { | |||
480 | void (*signal_change)(struct saa7134_dev *dev); | 493 | void (*signal_change)(struct saa7134_dev *dev); |
481 | }; | 494 | }; |
482 | 495 | ||
483 | enum saa7134_ts_status { | ||
484 | SAA7134_TS_STOPPED, | ||
485 | SAA7134_TS_BUFF_DONE, | ||
486 | SAA7134_TS_STARTED, | ||
487 | }; | ||
488 | |||
489 | /* global device status */ | 496 | /* global device status */ |
490 | struct saa7134_dev { | 497 | struct saa7134_dev { |
491 | struct list_head devlist; | 498 | struct list_head devlist; |
@@ -580,8 +587,7 @@ struct saa7134_dev { | |||
580 | /* SAA7134_MPEG_* */ | 587 | /* SAA7134_MPEG_* */ |
581 | struct saa7134_ts ts; | 588 | struct saa7134_ts ts; |
582 | struct saa7134_dmaqueue ts_q; | 589 | struct saa7134_dmaqueue ts_q; |
583 | enum saa7134_ts_status ts_state; | 590 | int ts_started; |
584 | unsigned int buff_cnt; | ||
585 | struct saa7134_mpeg_ops *mops; | 591 | struct saa7134_mpeg_ops *mops; |
586 | 592 | ||
587 | /* SAA7134_MPEG_EMPRESS only */ | 593 | /* SAA7134_MPEG_EMPRESS only */ |
@@ -739,6 +745,9 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops); | |||
739 | 745 | ||
740 | int saa7134_ts_init_hw(struct saa7134_dev *dev); | 746 | int saa7134_ts_init_hw(struct saa7134_dev *dev); |
741 | 747 | ||
748 | int saa7134_ts_start(struct saa7134_dev *dev); | ||
749 | int saa7134_ts_stop(struct saa7134_dev *dev); | ||
750 | |||
742 | /* ----------------------------------------------------------- */ | 751 | /* ----------------------------------------------------------- */ |
743 | /* saa7134-vbi.c */ | 752 | /* saa7134-vbi.c */ |
744 | 753 | ||
@@ -786,7 +795,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status); | |||
786 | int saa7134_input_init1(struct saa7134_dev *dev); | 795 | int saa7134_input_init1(struct saa7134_dev *dev); |
787 | void saa7134_input_fini(struct saa7134_dev *dev); | 796 | void saa7134_input_fini(struct saa7134_dev *dev); |
788 | void saa7134_input_irq(struct saa7134_dev *dev); | 797 | void saa7134_input_irq(struct saa7134_dev *dev); |
789 | void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir); | 798 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev); |
790 | void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir); | 799 | void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir); |
791 | void saa7134_ir_stop(struct saa7134_dev *dev); | 800 | void saa7134_ir_stop(struct saa7134_dev *dev); |
792 | 801 | ||
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index 5990ab38a124..c8f05297d0f0 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c | |||
@@ -38,7 +38,7 @@ static const char version[] = "0.24"; | |||
38 | static int flickerless; | 38 | static int flickerless; |
39 | static int video_nr = -1; | 39 | static int video_nr = -1; |
40 | 40 | ||
41 | static struct usb_device_id device_table [] = { | 41 | static struct usb_device_id device_table[] = { |
42 | { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */ | 42 | { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */ |
43 | { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */ | 43 | { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */ |
44 | { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */ | 44 | { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */ |
@@ -53,7 +53,8 @@ MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>"); | |||
53 | MODULE_DESCRIPTION("SE401 USB Camera Driver"); | 53 | MODULE_DESCRIPTION("SE401 USB Camera Driver"); |
54 | MODULE_LICENSE("GPL"); | 54 | MODULE_LICENSE("GPL"); |
55 | module_param(flickerless, int, 0); | 55 | module_param(flickerless, int, 0); |
56 | MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)"); | 56 | MODULE_PARM_DESC(flickerless, |
57 | "Net frequency to adjust exposure time to (0/50/60)"); | ||
57 | module_param(video_nr, int, 0); | 58 | module_param(video_nr, int, 0); |
58 | 59 | ||
59 | static struct usb_driver se401_driver; | 60 | static struct usb_driver se401_driver; |
@@ -78,8 +79,8 @@ static void *rvmalloc(unsigned long size) | |||
78 | adr = (unsigned long) mem; | 79 | adr = (unsigned long) mem; |
79 | while (size > 0) { | 80 | while (size > 0) { |
80 | SetPageReserved(vmalloc_to_page((void *)adr)); | 81 | SetPageReserved(vmalloc_to_page((void *)adr)); |
81 | adr += PAGE_SIZE; | 82 | adr += PAGE_SIZE; |
82 | size -= PAGE_SIZE; | 83 | size -= PAGE_SIZE; |
83 | } | 84 | } |
84 | 85 | ||
85 | return mem; | 86 | return mem; |
@@ -95,8 +96,8 @@ static void rvfree(void *mem, unsigned long size) | |||
95 | adr = (unsigned long) mem; | 96 | adr = (unsigned long) mem; |
96 | while ((long) size > 0) { | 97 | while ((long) size > 0) { |
97 | ClearPageReserved(vmalloc_to_page((void *)adr)); | 98 | ClearPageReserved(vmalloc_to_page((void *)adr)); |
98 | adr += PAGE_SIZE; | 99 | adr += PAGE_SIZE; |
99 | size -= PAGE_SIZE; | 100 | size -= PAGE_SIZE; |
100 | } | 101 | } |
101 | vfree(mem); | 102 | vfree(mem); |
102 | } | 103 | } |
@@ -112,7 +113,7 @@ static void rvfree(void *mem, unsigned long size) | |||
112 | static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req, | 113 | static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req, |
113 | unsigned short value, unsigned char *cp, int size) | 114 | unsigned short value, unsigned char *cp, int size) |
114 | { | 115 | { |
115 | return usb_control_msg ( | 116 | return usb_control_msg( |
116 | se401->dev, | 117 | se401->dev, |
117 | set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0), | 118 | set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0), |
118 | req, | 119 | req, |
@@ -132,7 +133,7 @@ static int se401_set_feature(struct usb_se401 *se401, unsigned short selector, | |||
132 | and the param in index, but in the logs of the windows driver they do | 133 | and the param in index, but in the logs of the windows driver they do |
133 | this the other way around... | 134 | this the other way around... |
134 | */ | 135 | */ |
135 | return usb_control_msg ( | 136 | return usb_control_msg( |
136 | se401->dev, | 137 | se401->dev, |
137 | usb_sndctrlpipe(se401->dev, 0), | 138 | usb_sndctrlpipe(se401->dev, 0), |
138 | SE401_REQ_SET_EXT_FEATURE, | 139 | SE401_REQ_SET_EXT_FEATURE, |
@@ -152,7 +153,7 @@ static unsigned short se401_get_feature(struct usb_se401 *se401, | |||
152 | wrong here to.... | 153 | wrong here to.... |
153 | */ | 154 | */ |
154 | unsigned char cp[2]; | 155 | unsigned char cp[2]; |
155 | usb_control_msg ( | 156 | usb_control_msg( |
156 | se401->dev, | 157 | se401->dev, |
157 | usb_rcvctrlpipe(se401->dev, 0), | 158 | usb_rcvctrlpipe(se401->dev, 0), |
158 | SE401_REQ_GET_EXT_FEATURE, | 159 | SE401_REQ_GET_EXT_FEATURE, |
@@ -175,46 +176,51 @@ static unsigned short se401_get_feature(struct usb_se401 *se401, | |||
175 | 176 | ||
176 | static int se401_send_pict(struct usb_se401 *se401) | 177 | static int se401_send_pict(struct usb_se401 *se401) |
177 | { | 178 | { |
178 | se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */ | 179 | /* integration time low */ |
179 | se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */ | 180 | se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l); |
180 | se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */ | 181 | /* integration time mid */ |
181 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */ | 182 | se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m); |
182 | se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */ | 183 | /* integration time mid */ |
183 | se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */ | 184 | se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h); |
184 | se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */ | 185 | /* reset level value */ |
186 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); | ||
187 | /* red color gain */ | ||
188 | se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain); | ||
189 | /* green color gain */ | ||
190 | se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain); | ||
191 | /* blue color gain */ | ||
192 | se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain); | ||
185 | 193 | ||
186 | return 0; | 194 | return 0; |
187 | } | 195 | } |
188 | 196 | ||
189 | static void se401_set_exposure(struct usb_se401 *se401, int brightness) | 197 | static void se401_set_exposure(struct usb_se401 *se401, int brightness) |
190 | { | 198 | { |
191 | int integration=brightness<<5; | 199 | int integration = brightness << 5; |
192 | 200 | ||
193 | if (flickerless==50) { | 201 | if (flickerless == 50) |
194 | integration=integration-integration%106667; | 202 | integration = integration-integration % 106667; |
195 | } | 203 | if (flickerless == 60) |
196 | if (flickerless==60) { | 204 | integration = integration-integration % 88889; |
197 | integration=integration-integration%88889; | 205 | se401->brightness = integration >> 5; |
198 | } | 206 | se401->expose_h = (integration >> 16) & 0xff; |
199 | se401->brightness=integration>>5; | 207 | se401->expose_m = (integration >> 8) & 0xff; |
200 | se401->expose_h=(integration>>16)&0xff; | 208 | se401->expose_l = integration & 0xff; |
201 | se401->expose_m=(integration>>8)&0xff; | ||
202 | se401->expose_l=integration&0xff; | ||
203 | } | 209 | } |
204 | 210 | ||
205 | static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p) | 211 | static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p) |
206 | { | 212 | { |
207 | p->brightness=se401->brightness; | 213 | p->brightness = se401->brightness; |
208 | if (se401->enhance) { | 214 | if (se401->enhance) |
209 | p->whiteness=32768; | 215 | p->whiteness = 32768; |
210 | } else { | 216 | else |
211 | p->whiteness=0; | 217 | p->whiteness = 0; |
212 | } | 218 | |
213 | p->colour=65535; | 219 | p->colour = 65535; |
214 | p->contrast=65535; | 220 | p->contrast = 65535; |
215 | p->hue=se401->rgain<<10; | 221 | p->hue = se401->rgain << 10; |
216 | p->palette=se401->palette; | 222 | p->palette = se401->palette; |
217 | p->depth=3; /* rgb24 */ | 223 | p->depth = 3; /* rgb24 */ |
218 | return 0; | 224 | return 0; |
219 | } | 225 | } |
220 | 226 | ||
@@ -223,20 +229,19 @@ static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p) | |||
223 | { | 229 | { |
224 | if (p->palette != VIDEO_PALETTE_RGB24) | 230 | if (p->palette != VIDEO_PALETTE_RGB24) |
225 | return 1; | 231 | return 1; |
226 | se401->palette=p->palette; | 232 | se401->palette = p->palette; |
227 | if (p->hue!=se401->hue) { | 233 | if (p->hue != se401->hue) { |
228 | se401->rgain= p->hue>>10; | 234 | se401->rgain = p->hue >> 10; |
229 | se401->bgain= 0x40-(p->hue>>10); | 235 | se401->bgain = 0x40-(p->hue >> 10); |
230 | se401->hue=p->hue; | 236 | se401->hue = p->hue; |
231 | } | 237 | } |
232 | if (p->brightness!=se401->brightness) { | 238 | if (p->brightness != se401->brightness) |
233 | se401_set_exposure(se401, p->brightness); | 239 | se401_set_exposure(se401, p->brightness); |
234 | } | 240 | |
235 | if (p->whiteness>=32768) { | 241 | if (p->whiteness >= 32768) |
236 | se401->enhance=1; | 242 | se401->enhance = 1; |
237 | } else { | 243 | else |
238 | se401->enhance=0; | 244 | se401->enhance = 0; |
239 | } | ||
240 | se401_send_pict(se401); | 245 | se401_send_pict(se401); |
241 | se401_send_pict(se401); | 246 | se401_send_pict(se401); |
242 | return 0; | 247 | return 0; |
@@ -249,7 +254,7 @@ static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p) | |||
249 | static void se401_auto_resetlevel(struct usb_se401 *se401) | 254 | static void se401_auto_resetlevel(struct usb_se401 *se401) |
250 | { | 255 | { |
251 | unsigned int ahrc, alrc; | 256 | unsigned int ahrc, alrc; |
252 | int oldreset=se401->resetlevel; | 257 | int oldreset = se401->resetlevel; |
253 | 258 | ||
254 | /* For some reason this normally read-only register doesn't get reset | 259 | /* For some reason this normally read-only register doesn't get reset |
255 | to zero after reading them just once... | 260 | to zero after reading them just once... |
@@ -258,24 +263,24 @@ static void se401_auto_resetlevel(struct usb_se401 *se401) | |||
258 | se401_get_feature(se401, HV7131_REG_HIREFNOL); | 263 | se401_get_feature(se401, HV7131_REG_HIREFNOL); |
259 | se401_get_feature(se401, HV7131_REG_LOREFNOH); | 264 | se401_get_feature(se401, HV7131_REG_LOREFNOH); |
260 | se401_get_feature(se401, HV7131_REG_LOREFNOL); | 265 | se401_get_feature(se401, HV7131_REG_LOREFNOL); |
261 | ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + | 266 | ahrc = 256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + |
262 | se401_get_feature(se401, HV7131_REG_HIREFNOL); | 267 | se401_get_feature(se401, HV7131_REG_HIREFNOL); |
263 | alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) + | 268 | alrc = 256*se401_get_feature(se401, HV7131_REG_LOREFNOH) + |
264 | se401_get_feature(se401, HV7131_REG_LOREFNOL); | 269 | se401_get_feature(se401, HV7131_REG_LOREFNOL); |
265 | 270 | ||
266 | /* Not an exact science, but it seems to work pretty well... */ | 271 | /* Not an exact science, but it seems to work pretty well... */ |
267 | if (alrc > 10) { | 272 | if (alrc > 10) { |
268 | while (alrc>=10 && se401->resetlevel < 63) { | 273 | while (alrc >= 10 && se401->resetlevel < 63) { |
269 | se401->resetlevel++; | 274 | se401->resetlevel++; |
270 | alrc /=2; | 275 | alrc /= 2; |
271 | } | 276 | } |
272 | } else if (ahrc > 20) { | 277 | } else if (ahrc > 20) { |
273 | while (ahrc>=20 && se401->resetlevel > 0) { | 278 | while (ahrc >= 20 && se401->resetlevel > 0) { |
274 | se401->resetlevel--; | 279 | se401->resetlevel--; |
275 | ahrc /=2; | 280 | ahrc /= 2; |
276 | } | 281 | } |
277 | } | 282 | } |
278 | if (se401->resetlevel!=oldreset) | 283 | if (se401->resetlevel != oldreset) |
279 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); | 284 | se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); |
280 | 285 | ||
281 | return; | 286 | return; |
@@ -300,21 +305,22 @@ static void se401_button_irq(struct urb *urb) | |||
300 | case -ENOENT: | 305 | case -ENOENT: |
301 | case -ESHUTDOWN: | 306 | case -ESHUTDOWN: |
302 | /* this urb is terminated, clean up */ | 307 | /* this urb is terminated, clean up */ |
303 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); | 308 | dbg("%s - urb shutting down with status: %d", |
309 | __func__, urb->status); | ||
304 | return; | 310 | return; |
305 | default: | 311 | default: |
306 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); | 312 | dbg("%s - nonzero urb status received: %d", |
313 | __func__, urb->status); | ||
307 | goto exit; | 314 | goto exit; |
308 | } | 315 | } |
309 | 316 | ||
310 | if (urb->actual_length >=2) { | 317 | if (urb->actual_length >= 2) |
311 | if (se401->button) | 318 | if (se401->button) |
312 | se401->buttonpressed=1; | 319 | se401->buttonpressed = 1; |
313 | } | ||
314 | exit: | 320 | exit: |
315 | status = usb_submit_urb (urb, GFP_ATOMIC); | 321 | status = usb_submit_urb(urb, GFP_ATOMIC); |
316 | if (status) | 322 | if (status) |
317 | err ("%s - usb_submit_urb failed with result %d", | 323 | err("%s - usb_submit_urb failed with result %d", |
318 | __func__, status); | 324 | __func__, status); |
319 | } | 325 | } |
320 | 326 | ||
@@ -336,55 +342,52 @@ static void se401_video_irq(struct urb *urb) | |||
336 | keeps sending them forever... | 342 | keeps sending them forever... |
337 | */ | 343 | */ |
338 | if (length && !urb->status) { | 344 | if (length && !urb->status) { |
339 | se401->nullpackets=0; | 345 | se401->nullpackets = 0; |
340 | switch(se401->scratch[se401->scratch_next].state) { | 346 | switch (se401->scratch[se401->scratch_next].state) { |
341 | case BUFFER_READY: | 347 | case BUFFER_READY: |
342 | case BUFFER_BUSY: { | 348 | case BUFFER_BUSY: |
343 | se401->dropped++; | 349 | se401->dropped++; |
344 | break; | 350 | break; |
345 | } | 351 | case BUFFER_UNUSED: |
346 | case BUFFER_UNUSED: { | 352 | memcpy(se401->scratch[se401->scratch_next].data, |
347 | memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length); | 353 | (unsigned char *)urb->transfer_buffer, length); |
348 | se401->scratch[se401->scratch_next].state=BUFFER_READY; | 354 | se401->scratch[se401->scratch_next].state |
349 | se401->scratch[se401->scratch_next].offset=se401->bayeroffset; | 355 | = BUFFER_READY; |
350 | se401->scratch[se401->scratch_next].length=length; | 356 | se401->scratch[se401->scratch_next].offset |
351 | if (waitqueue_active(&se401->wq)) { | 357 | = se401->bayeroffset; |
352 | wake_up_interruptible(&se401->wq); | 358 | se401->scratch[se401->scratch_next].length = length; |
353 | } | 359 | if (waitqueue_active(&se401->wq)) |
354 | se401->scratch_overflow=0; | 360 | wake_up_interruptible(&se401->wq); |
355 | se401->scratch_next++; | 361 | se401->scratch_overflow = 0; |
356 | if (se401->scratch_next>=SE401_NUMSCRATCH) | 362 | se401->scratch_next++; |
357 | se401->scratch_next=0; | 363 | if (se401->scratch_next >= SE401_NUMSCRATCH) |
358 | break; | 364 | se401->scratch_next = 0; |
359 | } | 365 | break; |
360 | } | ||
361 | se401->bayeroffset+=length; | ||
362 | if (se401->bayeroffset>=se401->cheight*se401->cwidth) { | ||
363 | se401->bayeroffset=0; | ||
364 | } | 366 | } |
367 | se401->bayeroffset += length; | ||
368 | if (se401->bayeroffset >= se401->cheight * se401->cwidth) | ||
369 | se401->bayeroffset = 0; | ||
365 | } else { | 370 | } else { |
366 | se401->nullpackets++; | 371 | se401->nullpackets++; |
367 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) { | 372 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) |
368 | if (waitqueue_active(&se401->wq)) { | 373 | if (waitqueue_active(&se401->wq)) |
369 | wake_up_interruptible(&se401->wq); | 374 | wake_up_interruptible(&se401->wq); |
370 | } | ||
371 | } | ||
372 | } | 375 | } |
373 | 376 | ||
374 | /* Resubmit urb for new data */ | 377 | /* Resubmit urb for new data */ |
375 | urb->status=0; | 378 | urb->status = 0; |
376 | urb->dev=se401->dev; | 379 | urb->dev = se401->dev; |
377 | if(usb_submit_urb(urb, GFP_KERNEL)) | 380 | if (usb_submit_urb(urb, GFP_KERNEL)) |
378 | dev_info(&urb->dev->dev, "urb burned down\n"); | 381 | dev_info(&urb->dev->dev, "urb burned down\n"); |
379 | return; | 382 | return; |
380 | } | 383 | } |
381 | 384 | ||
382 | static void se401_send_size(struct usb_se401 *se401, int width, int height) | 385 | static void se401_send_size(struct usb_se401 *se401, int width, int height) |
383 | { | 386 | { |
384 | int i=0; | 387 | int i = 0; |
385 | int mode=0x03; /* No compression */ | 388 | int mode = 0x03; /* No compression */ |
386 | int sendheight=height; | 389 | int sendheight = height; |
387 | int sendwidth=width; | 390 | int sendwidth = width; |
388 | 391 | ||
389 | /* JangGu compression can only be used with the camera supported sizes, | 392 | /* JangGu compression can only be used with the camera supported sizes, |
390 | but bayer seems to work with any size that fits on the sensor. | 393 | but bayer seems to work with any size that fits on the sensor. |
@@ -392,18 +395,21 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height) | |||
392 | 4 or 16 times subcapturing, if not we use uncompressed bayer data | 395 | 4 or 16 times subcapturing, if not we use uncompressed bayer data |
393 | but this will result in cutouts of the maximum size.... | 396 | but this will result in cutouts of the maximum size.... |
394 | */ | 397 | */ |
395 | while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height)) | 398 | while (i < se401->sizes && !(se401->width[i] == width && |
399 | se401->height[i] == height)) | ||
396 | i++; | 400 | i++; |
397 | while (i<se401->sizes) { | 401 | while (i < se401->sizes) { |
398 | if (se401->width[i]==width*2 && se401->height[i]==height*2) { | 402 | if (se401->width[i] == width * 2 && |
399 | sendheight=se401->height[i]; | 403 | se401->height[i] == height * 2) { |
400 | sendwidth=se401->width[i]; | 404 | sendheight = se401->height[i]; |
401 | mode=0x40; | 405 | sendwidth = se401->width[i]; |
406 | mode = 0x40; | ||
402 | } | 407 | } |
403 | if (se401->width[i]==width*4 && se401->height[i]==height*4) { | 408 | if (se401->width[i] == width * 4 && |
404 | sendheight=se401->height[i]; | 409 | se401->height[i] == height * 4) { |
405 | sendwidth=se401->width[i]; | 410 | sendheight = se401->height[i]; |
406 | mode=0x42; | 411 | sendwidth = se401->width[i]; |
412 | mode = 0x42; | ||
407 | } | 413 | } |
408 | i++; | 414 | i++; |
409 | } | 415 | } |
@@ -412,13 +418,10 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height) | |||
412 | se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0); | 418 | se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0); |
413 | se401_set_feature(se401, SE401_OPERATINGMODE, mode); | 419 | se401_set_feature(se401, SE401_OPERATINGMODE, mode); |
414 | 420 | ||
415 | if (mode==0x03) { | 421 | if (mode == 0x03) |
416 | se401->format=FMT_BAYER; | 422 | se401->format = FMT_BAYER; |
417 | } else { | 423 | else |
418 | se401->format=FMT_JANGGU; | 424 | se401->format = FMT_JANGGU; |
419 | } | ||
420 | |||
421 | return; | ||
422 | } | 425 | } |
423 | 426 | ||
424 | /* | 427 | /* |
@@ -429,29 +432,31 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height) | |||
429 | static int se401_start_stream(struct usb_se401 *se401) | 432 | static int se401_start_stream(struct usb_se401 *se401) |
430 | { | 433 | { |
431 | struct urb *urb; | 434 | struct urb *urb; |
432 | int err=0, i; | 435 | int err = 0, i; |
433 | se401->streaming=1; | 436 | se401->streaming = 1; |
434 | 437 | ||
435 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); | 438 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); |
436 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); | 439 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); |
437 | 440 | ||
438 | /* Set picture settings */ | 441 | /* Set picture settings */ |
439 | se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */ | 442 | /* windowed + pix intg */ |
443 | se401_set_feature(se401, HV7131_REG_MODE_B, 0x05); | ||
440 | se401_send_pict(se401); | 444 | se401_send_pict(se401); |
441 | 445 | ||
442 | se401_send_size(se401, se401->cwidth, se401->cheight); | 446 | se401_send_size(se401, se401->cwidth, se401->cheight); |
443 | 447 | ||
444 | se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0); | 448 | se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, |
449 | 0, NULL, 0); | ||
445 | 450 | ||
446 | /* Do some memory allocation */ | 451 | /* Do some memory allocation */ |
447 | for (i=0; i<SE401_NUMFRAMES; i++) { | 452 | for (i = 0; i < SE401_NUMFRAMES; i++) { |
448 | se401->frame[i].data=se401->fbuf + i * se401->maxframesize; | 453 | se401->frame[i].data = se401->fbuf + i * se401->maxframesize; |
449 | se401->frame[i].curpix=0; | 454 | se401->frame[i].curpix = 0; |
450 | } | 455 | } |
451 | for (i=0; i<SE401_NUMSBUF; i++) { | 456 | for (i = 0; i < SE401_NUMSBUF; i++) { |
452 | se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL); | 457 | se401->sbuf[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL); |
453 | if (!se401->sbuf[i].data) { | 458 | if (!se401->sbuf[i].data) { |
454 | for(i = i - 1; i >= 0; i--) { | 459 | for (i = i - 1; i >= 0; i--) { |
455 | kfree(se401->sbuf[i].data); | 460 | kfree(se401->sbuf[i].data); |
456 | se401->sbuf[i].data = NULL; | 461 | se401->sbuf[i].data = NULL; |
457 | } | 462 | } |
@@ -459,26 +464,26 @@ static int se401_start_stream(struct usb_se401 *se401) | |||
459 | } | 464 | } |
460 | } | 465 | } |
461 | 466 | ||
462 | se401->bayeroffset=0; | 467 | se401->bayeroffset = 0; |
463 | se401->scratch_next=0; | 468 | se401->scratch_next = 0; |
464 | se401->scratch_use=0; | 469 | se401->scratch_use = 0; |
465 | se401->scratch_overflow=0; | 470 | se401->scratch_overflow = 0; |
466 | for (i=0; i<SE401_NUMSCRATCH; i++) { | 471 | for (i = 0; i < SE401_NUMSCRATCH; i++) { |
467 | se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL); | 472 | se401->scratch[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL); |
468 | if (!se401->scratch[i].data) { | 473 | if (!se401->scratch[i].data) { |
469 | for(i = i - 1; i >= 0; i--) { | 474 | for (i = i - 1; i >= 0; i--) { |
470 | kfree(se401->scratch[i].data); | 475 | kfree(se401->scratch[i].data); |
471 | se401->scratch[i].data = NULL; | 476 | se401->scratch[i].data = NULL; |
472 | } | 477 | } |
473 | goto nomem_sbuf; | 478 | goto nomem_sbuf; |
474 | } | 479 | } |
475 | se401->scratch[i].state=BUFFER_UNUSED; | 480 | se401->scratch[i].state = BUFFER_UNUSED; |
476 | } | 481 | } |
477 | 482 | ||
478 | for (i=0; i<SE401_NUMSBUF; i++) { | 483 | for (i = 0; i < SE401_NUMSBUF; i++) { |
479 | urb=usb_alloc_urb(0, GFP_KERNEL); | 484 | urb = usb_alloc_urb(0, GFP_KERNEL); |
480 | if(!urb) { | 485 | if (!urb) { |
481 | for(i = i - 1; i >= 0; i--) { | 486 | for (i = i - 1; i >= 0; i--) { |
482 | usb_kill_urb(se401->urb[i]); | 487 | usb_kill_urb(se401->urb[i]); |
483 | usb_free_urb(se401->urb[i]); | 488 | usb_free_urb(se401->urb[i]); |
484 | se401->urb[i] = NULL; | 489 | se401->urb[i] = NULL; |
@@ -492,24 +497,24 @@ static int se401_start_stream(struct usb_se401 *se401) | |||
492 | se401_video_irq, | 497 | se401_video_irq, |
493 | se401); | 498 | se401); |
494 | 499 | ||
495 | se401->urb[i]=urb; | 500 | se401->urb[i] = urb; |
496 | 501 | ||
497 | err=usb_submit_urb(se401->urb[i], GFP_KERNEL); | 502 | err = usb_submit_urb(se401->urb[i], GFP_KERNEL); |
498 | if(err) | 503 | if (err) |
499 | err("urb burned down"); | 504 | err("urb burned down"); |
500 | } | 505 | } |
501 | 506 | ||
502 | se401->framecount=0; | 507 | se401->framecount = 0; |
503 | 508 | ||
504 | return 0; | 509 | return 0; |
505 | 510 | ||
506 | nomem_scratch: | 511 | nomem_scratch: |
507 | for (i=0; i<SE401_NUMSCRATCH; i++) { | 512 | for (i = 0; i < SE401_NUMSCRATCH; i++) { |
508 | kfree(se401->scratch[i].data); | 513 | kfree(se401->scratch[i].data); |
509 | se401->scratch[i].data = NULL; | 514 | se401->scratch[i].data = NULL; |
510 | } | 515 | } |
511 | nomem_sbuf: | 516 | nomem_sbuf: |
512 | for (i=0; i<SE401_NUMSBUF; i++) { | 517 | for (i = 0; i < SE401_NUMSBUF; i++) { |
513 | kfree(se401->sbuf[i].data); | 518 | kfree(se401->sbuf[i].data); |
514 | se401->sbuf[i].data = NULL; | 519 | se401->sbuf[i].data = NULL; |
515 | } | 520 | } |
@@ -523,22 +528,23 @@ static int se401_stop_stream(struct usb_se401 *se401) | |||
523 | if (!se401->streaming || !se401->dev) | 528 | if (!se401->streaming || !se401->dev) |
524 | return 1; | 529 | return 1; |
525 | 530 | ||
526 | se401->streaming=0; | 531 | se401->streaming = 0; |
527 | 532 | ||
528 | se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0); | 533 | se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0); |
529 | 534 | ||
530 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0); | 535 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0); |
531 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); | 536 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); |
532 | 537 | ||
533 | for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) { | 538 | for (i = 0; i < SE401_NUMSBUF; i++) |
534 | usb_kill_urb(se401->urb[i]); | 539 | if (se401->urb[i]) { |
535 | usb_free_urb(se401->urb[i]); | 540 | usb_kill_urb(se401->urb[i]); |
536 | se401->urb[i]=NULL; | 541 | usb_free_urb(se401->urb[i]); |
537 | kfree(se401->sbuf[i].data); | 542 | se401->urb[i] = NULL; |
538 | } | 543 | kfree(se401->sbuf[i].data); |
539 | for (i=0; i<SE401_NUMSCRATCH; i++) { | 544 | } |
545 | for (i = 0; i < SE401_NUMSCRATCH; i++) { | ||
540 | kfree(se401->scratch[i].data); | 546 | kfree(se401->scratch[i].data); |
541 | se401->scratch[i].data=NULL; | 547 | se401->scratch[i].data = NULL; |
542 | } | 548 | } |
543 | 549 | ||
544 | return 0; | 550 | return 0; |
@@ -546,9 +552,9 @@ static int se401_stop_stream(struct usb_se401 *se401) | |||
546 | 552 | ||
547 | static int se401_set_size(struct usb_se401 *se401, int width, int height) | 553 | static int se401_set_size(struct usb_se401 *se401, int width, int height) |
548 | { | 554 | { |
549 | int wasstreaming=se401->streaming; | 555 | int wasstreaming = se401->streaming; |
550 | /* Check to see if we need to change */ | 556 | /* Check to see if we need to change */ |
551 | if (se401->cwidth==width && se401->cheight==height) | 557 | if (se401->cwidth == width && se401->cheight == height) |
552 | return 0; | 558 | return 0; |
553 | 559 | ||
554 | /* Check for a valid mode */ | 560 | /* Check for a valid mode */ |
@@ -556,16 +562,16 @@ static int se401_set_size(struct usb_se401 *se401, int width, int height) | |||
556 | return 1; | 562 | return 1; |
557 | if ((width & 1) || (height & 1)) | 563 | if ((width & 1) || (height & 1)) |
558 | return 1; | 564 | return 1; |
559 | if (width>se401->width[se401->sizes-1]) | 565 | if (width > se401->width[se401->sizes-1]) |
560 | return 1; | 566 | return 1; |
561 | if (height>se401->height[se401->sizes-1]) | 567 | if (height > se401->height[se401->sizes-1]) |
562 | return 1; | 568 | return 1; |
563 | 569 | ||
564 | /* Stop a current stream and start it again at the new size */ | 570 | /* Stop a current stream and start it again at the new size */ |
565 | if (wasstreaming) | 571 | if (wasstreaming) |
566 | se401_stop_stream(se401); | 572 | se401_stop_stream(se401); |
567 | se401->cwidth=width; | 573 | se401->cwidth = width; |
568 | se401->cheight=height; | 574 | se401->cheight = height; |
569 | if (wasstreaming) | 575 | if (wasstreaming) |
570 | se401_start_stream(se401); | 576 | se401_start_stream(se401); |
571 | return 0; | 577 | return 0; |
@@ -586,68 +592,68 @@ static int se401_set_size(struct usb_se401 *se401, int width, int height) | |||
586 | static inline void enhance_picture(unsigned char *frame, int len) | 592 | static inline void enhance_picture(unsigned char *frame, int len) |
587 | { | 593 | { |
588 | while (len--) { | 594 | while (len--) { |
589 | *frame=(((*frame^255)*(*frame^255))/255)^255; | 595 | *frame = (((*frame^255)*(*frame^255))/255)^255; |
590 | frame++; | 596 | frame++; |
591 | } | 597 | } |
592 | } | 598 | } |
593 | 599 | ||
594 | static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data) | 600 | static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data) |
595 | { | 601 | { |
596 | struct se401_frame *frame=&se401->frame[se401->curframe]; | 602 | struct se401_frame *frame = &se401->frame[se401->curframe]; |
597 | int linelength=se401->cwidth*3; | 603 | int linelength = se401->cwidth * 3; |
598 | 604 | ||
599 | if (frame->curlinepix >= linelength) { | 605 | if (frame->curlinepix >= linelength) { |
600 | frame->curlinepix=0; | 606 | frame->curlinepix = 0; |
601 | frame->curline+=linelength; | 607 | frame->curline += linelength; |
602 | } | 608 | } |
603 | 609 | ||
604 | /* First three are absolute, all others relative. | 610 | /* First three are absolute, all others relative. |
605 | * Format is rgb from right to left (mirrorred image), | 611 | * Format is rgb from right to left (mirrorred image), |
606 | * we flip it to get bgr from left to right. */ | 612 | * we flip it to get bgr from left to right. */ |
607 | if (frame->curlinepix < 3) { | 613 | if (frame->curlinepix < 3) |
608 | *(frame->curline-frame->curlinepix)=1+data*4; | 614 | *(frame->curline-frame->curlinepix) = 1 + data * 4; |
609 | } else { | 615 | else |
610 | *(frame->curline-frame->curlinepix)= | 616 | *(frame->curline-frame->curlinepix) = |
611 | *(frame->curline-frame->curlinepix+3)+data*4; | 617 | *(frame->curline-frame->curlinepix + 3) + data * 4; |
612 | } | ||
613 | frame->curlinepix++; | 618 | frame->curlinepix++; |
614 | } | 619 | } |
615 | 620 | ||
616 | static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength) | 621 | static inline void decode_JangGu_vlc(struct usb_se401 *se401, |
622 | unsigned char *data, int bit_exp, int packetlength) | ||
617 | { | 623 | { |
618 | int pos=0; | 624 | int pos = 0; |
619 | int vlc_cod=0; | 625 | int vlc_cod = 0; |
620 | int vlc_size=0; | 626 | int vlc_size = 0; |
621 | int vlc_data=0; | 627 | int vlc_data = 0; |
622 | int bit_cur; | 628 | int bit_cur; |
623 | int bit; | 629 | int bit; |
624 | data+=4; | 630 | data += 4; |
625 | while (pos < packetlength) { | 631 | while (pos < packetlength) { |
626 | bit_cur=8; | 632 | bit_cur = 8; |
627 | while (bit_cur && bit_exp) { | 633 | while (bit_cur && bit_exp) { |
628 | bit=((*data)>>(bit_cur-1))&1; | 634 | bit = ((*data) >> (bit_cur-1))&1; |
629 | if (!vlc_cod) { | 635 | if (!vlc_cod) { |
630 | if (bit) { | 636 | if (bit) { |
631 | vlc_size++; | 637 | vlc_size++; |
632 | } else { | 638 | } else { |
633 | if (!vlc_size) { | 639 | if (!vlc_size) |
634 | decode_JangGu_integrate(se401, 0); | 640 | decode_JangGu_integrate(se401, 0); |
635 | } else { | 641 | else { |
636 | vlc_cod=2; | 642 | vlc_cod = 2; |
637 | vlc_data=0; | 643 | vlc_data = 0; |
638 | } | 644 | } |
639 | } | 645 | } |
640 | } else { | 646 | } else { |
641 | if (vlc_cod==2) { | 647 | if (vlc_cod == 2) { |
642 | if (!bit) | 648 | if (!bit) |
643 | vlc_data = -(1<<vlc_size) + 1; | 649 | vlc_data = -(1 << vlc_size) + 1; |
644 | vlc_cod--; | 650 | vlc_cod--; |
645 | } | 651 | } |
646 | vlc_size--; | 652 | vlc_size--; |
647 | vlc_data+=bit<<vlc_size; | 653 | vlc_data += bit << vlc_size; |
648 | if (!vlc_size) { | 654 | if (!vlc_size) { |
649 | decode_JangGu_integrate(se401, vlc_data); | 655 | decode_JangGu_integrate(se401, vlc_data); |
650 | vlc_cod=0; | 656 | vlc_cod = 0; |
651 | } | 657 | } |
652 | } | 658 | } |
653 | bit_cur--; | 659 | bit_cur--; |
@@ -658,186 +664,188 @@ static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *da | |||
658 | } | 664 | } |
659 | } | 665 | } |
660 | 666 | ||
661 | static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer) | 667 | static inline void decode_JangGu(struct usb_se401 *se401, |
668 | struct se401_scratch *buffer) | ||
662 | { | 669 | { |
663 | unsigned char *data=buffer->data; | 670 | unsigned char *data = buffer->data; |
664 | int len=buffer->length; | 671 | int len = buffer->length; |
665 | int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size; | 672 | int bit_exp = 0, pix_exp = 0, frameinfo = 0, packetlength = 0, size; |
666 | int datapos=0; | 673 | int datapos = 0; |
667 | 674 | ||
668 | /* New image? */ | 675 | /* New image? */ |
669 | if (!se401->frame[se401->curframe].curpix) { | 676 | if (!se401->frame[se401->curframe].curpix) { |
670 | se401->frame[se401->curframe].curlinepix=0; | 677 | se401->frame[se401->curframe].curlinepix = 0; |
671 | se401->frame[se401->curframe].curline= | 678 | se401->frame[se401->curframe].curline = |
672 | se401->frame[se401->curframe].data+ | 679 | se401->frame[se401->curframe].data+ |
673 | se401->cwidth*3-1; | 680 | se401->cwidth * 3 - 1; |
674 | if (se401->frame[se401->curframe].grabstate==FRAME_READY) | 681 | if (se401->frame[se401->curframe].grabstate == FRAME_READY) |
675 | se401->frame[se401->curframe].grabstate=FRAME_GRABBING; | 682 | se401->frame[se401->curframe].grabstate = FRAME_GRABBING; |
676 | se401->vlcdatapos=0; | 683 | se401->vlcdatapos = 0; |
677 | } | 684 | } |
678 | while (datapos < len) { | 685 | while (datapos < len) { |
679 | size=1024-se401->vlcdatapos; | 686 | size = 1024 - se401->vlcdatapos; |
680 | if (size+datapos > len) | 687 | if (size+datapos > len) |
681 | size=len-datapos; | 688 | size = len-datapos; |
682 | memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size); | 689 | memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size); |
683 | se401->vlcdatapos+=size; | 690 | se401->vlcdatapos += size; |
684 | packetlength=0; | 691 | packetlength = 0; |
685 | if (se401->vlcdatapos >= 4) { | 692 | if (se401->vlcdatapos >= 4) { |
686 | bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8); | 693 | bit_exp = se401->vlcdata[3] + (se401->vlcdata[2] << 8); |
687 | pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8); | 694 | pix_exp = se401->vlcdata[1] + |
688 | frameinfo=se401->vlcdata[0]&0xc0; | 695 | ((se401->vlcdata[0] & 0x3f) << 8); |
689 | packetlength=((bit_exp+47)>>4)<<1; | 696 | frameinfo = se401->vlcdata[0] & 0xc0; |
697 | packetlength = ((bit_exp + 47) >> 4) << 1; | ||
690 | if (packetlength > 1024) { | 698 | if (packetlength > 1024) { |
691 | se401->vlcdatapos=0; | 699 | se401->vlcdatapos = 0; |
692 | datapos=len; | 700 | datapos = len; |
693 | packetlength=0; | 701 | packetlength = 0; |
694 | se401->error++; | 702 | se401->error++; |
695 | se401->frame[se401->curframe].curpix=0; | 703 | se401->frame[se401->curframe].curpix = 0; |
696 | } | 704 | } |
697 | } | 705 | } |
698 | if (packetlength && se401->vlcdatapos >= packetlength) { | 706 | if (packetlength && se401->vlcdatapos >= packetlength) { |
699 | decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength); | 707 | decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, |
700 | se401->frame[se401->curframe].curpix+=pix_exp*3; | 708 | packetlength); |
701 | datapos+=size-(se401->vlcdatapos-packetlength); | 709 | se401->frame[se401->curframe].curpix += pix_exp * 3; |
702 | se401->vlcdatapos=0; | 710 | datapos += size-(se401->vlcdatapos-packetlength); |
703 | if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) { | 711 | se401->vlcdatapos = 0; |
704 | if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) { | 712 | if (se401->frame[se401->curframe].curpix >= se401->cwidth * se401->cheight * 3) { |
705 | if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) { | 713 | if (se401->frame[se401->curframe].curpix == se401->cwidth * se401->cheight * 3) { |
706 | se401->frame[se401->curframe].grabstate=FRAME_DONE; | 714 | if (se401->frame[se401->curframe].grabstate == FRAME_GRABBING) { |
715 | se401->frame[se401->curframe].grabstate = FRAME_DONE; | ||
707 | se401->framecount++; | 716 | se401->framecount++; |
708 | se401->readcount++; | 717 | se401->readcount++; |
709 | } | 718 | } |
710 | if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) { | 719 | if (se401->frame[(se401->curframe + 1) & (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) |
711 | se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1); | 720 | se401->curframe = (se401->curframe + 1) & (SE401_NUMFRAMES - 1); |
712 | } | 721 | } else |
713 | } else { | ||
714 | se401->error++; | 722 | se401->error++; |
715 | } | 723 | se401->frame[se401->curframe].curpix = 0; |
716 | se401->frame[se401->curframe].curpix=0; | 724 | datapos = len; |
717 | datapos=len; | ||
718 | } | 725 | } |
719 | } else { | 726 | } else |
720 | datapos+=size; | 727 | datapos += size; |
721 | } | ||
722 | } | 728 | } |
723 | } | 729 | } |
724 | 730 | ||
725 | static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer) | 731 | static inline void decode_bayer(struct usb_se401 *se401, |
732 | struct se401_scratch *buffer) | ||
726 | { | 733 | { |
727 | unsigned char *data=buffer->data; | 734 | unsigned char *data = buffer->data; |
728 | int len=buffer->length; | 735 | int len = buffer->length; |
729 | int offset=buffer->offset; | 736 | int offset = buffer->offset; |
730 | int datasize=se401->cwidth*se401->cheight; | 737 | int datasize = se401->cwidth * se401->cheight; |
731 | struct se401_frame *frame=&se401->frame[se401->curframe]; | 738 | struct se401_frame *frame = &se401->frame[se401->curframe]; |
739 | unsigned char *framedata = frame->data, *curline, *nextline; | ||
740 | int width = se401->cwidth; | ||
741 | int blineoffset = 0, bline; | ||
742 | int linelength = width * 3, i; | ||
732 | 743 | ||
733 | unsigned char *framedata=frame->data, *curline, *nextline; | ||
734 | int width=se401->cwidth; | ||
735 | int blineoffset=0, bline; | ||
736 | int linelength=width*3, i; | ||
737 | 744 | ||
745 | if (frame->curpix == 0) { | ||
746 | if (frame->grabstate == FRAME_READY) | ||
747 | frame->grabstate = FRAME_GRABBING; | ||
738 | 748 | ||
739 | if (frame->curpix==0) { | 749 | frame->curline = framedata + linelength; |
740 | if (frame->grabstate==FRAME_READY) { | 750 | frame->curlinepix = 0; |
741 | frame->grabstate=FRAME_GRABBING; | ||
742 | } | ||
743 | frame->curline=framedata+linelength; | ||
744 | frame->curlinepix=0; | ||
745 | } | 751 | } |
746 | 752 | ||
747 | if (offset!=frame->curpix) { | 753 | if (offset != frame->curpix) { |
748 | /* Regard frame as lost :( */ | 754 | /* Regard frame as lost :( */ |
749 | frame->curpix=0; | 755 | frame->curpix = 0; |
750 | se401->error++; | 756 | se401->error++; |
751 | return; | 757 | return; |
752 | } | 758 | } |
753 | 759 | ||
754 | /* Check if we have to much data */ | 760 | /* Check if we have to much data */ |
755 | if (frame->curpix+len > datasize) { | 761 | if (frame->curpix + len > datasize) |
756 | len=datasize-frame->curpix; | 762 | len = datasize-frame->curpix; |
757 | } | 763 | |
758 | if (se401->cheight%4) | 764 | if (se401->cheight % 4) |
759 | blineoffset=1; | 765 | blineoffset = 1; |
760 | bline=frame->curpix/se401->cwidth+blineoffset; | 766 | bline = frame->curpix / se401->cwidth+blineoffset; |
761 | 767 | ||
762 | curline=frame->curline; | 768 | curline = frame->curline; |
763 | nextline=curline+linelength; | 769 | nextline = curline + linelength; |
764 | if (nextline >= framedata+datasize*3) | 770 | if (nextline >= framedata+datasize * 3) |
765 | nextline=curline; | 771 | nextline = curline; |
766 | while (len) { | 772 | while (len) { |
767 | if (frame->curlinepix>=width) { | 773 | if (frame->curlinepix >= width) { |
768 | frame->curlinepix-=width; | 774 | frame->curlinepix -= width; |
769 | bline=frame->curpix/width+blineoffset; | 775 | bline = frame->curpix / width + blineoffset; |
770 | curline+=linelength*2; | 776 | curline += linelength*2; |
771 | nextline+=linelength*2; | 777 | nextline += linelength*2; |
772 | if (curline >= framedata+datasize*3) { | 778 | if (curline >= framedata+datasize * 3) { |
773 | frame->curlinepix++; | 779 | frame->curlinepix++; |
774 | curline-=3; | 780 | curline -= 3; |
775 | nextline-=3; | 781 | nextline -= 3; |
776 | len--; | 782 | len--; |
777 | data++; | 783 | data++; |
778 | frame->curpix++; | 784 | frame->curpix++; |
779 | } | 785 | } |
780 | if (nextline >= framedata+datasize*3) | 786 | if (nextline >= framedata+datasize*3) |
781 | nextline=curline; | 787 | nextline = curline; |
782 | } | 788 | } |
783 | if ((bline&1)) { | 789 | if (bline & 1) { |
784 | if ((frame->curlinepix&1)) { | 790 | if (frame->curlinepix & 1) { |
785 | *(curline+2)=*data; | 791 | *(curline + 2) = *data; |
786 | *(curline-1)=*data; | 792 | *(curline - 1) = *data; |
787 | *(nextline+2)=*data; | 793 | *(nextline + 2) = *data; |
788 | *(nextline-1)=*data; | 794 | *(nextline - 1) = *data; |
789 | } else { | 795 | } else { |
790 | *(curline+1)= | 796 | *(curline + 1) = |
791 | (*(curline+1)+*data)/2; | 797 | (*(curline + 1) + *data) / 2; |
792 | *(curline-2)= | 798 | *(curline-2) = |
793 | (*(curline-2)+*data)/2; | 799 | (*(curline - 2) + *data) / 2; |
794 | *(nextline+1)=*data; | 800 | *(nextline + 1) = *data; |
795 | *(nextline-2)=*data; | 801 | *(nextline - 2) = *data; |
796 | } | 802 | } |
797 | } else { | 803 | } else { |
798 | if ((frame->curlinepix&1)) { | 804 | if (frame->curlinepix & 1) { |
799 | *(curline+1)= | 805 | *(curline + 1) = |
800 | (*(curline+1)+*data)/2; | 806 | (*(curline + 1) + *data) / 2; |
801 | *(curline-2)= | 807 | *(curline - 2) = |
802 | (*(curline-2)+*data)/2; | 808 | (*(curline - 2) + *data) / 2; |
803 | *(nextline+1)=*data; | 809 | *(nextline + 1) = *data; |
804 | *(nextline-2)=*data; | 810 | *(nextline - 2) = *data; |
805 | } else { | 811 | } else { |
806 | *curline=*data; | 812 | *curline = *data; |
807 | *(curline-3)=*data; | 813 | *(curline - 3) = *data; |
808 | *nextline=*data; | 814 | *nextline = *data; |
809 | *(nextline-3)=*data; | 815 | *(nextline - 3) = *data; |
810 | } | 816 | } |
811 | } | 817 | } |
812 | frame->curlinepix++; | 818 | frame->curlinepix++; |
813 | curline-=3; | 819 | curline -= 3; |
814 | nextline-=3; | 820 | nextline -= 3; |
815 | len--; | 821 | len--; |
816 | data++; | 822 | data++; |
817 | frame->curpix++; | 823 | frame->curpix++; |
818 | } | 824 | } |
819 | frame->curline=curline; | 825 | frame->curline = curline; |
820 | 826 | ||
821 | if (frame->curpix>=datasize) { | 827 | if (frame->curpix >= datasize) { |
822 | /* Fix the top line */ | 828 | /* Fix the top line */ |
823 | framedata+=linelength; | 829 | framedata += linelength; |
824 | for (i=0; i<linelength; i++) { | 830 | for (i = 0; i < linelength; i++) { |
825 | framedata--; | 831 | framedata--; |
826 | *framedata=*(framedata+linelength); | 832 | *framedata = *(framedata + linelength); |
827 | } | 833 | } |
828 | /* Fix the left side (green is already present) */ | 834 | /* Fix the left side (green is already present) */ |
829 | for (i=0; i<se401->cheight; i++) { | 835 | for (i = 0; i < se401->cheight; i++) { |
830 | *framedata=*(framedata+3); | 836 | *framedata = *(framedata + 3); |
831 | *(framedata+1)=*(framedata+4); | 837 | *(framedata + 1) = *(framedata + 4); |
832 | *(framedata+2)=*(framedata+5); | 838 | *(framedata + 2) = *(framedata + 5); |
833 | framedata+=linelength; | 839 | framedata += linelength; |
834 | } | 840 | } |
835 | frame->curpix=0; | 841 | frame->curpix = 0; |
836 | frame->grabstate=FRAME_DONE; | 842 | frame->grabstate = FRAME_DONE; |
837 | se401->framecount++; | 843 | se401->framecount++; |
838 | se401->readcount++; | 844 | se401->readcount++; |
839 | if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) { | 845 | if (se401->frame[(se401->curframe + 1) & |
840 | se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1); | 846 | (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) { |
847 | se401->curframe = (se401->curframe+1) & | ||
848 | (SE401_NUMFRAMES-1); | ||
841 | } | 849 | } |
842 | } | 850 | } |
843 | } | 851 | } |
@@ -845,72 +853,76 @@ static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch * | |||
845 | static int se401_newframe(struct usb_se401 *se401, int framenr) | 853 | static int se401_newframe(struct usb_se401 *se401, int framenr) |
846 | { | 854 | { |
847 | DECLARE_WAITQUEUE(wait, current); | 855 | DECLARE_WAITQUEUE(wait, current); |
848 | int errors=0; | 856 | int errors = 0; |
849 | 857 | ||
850 | while (se401->streaming && | 858 | while (se401->streaming && |
851 | (se401->frame[framenr].grabstate==FRAME_READY || | 859 | (se401->frame[framenr].grabstate == FRAME_READY || |
852 | se401->frame[framenr].grabstate==FRAME_GRABBING) ) { | 860 | se401->frame[framenr].grabstate == FRAME_GRABBING)) { |
853 | if(!se401->frame[framenr].curpix) { | 861 | if (!se401->frame[framenr].curpix) |
854 | errors++; | 862 | errors++; |
855 | } | 863 | |
856 | wait_interruptible( | 864 | wait_interruptible( |
857 | se401->scratch[se401->scratch_use].state!=BUFFER_READY, | 865 | se401->scratch[se401->scratch_use].state != BUFFER_READY, |
858 | &se401->wq, | 866 | &se401->wq, &wait); |
859 | &wait | ||
860 | ); | ||
861 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) { | 867 | if (se401->nullpackets > SE401_MAX_NULLPACKETS) { |
862 | se401->nullpackets=0; | 868 | se401->nullpackets = 0; |
863 | dev_info(&se401->dev->dev, | 869 | dev_info(&se401->dev->dev, |
864 | "too many null length packets, restarting capture\n"); | 870 | "too many null length packets, restarting capture\n"); |
865 | se401_stop_stream(se401); | 871 | se401_stop_stream(se401); |
866 | se401_start_stream(se401); | 872 | se401_start_stream(se401); |
867 | } else { | 873 | } else { |
868 | if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) { | 874 | if (se401->scratch[se401->scratch_use].state != |
869 | se401->frame[framenr].grabstate=FRAME_ERROR; | 875 | BUFFER_READY) { |
876 | se401->frame[framenr].grabstate = FRAME_ERROR; | ||
870 | return -EIO; | 877 | return -EIO; |
871 | } | 878 | } |
872 | se401->scratch[se401->scratch_use].state=BUFFER_BUSY; | 879 | se401->scratch[se401->scratch_use].state = BUFFER_BUSY; |
873 | if (se401->format==FMT_JANGGU) { | 880 | if (se401->format == FMT_JANGGU) |
874 | decode_JangGu(se401, &se401->scratch[se401->scratch_use]); | 881 | decode_JangGu(se401, |
875 | } else { | 882 | &se401->scratch[se401->scratch_use]); |
876 | decode_bayer(se401, &se401->scratch[se401->scratch_use]); | 883 | else |
877 | } | 884 | decode_bayer(se401, |
878 | se401->scratch[se401->scratch_use].state=BUFFER_UNUSED; | 885 | &se401->scratch[se401->scratch_use]); |
886 | |||
887 | se401->scratch[se401->scratch_use].state = | ||
888 | BUFFER_UNUSED; | ||
879 | se401->scratch_use++; | 889 | se401->scratch_use++; |
880 | if (se401->scratch_use>=SE401_NUMSCRATCH) | 890 | if (se401->scratch_use >= SE401_NUMSCRATCH) |
881 | se401->scratch_use=0; | 891 | se401->scratch_use = 0; |
882 | if (errors > SE401_MAX_ERRORS) { | 892 | if (errors > SE401_MAX_ERRORS) { |
883 | errors=0; | 893 | errors = 0; |
884 | dev_info(&se401->dev->dev, | 894 | dev_info(&se401->dev->dev, |
885 | "too many errors, restarting capture\n"); | 895 | "too many errors, restarting capture\n"); |
886 | se401_stop_stream(se401); | 896 | se401_stop_stream(se401); |
887 | se401_start_stream(se401); | 897 | se401_start_stream(se401); |
888 | } | 898 | } |
889 | } | 899 | } |
890 | } | 900 | } |
891 | 901 | ||
892 | if (se401->frame[framenr].grabstate==FRAME_DONE) | 902 | if (se401->frame[framenr].grabstate == FRAME_DONE) |
893 | if (se401->enhance) | 903 | if (se401->enhance) |
894 | enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3); | 904 | enhance_picture(se401->frame[framenr].data, |
905 | se401->cheight * se401->cwidth * 3); | ||
895 | return 0; | 906 | return 0; |
896 | } | 907 | } |
897 | 908 | ||
898 | static void usb_se401_remove_disconnected (struct usb_se401 *se401) | 909 | static void usb_se401_remove_disconnected(struct usb_se401 *se401) |
899 | { | 910 | { |
900 | int i; | 911 | int i; |
901 | 912 | ||
902 | se401->dev = NULL; | 913 | se401->dev = NULL; |
903 | 914 | ||
904 | for (i=0; i<SE401_NUMSBUF; i++) | 915 | for (i = 0; i < SE401_NUMSBUF; i++) |
905 | if (se401->urb[i]) { | 916 | if (se401->urb[i]) { |
906 | usb_kill_urb(se401->urb[i]); | 917 | usb_kill_urb(se401->urb[i]); |
907 | usb_free_urb(se401->urb[i]); | 918 | usb_free_urb(se401->urb[i]); |
908 | se401->urb[i] = NULL; | 919 | se401->urb[i] = NULL; |
909 | kfree(se401->sbuf[i].data); | 920 | kfree(se401->sbuf[i].data); |
910 | } | 921 | } |
911 | for (i=0; i<SE401_NUMSCRATCH; i++) { | 922 | |
923 | for (i = 0; i < SE401_NUMSCRATCH; i++) | ||
912 | kfree(se401->scratch[i].data); | 924 | kfree(se401->scratch[i].data); |
913 | } | 925 | |
914 | if (se401->inturb) { | 926 | if (se401->inturb) { |
915 | usb_kill_urb(se401->inturb); | 927 | usb_kill_urb(se401->inturb); |
916 | usb_free_urb(se401->inturb); | 928 | usb_free_urb(se401->inturb); |
@@ -965,11 +977,11 @@ static int se401_close(struct file *file) | |||
965 | dev_info(&se401->dev->dev, "device unregistered\n"); | 977 | dev_info(&se401->dev->dev, "device unregistered\n"); |
966 | usb_se401_remove_disconnected(se401); | 978 | usb_se401_remove_disconnected(se401); |
967 | } else { | 979 | } else { |
968 | for (i=0; i<SE401_NUMFRAMES; i++) | 980 | for (i = 0; i < SE401_NUMFRAMES; i++) |
969 | se401->frame[i].grabstate=FRAME_UNUSED; | 981 | se401->frame[i].grabstate = FRAME_UNUSED; |
970 | if (se401->streaming) | 982 | if (se401->streaming) |
971 | se401_stop_stream(se401); | 983 | se401_stop_stream(se401); |
972 | se401->user=0; | 984 | se401->user = 0; |
973 | } | 985 | } |
974 | file->private_data = NULL; | 986 | file->private_data = NULL; |
975 | return 0; | 987 | return 0; |
@@ -1065,7 +1077,7 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1065 | memset(vm, 0, sizeof(*vm)); | 1077 | memset(vm, 0, sizeof(*vm)); |
1066 | vm->size = SE401_NUMFRAMES * se401->maxframesize; | 1078 | vm->size = SE401_NUMFRAMES * se401->maxframesize; |
1067 | vm->frames = SE401_NUMFRAMES; | 1079 | vm->frames = SE401_NUMFRAMES; |
1068 | for (i=0; i<SE401_NUMFRAMES; i++) | 1080 | for (i = 0; i < SE401_NUMFRAMES; i++) |
1069 | vm->offsets[i] = se401->maxframesize * i; | 1081 | vm->offsets[i] = se401->maxframesize * i; |
1070 | return 0; | 1082 | return 0; |
1071 | } | 1083 | } |
@@ -1083,16 +1095,16 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1083 | /* Is this according to the v4l spec??? */ | 1095 | /* Is this according to the v4l spec??? */ |
1084 | if (se401_set_size(se401, vm->width, vm->height)) | 1096 | if (se401_set_size(se401, vm->width, vm->height)) |
1085 | return -EINVAL; | 1097 | return -EINVAL; |
1086 | se401->frame[vm->frame].grabstate=FRAME_READY; | 1098 | se401->frame[vm->frame].grabstate = FRAME_READY; |
1087 | 1099 | ||
1088 | if (!se401->streaming) | 1100 | if (!se401->streaming) |
1089 | se401_start_stream(se401); | 1101 | se401_start_stream(se401); |
1090 | 1102 | ||
1091 | /* Set the picture properties */ | 1103 | /* Set the picture properties */ |
1092 | if (se401->framecount==0) | 1104 | if (se401->framecount == 0) |
1093 | se401_send_pict(se401); | 1105 | se401_send_pict(se401); |
1094 | /* Calibrate the reset level after a few frames. */ | 1106 | /* Calibrate the reset level after a few frames. */ |
1095 | if (se401->framecount%20==1) | 1107 | if (se401->framecount % 20 == 1) |
1096 | se401_auto_resetlevel(se401); | 1108 | se401_auto_resetlevel(se401); |
1097 | 1109 | ||
1098 | return 0; | 1110 | return 0; |
@@ -1100,13 +1112,13 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1100 | case VIDIOCSYNC: | 1112 | case VIDIOCSYNC: |
1101 | { | 1113 | { |
1102 | int *frame = arg; | 1114 | int *frame = arg; |
1103 | int ret=0; | 1115 | int ret = 0; |
1104 | 1116 | ||
1105 | if(*frame <0 || *frame >= SE401_NUMFRAMES) | 1117 | if (*frame < 0 || *frame >= SE401_NUMFRAMES) |
1106 | return -EINVAL; | 1118 | return -EINVAL; |
1107 | 1119 | ||
1108 | ret=se401_newframe(se401, *frame); | 1120 | ret = se401_newframe(se401, *frame); |
1109 | se401->frame[*frame].grabstate=FRAME_UNUSED; | 1121 | se401->frame[*frame].grabstate = FRAME_UNUSED; |
1110 | return ret; | 1122 | return ret; |
1111 | } | 1123 | } |
1112 | case VIDIOCGFBUF: | 1124 | case VIDIOCGFBUF: |
@@ -1147,36 +1159,36 @@ static long se401_ioctl(struct file *file, | |||
1147 | static ssize_t se401_read(struct file *file, char __user *buf, | 1159 | static ssize_t se401_read(struct file *file, char __user *buf, |
1148 | size_t count, loff_t *ppos) | 1160 | size_t count, loff_t *ppos) |
1149 | { | 1161 | { |
1150 | int realcount=count, ret=0; | 1162 | int realcount = count, ret = 0; |
1151 | struct video_device *dev = file->private_data; | 1163 | struct video_device *dev = file->private_data; |
1152 | struct usb_se401 *se401 = (struct usb_se401 *)dev; | 1164 | struct usb_se401 *se401 = (struct usb_se401 *)dev; |
1153 | 1165 | ||
1154 | 1166 | ||
1155 | if (se401->dev == NULL) | 1167 | if (se401->dev == NULL) |
1156 | return -EIO; | 1168 | return -EIO; |
1157 | if (realcount > se401->cwidth*se401->cheight*3) | 1169 | if (realcount > se401->cwidth*se401->cheight*3) |
1158 | realcount=se401->cwidth*se401->cheight*3; | 1170 | realcount = se401->cwidth*se401->cheight*3; |
1159 | 1171 | ||
1160 | /* Shouldn't happen: */ | 1172 | /* Shouldn't happen: */ |
1161 | if (se401->frame[0].grabstate==FRAME_GRABBING) | 1173 | if (se401->frame[0].grabstate == FRAME_GRABBING) |
1162 | return -EBUSY; | 1174 | return -EBUSY; |
1163 | se401->frame[0].grabstate=FRAME_READY; | 1175 | se401->frame[0].grabstate = FRAME_READY; |
1164 | se401->frame[1].grabstate=FRAME_UNUSED; | 1176 | se401->frame[1].grabstate = FRAME_UNUSED; |
1165 | se401->curframe=0; | 1177 | se401->curframe = 0; |
1166 | 1178 | ||
1167 | if (!se401->streaming) | 1179 | if (!se401->streaming) |
1168 | se401_start_stream(se401); | 1180 | se401_start_stream(se401); |
1169 | 1181 | ||
1170 | /* Set the picture properties */ | 1182 | /* Set the picture properties */ |
1171 | if (se401->framecount==0) | 1183 | if (se401->framecount == 0) |
1172 | se401_send_pict(se401); | 1184 | se401_send_pict(se401); |
1173 | /* Calibrate the reset level after a few frames. */ | 1185 | /* Calibrate the reset level after a few frames. */ |
1174 | if (se401->framecount%20==1) | 1186 | if (se401->framecount%20 == 1) |
1175 | se401_auto_resetlevel(se401); | 1187 | se401_auto_resetlevel(se401); |
1176 | 1188 | ||
1177 | ret=se401_newframe(se401, 0); | 1189 | ret = se401_newframe(se401, 0); |
1178 | 1190 | ||
1179 | se401->frame[0].grabstate=FRAME_UNUSED; | 1191 | se401->frame[0].grabstate = FRAME_UNUSED; |
1180 | if (ret) | 1192 | if (ret) |
1181 | return ret; | 1193 | return ret; |
1182 | if (copy_to_user(buf, se401->frame[0].data, realcount)) | 1194 | if (copy_to_user(buf, se401->frame[0].data, realcount)) |
@@ -1195,11 +1207,12 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) | |||
1195 | 1207 | ||
1196 | mutex_lock(&se401->lock); | 1208 | mutex_lock(&se401->lock); |
1197 | 1209 | ||
1198 | if (se401->dev == NULL) { | 1210 | if (se401->dev == NULL) { |
1199 | mutex_unlock(&se401->lock); | 1211 | mutex_unlock(&se401->lock); |
1200 | return -EIO; | 1212 | return -EIO; |
1201 | } | 1213 | } |
1202 | if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) { | 1214 | if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) |
1215 | & ~(PAGE_SIZE - 1))) { | ||
1203 | mutex_unlock(&se401->lock); | 1216 | mutex_unlock(&se401->lock); |
1204 | return -EINVAL; | 1217 | return -EINVAL; |
1205 | } | 1218 | } |
@@ -1210,10 +1223,10 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) | |||
1210 | mutex_unlock(&se401->lock); | 1223 | mutex_unlock(&se401->lock); |
1211 | return -EAGAIN; | 1224 | return -EAGAIN; |
1212 | } | 1225 | } |
1213 | start += PAGE_SIZE; | 1226 | start += PAGE_SIZE; |
1214 | pos += PAGE_SIZE; | 1227 | pos += PAGE_SIZE; |
1215 | if (size > PAGE_SIZE) | 1228 | if (size > PAGE_SIZE) |
1216 | size -= PAGE_SIZE; | 1229 | size -= PAGE_SIZE; |
1217 | else | 1230 | else |
1218 | size = 0; | 1231 | size = 0; |
1219 | } | 1232 | } |
@@ -1223,7 +1236,7 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) | |||
1223 | } | 1236 | } |
1224 | 1237 | ||
1225 | static const struct v4l2_file_operations se401_fops = { | 1238 | static const struct v4l2_file_operations se401_fops = { |
1226 | .owner = THIS_MODULE, | 1239 | .owner = THIS_MODULE, |
1227 | .open = se401_open, | 1240 | .open = se401_open, |
1228 | .release = se401_close, | 1241 | .release = se401_close, |
1229 | .read = se401_read, | 1242 | .read = se401_read, |
@@ -1241,71 +1254,76 @@ static struct video_device se401_template = { | |||
1241 | /***************************/ | 1254 | /***************************/ |
1242 | static int se401_init(struct usb_se401 *se401, int button) | 1255 | static int se401_init(struct usb_se401 *se401, int button) |
1243 | { | 1256 | { |
1244 | int i=0, rc; | 1257 | int i = 0, rc; |
1245 | unsigned char cp[0x40]; | 1258 | unsigned char cp[0x40]; |
1246 | char temp[200]; | 1259 | char temp[200]; |
1260 | int slen; | ||
1247 | 1261 | ||
1248 | /* led on */ | 1262 | /* led on */ |
1249 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); | 1263 | se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); |
1250 | 1264 | ||
1251 | /* get camera descriptor */ | 1265 | /* get camera descriptor */ |
1252 | rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp)); | 1266 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, |
1253 | if (cp[1]!=0x41) { | 1267 | cp, sizeof(cp)); |
1268 | if (cp[1] != 0x41) { | ||
1254 | err("Wrong descriptor type"); | 1269 | err("Wrong descriptor type"); |
1255 | return 1; | 1270 | return 1; |
1256 | } | 1271 | } |
1257 | sprintf (temp, "ExtraFeatures: %d", cp[3]); | 1272 | slen = snprintf(temp, 200, "ExtraFeatures: %d", cp[3]); |
1258 | 1273 | ||
1259 | se401->sizes=cp[4]+cp[5]*256; | 1274 | se401->sizes = cp[4] + cp[5] * 256; |
1260 | se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); | 1275 | se401->width = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); |
1261 | if (!se401->width) | 1276 | if (!se401->width) |
1262 | return 1; | 1277 | return 1; |
1263 | se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); | 1278 | se401->height = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); |
1264 | if (!se401->height) { | 1279 | if (!se401->height) { |
1265 | kfree(se401->width); | 1280 | kfree(se401->width); |
1266 | return 1; | 1281 | return 1; |
1267 | } | 1282 | } |
1268 | for (i=0; i<se401->sizes; i++) { | 1283 | for (i = 0; i < se401->sizes; i++) { |
1269 | se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256; | 1284 | se401->width[i] = cp[6 + i * 4 + 0] + cp[6 + i*4 + 1] * 256; |
1270 | se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256; | 1285 | se401->height[i] = cp[6 + i * 4 + 2] + cp[6 + i * 4 + 3] * 256; |
1271 | } | 1286 | } |
1272 | sprintf (temp, "%s Sizes:", temp); | 1287 | slen += snprintf(temp + slen, 200 - slen, " Sizes:"); |
1273 | for (i=0; i<se401->sizes; i++) { | 1288 | for (i = 0; i < se401->sizes; i++) { |
1274 | sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]); | 1289 | slen += snprintf(temp + slen, 200 - slen, |
1290 | " %dx%d", se401->width[i], se401->height[i]); | ||
1275 | } | 1291 | } |
1276 | dev_info(&se401->dev->dev, "%s\n", temp); | 1292 | dev_info(&se401->dev->dev, "%s\n", temp); |
1277 | se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3; | 1293 | se401->maxframesize = se401->width[se401->sizes-1] * |
1294 | se401->height[se401->sizes - 1] * 3; | ||
1278 | 1295 | ||
1279 | rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp)); | 1296 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp)); |
1280 | se401->cwidth=cp[0]+cp[1]*256; | 1297 | se401->cwidth = cp[0]+cp[1]*256; |
1281 | rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp)); | 1298 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp)); |
1282 | se401->cheight=cp[0]+cp[1]*256; | 1299 | se401->cheight = cp[0]+cp[1]*256; |
1283 | 1300 | ||
1284 | if (!(cp[2] & SE401_FORMAT_BAYER)) { | 1301 | if (!(cp[2] & SE401_FORMAT_BAYER)) { |
1285 | err("Bayer format not supported!"); | 1302 | err("Bayer format not supported!"); |
1286 | return 1; | 1303 | return 1; |
1287 | } | 1304 | } |
1288 | /* set output mode (BAYER) */ | 1305 | /* set output mode (BAYER) */ |
1289 | se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0); | 1306 | se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, |
1307 | SE401_FORMAT_BAYER, NULL, 0); | ||
1290 | 1308 | ||
1291 | rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp)); | 1309 | rc = se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp)); |
1292 | se401->brightness=cp[0]+cp[1]*256; | 1310 | se401->brightness = cp[0]+cp[1]*256; |
1293 | /* some default values */ | 1311 | /* some default values */ |
1294 | se401->resetlevel=0x2d; | 1312 | se401->resetlevel = 0x2d; |
1295 | se401->rgain=0x20; | 1313 | se401->rgain = 0x20; |
1296 | se401->ggain=0x20; | 1314 | se401->ggain = 0x20; |
1297 | se401->bgain=0x20; | 1315 | se401->bgain = 0x20; |
1298 | se401_set_exposure(se401, 20000); | 1316 | se401_set_exposure(se401, 20000); |
1299 | se401->palette=VIDEO_PALETTE_RGB24; | 1317 | se401->palette = VIDEO_PALETTE_RGB24; |
1300 | se401->enhance=1; | 1318 | se401->enhance = 1; |
1301 | se401->dropped=0; | 1319 | se401->dropped = 0; |
1302 | se401->error=0; | 1320 | se401->error = 0; |
1303 | se401->framecount=0; | 1321 | se401->framecount = 0; |
1304 | se401->readcount=0; | 1322 | se401->readcount = 0; |
1305 | 1323 | ||
1306 | /* Start interrupt transfers for snapshot button */ | 1324 | /* Start interrupt transfers for snapshot button */ |
1307 | if (button) { | 1325 | if (button) { |
1308 | se401->inturb=usb_alloc_urb(0, GFP_KERNEL); | 1326 | se401->inturb = usb_alloc_urb(0, GFP_KERNEL); |
1309 | if (!se401->inturb) { | 1327 | if (!se401->inturb) { |
1310 | dev_info(&se401->dev->dev, | 1328 | dev_info(&se401->dev->dev, |
1311 | "Allocation of inturb failed\n"); | 1329 | "Allocation of inturb failed\n"); |
@@ -1323,7 +1341,7 @@ static int se401_init(struct usb_se401 *se401, int button) | |||
1323 | return 1; | 1341 | return 1; |
1324 | } | 1342 | } |
1325 | } else | 1343 | } else |
1326 | se401->inturb=NULL; | 1344 | se401->inturb = NULL; |
1327 | 1345 | ||
1328 | /* Flash the led */ | 1346 | /* Flash the led */ |
1329 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); | 1347 | se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); |
@@ -1340,8 +1358,8 @@ static int se401_probe(struct usb_interface *intf, | |||
1340 | struct usb_device *dev = interface_to_usbdev(intf); | 1358 | struct usb_device *dev = interface_to_usbdev(intf); |
1341 | struct usb_interface_descriptor *interface; | 1359 | struct usb_interface_descriptor *interface; |
1342 | struct usb_se401 *se401; | 1360 | struct usb_se401 *se401; |
1343 | char *camera_name=NULL; | 1361 | char *camera_name = NULL; |
1344 | int button=1; | 1362 | int button = 1; |
1345 | 1363 | ||
1346 | /* We don't handle multi-config cameras */ | 1364 | /* We don't handle multi-config cameras */ |
1347 | if (dev->descriptor.bNumConfigurations != 1) | 1365 | if (dev->descriptor.bNumConfigurations != 1) |
@@ -1350,22 +1368,22 @@ static int se401_probe(struct usb_interface *intf, | |||
1350 | interface = &intf->cur_altsetting->desc; | 1368 | interface = &intf->cur_altsetting->desc; |
1351 | 1369 | ||
1352 | /* Is it an se401? */ | 1370 | /* Is it an se401? */ |
1353 | if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 && | 1371 | if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 && |
1354 | le16_to_cpu(dev->descriptor.idProduct) == 0x0004) { | 1372 | le16_to_cpu(dev->descriptor.idProduct) == 0x0004) { |
1355 | camera_name="Endpoints/Aox SE401"; | 1373 | camera_name = "Endpoints/Aox SE401"; |
1356 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 && | 1374 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 && |
1357 | le16_to_cpu(dev->descriptor.idProduct) == 0x030b) { | 1375 | le16_to_cpu(dev->descriptor.idProduct) == 0x030b) { |
1358 | camera_name="Philips PCVC665K"; | 1376 | camera_name = "Philips PCVC665K"; |
1359 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | 1377 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && |
1360 | le16_to_cpu(dev->descriptor.idProduct) == 0x5001) { | 1378 | le16_to_cpu(dev->descriptor.idProduct) == 0x5001) { |
1361 | camera_name="Kensington VideoCAM 67014"; | 1379 | camera_name = "Kensington VideoCAM 67014"; |
1362 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | 1380 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && |
1363 | le16_to_cpu(dev->descriptor.idProduct) == 0x5002) { | 1381 | le16_to_cpu(dev->descriptor.idProduct) == 0x5002) { |
1364 | camera_name="Kensington VideoCAM 6701(5/7)"; | 1382 | camera_name = "Kensington VideoCAM 6701(5/7)"; |
1365 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && | 1383 | } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && |
1366 | le16_to_cpu(dev->descriptor.idProduct) == 0x5003) { | 1384 | le16_to_cpu(dev->descriptor.idProduct) == 0x5003) { |
1367 | camera_name="Kensington VideoCAM 67016"; | 1385 | camera_name = "Kensington VideoCAM 67016"; |
1368 | button=0; | 1386 | button = 0; |
1369 | } else | 1387 | } else |
1370 | return -ENODEV; | 1388 | return -ENODEV; |
1371 | 1389 | ||
@@ -1378,7 +1396,8 @@ static int se401_probe(struct usb_interface *intf, | |||
1378 | /* We found one */ | 1396 | /* We found one */ |
1379 | dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name); | 1397 | dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name); |
1380 | 1398 | ||
1381 | if ((se401 = kzalloc(sizeof(*se401), GFP_KERNEL)) == NULL) { | 1399 | se401 = kzalloc(sizeof(*se401), GFP_KERNEL); |
1400 | if (se401 == NULL) { | ||
1382 | err("couldn't kmalloc se401 struct"); | 1401 | err("couldn't kmalloc se401 struct"); |
1383 | return -ENOMEM; | 1402 | return -ENOMEM; |
1384 | } | 1403 | } |
@@ -1396,12 +1415,14 @@ static int se401_probe(struct usb_interface *intf, | |||
1396 | } | 1415 | } |
1397 | 1416 | ||
1398 | memcpy(&se401->vdev, &se401_template, sizeof(se401_template)); | 1417 | memcpy(&se401->vdev, &se401_template, sizeof(se401_template)); |
1399 | memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name)); | 1418 | memcpy(se401->vdev.name, se401->camera_name, |
1419 | strlen(se401->camera_name)); | ||
1400 | init_waitqueue_head(&se401->wq); | 1420 | init_waitqueue_head(&se401->wq); |
1401 | mutex_init(&se401->lock); | 1421 | mutex_init(&se401->lock); |
1402 | wmb(); | 1422 | wmb(); |
1403 | 1423 | ||
1404 | if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { | 1424 | if (video_register_device(&se401->vdev, |
1425 | VFL_TYPE_GRABBER, video_nr) < 0) { | ||
1405 | kfree(se401); | 1426 | kfree(se401); |
1406 | err("video_register_device failed"); | 1427 | err("video_register_device failed"); |
1407 | return -EIO; | 1428 | return -EIO; |
@@ -1409,20 +1430,20 @@ static int se401_probe(struct usb_interface *intf, | |||
1409 | dev_info(&intf->dev, "registered new video device: video%d\n", | 1430 | dev_info(&intf->dev, "registered new video device: video%d\n", |
1410 | se401->vdev.num); | 1431 | se401->vdev.num); |
1411 | 1432 | ||
1412 | usb_set_intfdata (intf, se401); | 1433 | usb_set_intfdata(intf, se401); |
1413 | return 0; | 1434 | return 0; |
1414 | } | 1435 | } |
1415 | 1436 | ||
1416 | static void se401_disconnect(struct usb_interface *intf) | 1437 | static void se401_disconnect(struct usb_interface *intf) |
1417 | { | 1438 | { |
1418 | struct usb_se401 *se401 = usb_get_intfdata (intf); | 1439 | struct usb_se401 *se401 = usb_get_intfdata(intf); |
1419 | 1440 | ||
1420 | usb_set_intfdata (intf, NULL); | 1441 | usb_set_intfdata(intf, NULL); |
1421 | if (se401) { | 1442 | if (se401) { |
1422 | video_unregister_device(&se401->vdev); | 1443 | video_unregister_device(&se401->vdev); |
1423 | if (!se401->user){ | 1444 | if (!se401->user) |
1424 | usb_se401_remove_disconnected(se401); | 1445 | usb_se401_remove_disconnected(se401); |
1425 | } else { | 1446 | else { |
1426 | se401->frame[0].grabstate = FRAME_ERROR; | 1447 | se401->frame[0].grabstate = FRAME_ERROR; |
1427 | se401->frame[0].grabstate = FRAME_ERROR; | 1448 | se401->frame[0].grabstate = FRAME_ERROR; |
1428 | 1449 | ||
@@ -1435,10 +1456,10 @@ static void se401_disconnect(struct usb_interface *intf) | |||
1435 | } | 1456 | } |
1436 | 1457 | ||
1437 | static struct usb_driver se401_driver = { | 1458 | static struct usb_driver se401_driver = { |
1438 | .name = "se401", | 1459 | .name = "se401", |
1439 | .id_table = device_table, | 1460 | .id_table = device_table, |
1440 | .probe = se401_probe, | 1461 | .probe = se401_probe, |
1441 | .disconnect = se401_disconnect, | 1462 | .disconnect = se401_disconnect, |
1442 | }; | 1463 | }; |
1443 | 1464 | ||
1444 | 1465 | ||
@@ -1451,9 +1472,10 @@ static struct usb_driver se401_driver = { | |||
1451 | 1472 | ||
1452 | static int __init usb_se401_init(void) | 1473 | static int __init usb_se401_init(void) |
1453 | { | 1474 | { |
1454 | printk(KERN_INFO "SE401 usb camera driver version %s registering\n", version); | 1475 | printk(KERN_INFO "SE401 usb camera driver version %s registering\n", |
1476 | version); | ||
1455 | if (flickerless) | 1477 | if (flickerless) |
1456 | if (flickerless!=50 && flickerless!=60) { | 1478 | if (flickerless != 50 && flickerless != 60) { |
1457 | printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n"); | 1479 | printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n"); |
1458 | return -1; | 1480 | return -1; |
1459 | } | 1481 | } |
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h index 2ce685db5d8b..bf7d2e9765b0 100644 --- a/drivers/media/video/se401.h +++ b/drivers/media/video/se401.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #ifndef __LINUX_se401_H | 2 | #ifndef __LINUX_se401_H |
3 | #define __LINUX_se401_H | 3 | #define __LINUX_se401_H |
4 | 4 | ||
5 | #include <asm/uaccess.h> | 5 | #include <linux/uaccess.h> |
6 | #include <linux/videodev.h> | 6 | #include <linux/videodev.h> |
7 | #include <media/v4l2-common.h> | 7 | #include <media/v4l2-common.h> |
8 | #include <media/v4l2-ioctl.h> | 8 | #include <media/v4l2-ioctl.h> |
@@ -12,9 +12,10 @@ | |||
12 | 12 | ||
13 | #ifdef se401_DEBUG | 13 | #ifdef se401_DEBUG |
14 | # define PDEBUG(level, fmt, args...) \ | 14 | # define PDEBUG(level, fmt, args...) \ |
15 | if (debug >= level) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args) | 15 | if (debug >= level) \ |
16 | info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args) | ||
16 | #else | 17 | #else |
17 | # define PDEBUG(level, fmt, args...) do {} while(0) | 18 | # define PDEBUG(level, fmt, args...) do {} while (0) |
18 | #endif | 19 | #endif |
19 | 20 | ||
20 | /* An almost drop-in replacement for sleep_on_interruptible */ | 21 | /* An almost drop-in replacement for sleep_on_interruptible */ |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index b5e37a530c62..d369e8409ab8 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -81,7 +81,6 @@ struct sh_mobile_ceu_buffer { | |||
81 | }; | 81 | }; |
82 | 82 | ||
83 | struct sh_mobile_ceu_dev { | 83 | struct sh_mobile_ceu_dev { |
84 | struct device *dev; | ||
85 | struct soc_camera_host ici; | 84 | struct soc_camera_host ici; |
86 | struct soc_camera_device *icd; | 85 | struct soc_camera_device *icd; |
87 | 86 | ||
@@ -617,7 +616,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, | |||
617 | xlate->cam_fmt = icd->formats + idx; | 616 | xlate->cam_fmt = icd->formats + idx; |
618 | xlate->buswidth = icd->formats[idx].depth; | 617 | xlate->buswidth = icd->formats[idx].depth; |
619 | xlate++; | 618 | xlate++; |
620 | dev_dbg(&ici->dev, "Providing format %s using %s\n", | 619 | dev_dbg(ici->dev, "Providing format %s using %s\n", |
621 | sh_mobile_ceu_formats[k].name, | 620 | sh_mobile_ceu_formats[k].name, |
622 | icd->formats[idx].name); | 621 | icd->formats[idx].name); |
623 | } | 622 | } |
@@ -630,7 +629,7 @@ add_single_format: | |||
630 | xlate->cam_fmt = icd->formats + idx; | 629 | xlate->cam_fmt = icd->formats + idx; |
631 | xlate->buswidth = icd->formats[idx].depth; | 630 | xlate->buswidth = icd->formats[idx].depth; |
632 | xlate++; | 631 | xlate++; |
633 | dev_dbg(&ici->dev, | 632 | dev_dbg(ici->dev, |
634 | "Providing format %s in pass-through mode\n", | 633 | "Providing format %s in pass-through mode\n", |
635 | icd->formats[idx].name); | 634 | icd->formats[idx].name); |
636 | } | 635 | } |
@@ -657,7 +656,7 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, | |||
657 | 656 | ||
658 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 657 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
659 | if (!xlate) { | 658 | if (!xlate) { |
660 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 659 | dev_warn(ici->dev, "Format %x not found\n", pixfmt); |
661 | return -EINVAL; | 660 | return -EINVAL; |
662 | } | 661 | } |
663 | 662 | ||
@@ -684,7 +683,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, | |||
684 | 683 | ||
685 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 684 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
686 | if (!xlate) { | 685 | if (!xlate) { |
687 | dev_warn(&ici->dev, "Format %x not found\n", pixfmt); | 686 | dev_warn(ici->dev, "Format %x not found\n", pixfmt); |
688 | return -EINVAL; | 687 | return -EINVAL; |
689 | } | 688 | } |
690 | 689 | ||
@@ -782,7 +781,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q, | |||
782 | 781 | ||
783 | videobuf_queue_dma_contig_init(q, | 782 | videobuf_queue_dma_contig_init(q, |
784 | &sh_mobile_ceu_videobuf_ops, | 783 | &sh_mobile_ceu_videobuf_ops, |
785 | &ici->dev, &pcdev->lock, | 784 | ici->dev, &pcdev->lock, |
786 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 785 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
787 | pcdev->is_interlaced ? | 786 | pcdev->is_interlaced ? |
788 | V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE, | 787 | V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE, |
@@ -829,7 +828,6 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
829 | goto exit; | 828 | goto exit; |
830 | } | 829 | } |
831 | 830 | ||
832 | platform_set_drvdata(pdev, pcdev); | ||
833 | INIT_LIST_HEAD(&pcdev->capture); | 831 | INIT_LIST_HEAD(&pcdev->capture); |
834 | spin_lock_init(&pcdev->lock); | 832 | spin_lock_init(&pcdev->lock); |
835 | 833 | ||
@@ -840,7 +838,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
840 | goto exit_kfree; | 838 | goto exit_kfree; |
841 | } | 839 | } |
842 | 840 | ||
843 | base = ioremap_nocache(res->start, res->end - res->start + 1); | 841 | base = ioremap_nocache(res->start, resource_size(res)); |
844 | if (!base) { | 842 | if (!base) { |
845 | err = -ENXIO; | 843 | err = -ENXIO; |
846 | dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n"); | 844 | dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n"); |
@@ -850,13 +848,12 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
850 | pcdev->irq = irq; | 848 | pcdev->irq = irq; |
851 | pcdev->base = base; | 849 | pcdev->base = base; |
852 | pcdev->video_limit = 0; /* only enabled if second resource exists */ | 850 | pcdev->video_limit = 0; /* only enabled if second resource exists */ |
853 | pcdev->dev = &pdev->dev; | ||
854 | 851 | ||
855 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 852 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
856 | if (res) { | 853 | if (res) { |
857 | err = dma_declare_coherent_memory(&pdev->dev, res->start, | 854 | err = dma_declare_coherent_memory(&pdev->dev, res->start, |
858 | res->start, | 855 | res->start, |
859 | (res->end - res->start) + 1, | 856 | resource_size(res), |
860 | DMA_MEMORY_MAP | | 857 | DMA_MEMORY_MAP | |
861 | DMA_MEMORY_EXCLUSIVE); | 858 | DMA_MEMORY_EXCLUSIVE); |
862 | if (!err) { | 859 | if (!err) { |
@@ -865,7 +862,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
865 | goto exit_iounmap; | 862 | goto exit_iounmap; |
866 | } | 863 | } |
867 | 864 | ||
868 | pcdev->video_limit = (res->end - res->start) + 1; | 865 | pcdev->video_limit = resource_size(res); |
869 | } | 866 | } |
870 | 867 | ||
871 | /* request irq */ | 868 | /* request irq */ |
@@ -885,7 +882,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
885 | } | 882 | } |
886 | 883 | ||
887 | pcdev->ici.priv = pcdev; | 884 | pcdev->ici.priv = pcdev; |
888 | pcdev->ici.dev.parent = &pdev->dev; | 885 | pcdev->ici.dev = &pdev->dev; |
889 | pcdev->ici.nr = pdev->id; | 886 | pcdev->ici.nr = pdev->id; |
890 | pcdev->ici.drv_name = dev_name(&pdev->dev); | 887 | pcdev->ici.drv_name = dev_name(&pdev->dev); |
891 | pcdev->ici.ops = &sh_mobile_ceu_host_ops; | 888 | pcdev->ici.ops = &sh_mobile_ceu_host_ops; |
@@ -913,9 +910,11 @@ exit: | |||
913 | 910 | ||
914 | static int sh_mobile_ceu_remove(struct platform_device *pdev) | 911 | static int sh_mobile_ceu_remove(struct platform_device *pdev) |
915 | { | 912 | { |
916 | struct sh_mobile_ceu_dev *pcdev = platform_get_drvdata(pdev); | 913 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); |
914 | struct sh_mobile_ceu_dev *pcdev = container_of(soc_host, | ||
915 | struct sh_mobile_ceu_dev, ici); | ||
917 | 916 | ||
918 | soc_camera_host_unregister(&pcdev->ici); | 917 | soc_camera_host_unregister(soc_host); |
919 | clk_put(pcdev->clk); | 918 | clk_put(pcdev->clk); |
920 | free_irq(pcdev->irq, pcdev); | 919 | free_irq(pcdev->irq, pcdev); |
921 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) | 920 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 0e890cc23377..16f595d4337a 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -16,19 +16,21 @@ | |||
16 | * published by the Free Software Foundation. | 16 | * published by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/device.h> | 19 | #include <linux/device.h> |
22 | #include <linux/list.h> | ||
23 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/i2c.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/module.h> | ||
24 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/platform_device.h> | ||
25 | #include <linux/vmalloc.h> | 27 | #include <linux/vmalloc.h> |
26 | 28 | ||
29 | #include <media/soc_camera.h> | ||
27 | #include <media/v4l2-common.h> | 30 | #include <media/v4l2-common.h> |
28 | #include <media/v4l2-ioctl.h> | ||
29 | #include <media/v4l2-dev.h> | 31 | #include <media/v4l2-dev.h> |
32 | #include <media/v4l2-ioctl.h> | ||
30 | #include <media/videobuf-core.h> | 33 | #include <media/videobuf-core.h> |
31 | #include <media/soc_camera.h> | ||
32 | 34 | ||
33 | /* Default to VGA resolution */ | 35 | /* Default to VGA resolution */ |
34 | #define DEFAULT_WIDTH 640 | 36 | #define DEFAULT_WIDTH 640 |
@@ -279,7 +281,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf, | |||
279 | return ret; | 281 | return ret; |
280 | } else if (!icd->current_fmt || | 282 | } else if (!icd->current_fmt || |
281 | icd->current_fmt->fourcc != pix->pixelformat) { | 283 | icd->current_fmt->fourcc != pix->pixelformat) { |
282 | dev_err(&ici->dev, | 284 | dev_err(ici->dev, |
283 | "Host driver hasn't set up current format correctly!\n"); | 285 | "Host driver hasn't set up current format correctly!\n"); |
284 | return -EINVAL; | 286 | return -EINVAL; |
285 | } | 287 | } |
@@ -794,7 +796,7 @@ static void scan_add_host(struct soc_camera_host *ici) | |||
794 | 796 | ||
795 | list_for_each_entry(icd, &devices, list) { | 797 | list_for_each_entry(icd, &devices, list) { |
796 | if (icd->iface == ici->nr) { | 798 | if (icd->iface == ici->nr) { |
797 | icd->dev.parent = &ici->dev; | 799 | icd->dev.parent = ici->dev; |
798 | device_register_link(icd); | 800 | device_register_link(icd); |
799 | } | 801 | } |
800 | } | 802 | } |
@@ -818,7 +820,7 @@ static int scan_add_device(struct soc_camera_device *icd) | |||
818 | list_for_each_entry(ici, &hosts, list) { | 820 | list_for_each_entry(ici, &hosts, list) { |
819 | if (icd->iface == ici->nr) { | 821 | if (icd->iface == ici->nr) { |
820 | ret = 1; | 822 | ret = 1; |
821 | icd->dev.parent = &ici->dev; | 823 | icd->dev.parent = ici->dev; |
822 | break; | 824 | break; |
823 | } | 825 | } |
824 | } | 826 | } |
@@ -952,7 +954,6 @@ static void dummy_release(struct device *dev) | |||
952 | 954 | ||
953 | int soc_camera_host_register(struct soc_camera_host *ici) | 955 | int soc_camera_host_register(struct soc_camera_host *ici) |
954 | { | 956 | { |
955 | int ret; | ||
956 | struct soc_camera_host *ix; | 957 | struct soc_camera_host *ix; |
957 | 958 | ||
958 | if (!ici || !ici->ops || | 959 | if (!ici || !ici->ops || |
@@ -965,12 +966,10 @@ int soc_camera_host_register(struct soc_camera_host *ici) | |||
965 | !ici->ops->reqbufs || | 966 | !ici->ops->reqbufs || |
966 | !ici->ops->add || | 967 | !ici->ops->add || |
967 | !ici->ops->remove || | 968 | !ici->ops->remove || |
968 | !ici->ops->poll) | 969 | !ici->ops->poll || |
970 | !ici->dev) | ||
969 | return -EINVAL; | 971 | return -EINVAL; |
970 | 972 | ||
971 | /* Number might be equal to the platform device ID */ | ||
972 | dev_set_name(&ici->dev, "camera_host%d", ici->nr); | ||
973 | |||
974 | mutex_lock(&list_lock); | 973 | mutex_lock(&list_lock); |
975 | list_for_each_entry(ix, &hosts, list) { | 974 | list_for_each_entry(ix, &hosts, list) { |
976 | if (ix->nr == ici->nr) { | 975 | if (ix->nr == ici->nr) { |
@@ -979,26 +978,14 @@ int soc_camera_host_register(struct soc_camera_host *ici) | |||
979 | } | 978 | } |
980 | } | 979 | } |
981 | 980 | ||
981 | dev_set_drvdata(ici->dev, ici); | ||
982 | |||
982 | list_add_tail(&ici->list, &hosts); | 983 | list_add_tail(&ici->list, &hosts); |
983 | mutex_unlock(&list_lock); | 984 | mutex_unlock(&list_lock); |
984 | 985 | ||
985 | ici->dev.release = dummy_release; | ||
986 | |||
987 | ret = device_register(&ici->dev); | ||
988 | |||
989 | if (ret) | ||
990 | goto edevr; | ||
991 | |||
992 | scan_add_host(ici); | 986 | scan_add_host(ici); |
993 | 987 | ||
994 | return 0; | 988 | return 0; |
995 | |||
996 | edevr: | ||
997 | mutex_lock(&list_lock); | ||
998 | list_del(&ici->list); | ||
999 | mutex_unlock(&list_lock); | ||
1000 | |||
1001 | return ret; | ||
1002 | } | 989 | } |
1003 | EXPORT_SYMBOL(soc_camera_host_register); | 990 | EXPORT_SYMBOL(soc_camera_host_register); |
1004 | 991 | ||
@@ -1012,7 +999,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) | |||
1012 | list_del(&ici->list); | 999 | list_del(&ici->list); |
1013 | 1000 | ||
1014 | list_for_each_entry(icd, &devices, list) { | 1001 | list_for_each_entry(icd, &devices, list) { |
1015 | if (icd->dev.parent == &ici->dev) { | 1002 | if (icd->dev.parent == ici->dev) { |
1016 | device_unregister(&icd->dev); | 1003 | device_unregister(&icd->dev); |
1017 | /* Not before device_unregister(), .remove | 1004 | /* Not before device_unregister(), .remove |
1018 | * needs parent to call ici->ops->remove() */ | 1005 | * needs parent to call ici->ops->remove() */ |
@@ -1023,7 +1010,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) | |||
1023 | 1010 | ||
1024 | mutex_unlock(&list_lock); | 1011 | mutex_unlock(&list_lock); |
1025 | 1012 | ||
1026 | device_unregister(&ici->dev); | 1013 | dev_set_drvdata(ici->dev, NULL); |
1027 | } | 1014 | } |
1028 | EXPORT_SYMBOL(soc_camera_host_unregister); | 1015 | EXPORT_SYMBOL(soc_camera_host_unregister); |
1029 | 1016 | ||
@@ -1130,7 +1117,7 @@ int soc_camera_video_start(struct soc_camera_device *icd) | |||
1130 | vdev = video_device_alloc(); | 1117 | vdev = video_device_alloc(); |
1131 | if (!vdev) | 1118 | if (!vdev) |
1132 | goto evidallocd; | 1119 | goto evidallocd; |
1133 | dev_dbg(&ici->dev, "Allocated video_device %p\n", vdev); | 1120 | dev_dbg(ici->dev, "Allocated video_device %p\n", vdev); |
1134 | 1121 | ||
1135 | strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); | 1122 | strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); |
1136 | 1123 | ||
@@ -1174,6 +1161,57 @@ void soc_camera_video_stop(struct soc_camera_device *icd) | |||
1174 | } | 1161 | } |
1175 | EXPORT_SYMBOL(soc_camera_video_stop); | 1162 | EXPORT_SYMBOL(soc_camera_video_stop); |
1176 | 1163 | ||
1164 | static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) | ||
1165 | { | ||
1166 | struct soc_camera_link *icl = pdev->dev.platform_data; | ||
1167 | struct i2c_adapter *adap; | ||
1168 | struct i2c_client *client; | ||
1169 | |||
1170 | if (!icl) | ||
1171 | return -EINVAL; | ||
1172 | |||
1173 | adap = i2c_get_adapter(icl->i2c_adapter_id); | ||
1174 | if (!adap) { | ||
1175 | dev_warn(&pdev->dev, "Cannot get adapter #%d. No driver?\n", | ||
1176 | icl->i2c_adapter_id); | ||
1177 | /* -ENODEV and -ENXIO do not produce an error on probe()... */ | ||
1178 | return -ENOENT; | ||
1179 | } | ||
1180 | |||
1181 | icl->board_info->platform_data = icl; | ||
1182 | client = i2c_new_device(adap, icl->board_info); | ||
1183 | if (!client) { | ||
1184 | i2c_put_adapter(adap); | ||
1185 | return -ENOMEM; | ||
1186 | } | ||
1187 | |||
1188 | platform_set_drvdata(pdev, client); | ||
1189 | |||
1190 | return 0; | ||
1191 | } | ||
1192 | |||
1193 | static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) | ||
1194 | { | ||
1195 | struct i2c_client *client = platform_get_drvdata(pdev); | ||
1196 | |||
1197 | if (!client) | ||
1198 | return -ENODEV; | ||
1199 | |||
1200 | i2c_unregister_device(client); | ||
1201 | i2c_put_adapter(client->adapter); | ||
1202 | |||
1203 | return 0; | ||
1204 | } | ||
1205 | |||
1206 | static struct platform_driver __refdata soc_camera_pdrv = { | ||
1207 | .probe = soc_camera_pdrv_probe, | ||
1208 | .remove = __devexit_p(soc_camera_pdrv_remove), | ||
1209 | .driver = { | ||
1210 | .name = "soc-camera-pdrv", | ||
1211 | .owner = THIS_MODULE, | ||
1212 | }, | ||
1213 | }; | ||
1214 | |||
1177 | static int __init soc_camera_init(void) | 1215 | static int __init soc_camera_init(void) |
1178 | { | 1216 | { |
1179 | int ret = bus_register(&soc_camera_bus_type); | 1217 | int ret = bus_register(&soc_camera_bus_type); |
@@ -1183,8 +1221,14 @@ static int __init soc_camera_init(void) | |||
1183 | if (ret) | 1221 | if (ret) |
1184 | goto edrvr; | 1222 | goto edrvr; |
1185 | 1223 | ||
1224 | ret = platform_driver_register(&soc_camera_pdrv); | ||
1225 | if (ret) | ||
1226 | goto epdr; | ||
1227 | |||
1186 | return 0; | 1228 | return 0; |
1187 | 1229 | ||
1230 | epdr: | ||
1231 | driver_unregister(&ic_drv); | ||
1188 | edrvr: | 1232 | edrvr: |
1189 | bus_unregister(&soc_camera_bus_type); | 1233 | bus_unregister(&soc_camera_bus_type); |
1190 | return ret; | 1234 | return ret; |
@@ -1192,6 +1236,7 @@ edrvr: | |||
1192 | 1236 | ||
1193 | static void __exit soc_camera_exit(void) | 1237 | static void __exit soc_camera_exit(void) |
1194 | { | 1238 | { |
1239 | platform_driver_unregister(&soc_camera_pdrv); | ||
1195 | driver_unregister(&ic_drv); | 1240 | driver_unregister(&ic_drv); |
1196 | bus_unregister(&soc_camera_bus_type); | 1241 | bus_unregister(&soc_camera_bus_type); |
1197 | } | 1242 | } |
@@ -1202,3 +1247,4 @@ module_exit(soc_camera_exit); | |||
1202 | MODULE_DESCRIPTION("Image capture bus driver"); | 1247 | MODULE_DESCRIPTION("Image capture bus driver"); |
1203 | MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); | 1248 | MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); |
1204 | MODULE_LICENSE("GPL"); | 1249 | MODULE_LICENSE("GPL"); |
1250 | MODULE_ALIAS("platform:soc-camera-pdrv"); | ||
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 1a6d39cbd6f3..2e5937047278 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c | |||
@@ -1137,7 +1137,7 @@ static int stk_vidioc_querybuf(struct file *filp, | |||
1137 | struct stk_camera *dev = priv; | 1137 | struct stk_camera *dev = priv; |
1138 | struct stk_sio_buffer *sbuf; | 1138 | struct stk_sio_buffer *sbuf; |
1139 | 1139 | ||
1140 | if (buf->index < 0 || buf->index >= dev->n_sbufs) | 1140 | if (buf->index >= dev->n_sbufs) |
1141 | return -EINVAL; | 1141 | return -EINVAL; |
1142 | sbuf = dev->sio_bufs + buf->index; | 1142 | sbuf = dev->sio_bufs + buf->index; |
1143 | *buf = sbuf->v4lbuf; | 1143 | *buf = sbuf->v4lbuf; |
@@ -1154,7 +1154,7 @@ static int stk_vidioc_qbuf(struct file *filp, | |||
1154 | if (buf->memory != V4L2_MEMORY_MMAP) | 1154 | if (buf->memory != V4L2_MEMORY_MMAP) |
1155 | return -EINVAL; | 1155 | return -EINVAL; |
1156 | 1156 | ||
1157 | if (buf->index < 0 || buf->index >= dev->n_sbufs) | 1157 | if (buf->index >= dev->n_sbufs) |
1158 | return -EINVAL; | 1158 | return -EINVAL; |
1159 | sbuf = dev->sio_bufs + buf->index; | 1159 | sbuf = dev->sio_bufs + buf->index; |
1160 | if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) | 1160 | if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) |
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 005f8a468031..80f1cee23fa5 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c | |||
@@ -20,20 +20,6 @@ | |||
20 | * loudness - set between 0 and 15 for varying degrees of loudness effect | 20 | * loudness - set between 0 and 15 for varying degrees of loudness effect |
21 | * | 21 | * |
22 | * maxvol - set maximium volume to +20db (1), default is 0db(0) | 22 | * maxvol - set maximium volume to +20db (1), default is 0db(0) |
23 | * | ||
24 | * | ||
25 | * Revision: 0.7 - maxvol module parm to set maximium volume 0db or +20db | ||
26 | * store if muted so we can return it | ||
27 | * change balance only if flaged to | ||
28 | * Revision: 0.6 - added tone controls | ||
29 | * Revision: 0.5 - Fixed odd balance problem | ||
30 | * Revision: 0.4 - added muting | ||
31 | * Revision: 0.3 - Fixed silly reversed volume controls. :) | ||
32 | * Revision: 0.2 - Cleaned up #defines | ||
33 | * fixed volume control | ||
34 | * Added I2C_DRIVERID_TDA7432 | ||
35 | * added loudness insmod control | ||
36 | * Revision: 0.1 - initial version | ||
37 | */ | 23 | */ |
38 | 24 | ||
39 | #include <linux/module.h> | 25 | #include <linux/module.h> |
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index d4a9ed45764b..1585839bd0bd 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
@@ -141,7 +141,6 @@ static const struct v4l2_subdev_ops tea6415c_ops = { | |||
141 | .video = &tea6415c_video_ops, | 141 | .video = &tea6415c_video_ops, |
142 | }; | 142 | }; |
143 | 143 | ||
144 | /* this function is called by i2c_probe */ | ||
145 | static int tea6415c_probe(struct i2c_client *client, | 144 | static int tea6415c_probe(struct i2c_client *client, |
146 | const struct i2c_device_id *id) | 145 | const struct i2c_device_id *id) |
147 | { | 146 | { |
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index ced6eadf347a..0446524d3543 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c | |||
@@ -112,7 +112,6 @@ static const struct v4l2_subdev_ops tea6420_ops = { | |||
112 | .audio = &tea6420_audio_ops, | 112 | .audio = &tea6420_audio_ops, |
113 | }; | 113 | }; |
114 | 114 | ||
115 | /* this function is called by i2c_probe */ | ||
116 | static int tea6420_probe(struct i2c_client *client, | 115 | static int tea6420_probe(struct i2c_client *client, |
117 | const struct i2c_device_id *id) | 116 | const struct i2c_device_id *id) |
118 | { | 117 | { |
diff --git a/drivers/media/video/ths7303.c b/drivers/media/video/ths7303.c new file mode 100644 index 000000000000..21781f8a0e8e --- /dev/null +++ b/drivers/media/video/ths7303.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * ths7303- THS7303 Video Amplifier driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ | ||
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 as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed .as is. WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/ctype.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/uaccess.h> | ||
24 | #include <linux/videodev2.h> | ||
25 | |||
26 | #include <media/v4l2-device.h> | ||
27 | #include <media/v4l2-subdev.h> | ||
28 | #include <media/v4l2-chip-ident.h> | ||
29 | |||
30 | MODULE_DESCRIPTION("TI THS7303 video amplifier driver"); | ||
31 | MODULE_AUTHOR("Chaithrika U S"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | static int debug; | ||
35 | module_param(debug, int, 0644); | ||
36 | MODULE_PARM_DESC(debug, "Debug level 0-1"); | ||
37 | |||
38 | /* following function is used to set ths7303 */ | ||
39 | static int ths7303_setvalue(struct v4l2_subdev *sd, v4l2_std_id std) | ||
40 | { | ||
41 | int err = 0; | ||
42 | u8 val; | ||
43 | struct i2c_client *client; | ||
44 | |||
45 | client = v4l2_get_subdevdata(sd); | ||
46 | |||
47 | if (std & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) { | ||
48 | val = 0x02; | ||
49 | v4l2_dbg(1, debug, sd, "setting value for SDTV format\n"); | ||
50 | } else { | ||
51 | val = 0x00; | ||
52 | v4l2_dbg(1, debug, sd, "disabling all channels\n"); | ||
53 | } | ||
54 | |||
55 | err |= i2c_smbus_write_byte_data(client, 0x01, val); | ||
56 | err |= i2c_smbus_write_byte_data(client, 0x02, val); | ||
57 | err |= i2c_smbus_write_byte_data(client, 0x03, val); | ||
58 | |||
59 | if (err) | ||
60 | v4l2_err(sd, "write failed\n"); | ||
61 | |||
62 | return err; | ||
63 | } | ||
64 | |||
65 | static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) | ||
66 | { | ||
67 | return ths7303_setvalue(sd, norm); | ||
68 | } | ||
69 | |||
70 | static int ths7303_g_chip_ident(struct v4l2_subdev *sd, | ||
71 | struct v4l2_dbg_chip_ident *chip) | ||
72 | { | ||
73 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
74 | |||
75 | return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_THS7303, 0); | ||
76 | } | ||
77 | |||
78 | static const struct v4l2_subdev_video_ops ths7303_video_ops = { | ||
79 | .s_std_output = ths7303_s_std_output, | ||
80 | }; | ||
81 | |||
82 | static const struct v4l2_subdev_core_ops ths7303_core_ops = { | ||
83 | .g_chip_ident = ths7303_g_chip_ident, | ||
84 | }; | ||
85 | |||
86 | static const struct v4l2_subdev_ops ths7303_ops = { | ||
87 | .core = &ths7303_core_ops, | ||
88 | .video = &ths7303_video_ops, | ||
89 | }; | ||
90 | |||
91 | static int ths7303_probe(struct i2c_client *client, | ||
92 | const struct i2c_device_id *id) | ||
93 | { | ||
94 | struct v4l2_subdev *sd; | ||
95 | v4l2_std_id std_id = V4L2_STD_NTSC; | ||
96 | |||
97 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
98 | return -ENODEV; | ||
99 | |||
100 | v4l_info(client, "chip found @ 0x%x (%s)\n", | ||
101 | client->addr << 1, client->adapter->name); | ||
102 | |||
103 | sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | ||
104 | if (sd == NULL) | ||
105 | return -ENOMEM; | ||
106 | |||
107 | v4l2_i2c_subdev_init(sd, client, &ths7303_ops); | ||
108 | |||
109 | return ths7303_setvalue(sd, std_id); | ||
110 | } | ||
111 | |||
112 | static int ths7303_remove(struct i2c_client *client) | ||
113 | { | ||
114 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
115 | |||
116 | v4l2_device_unregister_subdev(sd); | ||
117 | kfree(sd); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static const struct i2c_device_id ths7303_id[] = { | ||
123 | {"ths7303", 0}, | ||
124 | {}, | ||
125 | }; | ||
126 | |||
127 | MODULE_DEVICE_TABLE(i2c, ths7303_id); | ||
128 | |||
129 | static struct i2c_driver ths7303_driver = { | ||
130 | .driver = { | ||
131 | .owner = THIS_MODULE, | ||
132 | .name = "ths7303", | ||
133 | }, | ||
134 | .probe = ths7303_probe, | ||
135 | .remove = ths7303_remove, | ||
136 | .id_table = ths7303_id, | ||
137 | }; | ||
138 | |||
139 | static int __init ths7303_init(void) | ||
140 | { | ||
141 | return i2c_add_driver(&ths7303_driver); | ||
142 | } | ||
143 | |||
144 | static void __exit ths7303_exit(void) | ||
145 | { | ||
146 | i2c_del_driver(&ths7303_driver); | ||
147 | } | ||
148 | |||
149 | module_init(ths7303_init); | ||
150 | module_exit(ths7303_exit); | ||
151 | |||
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 78c377a399cb..537594211a90 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -309,32 +309,6 @@ static void set_freq(struct i2c_client *c, unsigned long freq) | |||
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
312 | static void tuner_i2c_address_check(struct tuner *t) | ||
313 | { | ||
314 | if ((t->type == UNSET || t->type == TUNER_ABSENT) || | ||
315 | ((t->i2c->addr < 0x64) || (t->i2c->addr > 0x6f))) | ||
316 | return; | ||
317 | |||
318 | /* We already know that the XC5000 can only be located at | ||
319 | * i2c address 0x61, 0x62, 0x63 or 0x64 */ | ||
320 | if ((t->type == TUNER_XC5000) && | ||
321 | ((t->i2c->addr <= 0x64)) && (t->i2c->addr >= 0x61)) | ||
322 | return; | ||
323 | |||
324 | tuner_warn("====================== WARNING! ======================\n"); | ||
325 | tuner_warn("Support for tuners in i2c address range 0x64 thru 0x6f\n"); | ||
326 | tuner_warn("will soon be dropped. This message indicates that your\n"); | ||
327 | tuner_warn("hardware has a %s tuner at i2c address 0x%02x.\n", | ||
328 | t->name, t->i2c->addr); | ||
329 | tuner_warn("To ensure continued support for your device, please\n"); | ||
330 | tuner_warn("send a copy of this message, along with full dmesg\n"); | ||
331 | tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n"); | ||
332 | tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n"); | ||
333 | tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n", | ||
334 | t->i2c->adapter->name, t->i2c->addr, t->type, t->name); | ||
335 | tuner_warn("====================== WARNING! ======================\n"); | ||
336 | } | ||
337 | |||
338 | static struct xc5000_config xc5000_cfg; | 312 | static struct xc5000_config xc5000_cfg; |
339 | 313 | ||
340 | static void set_type(struct i2c_client *c, unsigned int type, | 314 | static void set_type(struct i2c_client *c, unsigned int type, |
@@ -438,18 +412,12 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
438 | break; | 412 | break; |
439 | case TUNER_XC5000: | 413 | case TUNER_XC5000: |
440 | { | 414 | { |
441 | struct dvb_tuner_ops *xc_tuner_ops; | ||
442 | |||
443 | xc5000_cfg.i2c_address = t->i2c->addr; | 415 | xc5000_cfg.i2c_address = t->i2c->addr; |
444 | /* if_khz will be set when the digital dvb_attach() occurs */ | 416 | /* if_khz will be set when the digital dvb_attach() occurs */ |
445 | xc5000_cfg.if_khz = 0; | 417 | xc5000_cfg.if_khz = 0; |
446 | if (!dvb_attach(xc5000_attach, | 418 | if (!dvb_attach(xc5000_attach, |
447 | &t->fe, t->i2c->adapter, &xc5000_cfg)) | 419 | &t->fe, t->i2c->adapter, &xc5000_cfg)) |
448 | goto attach_failed; | 420 | goto attach_failed; |
449 | |||
450 | xc_tuner_ops = &t->fe.ops.tuner_ops; | ||
451 | if (xc_tuner_ops->init) | ||
452 | xc_tuner_ops->init(&t->fe); | ||
453 | break; | 421 | break; |
454 | } | 422 | } |
455 | default: | 423 | default: |
@@ -490,7 +458,6 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
490 | tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", | 458 | tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", |
491 | c->adapter->name, c->driver->driver.name, c->addr << 1, type, | 459 | c->adapter->name, c->driver->driver.name, c->addr << 1, type, |
492 | t->mode_mask); | 460 | t->mode_mask); |
493 | tuner_i2c_address_check(t); | ||
494 | return; | 461 | return; |
495 | 462 | ||
496 | attach_failed: | 463 | attach_failed: |
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index e24a38c7fa46..ac02808106c1 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -184,7 +184,7 @@ hauppauge_tuner[] = | |||
184 | { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"}, | 184 | { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"}, |
185 | { TUNER_ABSENT, "Thompson DTT757"}, | 185 | { TUNER_ABSENT, "Thompson DTT757"}, |
186 | /* 80-89 */ | 186 | /* 80-89 */ |
187 | { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216LME MK3"}, | 187 | { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK3"}, |
188 | { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, | 188 | { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, |
189 | { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, | 189 | { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, |
190 | { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, | 190 | { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, |
@@ -210,7 +210,7 @@ hauppauge_tuner[] = | |||
210 | { TUNER_TEA5767, "Philips TEA5768HL FM Radio"}, | 210 | { TUNER_TEA5767, "Philips TEA5768HL FM Radio"}, |
211 | { TUNER_ABSENT, "Panasonic ENV57H12D5"}, | 211 | { TUNER_ABSENT, "Panasonic ENV57H12D5"}, |
212 | { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"}, | 212 | { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"}, |
213 | { TUNER_ABSENT, "TCL MNM05-4"}, | 213 | { TUNER_PHILIPS_FM1236_MK3, "TCL MNM05-4"}, |
214 | { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"}, | 214 | { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"}, |
215 | { TUNER_ABSENT, "TCL MQNM05-4"}, | 215 | { TUNER_ABSENT, "TCL MQNM05-4"}, |
216 | { TUNER_ABSENT, "LG TAPC-W701D"}, | 216 | { TUNER_ABSENT, "LG TAPC-W701D"}, |
@@ -229,7 +229,7 @@ hauppauge_tuner[] = | |||
229 | { TUNER_ABSENT, "Samsung THPD5222FG30A"}, | 229 | { TUNER_ABSENT, "Samsung THPD5222FG30A"}, |
230 | /* 120-129 */ | 230 | /* 120-129 */ |
231 | { TUNER_XC2028, "Xceive XC3028"}, | 231 | { TUNER_XC2028, "Xceive XC3028"}, |
232 | { TUNER_ABSENT, "Philips FQ1216LME MK5"}, | 232 | { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK5"}, |
233 | { TUNER_ABSENT, "Philips FQD1216LME"}, | 233 | { TUNER_ABSENT, "Philips FQD1216LME"}, |
234 | { TUNER_ABSENT, "Conexant CX24118A"}, | 234 | { TUNER_ABSENT, "Conexant CX24118A"}, |
235 | { TUNER_ABSENT, "TCL DMF11WIP"}, | 235 | { TUNER_ABSENT, "TCL DMF11WIP"}, |
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index 4262e60b8116..3750f7fadb12 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c | |||
@@ -692,7 +692,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s, | |||
692 | break; /* Input detected */ | 692 | break; /* Input detected */ |
693 | } | 693 | } |
694 | 694 | ||
695 | if ((current_std == STD_INVALID) || (try_count <= 0)) | 695 | if ((current_std == STD_INVALID) || (try_count < 0)) |
696 | return -EINVAL; | 696 | return -EINVAL; |
697 | 697 | ||
698 | decoder->current_std = current_std; | 698 | decoder->current_std = current_std; |
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c index 900ec2129ca1..31d57f2d09e1 100644 --- a/drivers/media/video/usbvideo/konicawc.c +++ b/drivers/media/video/usbvideo/konicawc.c | |||
@@ -240,7 +240,7 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev | |||
240 | input_dev->dev.parent = &dev->dev; | 240 | input_dev->dev.parent = &dev->dev; |
241 | 241 | ||
242 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | 242 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
243 | input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); | 243 | input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); |
244 | 244 | ||
245 | error = input_register_device(cam->input); | 245 | error = input_register_device(cam->input); |
246 | if (error) { | 246 | if (error) { |
@@ -263,7 +263,7 @@ static void konicawc_unregister_input(struct konicawc *cam) | |||
263 | static void konicawc_report_buttonstat(struct konicawc *cam) | 263 | static void konicawc_report_buttonstat(struct konicawc *cam) |
264 | { | 264 | { |
265 | if (cam->input) { | 265 | if (cam->input) { |
266 | input_report_key(cam->input, BTN_0, cam->buttonsts); | 266 | input_report_key(cam->input, KEY_CAMERA, cam->buttonsts); |
267 | input_sync(cam->input); | 267 | input_sync(cam->input); |
268 | } | 268 | } |
269 | } | 269 | } |
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c index fd112f0b9d35..803d3e4e29a2 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/drivers/media/video/usbvideo/quickcam_messenger.c | |||
@@ -103,7 +103,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev) | |||
103 | input_dev->dev.parent = &dev->dev; | 103 | input_dev->dev.parent = &dev->dev; |
104 | 104 | ||
105 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | 105 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
106 | input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); | 106 | input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); |
107 | 107 | ||
108 | error = input_register_device(cam->input); | 108 | error = input_register_device(cam->input); |
109 | if (error) { | 109 | if (error) { |
@@ -126,7 +126,7 @@ static void qcm_unregister_input(struct qcm *cam) | |||
126 | static void qcm_report_buttonstat(struct qcm *cam) | 126 | static void qcm_report_buttonstat(struct qcm *cam) |
127 | { | 127 | { |
128 | if (cam->input) { | 128 | if (cam->input) { |
129 | input_report_key(cam->input, BTN_0, cam->button_sts); | 129 | input_report_key(cam->input, KEY_CAMERA, cam->button_sts); |
130 | input_sync(cam->input); | 130 | input_sync(cam->input); |
131 | } | 131 | } |
132 | } | 132 | } |
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index 8bc03b9e1315..6ba16abeebdd 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c | |||
@@ -390,10 +390,9 @@ int usbvision_scratch_alloc(struct usb_usbvision *usbvision) | |||
390 | 390 | ||
391 | void usbvision_scratch_free(struct usb_usbvision *usbvision) | 391 | void usbvision_scratch_free(struct usb_usbvision *usbvision) |
392 | { | 392 | { |
393 | if (usbvision->scratch != NULL) { | 393 | vfree(usbvision->scratch); |
394 | vfree(usbvision->scratch); | 394 | usbvision->scratch = NULL; |
395 | usbvision->scratch = NULL; | 395 | |
396 | } | ||
397 | } | 396 | } |
398 | 397 | ||
399 | /* | 398 | /* |
@@ -506,10 +505,9 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision) | |||
506 | */ | 505 | */ |
507 | void usbvision_decompress_free(struct usb_usbvision *usbvision) | 506 | void usbvision_decompress_free(struct usb_usbvision *usbvision) |
508 | { | 507 | { |
509 | if (usbvision->IntraFrameBuffer != NULL) { | 508 | vfree(usbvision->IntraFrameBuffer); |
510 | vfree(usbvision->IntraFrameBuffer); | 509 | usbvision->IntraFrameBuffer = NULL; |
511 | usbvision->IntraFrameBuffer = NULL; | 510 | |
512 | } | ||
513 | } | 511 | } |
514 | 512 | ||
515 | /************************************************************ | 513 | /************************************************************ |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index d7056a5b7f9b..90b58914f984 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -541,7 +541,7 @@ static int vidioc_enum_input (struct file *file, void *priv, | |||
541 | struct usb_usbvision *usbvision = video_drvdata(file); | 541 | struct usb_usbvision *usbvision = video_drvdata(file); |
542 | int chan; | 542 | int chan; |
543 | 543 | ||
544 | if ((vi->index >= usbvision->video_inputs) || (vi->index < 0) ) | 544 | if (vi->index >= usbvision->video_inputs) |
545 | return -EINVAL; | 545 | return -EINVAL; |
546 | if (usbvision->have_tuner) { | 546 | if (usbvision->have_tuner) { |
547 | chan = vi->index; | 547 | chan = vi->index; |
@@ -1794,7 +1794,7 @@ static struct usb_driver usbvision_driver = { | |||
1794 | .name = "usbvision", | 1794 | .name = "usbvision", |
1795 | .id_table = usbvision_table, | 1795 | .id_table = usbvision_table, |
1796 | .probe = usbvision_probe, | 1796 | .probe = usbvision_probe, |
1797 | .disconnect = usbvision_disconnect | 1797 | .disconnect = __devexit_p(usbvision_disconnect), |
1798 | }; | 1798 | }; |
1799 | 1799 | ||
1800 | /* | 1800 | /* |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 0d7e38d6ff6a..36a6ba92df27 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
@@ -1372,21 +1372,19 @@ end: | |||
1372 | } | 1372 | } |
1373 | 1373 | ||
1374 | /* | 1374 | /* |
1375 | * Prune an entity of its bogus controls. This currently includes processing | 1375 | * Prune an entity of its bogus controls using a blacklist. Bogus controls |
1376 | * unit auto controls for which no corresponding manual control is available. | 1376 | * are currently the ones that crash the camera or unconditionally return an |
1377 | * Such auto controls make little sense if any, and are known to crash at | 1377 | * error when queried. |
1378 | * least the SiGma Micro webcam. | ||
1379 | */ | 1378 | */ |
1380 | static void | 1379 | static void |
1381 | uvc_ctrl_prune_entity(struct uvc_entity *entity) | 1380 | uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity) |
1382 | { | 1381 | { |
1383 | static const struct { | 1382 | static const struct { |
1384 | u8 idx_manual; | 1383 | struct usb_device_id id; |
1385 | u8 idx_auto; | 1384 | u8 index; |
1386 | } blacklist[] = { | 1385 | } blacklist[] = { |
1387 | { 2, 11 }, /* Hue */ | 1386 | { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */ |
1388 | { 6, 12 }, /* White Balance Temperature */ | 1387 | { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */ |
1389 | { 7, 13 }, /* White Balance Component */ | ||
1390 | }; | 1388 | }; |
1391 | 1389 | ||
1392 | u8 *controls; | 1390 | u8 *controls; |
@@ -1400,19 +1398,17 @@ uvc_ctrl_prune_entity(struct uvc_entity *entity) | |||
1400 | size = entity->processing.bControlSize; | 1398 | size = entity->processing.bControlSize; |
1401 | 1399 | ||
1402 | for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { | 1400 | for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { |
1403 | if (blacklist[i].idx_auto >= 8 * size || | 1401 | if (!usb_match_id(dev->intf, &blacklist[i].id)) |
1404 | blacklist[i].idx_manual >= 8 * size) | ||
1405 | continue; | 1402 | continue; |
1406 | 1403 | ||
1407 | if (!uvc_test_bit(controls, blacklist[i].idx_auto) || | 1404 | if (blacklist[i].index >= 8 * size || |
1408 | uvc_test_bit(controls, blacklist[i].idx_manual)) | 1405 | !uvc_test_bit(controls, blacklist[i].index)) |
1409 | continue; | 1406 | continue; |
1410 | 1407 | ||
1411 | uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no " | 1408 | uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, " |
1412 | "matching manual control, removing it.\n", entity->id, | 1409 | "removing it.\n", entity->id, blacklist[i].index); |
1413 | blacklist[i].idx_auto); | ||
1414 | 1410 | ||
1415 | uvc_clear_bit(controls, blacklist[i].idx_auto); | 1411 | uvc_clear_bit(controls, blacklist[i].index); |
1416 | } | 1412 | } |
1417 | } | 1413 | } |
1418 | 1414 | ||
@@ -1442,8 +1438,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev) | |||
1442 | bControlSize = entity->camera.bControlSize; | 1438 | bControlSize = entity->camera.bControlSize; |
1443 | } | 1439 | } |
1444 | 1440 | ||
1445 | if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS) | 1441 | uvc_ctrl_prune_entity(dev, entity); |
1446 | uvc_ctrl_prune_entity(entity); | ||
1447 | 1442 | ||
1448 | for (i = 0; i < bControlSize; ++i) | 1443 | for (i = 0; i < bControlSize; ++i) |
1449 | ncontrols += hweight8(bmControls[i]); | 1444 | ncontrols += hweight8(bmControls[i]); |
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 507dc85646b2..89927b7aec28 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
@@ -289,10 +289,8 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
289 | struct uvc_format_desc *fmtdesc; | 289 | struct uvc_format_desc *fmtdesc; |
290 | struct uvc_frame *frame; | 290 | struct uvc_frame *frame; |
291 | const unsigned char *start = buffer; | 291 | const unsigned char *start = buffer; |
292 | unsigned char *_buffer; | ||
293 | unsigned int interval; | 292 | unsigned int interval; |
294 | unsigned int i, n; | 293 | unsigned int i, n; |
295 | int _buflen; | ||
296 | __u8 ftype; | 294 | __u8 ftype; |
297 | 295 | ||
298 | format->type = buffer[2]; | 296 | format->type = buffer[2]; |
@@ -303,7 +301,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
303 | case VS_FORMAT_FRAME_BASED: | 301 | case VS_FORMAT_FRAME_BASED: |
304 | n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28; | 302 | n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28; |
305 | if (buflen < n) { | 303 | if (buflen < n) { |
306 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 304 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
307 | "interface %d FORMAT error\n", | 305 | "interface %d FORMAT error\n", |
308 | dev->udev->devnum, | 306 | dev->udev->devnum, |
309 | alts->desc.bInterfaceNumber); | 307 | alts->desc.bInterfaceNumber); |
@@ -338,7 +336,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
338 | 336 | ||
339 | case VS_FORMAT_MJPEG: | 337 | case VS_FORMAT_MJPEG: |
340 | if (buflen < 11) { | 338 | if (buflen < 11) { |
341 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 339 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
342 | "interface %d FORMAT error\n", | 340 | "interface %d FORMAT error\n", |
343 | dev->udev->devnum, | 341 | dev->udev->devnum, |
344 | alts->desc.bInterfaceNumber); | 342 | alts->desc.bInterfaceNumber); |
@@ -354,7 +352,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
354 | 352 | ||
355 | case VS_FORMAT_DV: | 353 | case VS_FORMAT_DV: |
356 | if (buflen < 9) { | 354 | if (buflen < 9) { |
357 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 355 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
358 | "interface %d FORMAT error\n", | 356 | "interface %d FORMAT error\n", |
359 | dev->udev->devnum, | 357 | dev->udev->devnum, |
360 | alts->desc.bInterfaceNumber); | 358 | alts->desc.bInterfaceNumber); |
@@ -372,7 +370,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
372 | strlcpy(format->name, "HD-DV", sizeof format->name); | 370 | strlcpy(format->name, "HD-DV", sizeof format->name); |
373 | break; | 371 | break; |
374 | default: | 372 | default: |
375 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 373 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
376 | "interface %d: unknown DV format %u\n", | 374 | "interface %d: unknown DV format %u\n", |
377 | dev->udev->devnum, | 375 | dev->udev->devnum, |
378 | alts->desc.bInterfaceNumber, buffer[8]); | 376 | alts->desc.bInterfaceNumber, buffer[8]); |
@@ -401,7 +399,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
401 | case VS_FORMAT_STREAM_BASED: | 399 | case VS_FORMAT_STREAM_BASED: |
402 | /* Not supported yet. */ | 400 | /* Not supported yet. */ |
403 | default: | 401 | default: |
404 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 402 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
405 | "interface %d unsupported format %u\n", | 403 | "interface %d unsupported format %u\n", |
406 | dev->udev->devnum, alts->desc.bInterfaceNumber, | 404 | dev->udev->devnum, alts->desc.bInterfaceNumber, |
407 | buffer[2]); | 405 | buffer[2]); |
@@ -413,20 +411,11 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
413 | buflen -= buffer[0]; | 411 | buflen -= buffer[0]; |
414 | buffer += buffer[0]; | 412 | buffer += buffer[0]; |
415 | 413 | ||
416 | /* Count the number of frame descriptors to test the bFrameIndex | ||
417 | * field when parsing the descriptors. We can't rely on the | ||
418 | * bNumFrameDescriptors field as some cameras don't initialize it | ||
419 | * properly. | ||
420 | */ | ||
421 | for (_buflen = buflen, _buffer = buffer; | ||
422 | _buflen > 2 && _buffer[2] == ftype; | ||
423 | _buflen -= _buffer[0], _buffer += _buffer[0]) | ||
424 | format->nframes++; | ||
425 | |||
426 | /* Parse the frame descriptors. Only uncompressed, MJPEG and frame | 414 | /* Parse the frame descriptors. Only uncompressed, MJPEG and frame |
427 | * based formats have frame descriptors. | 415 | * based formats have frame descriptors. |
428 | */ | 416 | */ |
429 | while (buflen > 2 && buffer[2] == ftype) { | 417 | while (buflen > 2 && buffer[2] == ftype) { |
418 | frame = &format->frame[format->nframes]; | ||
430 | if (ftype != VS_FRAME_FRAME_BASED) | 419 | if (ftype != VS_FRAME_FRAME_BASED) |
431 | n = buflen > 25 ? buffer[25] : 0; | 420 | n = buflen > 25 ? buffer[25] : 0; |
432 | else | 421 | else |
@@ -435,22 +424,12 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
435 | n = n ? n : 3; | 424 | n = n ? n : 3; |
436 | 425 | ||
437 | if (buflen < 26 + 4*n) { | 426 | if (buflen < 26 + 4*n) { |
438 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 427 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
439 | "interface %d FRAME error\n", dev->udev->devnum, | 428 | "interface %d FRAME error\n", dev->udev->devnum, |
440 | alts->desc.bInterfaceNumber); | 429 | alts->desc.bInterfaceNumber); |
441 | return -EINVAL; | 430 | return -EINVAL; |
442 | } | 431 | } |
443 | 432 | ||
444 | if (buffer[3] - 1 >= format->nframes) { | ||
445 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | ||
446 | "interface %d frame index %u out of range\n", | ||
447 | dev->udev->devnum, alts->desc.bInterfaceNumber, | ||
448 | buffer[3]); | ||
449 | return -EINVAL; | ||
450 | } | ||
451 | |||
452 | frame = &format->frame[buffer[3] - 1]; | ||
453 | |||
454 | frame->bFrameIndex = buffer[3]; | 433 | frame->bFrameIndex = buffer[3]; |
455 | frame->bmCapabilities = buffer[4]; | 434 | frame->bmCapabilities = buffer[4]; |
456 | frame->wWidth = get_unaligned_le16(&buffer[5]); | 435 | frame->wWidth = get_unaligned_le16(&buffer[5]); |
@@ -507,6 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
507 | 10000000/frame->dwDefaultFrameInterval, | 486 | 10000000/frame->dwDefaultFrameInterval, |
508 | (100000000/frame->dwDefaultFrameInterval)%10); | 487 | (100000000/frame->dwDefaultFrameInterval)%10); |
509 | 488 | ||
489 | format->nframes++; | ||
510 | buflen -= buffer[0]; | 490 | buflen -= buffer[0]; |
511 | buffer += buffer[0]; | 491 | buffer += buffer[0]; |
512 | } | 492 | } |
@@ -518,7 +498,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
518 | 498 | ||
519 | if (buflen > 2 && buffer[2] == VS_COLORFORMAT) { | 499 | if (buflen > 2 && buffer[2] == VS_COLORFORMAT) { |
520 | if (buflen < 6) { | 500 | if (buflen < 6) { |
521 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" | 501 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
522 | "interface %d COLORFORMAT error\n", | 502 | "interface %d COLORFORMAT error\n", |
523 | dev->udev->devnum, | 503 | dev->udev->devnum, |
524 | alts->desc.bInterfaceNumber); | 504 | alts->desc.bInterfaceNumber); |
@@ -664,7 +644,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, | |||
664 | _buflen = buflen; | 644 | _buflen = buflen; |
665 | 645 | ||
666 | /* Count the format and frame descriptors. */ | 646 | /* Count the format and frame descriptors. */ |
667 | while (_buflen > 2) { | 647 | while (_buflen > 2 && _buffer[1] == CS_INTERFACE) { |
668 | switch (_buffer[2]) { | 648 | switch (_buffer[2]) { |
669 | case VS_FORMAT_UNCOMPRESSED: | 649 | case VS_FORMAT_UNCOMPRESSED: |
670 | case VS_FORMAT_MJPEG: | 650 | case VS_FORMAT_MJPEG: |
@@ -729,7 +709,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, | |||
729 | streaming->nformats = nformats; | 709 | streaming->nformats = nformats; |
730 | 710 | ||
731 | /* Parse the format descriptors. */ | 711 | /* Parse the format descriptors. */ |
732 | while (buflen > 2) { | 712 | while (buflen > 2 && buffer[1] == CS_INTERFACE) { |
733 | switch (buffer[2]) { | 713 | switch (buffer[2]) { |
734 | case VS_FORMAT_UNCOMPRESSED: | 714 | case VS_FORMAT_UNCOMPRESSED: |
735 | case VS_FORMAT_MJPEG: | 715 | case VS_FORMAT_MJPEG: |
@@ -1316,7 +1296,7 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video, | |||
1316 | continue; | 1296 | continue; |
1317 | 1297 | ||
1318 | if (forward->extension.bNrInPins != 1) { | 1298 | if (forward->extension.bNrInPins != 1) { |
1319 | uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has" | 1299 | uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has " |
1320 | "more than 1 input pin.\n", entity->id); | 1300 | "more than 1 input pin.\n", entity->id); |
1321 | return -1; | 1301 | return -1; |
1322 | } | 1302 | } |
@@ -1614,6 +1594,7 @@ static int uvc_probe(struct usb_interface *intf, | |||
1614 | INIT_LIST_HEAD(&dev->entities); | 1594 | INIT_LIST_HEAD(&dev->entities); |
1615 | INIT_LIST_HEAD(&dev->streaming); | 1595 | INIT_LIST_HEAD(&dev->streaming); |
1616 | kref_init(&dev->kref); | 1596 | kref_init(&dev->kref); |
1597 | atomic_set(&dev->users, 0); | ||
1617 | 1598 | ||
1618 | dev->udev = usb_get_dev(udev); | 1599 | dev->udev = usb_get_dev(udev); |
1619 | dev->intf = usb_get_intf(intf); | 1600 | dev->intf = usb_get_intf(intf); |
@@ -1927,7 +1908,7 @@ static struct usb_device_id uvc_ids[] = { | |||
1927 | .bInterfaceSubClass = 1, | 1908 | .bInterfaceSubClass = 1, |
1928 | .bInterfaceProtocol = 0, | 1909 | .bInterfaceProtocol = 0, |
1929 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, | 1910 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, |
1930 | /* Lenovo Thinkpad SL500 */ | 1911 | /* Lenovo Thinkpad SL400/SL500 */ |
1931 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1912 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1932 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1913 | | USB_DEVICE_ID_MATCH_INT_INFO, |
1933 | .idVendor = 0x17ef, | 1914 | .idVendor = 0x17ef, |
@@ -1936,6 +1917,15 @@ static struct usb_device_id uvc_ids[] = { | |||
1936 | .bInterfaceSubClass = 1, | 1917 | .bInterfaceSubClass = 1, |
1937 | .bInterfaceProtocol = 0, | 1918 | .bInterfaceProtocol = 0, |
1938 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, | 1919 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, |
1920 | /* Aveo Technology USB 2.0 Camera */ | ||
1921 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
1922 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
1923 | .idVendor = 0x1871, | ||
1924 | .idProduct = 0x0306, | ||
1925 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
1926 | .bInterfaceSubClass = 1, | ||
1927 | .bInterfaceProtocol = 0, | ||
1928 | .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, | ||
1939 | /* Ecamm Pico iMage */ | 1929 | /* Ecamm Pico iMage */ |
1940 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1930 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1941 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1931 | | USB_DEVICE_ID_MATCH_INT_INFO, |
@@ -1945,6 +1935,15 @@ static struct usb_device_id uvc_ids[] = { | |||
1945 | .bInterfaceSubClass = 1, | 1935 | .bInterfaceSubClass = 1, |
1946 | .bInterfaceProtocol = 0, | 1936 | .bInterfaceProtocol = 0, |
1947 | .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, | 1937 | .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, |
1938 | /* FSC WebCam V30S */ | ||
1939 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
1940 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
1941 | .idVendor = 0x18ec, | ||
1942 | .idProduct = 0x3288, | ||
1943 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
1944 | .bInterfaceSubClass = 1, | ||
1945 | .bInterfaceProtocol = 0, | ||
1946 | .driver_info = UVC_QUIRK_PROBE_MINMAX }, | ||
1948 | /* Bodelin ProScopeHR */ | 1947 | /* Bodelin ProScopeHR */ |
1949 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1948 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1950 | | USB_DEVICE_ID_MATCH_DEV_HI | 1949 | | USB_DEVICE_ID_MATCH_DEV_HI |
@@ -1965,8 +1964,7 @@ static struct usb_device_id uvc_ids[] = { | |||
1965 | .bInterfaceSubClass = 1, | 1964 | .bInterfaceSubClass = 1, |
1966 | .bInterfaceProtocol = 0, | 1965 | .bInterfaceProtocol = 0, |
1967 | .driver_info = UVC_QUIRK_PROBE_MINMAX | 1966 | .driver_info = UVC_QUIRK_PROBE_MINMAX |
1968 | | UVC_QUIRK_IGNORE_SELECTOR_UNIT | 1967 | | UVC_QUIRK_IGNORE_SELECTOR_UNIT }, |
1969 | | UVC_QUIRK_PRUNE_CONTROLS }, | ||
1970 | /* Generic USB Video Class */ | 1968 | /* Generic USB Video Class */ |
1971 | { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, | 1969 | { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, |
1972 | {} | 1970 | {} |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 0155752e4a5a..f854698c4061 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -172,6 +172,20 @@ int uvc_free_buffers(struct uvc_video_queue *queue) | |||
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
174 | 174 | ||
175 | /* | ||
176 | * Check if buffers have been allocated. | ||
177 | */ | ||
178 | int uvc_queue_allocated(struct uvc_video_queue *queue) | ||
179 | { | ||
180 | int allocated; | ||
181 | |||
182 | mutex_lock(&queue->mutex); | ||
183 | allocated = queue->count != 0; | ||
184 | mutex_unlock(&queue->mutex); | ||
185 | |||
186 | return allocated; | ||
187 | } | ||
188 | |||
175 | static void __uvc_query_buffer(struct uvc_buffer *buf, | 189 | static void __uvc_query_buffer(struct uvc_buffer *buf, |
176 | struct v4l2_buffer *v4l2_buf) | 190 | struct v4l2_buffer *v4l2_buf) |
177 | { | 191 | { |
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index 21d87124986b..f152a9903862 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c | |||
@@ -194,7 +194,7 @@ int uvc_status_init(struct uvc_device *dev) | |||
194 | dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, | 194 | dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, |
195 | dev, interval); | 195 | dev, interval); |
196 | 196 | ||
197 | return usb_submit_urb(dev->int_urb, GFP_KERNEL); | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | void uvc_status_cleanup(struct uvc_device *dev) | 200 | void uvc_status_cleanup(struct uvc_device *dev) |
@@ -205,15 +205,30 @@ void uvc_status_cleanup(struct uvc_device *dev) | |||
205 | uvc_input_cleanup(dev); | 205 | uvc_input_cleanup(dev); |
206 | } | 206 | } |
207 | 207 | ||
208 | int uvc_status_suspend(struct uvc_device *dev) | 208 | int uvc_status_start(struct uvc_device *dev) |
209 | { | ||
210 | if (dev->int_urb == NULL) | ||
211 | return 0; | ||
212 | |||
213 | return usb_submit_urb(dev->int_urb, GFP_KERNEL); | ||
214 | } | ||
215 | |||
216 | void uvc_status_stop(struct uvc_device *dev) | ||
209 | { | 217 | { |
210 | usb_kill_urb(dev->int_urb); | 218 | usb_kill_urb(dev->int_urb); |
219 | } | ||
220 | |||
221 | int uvc_status_suspend(struct uvc_device *dev) | ||
222 | { | ||
223 | if (atomic_read(&dev->users)) | ||
224 | usb_kill_urb(dev->int_urb); | ||
225 | |||
211 | return 0; | 226 | return 0; |
212 | } | 227 | } |
213 | 228 | ||
214 | int uvc_status_resume(struct uvc_device *dev) | 229 | int uvc_status_resume(struct uvc_device *dev) |
215 | { | 230 | { |
216 | if (dev->int_urb == NULL) | 231 | if (dev->int_urb == NULL || atomic_read(&dev->users) == 0) |
217 | return 0; | 232 | return 0; |
218 | 233 | ||
219 | return usb_submit_urb(dev->int_urb, GFP_NOIO); | 234 | return usb_submit_urb(dev->int_urb, GFP_NOIO); |
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 2a80caa54fb4..5e77cad29690 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
@@ -46,6 +46,8 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video, | |||
46 | struct uvc_menu_info *menu_info; | 46 | struct uvc_menu_info *menu_info; |
47 | struct uvc_control_mapping *mapping; | 47 | struct uvc_control_mapping *mapping; |
48 | struct uvc_control *ctrl; | 48 | struct uvc_control *ctrl; |
49 | u32 index = query_menu->index; | ||
50 | u32 id = query_menu->id; | ||
49 | 51 | ||
50 | ctrl = uvc_find_control(video, query_menu->id, &mapping); | 52 | ctrl = uvc_find_control(video, query_menu->id, &mapping); |
51 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) | 53 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) |
@@ -54,6 +56,10 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video, | |||
54 | if (query_menu->index >= mapping->menu_count) | 56 | if (query_menu->index >= mapping->menu_count) |
55 | return -EINVAL; | 57 | return -EINVAL; |
56 | 58 | ||
59 | memset(query_menu, 0, sizeof(*query_menu)); | ||
60 | query_menu->id = id; | ||
61 | query_menu->index = index; | ||
62 | |||
57 | menu_info = &mapping->menu_info[query_menu->index]; | 63 | menu_info = &mapping->menu_info[query_menu->index]; |
58 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | 64 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); |
59 | return 0; | 65 | return 0; |
@@ -245,7 +251,7 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video, | |||
245 | if (fmt->type != video->streaming->type) | 251 | if (fmt->type != video->streaming->type) |
246 | return -EINVAL; | 252 | return -EINVAL; |
247 | 253 | ||
248 | if (uvc_queue_streaming(&video->queue)) | 254 | if (uvc_queue_allocated(&video->queue)) |
249 | return -EBUSY; | 255 | return -EBUSY; |
250 | 256 | ||
251 | ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame); | 257 | ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame); |
@@ -433,6 +439,15 @@ static int uvc_v4l2_open(struct file *file) | |||
433 | goto done; | 439 | goto done; |
434 | } | 440 | } |
435 | 441 | ||
442 | if (atomic_inc_return(&video->dev->users) == 1) { | ||
443 | if ((ret = uvc_status_start(video->dev)) < 0) { | ||
444 | usb_autopm_put_interface(video->dev->intf); | ||
445 | atomic_dec(&video->dev->users); | ||
446 | kfree(handle); | ||
447 | goto done; | ||
448 | } | ||
449 | } | ||
450 | |||
436 | handle->device = video; | 451 | handle->device = video; |
437 | handle->state = UVC_HANDLE_PASSIVE; | 452 | handle->state = UVC_HANDLE_PASSIVE; |
438 | file->private_data = handle; | 453 | file->private_data = handle; |
@@ -467,6 +482,9 @@ static int uvc_v4l2_release(struct file *file) | |||
467 | kfree(handle); | 482 | kfree(handle); |
468 | file->private_data = NULL; | 483 | file->private_data = NULL; |
469 | 484 | ||
485 | if (atomic_dec_return(&video->dev->users) == 0) | ||
486 | uvc_status_stop(video->dev); | ||
487 | |||
470 | usb_autopm_put_interface(video->dev->intf); | 488 | usb_autopm_put_interface(video->dev->intf); |
471 | kref_put(&video->dev->kref, uvc_delete); | 489 | kref_put(&video->dev->kref, uvc_delete); |
472 | return 0; | 490 | return 0; |
@@ -512,7 +530,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
512 | memset(&xctrl, 0, sizeof xctrl); | 530 | memset(&xctrl, 0, sizeof xctrl); |
513 | xctrl.id = ctrl->id; | 531 | xctrl.id = ctrl->id; |
514 | 532 | ||
515 | uvc_ctrl_begin(video); | 533 | ret = uvc_ctrl_begin(video); |
534 | if (ret < 0) | ||
535 | return ret; | ||
536 | |||
516 | ret = uvc_ctrl_get(video, &xctrl); | 537 | ret = uvc_ctrl_get(video, &xctrl); |
517 | uvc_ctrl_rollback(video); | 538 | uvc_ctrl_rollback(video); |
518 | if (ret >= 0) | 539 | if (ret >= 0) |
@@ -529,7 +550,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
529 | xctrl.id = ctrl->id; | 550 | xctrl.id = ctrl->id; |
530 | xctrl.value = ctrl->value; | 551 | xctrl.value = ctrl->value; |
531 | 552 | ||
532 | uvc_ctrl_begin(video); | 553 | ret = uvc_ctrl_begin(video); |
554 | if (ret < 0) | ||
555 | return ret; | ||
556 | |||
533 | ret = uvc_ctrl_set(video, &xctrl); | 557 | ret = uvc_ctrl_set(video, &xctrl); |
534 | if (ret < 0) { | 558 | if (ret < 0) { |
535 | uvc_ctrl_rollback(video); | 559 | uvc_ctrl_rollback(video); |
@@ -548,7 +572,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
548 | struct v4l2_ext_control *ctrl = ctrls->controls; | 572 | struct v4l2_ext_control *ctrl = ctrls->controls; |
549 | unsigned int i; | 573 | unsigned int i; |
550 | 574 | ||
551 | uvc_ctrl_begin(video); | 575 | ret = uvc_ctrl_begin(video); |
576 | if (ret < 0) | ||
577 | return ret; | ||
578 | |||
552 | for (i = 0; i < ctrls->count; ++ctrl, ++i) { | 579 | for (i = 0; i < ctrls->count; ++ctrl, ++i) { |
553 | ret = uvc_ctrl_get(video, ctrl); | 580 | ret = uvc_ctrl_get(video, ctrl); |
554 | if (ret < 0) { | 581 | if (ret < 0) { |
@@ -648,7 +675,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
648 | 675 | ||
649 | case VIDIOC_S_INPUT: | 676 | case VIDIOC_S_INPUT: |
650 | { | 677 | { |
651 | u8 input = *(u32 *)arg + 1; | 678 | u32 input = *(u32 *)arg + 1; |
652 | 679 | ||
653 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 680 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
654 | return ret; | 681 | return ret; |
@@ -660,7 +687,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
660 | break; | 687 | break; |
661 | } | 688 | } |
662 | 689 | ||
663 | if (input > video->selector->selector.bNrInPins) | 690 | if (input == 0 || input > video->selector->selector.bNrInPins) |
664 | return -EINVAL; | 691 | return -EINVAL; |
665 | 692 | ||
666 | return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id, | 693 | return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id, |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 6ce974d7362f..01b633c73480 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -65,7 +65,8 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, | |||
65 | struct uvc_streaming_control *ctrl) | 65 | struct uvc_streaming_control *ctrl) |
66 | { | 66 | { |
67 | struct uvc_format *format; | 67 | struct uvc_format *format; |
68 | struct uvc_frame *frame; | 68 | struct uvc_frame *frame = NULL; |
69 | unsigned int i; | ||
69 | 70 | ||
70 | if (ctrl->bFormatIndex <= 0 || | 71 | if (ctrl->bFormatIndex <= 0 || |
71 | ctrl->bFormatIndex > video->streaming->nformats) | 72 | ctrl->bFormatIndex > video->streaming->nformats) |
@@ -73,11 +74,15 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, | |||
73 | 74 | ||
74 | format = &video->streaming->format[ctrl->bFormatIndex - 1]; | 75 | format = &video->streaming->format[ctrl->bFormatIndex - 1]; |
75 | 76 | ||
76 | if (ctrl->bFrameIndex <= 0 || | 77 | for (i = 0; i < format->nframes; ++i) { |
77 | ctrl->bFrameIndex > format->nframes) | 78 | if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) { |
78 | return; | 79 | frame = &format->frame[i]; |
80 | break; | ||
81 | } | ||
82 | } | ||
79 | 83 | ||
80 | frame = &format->frame[ctrl->bFrameIndex - 1]; | 84 | if (frame == NULL) |
85 | return; | ||
81 | 86 | ||
82 | if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) || | 87 | if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) || |
83 | (ctrl->dwMaxVideoFrameSize == 0 && | 88 | (ctrl->dwMaxVideoFrameSize == 0 && |
@@ -1089,7 +1094,7 @@ int uvc_video_init(struct uvc_video_device *video) | |||
1089 | /* Zero bFrameIndex might be correct. Stream-based formats (including | 1094 | /* Zero bFrameIndex might be correct. Stream-based formats (including |
1090 | * MPEG-2 TS and DV) do not support frames but have a dummy frame | 1095 | * MPEG-2 TS and DV) do not support frames but have a dummy frame |
1091 | * descriptor with bFrameIndex set to zero. If the default frame | 1096 | * descriptor with bFrameIndex set to zero. If the default frame |
1092 | * descriptor is not found, use the first avalable frame. | 1097 | * descriptor is not found, use the first available frame. |
1093 | */ | 1098 | */ |
1094 | for (i = format->nframes; i > 0; --i) { | 1099 | for (i = format->nframes; i > 0; --i) { |
1095 | frame = &format->frame[i-1]; | 1100 | frame = &format->frame[i-1]; |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index e5014e668f99..3c78d3c1e4c0 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -313,7 +313,6 @@ struct uvc_xu_control { | |||
313 | #define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 | 313 | #define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 |
314 | #define UVC_QUIRK_STREAM_NO_FID 0x00000010 | 314 | #define UVC_QUIRK_STREAM_NO_FID 0x00000010 |
315 | #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 | 315 | #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 |
316 | #define UVC_QUIRK_PRUNE_CONTROLS 0x00000040 | ||
317 | #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 | 316 | #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 |
318 | 317 | ||
319 | /* Format flags */ | 318 | /* Format flags */ |
@@ -634,6 +633,7 @@ struct uvc_device { | |||
634 | enum uvc_device_state state; | 633 | enum uvc_device_state state; |
635 | struct kref kref; | 634 | struct kref kref; |
636 | struct list_head list; | 635 | struct list_head list; |
636 | atomic_t users; | ||
637 | 637 | ||
638 | /* Video control interface */ | 638 | /* Video control interface */ |
639 | __u16 uvc_version; | 639 | __u16 uvc_version; |
@@ -747,6 +747,7 @@ extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
747 | struct uvc_buffer *buf); | 747 | struct uvc_buffer *buf); |
748 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, | 748 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, |
749 | struct file *file, poll_table *wait); | 749 | struct file *file, poll_table *wait); |
750 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); | ||
750 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) | 751 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) |
751 | { | 752 | { |
752 | return queue->flags & UVC_QUEUE_STREAMING; | 753 | return queue->flags & UVC_QUEUE_STREAMING; |
@@ -770,6 +771,8 @@ extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | |||
770 | /* Status */ | 771 | /* Status */ |
771 | extern int uvc_status_init(struct uvc_device *dev); | 772 | extern int uvc_status_init(struct uvc_device *dev); |
772 | extern void uvc_status_cleanup(struct uvc_device *dev); | 773 | extern void uvc_status_cleanup(struct uvc_device *dev); |
774 | extern int uvc_status_start(struct uvc_device *dev); | ||
775 | extern void uvc_status_stop(struct uvc_device *dev); | ||
773 | extern int uvc_status_suspend(struct uvc_device *dev); | 776 | extern int uvc_status_suspend(struct uvc_device *dev); |
774 | extern int uvc_status_resume(struct uvc_device *dev); | 777 | extern int uvc_status_resume(struct uvc_device *dev); |
775 | 778 | ||
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index f576ef66b807..f96475626da7 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -746,6 +746,7 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, | |||
746 | const struct v4l2_subdev_ops *ops) | 746 | const struct v4l2_subdev_ops *ops) |
747 | { | 747 | { |
748 | v4l2_subdev_init(sd, ops); | 748 | v4l2_subdev_init(sd, ops); |
749 | sd->flags |= V4L2_SUBDEV_FL_IS_I2C; | ||
749 | /* the owner is the same as the i2c_client's driver owner */ | 750 | /* the owner is the same as the i2c_client's driver owner */ |
750 | sd->owner = client->driver->driver.owner; | 751 | sd->owner = client->driver->driver.owner; |
751 | /* i2c_client and v4l2_subdev point to one another */ | 752 | /* i2c_client and v4l2_subdev point to one another */ |
@@ -897,8 +898,7 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type) | |||
897 | }; | 898 | }; |
898 | static const unsigned short tv_addrs[] = { | 899 | static const unsigned short tv_addrs[] = { |
899 | 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ | 900 | 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ |
900 | 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, | 901 | 0x60, 0x61, 0x62, 0x63, 0x64, |
901 | 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, | ||
902 | I2C_CLIENT_END | 902 | I2C_CLIENT_END |
903 | }; | 903 | }; |
904 | 904 | ||
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index 94aa485ade52..0d06e7cbd5b3 100644 --- a/drivers/media/video/v4l2-device.c +++ b/drivers/media/video/v4l2-device.c | |||
@@ -49,6 +49,22 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) | |||
49 | } | 49 | } |
50 | EXPORT_SYMBOL_GPL(v4l2_device_register); | 50 | EXPORT_SYMBOL_GPL(v4l2_device_register); |
51 | 51 | ||
52 | int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, | ||
53 | atomic_t *instance) | ||
54 | { | ||
55 | int num = atomic_inc_return(instance) - 1; | ||
56 | int len = strlen(basename); | ||
57 | |||
58 | if (basename[len - 1] >= '0' && basename[len - 1] <= '9') | ||
59 | snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), | ||
60 | "%s-%d", basename, num); | ||
61 | else | ||
62 | snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), | ||
63 | "%s%d", basename, num); | ||
64 | return num; | ||
65 | } | ||
66 | EXPORT_SYMBOL_GPL(v4l2_device_set_name); | ||
67 | |||
52 | void v4l2_device_disconnect(struct v4l2_device *v4l2_dev) | 68 | void v4l2_device_disconnect(struct v4l2_device *v4l2_dev) |
53 | { | 69 | { |
54 | if (v4l2_dev->dev) { | 70 | if (v4l2_dev->dev) { |
@@ -67,8 +83,21 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev) | |||
67 | v4l2_device_disconnect(v4l2_dev); | 83 | v4l2_device_disconnect(v4l2_dev); |
68 | 84 | ||
69 | /* Unregister subdevs */ | 85 | /* Unregister subdevs */ |
70 | list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) | 86 | list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) { |
71 | v4l2_device_unregister_subdev(sd); | 87 | v4l2_device_unregister_subdev(sd); |
88 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
89 | if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) { | ||
90 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
91 | |||
92 | /* We need to unregister the i2c client explicitly. | ||
93 | We cannot rely on i2c_del_adapter to always | ||
94 | unregister clients for us, since if the i2c bus | ||
95 | is a platform bus, then it is never deleted. */ | ||
96 | if (client) | ||
97 | i2c_unregister_device(client); | ||
98 | } | ||
99 | #endif | ||
100 | } | ||
72 | } | 101 | } |
73 | EXPORT_SYMBOL_GPL(v4l2_device_unregister); | 102 | EXPORT_SYMBOL_GPL(v4l2_device_unregister); |
74 | 103 | ||
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index b7b05842cf28..f1ccf98c0a6f 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c | |||
@@ -118,6 +118,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q, | |||
118 | void *priv, | 118 | void *priv, |
119 | struct videobuf_qtype_ops *int_ops) | 119 | struct videobuf_qtype_ops *int_ops) |
120 | { | 120 | { |
121 | BUG_ON(!q); | ||
121 | memset(q, 0, sizeof(*q)); | 122 | memset(q, 0, sizeof(*q)); |
122 | q->irqlock = irqlock; | 123 | q->irqlock = irqlock; |
123 | q->dev = dev; | 124 | q->dev = dev; |
@@ -439,6 +440,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, | |||
439 | } | 440 | } |
440 | 441 | ||
441 | req->count = retval; | 442 | req->count = retval; |
443 | retval = 0; | ||
442 | 444 | ||
443 | done: | 445 | done: |
444 | mutex_unlock(&q->vb_lock); | 446 | mutex_unlock(&q->vb_lock); |
@@ -454,7 +456,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) | |||
454 | dprintk(1, "querybuf: Wrong type.\n"); | 456 | dprintk(1, "querybuf: Wrong type.\n"); |
455 | goto done; | 457 | goto done; |
456 | } | 458 | } |
457 | if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) { | 459 | if (unlikely(b->index >= VIDEO_MAX_FRAME)) { |
458 | dprintk(1, "querybuf: index out of range.\n"); | 460 | dprintk(1, "querybuf: index out of range.\n"); |
459 | goto done; | 461 | goto done; |
460 | } | 462 | } |
@@ -495,7 +497,7 @@ int videobuf_qbuf(struct videobuf_queue *q, | |||
495 | dprintk(1, "qbuf: Wrong type.\n"); | 497 | dprintk(1, "qbuf: Wrong type.\n"); |
496 | goto done; | 498 | goto done; |
497 | } | 499 | } |
498 | if (b->index < 0 || b->index >= VIDEO_MAX_FRAME) { | 500 | if (b->index >= VIDEO_MAX_FRAME) { |
499 | dprintk(1, "qbuf: index out of range.\n"); | 501 | dprintk(1, "qbuf: index out of range.\n"); |
500 | goto done; | 502 | goto done; |
501 | } | 503 | } |
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 0c29a019bc89..d09ce83a9429 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c | |||
@@ -259,19 +259,6 @@ static int __videobuf_iolock(struct videobuf_queue *q, | |||
259 | return 0; | 259 | return 0; |
260 | } | 260 | } |
261 | 261 | ||
262 | static int __videobuf_sync(struct videobuf_queue *q, | ||
263 | struct videobuf_buffer *buf) | ||
264 | { | ||
265 | struct videobuf_dma_contig_memory *mem = buf->priv; | ||
266 | |||
267 | BUG_ON(!mem); | ||
268 | MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); | ||
269 | |||
270 | dma_sync_single_for_cpu(q->dev, mem->dma_handle, mem->size, | ||
271 | DMA_FROM_DEVICE); | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static int __videobuf_mmap_free(struct videobuf_queue *q) | 262 | static int __videobuf_mmap_free(struct videobuf_queue *q) |
276 | { | 263 | { |
277 | unsigned int i; | 264 | unsigned int i; |
@@ -433,7 +420,6 @@ static struct videobuf_qtype_ops qops = { | |||
433 | 420 | ||
434 | .alloc = __videobuf_alloc, | 421 | .alloc = __videobuf_alloc, |
435 | .iolock = __videobuf_iolock, | 422 | .iolock = __videobuf_iolock, |
436 | .sync = __videobuf_sync, | ||
437 | .mmap_free = __videobuf_mmap_free, | 423 | .mmap_free = __videobuf_mmap_free, |
438 | .mmap_mapper = __videobuf_mmap_mapper, | 424 | .mmap_mapper = __videobuf_mmap_mapper, |
439 | .video_copy_to_user = __videobuf_copy_to_user, | 425 | .video_copy_to_user = __videobuf_copy_to_user, |
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index da1790e57a86..a8dd22ace3fb 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c | |||
@@ -58,9 +58,10 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages) | |||
58 | struct page *pg; | 58 | struct page *pg; |
59 | int i; | 59 | int i; |
60 | 60 | ||
61 | sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL); | 61 | sglist = vmalloc(nr_pages * sizeof(*sglist)); |
62 | if (NULL == sglist) | 62 | if (NULL == sglist) |
63 | return NULL; | 63 | return NULL; |
64 | memset(sglist, 0, nr_pages * sizeof(*sglist)); | ||
64 | sg_init_table(sglist, nr_pages); | 65 | sg_init_table(sglist, nr_pages); |
65 | for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) { | 66 | for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) { |
66 | pg = vmalloc_to_page(virt); | 67 | pg = vmalloc_to_page(virt); |
@@ -72,7 +73,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages) | |||
72 | return sglist; | 73 | return sglist; |
73 | 74 | ||
74 | err: | 75 | err: |
75 | kfree(sglist); | 76 | vfree(sglist); |
76 | return NULL; | 77 | return NULL; |
77 | } | 78 | } |
78 | 79 | ||
@@ -84,7 +85,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset) | |||
84 | 85 | ||
85 | if (NULL == pages[0]) | 86 | if (NULL == pages[0]) |
86 | return NULL; | 87 | return NULL; |
87 | sglist = kmalloc(nr_pages * sizeof(*sglist), GFP_KERNEL); | 88 | sglist = vmalloc(nr_pages * sizeof(*sglist)); |
88 | if (NULL == sglist) | 89 | if (NULL == sglist) |
89 | return NULL; | 90 | return NULL; |
90 | sg_init_table(sglist, nr_pages); | 91 | sg_init_table(sglist, nr_pages); |
@@ -104,12 +105,12 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset) | |||
104 | 105 | ||
105 | nopage: | 106 | nopage: |
106 | dprintk(2,"sgl: oops - no page\n"); | 107 | dprintk(2,"sgl: oops - no page\n"); |
107 | kfree(sglist); | 108 | vfree(sglist); |
108 | return NULL; | 109 | return NULL; |
109 | 110 | ||
110 | highmem: | 111 | highmem: |
111 | dprintk(2,"sgl: oops - highmem page\n"); | 112 | dprintk(2,"sgl: oops - highmem page\n"); |
112 | kfree(sglist); | 113 | vfree(sglist); |
113 | return NULL; | 114 | return NULL; |
114 | } | 115 | } |
115 | 116 | ||
@@ -230,7 +231,7 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma) | |||
230 | (dma->vmalloc,dma->nr_pages); | 231 | (dma->vmalloc,dma->nr_pages); |
231 | } | 232 | } |
232 | if (dma->bus_addr) { | 233 | if (dma->bus_addr) { |
233 | dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL); | 234 | dma->sglist = vmalloc(sizeof(*dma->sglist)); |
234 | if (NULL != dma->sglist) { | 235 | if (NULL != dma->sglist) { |
235 | dma->sglen = 1; | 236 | dma->sglen = 1; |
236 | sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK; | 237 | sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK; |
@@ -248,10 +249,10 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma) | |||
248 | if (0 == dma->sglen) { | 249 | if (0 == dma->sglen) { |
249 | printk(KERN_WARNING | 250 | printk(KERN_WARNING |
250 | "%s: videobuf_map_sg failed\n",__func__); | 251 | "%s: videobuf_map_sg failed\n",__func__); |
251 | kfree(dma->sglist); | 252 | vfree(dma->sglist); |
252 | dma->sglist = NULL; | 253 | dma->sglist = NULL; |
253 | dma->sglen = 0; | 254 | dma->sglen = 0; |
254 | return -EIO; | 255 | return -ENOMEM; |
255 | } | 256 | } |
256 | } | 257 | } |
257 | return 0; | 258 | return 0; |
@@ -274,7 +275,7 @@ int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma) | |||
274 | 275 | ||
275 | dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction); | 276 | dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction); |
276 | 277 | ||
277 | kfree(dma->sglist); | 278 | vfree(dma->sglist); |
278 | dma->sglist = NULL; | 279 | dma->sglist = NULL; |
279 | dma->sglen = 0; | 280 | dma->sglen = 0; |
280 | return 0; | 281 | return 0; |
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 43e0998adb53..97b082fe4473 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -868,9 +868,9 @@ static void vino_sync_buffer(struct vino_framebuffer *fb) | |||
868 | dprintk("vino_sync_buffer():\n"); | 868 | dprintk("vino_sync_buffer():\n"); |
869 | 869 | ||
870 | for (i = 0; i < fb->desc_table.page_count; i++) | 870 | for (i = 0; i < fb->desc_table.page_count; i++) |
871 | dma_sync_single(NULL, | 871 | dma_sync_single_for_cpu(NULL, |
872 | fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], | 872 | fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], |
873 | PAGE_SIZE, DMA_FROM_DEVICE); | 873 | PAGE_SIZE, DMA_FROM_DEVICE); |
874 | } | 874 | } |
875 | 875 | ||
876 | /* Framebuffer fifo functions (need to be locked externally) */ | 876 | /* Framebuffer fifo functions (need to be locked externally) */ |
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index ea6c577b0eb3..03dc2f3cf84a 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c | |||
@@ -1022,7 +1022,7 @@ zr36057_init (struct zoran *zr) | |||
1022 | zr->vbuf_bytesperline = 0; | 1022 | zr->vbuf_bytesperline = 0; |
1023 | 1023 | ||
1024 | /* Avoid nonsense settings from user for default input/norm */ | 1024 | /* Avoid nonsense settings from user for default input/norm */ |
1025 | if (default_norm < 0 && default_norm > 2) | 1025 | if (default_norm < 0 || default_norm > 2) |
1026 | default_norm = 0; | 1026 | default_norm = 0; |
1027 | if (default_norm == 0) { | 1027 | if (default_norm == 0) { |
1028 | zr->norm = V4L2_STD_PAL; | 1028 | zr->norm = V4L2_STD_PAL; |
@@ -1477,7 +1477,7 @@ static struct pci_driver zoran_driver = { | |||
1477 | .name = "zr36067", | 1477 | .name = "zr36067", |
1478 | .id_table = zr36067_pci_tbl, | 1478 | .id_table = zr36067_pci_tbl, |
1479 | .probe = zoran_probe, | 1479 | .probe = zoran_probe, |
1480 | .remove = zoran_remove, | 1480 | .remove = __devexit_p(zoran_remove), |
1481 | }; | 1481 | }; |
1482 | 1482 | ||
1483 | static int __init zoran_init(void) | 1483 | static int __init zoran_init(void) |
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index ac169c9eb18d..fc976f42f432 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c | |||
@@ -882,9 +882,11 @@ static void zr364xx_disconnect(struct usb_interface *intf) | |||
882 | video_unregister_device(cam->vdev); | 882 | video_unregister_device(cam->vdev); |
883 | cam->vdev = NULL; | 883 | cam->vdev = NULL; |
884 | kfree(cam->buffer); | 884 | kfree(cam->buffer); |
885 | if (cam->framebuf) | 885 | cam->buffer = NULL; |
886 | vfree(cam->framebuf); | 886 | vfree(cam->framebuf); |
887 | cam->framebuf = NULL; | ||
887 | kfree(cam); | 888 | kfree(cam); |
889 | cam = NULL; | ||
888 | } | 890 | } |
889 | 891 | ||
890 | 892 | ||