diff options
Diffstat (limited to 'drivers/media')
47 files changed, 683 insertions, 619 deletions
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 27555995f7e4..b5ee3ebfcfca 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
@@ -24,6 +24,21 @@ | |||
24 | #include <linux/dvb/frontend.h> | 24 | #include <linux/dvb/frontend.h> |
25 | #include "dvb_frontend.h" | 25 | #include "dvb_frontend.h" |
26 | 26 | ||
27 | /* Registers (Write-only) */ | ||
28 | #define XREG_INIT 0x00 | ||
29 | #define XREG_RF_FREQ 0x02 | ||
30 | #define XREG_POWER_DOWN 0x08 | ||
31 | |||
32 | /* Registers (Read-only) */ | ||
33 | #define XREG_FREQ_ERROR 0x01 | ||
34 | #define XREG_LOCK 0x02 | ||
35 | #define XREG_VERSION 0x04 | ||
36 | #define XREG_PRODUCT_ID 0x08 | ||
37 | #define XREG_HSYNC_FREQ 0x10 | ||
38 | #define XREG_FRAME_LINES 0x20 | ||
39 | #define XREG_SNR 0x40 | ||
40 | |||
41 | #define XREG_ADC_ENV 0x0100 | ||
27 | 42 | ||
28 | static int debug; | 43 | static int debug; |
29 | module_param(debug, int, 0644); | 44 | module_param(debug, int, 0644); |
@@ -885,7 +900,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) | |||
885 | mutex_lock(&priv->lock); | 900 | mutex_lock(&priv->lock); |
886 | 901 | ||
887 | /* Sync Lock Indicator */ | 902 | /* Sync Lock Indicator */ |
888 | rc = xc2028_get_reg(priv, 0x0002, &frq_lock); | 903 | rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock); |
889 | if (rc < 0) | 904 | if (rc < 0) |
890 | goto ret; | 905 | goto ret; |
891 | 906 | ||
@@ -894,7 +909,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) | |||
894 | signal = 1 << 11; | 909 | signal = 1 << 11; |
895 | 910 | ||
896 | /* Get SNR of the video signal */ | 911 | /* Get SNR of the video signal */ |
897 | rc = xc2028_get_reg(priv, 0x0040, &signal); | 912 | rc = xc2028_get_reg(priv, XREG_SNR, &signal); |
898 | if (rc < 0) | 913 | if (rc < 0) |
899 | goto ret; | 914 | goto ret; |
900 | 915 | ||
@@ -1019,9 +1034,9 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | |||
1019 | 1034 | ||
1020 | /* CMD= Set frequency */ | 1035 | /* CMD= Set frequency */ |
1021 | if (priv->firm_version < 0x0202) | 1036 | if (priv->firm_version < 0x0202) |
1022 | rc = send_seq(priv, {0x00, 0x02, 0x00, 0x00}); | 1037 | rc = send_seq(priv, {0x00, XREG_RF_FREQ, 0x00, 0x00}); |
1023 | else | 1038 | else |
1024 | rc = send_seq(priv, {0x80, 0x02, 0x00, 0x00}); | 1039 | rc = send_seq(priv, {0x80, XREG_RF_FREQ, 0x00, 0x00}); |
1025 | if (rc < 0) | 1040 | if (rc < 0) |
1026 | goto ret; | 1041 | goto ret; |
1027 | 1042 | ||
@@ -1201,9 +1216,9 @@ static int xc2028_sleep(struct dvb_frontend *fe) | |||
1201 | mutex_lock(&priv->lock); | 1216 | mutex_lock(&priv->lock); |
1202 | 1217 | ||
1203 | if (priv->firm_version < 0x0202) | 1218 | if (priv->firm_version < 0x0202) |
1204 | rc = send_seq(priv, {0x00, 0x08, 0x00, 0x00}); | 1219 | rc = send_seq(priv, {0x00, XREG_POWER_DOWN, 0x00, 0x00}); |
1205 | else | 1220 | else |
1206 | rc = send_seq(priv, {0x80, 0x08, 0x00, 0x00}); | 1221 | rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00}); |
1207 | 1222 | ||
1208 | priv->cur_fw.type = 0; /* need firmware reload */ | 1223 | priv->cur_fw.type = 0; /* need firmware reload */ |
1209 | 1224 | ||
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c index d218c1d68c33..68397110b7d9 100644 --- a/drivers/media/common/tuners/xc4000.c +++ b/drivers/media/common/tuners/xc4000.c | |||
@@ -154,6 +154,8 @@ struct xc4000_priv { | |||
154 | #define XREG_SNR 0x06 | 154 | #define XREG_SNR 0x06 |
155 | #define XREG_VERSION 0x07 | 155 | #define XREG_VERSION 0x07 |
156 | #define XREG_PRODUCT_ID 0x08 | 156 | #define XREG_PRODUCT_ID 0x08 |
157 | #define XREG_SIGNAL_LEVEL 0x0A | ||
158 | #define XREG_NOISE_LEVEL 0x0B | ||
157 | 159 | ||
158 | /* | 160 | /* |
159 | Basic firmware description. This will remain with | 161 | Basic firmware description. This will remain with |
@@ -486,6 +488,16 @@ static int xc_get_quality(struct xc4000_priv *priv, u16 *quality) | |||
486 | return xc4000_readreg(priv, XREG_QUALITY, quality); | 488 | return xc4000_readreg(priv, XREG_QUALITY, quality); |
487 | } | 489 | } |
488 | 490 | ||
491 | static int xc_get_signal_level(struct xc4000_priv *priv, u16 *signal) | ||
492 | { | ||
493 | return xc4000_readreg(priv, XREG_SIGNAL_LEVEL, signal); | ||
494 | } | ||
495 | |||
496 | static int xc_get_noise_level(struct xc4000_priv *priv, u16 *noise) | ||
497 | { | ||
498 | return xc4000_readreg(priv, XREG_NOISE_LEVEL, noise); | ||
499 | } | ||
500 | |||
489 | static u16 xc_wait_for_lock(struct xc4000_priv *priv) | 501 | static u16 xc_wait_for_lock(struct xc4000_priv *priv) |
490 | { | 502 | { |
491 | u16 lock_state = 0; | 503 | u16 lock_state = 0; |
@@ -1089,6 +1101,8 @@ static void xc_debug_dump(struct xc4000_priv *priv) | |||
1089 | u32 hsync_freq_hz = 0; | 1101 | u32 hsync_freq_hz = 0; |
1090 | u16 frame_lines; | 1102 | u16 frame_lines; |
1091 | u16 quality; | 1103 | u16 quality; |
1104 | u16 signal = 0; | ||
1105 | u16 noise = 0; | ||
1092 | u8 hw_majorversion = 0, hw_minorversion = 0; | 1106 | u8 hw_majorversion = 0, hw_minorversion = 0; |
1093 | u8 fw_majorversion = 0, fw_minorversion = 0; | 1107 | u8 fw_majorversion = 0, fw_minorversion = 0; |
1094 | 1108 | ||
@@ -1119,6 +1133,12 @@ static void xc_debug_dump(struct xc4000_priv *priv) | |||
1119 | 1133 | ||
1120 | xc_get_quality(priv, &quality); | 1134 | xc_get_quality(priv, &quality); |
1121 | dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality); | 1135 | dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality); |
1136 | |||
1137 | xc_get_signal_level(priv, &signal); | ||
1138 | dprintk(1, "*** Signal level = -%ddB (%d)\n", signal >> 8, signal); | ||
1139 | |||
1140 | xc_get_noise_level(priv, &noise); | ||
1141 | dprintk(1, "*** Noise level = %ddB (%d)\n", noise >> 8, noise); | ||
1122 | } | 1142 | } |
1123 | 1143 | ||
1124 | static int xc4000_set_params(struct dvb_frontend *fe) | 1144 | static int xc4000_set_params(struct dvb_frontend *fe) |
@@ -1432,6 +1452,71 @@ fail: | |||
1432 | return ret; | 1452 | return ret; |
1433 | } | 1453 | } |
1434 | 1454 | ||
1455 | static int xc4000_get_signal(struct dvb_frontend *fe, u16 *strength) | ||
1456 | { | ||
1457 | struct xc4000_priv *priv = fe->tuner_priv; | ||
1458 | u16 value = 0; | ||
1459 | int rc; | ||
1460 | |||
1461 | mutex_lock(&priv->lock); | ||
1462 | rc = xc4000_readreg(priv, XREG_SIGNAL_LEVEL, &value); | ||
1463 | mutex_unlock(&priv->lock); | ||
1464 | |||
1465 | if (rc < 0) | ||
1466 | goto ret; | ||
1467 | |||
1468 | /* Informations from real testing of DVB-T and radio part, | ||
1469 | coeficient for one dB is 0xff. | ||
1470 | */ | ||
1471 | tuner_dbg("Signal strength: -%ddB (%05d)\n", value >> 8, value); | ||
1472 | |||
1473 | /* all known digital modes */ | ||
1474 | if ((priv->video_standard == XC4000_DTV6) || | ||
1475 | (priv->video_standard == XC4000_DTV7) || | ||
1476 | (priv->video_standard == XC4000_DTV7_8) || | ||
1477 | (priv->video_standard == XC4000_DTV8)) | ||
1478 | goto digital; | ||
1479 | |||
1480 | /* Analog mode has NOISE LEVEL important, signal | ||
1481 | depends only on gain of antenna and amplifiers, | ||
1482 | but it doesn't tell anything about real quality | ||
1483 | of reception. | ||
1484 | */ | ||
1485 | mutex_lock(&priv->lock); | ||
1486 | rc = xc4000_readreg(priv, XREG_NOISE_LEVEL, &value); | ||
1487 | mutex_unlock(&priv->lock); | ||
1488 | |||
1489 | tuner_dbg("Noise level: %ddB (%05d)\n", value >> 8, value); | ||
1490 | |||
1491 | /* highest noise level: 32dB */ | ||
1492 | if (value >= 0x2000) { | ||
1493 | value = 0; | ||
1494 | } else { | ||
1495 | value = ~value << 3; | ||
1496 | } | ||
1497 | |||
1498 | goto ret; | ||
1499 | |||
1500 | /* Digital mode has SIGNAL LEVEL important and real | ||
1501 | noise level is stored in demodulator registers. | ||
1502 | */ | ||
1503 | digital: | ||
1504 | /* best signal: -50dB */ | ||
1505 | if (value <= 0x3200) { | ||
1506 | value = 0xffff; | ||
1507 | /* minimum: -114dB - should be 0x7200 but real zero is 0x713A */ | ||
1508 | } else if (value >= 0x713A) { | ||
1509 | value = 0; | ||
1510 | } else { | ||
1511 | value = ~(value - 0x3200) << 2; | ||
1512 | } | ||
1513 | |||
1514 | ret: | ||
1515 | *strength = value; | ||
1516 | |||
1517 | return rc; | ||
1518 | } | ||
1519 | |||
1435 | static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq) | 1520 | static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq) |
1436 | { | 1521 | { |
1437 | struct xc4000_priv *priv = fe->tuner_priv; | 1522 | struct xc4000_priv *priv = fe->tuner_priv; |
@@ -1559,6 +1644,7 @@ static const struct dvb_tuner_ops xc4000_tuner_ops = { | |||
1559 | .set_params = xc4000_set_params, | 1644 | .set_params = xc4000_set_params, |
1560 | .set_analog_params = xc4000_set_analog_params, | 1645 | .set_analog_params = xc4000_set_analog_params, |
1561 | .get_frequency = xc4000_get_frequency, | 1646 | .get_frequency = xc4000_get_frequency, |
1647 | .get_rf_strength = xc4000_get_signal, | ||
1562 | .get_bandwidth = xc4000_get_bandwidth, | 1648 | .get_bandwidth = xc4000_get_bandwidth, |
1563 | .get_status = xc4000_get_status | 1649 | .get_status = xc4000_get_status |
1564 | }; | 1650 | }; |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index b15db4fe347b..fbbe545a74cb 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -904,8 +904,11 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) | |||
904 | { | 904 | { |
905 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 905 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
906 | int i; | 906 | int i; |
907 | u32 delsys; | ||
907 | 908 | ||
909 | delsys = c->delivery_system; | ||
908 | memset(c, 0, sizeof(struct dtv_frontend_properties)); | 910 | memset(c, 0, sizeof(struct dtv_frontend_properties)); |
911 | c->delivery_system = delsys; | ||
909 | 912 | ||
910 | c->state = DTV_CLEAR; | 913 | c->state = DTV_CLEAR; |
911 | 914 | ||
@@ -1009,25 +1012,6 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { | |||
1009 | _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0), | 1012 | _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0), |
1010 | _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0), | 1013 | _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0), |
1011 | 1014 | ||
1012 | _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0), | ||
1013 | _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0), | ||
1014 | _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0), | ||
1015 | _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0), | ||
1016 | _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0), | ||
1017 | _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 0, 0), | ||
1018 | _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0), | ||
1019 | _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0), | ||
1020 | _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0), | ||
1021 | _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0), | ||
1022 | _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0), | ||
1023 | _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0), | ||
1024 | _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0), | ||
1025 | _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0), | ||
1026 | _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0), | ||
1027 | _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0), | ||
1028 | _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0), | ||
1029 | _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0), | ||
1030 | |||
1031 | _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0), | 1015 | _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0), |
1032 | _DTV_CMD(DTV_DVBT2_PLP_ID, 1, 0), | 1016 | _DTV_CMD(DTV_DVBT2_PLP_ID, 1, 0), |
1033 | 1017 | ||
@@ -1413,6 +1397,15 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) | |||
1413 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 1397 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
1414 | enum dvbv3_emulation_type type; | 1398 | enum dvbv3_emulation_type type; |
1415 | 1399 | ||
1400 | /* | ||
1401 | * It was reported that some old DVBv5 applications were | ||
1402 | * filling delivery_system with SYS_UNDEFINED. If this happens, | ||
1403 | * assume that the application wants to use the first supported | ||
1404 | * delivery system. | ||
1405 | */ | ||
1406 | if (c->delivery_system == SYS_UNDEFINED) | ||
1407 | c->delivery_system = fe->ops.delsys[0]; | ||
1408 | |||
1416 | if (desired_system == SYS_UNDEFINED) { | 1409 | if (desired_system == SYS_UNDEFINED) { |
1417 | /* | 1410 | /* |
1418 | * A DVBv3 call doesn't know what's the desired system. | 1411 | * A DVBv3 call doesn't know what's the desired system. |
@@ -1732,6 +1725,7 @@ static int dvb_frontend_ioctl_properties(struct file *file, | |||
1732 | { | 1725 | { |
1733 | struct dvb_device *dvbdev = file->private_data; | 1726 | struct dvb_device *dvbdev = file->private_data; |
1734 | struct dvb_frontend *fe = dvbdev->priv; | 1727 | struct dvb_frontend *fe = dvbdev->priv; |
1728 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | ||
1735 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 1729 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
1736 | int err = 0; | 1730 | int err = 0; |
1737 | 1731 | ||
@@ -1798,9 +1792,14 @@ static int dvb_frontend_ioctl_properties(struct file *file, | |||
1798 | 1792 | ||
1799 | /* | 1793 | /* |
1800 | * Fills the cache out struct with the cache contents, plus | 1794 | * Fills the cache out struct with the cache contents, plus |
1801 | * the data retrieved from get_frontend. | 1795 | * the data retrieved from get_frontend, if the frontend |
1796 | * is not idle. Otherwise, returns the cached content | ||
1802 | */ | 1797 | */ |
1803 | dtv_get_frontend(fe, NULL); | 1798 | if (fepriv->state != FESTATE_IDLE) { |
1799 | err = dtv_get_frontend(fe, NULL); | ||
1800 | if (err < 0) | ||
1801 | goto out; | ||
1802 | } | ||
1804 | for (i = 0; i < tvps->num; i++) { | 1803 | for (i = 0; i < tvps->num; i++) { |
1805 | err = dtv_property_process_get(fe, c, tvp + i, file); | 1804 | err = dtv_property_process_get(fe, c, tvp + i, file); |
1806 | if (err < 0) | 1805 | if (err < 0) |
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index d66192974d68..1455e2644ab5 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c | |||
@@ -877,24 +877,18 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
877 | case ANYSEE_HW_508T2C: /* 20 */ | 877 | case ANYSEE_HW_508T2C: /* 20 */ |
878 | /* E7 T2C */ | 878 | /* E7 T2C */ |
879 | 879 | ||
880 | if (state->fe_id) | ||
881 | break; | ||
882 | |||
880 | /* enable DVB-T/T2/C demod on IOE[5] */ | 883 | /* enable DVB-T/T2/C demod on IOE[5] */ |
881 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); | 884 | ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); |
882 | if (ret) | 885 | if (ret) |
883 | goto error; | 886 | goto error; |
884 | 887 | ||
885 | if (state->fe_id == 0) { | 888 | /* attach demod */ |
886 | /* DVB-T/T2 */ | 889 | adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach, |
887 | adap->fe_adap[state->fe_id].fe = | 890 | &anysee_cxd2820r_config, &adap->dev->i2c_adap, |
888 | dvb_attach(cxd2820r_attach, | 891 | NULL); |
889 | &anysee_cxd2820r_config, | ||
890 | &adap->dev->i2c_adap, NULL); | ||
891 | } else { | ||
892 | /* DVB-C */ | ||
893 | adap->fe_adap[state->fe_id].fe = | ||
894 | dvb_attach(cxd2820r_attach, | ||
895 | &anysee_cxd2820r_config, | ||
896 | &adap->dev->i2c_adap, adap->fe_adap[0].fe); | ||
897 | } | ||
898 | 892 | ||
899 | state->has_ci = true; | 893 | state->has_ci = true; |
900 | 894 | ||
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index 9bd6d51b3b93..7de125c0b36f 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h | |||
@@ -48,6 +48,8 @@ struct dib0700_state { | |||
48 | u8 disable_streaming_master_mode; | 48 | u8 disable_streaming_master_mode; |
49 | u32 fw_version; | 49 | u32 fw_version; |
50 | u32 nb_packet_buffer_size; | 50 | u32 nb_packet_buffer_size; |
51 | int (*read_status)(struct dvb_frontend *, fe_status_t *); | ||
52 | int (*sleep)(struct dvb_frontend* fe); | ||
51 | u8 buf[255]; | 53 | u8 buf[255]; |
52 | }; | 54 | }; |
53 | 55 | ||
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index 206999476f02..070e82aa53f5 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c | |||
@@ -834,6 +834,7 @@ static struct usb_driver dib0700_driver = { | |||
834 | 834 | ||
835 | module_usb_driver(dib0700_driver); | 835 | module_usb_driver(dib0700_driver); |
836 | 836 | ||
837 | MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw"); | ||
837 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); | 838 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); |
838 | MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge"); | 839 | MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge"); |
839 | MODULE_VERSION("1.0"); | 840 | MODULE_VERSION("1.0"); |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 81ef4b46f790..f9e966aa26e7 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
@@ -3066,19 +3066,25 @@ static struct dib7000p_config stk7070pd_dib7000p_config[2] = { | |||
3066 | } | 3066 | } |
3067 | }; | 3067 | }; |
3068 | 3068 | ||
3069 | static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) | 3069 | static void stk7070pd_init(struct dvb_usb_device *dev) |
3070 | { | 3070 | { |
3071 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | 3071 | dib0700_set_gpio(dev, GPIO6, GPIO_OUT, 1); |
3072 | msleep(10); | 3072 | msleep(10); |
3073 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | 3073 | dib0700_set_gpio(dev, GPIO9, GPIO_OUT, 1); |
3074 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | 3074 | dib0700_set_gpio(dev, GPIO4, GPIO_OUT, 1); |
3075 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | 3075 | dib0700_set_gpio(dev, GPIO7, GPIO_OUT, 1); |
3076 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | 3076 | dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 0); |
3077 | 3077 | ||
3078 | dib0700_ctrl_clock(adap->dev, 72, 1); | 3078 | dib0700_ctrl_clock(dev, 72, 1); |
3079 | 3079 | ||
3080 | msleep(10); | 3080 | msleep(10); |
3081 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | 3081 | dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 1); |
3082 | } | ||
3083 | |||
3084 | static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) | ||
3085 | { | ||
3086 | stk7070pd_init(adap->dev); | ||
3087 | |||
3082 | msleep(10); | 3088 | msleep(10); |
3083 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | 3089 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); |
3084 | 3090 | ||
@@ -3099,6 +3105,77 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap) | |||
3099 | return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; | 3105 | return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; |
3100 | } | 3106 | } |
3101 | 3107 | ||
3108 | static int novatd_read_status_override(struct dvb_frontend *fe, | ||
3109 | fe_status_t *stat) | ||
3110 | { | ||
3111 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
3112 | struct dvb_usb_device *dev = adap->dev; | ||
3113 | struct dib0700_state *state = dev->priv; | ||
3114 | int ret; | ||
3115 | |||
3116 | ret = state->read_status(fe, stat); | ||
3117 | |||
3118 | if (!ret) | ||
3119 | dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, | ||
3120 | !!(*stat & FE_HAS_LOCK)); | ||
3121 | |||
3122 | return ret; | ||
3123 | } | ||
3124 | |||
3125 | static int novatd_sleep_override(struct dvb_frontend* fe) | ||
3126 | { | ||
3127 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
3128 | struct dvb_usb_device *dev = adap->dev; | ||
3129 | struct dib0700_state *state = dev->priv; | ||
3130 | |||
3131 | /* turn off LED */ | ||
3132 | dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, 0); | ||
3133 | |||
3134 | return state->sleep(fe); | ||
3135 | } | ||
3136 | |||
3137 | /** | ||
3138 | * novatd_frontend_attach - Nova-TD specific attach | ||
3139 | * | ||
3140 | * Nova-TD has GPIO0, 1 and 2 for LEDs. So do not fiddle with them except for | ||
3141 | * information purposes. | ||
3142 | */ | ||
3143 | static int novatd_frontend_attach(struct dvb_usb_adapter *adap) | ||
3144 | { | ||
3145 | struct dvb_usb_device *dev = adap->dev; | ||
3146 | struct dib0700_state *st = dev->priv; | ||
3147 | |||
3148 | if (adap->id == 0) { | ||
3149 | stk7070pd_init(dev); | ||
3150 | |||
3151 | /* turn the power LED on, the other two off (just in case) */ | ||
3152 | dib0700_set_gpio(dev, GPIO0, GPIO_OUT, 0); | ||
3153 | dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0); | ||
3154 | dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1); | ||
3155 | |||
3156 | if (dib7000p_i2c_enumeration(&dev->i2c_adap, 2, 18, | ||
3157 | stk7070pd_dib7000p_config) != 0) { | ||
3158 | err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", | ||
3159 | __func__); | ||
3160 | return -ENODEV; | ||
3161 | } | ||
3162 | } | ||
3163 | |||
3164 | adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap, | ||
3165 | adap->id == 0 ? 0x80 : 0x82, | ||
3166 | &stk7070pd_dib7000p_config[adap->id]); | ||
3167 | |||
3168 | if (adap->fe_adap[0].fe == NULL) | ||
3169 | return -ENODEV; | ||
3170 | |||
3171 | st->read_status = adap->fe_adap[0].fe->ops.read_status; | ||
3172 | adap->fe_adap[0].fe->ops.read_status = novatd_read_status_override; | ||
3173 | st->sleep = adap->fe_adap[0].fe->ops.sleep; | ||
3174 | adap->fe_adap[0].fe->ops.sleep = novatd_sleep_override; | ||
3175 | |||
3176 | return 0; | ||
3177 | } | ||
3178 | |||
3102 | /* S5H1411 */ | 3179 | /* S5H1411 */ |
3103 | static struct s5h1411_config pinnacle_801e_config = { | 3180 | static struct s5h1411_config pinnacle_801e_config = { |
3104 | .output_mode = S5H1411_PARALLEL_OUTPUT, | 3181 | .output_mode = S5H1411_PARALLEL_OUTPUT, |
@@ -3870,6 +3947,57 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
3870 | .pid_filter_count = 32, | 3947 | .pid_filter_count = 32, |
3871 | .pid_filter = stk70x0p_pid_filter, | 3948 | .pid_filter = stk70x0p_pid_filter, |
3872 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | 3949 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, |
3950 | .frontend_attach = novatd_frontend_attach, | ||
3951 | .tuner_attach = dib7070p_tuner_attach, | ||
3952 | |||
3953 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | ||
3954 | }}, | ||
3955 | .size_of_priv = sizeof(struct dib0700_adapter_state), | ||
3956 | }, { | ||
3957 | .num_frontends = 1, | ||
3958 | .fe = {{ | ||
3959 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
3960 | .pid_filter_count = 32, | ||
3961 | .pid_filter = stk70x0p_pid_filter, | ||
3962 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | ||
3963 | .frontend_attach = novatd_frontend_attach, | ||
3964 | .tuner_attach = dib7070p_tuner_attach, | ||
3965 | |||
3966 | DIB0700_DEFAULT_STREAMING_CONFIG(0x03), | ||
3967 | }}, | ||
3968 | .size_of_priv = sizeof(struct dib0700_adapter_state), | ||
3969 | } | ||
3970 | }, | ||
3971 | |||
3972 | .num_device_descs = 1, | ||
3973 | .devices = { | ||
3974 | { "Hauppauge Nova-TD Stick (52009)", | ||
3975 | { &dib0700_usb_id_table[35], NULL }, | ||
3976 | { NULL }, | ||
3977 | }, | ||
3978 | }, | ||
3979 | |||
3980 | .rc.core = { | ||
3981 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
3982 | .rc_codes = RC_MAP_DIB0700_RC5_TABLE, | ||
3983 | .module_name = "dib0700", | ||
3984 | .rc_query = dib0700_rc_query_old_firmware, | ||
3985 | .allowed_protos = RC_TYPE_RC5 | | ||
3986 | RC_TYPE_RC6 | | ||
3987 | RC_TYPE_NEC, | ||
3988 | .change_protocol = dib0700_change_protocol, | ||
3989 | }, | ||
3990 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
3991 | |||
3992 | .num_adapters = 2, | ||
3993 | .adapter = { | ||
3994 | { | ||
3995 | .num_frontends = 1, | ||
3996 | .fe = {{ | ||
3997 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
3998 | .pid_filter_count = 32, | ||
3999 | .pid_filter = stk70x0p_pid_filter, | ||
4000 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | ||
3873 | .frontend_attach = stk7070pd_frontend_attach0, | 4001 | .frontend_attach = stk7070pd_frontend_attach0, |
3874 | .tuner_attach = dib7070p_tuner_attach, | 4002 | .tuner_attach = dib7070p_tuner_attach, |
3875 | 4003 | ||
@@ -3892,7 +4020,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
3892 | } | 4020 | } |
3893 | }, | 4021 | }, |
3894 | 4022 | ||
3895 | .num_device_descs = 6, | 4023 | .num_device_descs = 5, |
3896 | .devices = { | 4024 | .devices = { |
3897 | { "DiBcom STK7070PD reference design", | 4025 | { "DiBcom STK7070PD reference design", |
3898 | { &dib0700_usb_id_table[17], NULL }, | 4026 | { &dib0700_usb_id_table[17], NULL }, |
@@ -3902,10 +4030,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
3902 | { &dib0700_usb_id_table[18], NULL }, | 4030 | { &dib0700_usb_id_table[18], NULL }, |
3903 | { NULL }, | 4031 | { NULL }, |
3904 | }, | 4032 | }, |
3905 | { "Hauppauge Nova-TD Stick (52009)", | ||
3906 | { &dib0700_usb_id_table[35], NULL }, | ||
3907 | { NULL }, | ||
3908 | }, | ||
3909 | { "Hauppauge Nova-TD-500 (84xxx)", | 4033 | { "Hauppauge Nova-TD-500 (84xxx)", |
3910 | { &dib0700_usb_id_table[36], NULL }, | 4034 | { &dib0700_usb_id_table[36], NULL }, |
3911 | { NULL }, | 4035 | { NULL }, |
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c index 93e1b12e7907..caae7f79c837 100644 --- a/drivers/media/dvb/frontends/cxd2820r_core.c +++ b/drivers/media/dvb/frontends/cxd2820r_core.c | |||
@@ -309,9 +309,14 @@ static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
309 | 309 | ||
310 | static int cxd2820r_get_frontend(struct dvb_frontend *fe) | 310 | static int cxd2820r_get_frontend(struct dvb_frontend *fe) |
311 | { | 311 | { |
312 | struct cxd2820r_priv *priv = fe->demodulator_priv; | ||
312 | int ret; | 313 | int ret; |
313 | 314 | ||
314 | dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); | 315 | dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); |
316 | |||
317 | if (priv->delivery_system == SYS_UNDEFINED) | ||
318 | return 0; | ||
319 | |||
315 | switch (fe->dtv_property_cache.delivery_system) { | 320 | switch (fe->dtv_property_cache.delivery_system) { |
316 | case SYS_DVBT: | 321 | case SYS_DVBT: |
317 | ret = cxd2820r_get_frontend_t(fe); | 322 | ret = cxd2820r_get_frontend_t(fe); |
@@ -476,10 +481,10 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) | |||
476 | dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); | 481 | dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); |
477 | 482 | ||
478 | /* switch between DVB-T and DVB-T2 when tune fails */ | 483 | /* switch between DVB-T and DVB-T2 when tune fails */ |
479 | if (priv->last_tune_failed && (priv->delivery_system != SYS_DVBC_ANNEX_A)) { | 484 | if (priv->last_tune_failed) { |
480 | if (priv->delivery_system == SYS_DVBT) | 485 | if (priv->delivery_system == SYS_DVBT) |
481 | c->delivery_system = SYS_DVBT2; | 486 | c->delivery_system = SYS_DVBT2; |
482 | else | 487 | else if (priv->delivery_system == SYS_DVBT2) |
483 | c->delivery_system = SYS_DVBT; | 488 | c->delivery_system = SYS_DVBT; |
484 | } | 489 | } |
485 | 490 | ||
@@ -492,6 +497,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) | |||
492 | /* frontend lock wait loop count */ | 497 | /* frontend lock wait loop count */ |
493 | switch (priv->delivery_system) { | 498 | switch (priv->delivery_system) { |
494 | case SYS_DVBT: | 499 | case SYS_DVBT: |
500 | case SYS_DVBC_ANNEX_A: | ||
495 | i = 20; | 501 | i = 20; |
496 | break; | 502 | break; |
497 | case SYS_DVBT2: | 503 | case SYS_DVBT2: |
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c index 938777065de6..af65d013db11 100644 --- a/drivers/media/dvb/frontends/ds3000.c +++ b/drivers/media/dvb/frontends/ds3000.c | |||
@@ -1195,7 +1195,7 @@ static int ds3000_set_frontend(struct dvb_frontend *fe) | |||
1195 | 1195 | ||
1196 | for (i = 0; i < 30 ; i++) { | 1196 | for (i = 0; i < 30 ; i++) { |
1197 | ds3000_read_status(fe, &status); | 1197 | ds3000_read_status(fe, &status); |
1198 | if (status && FE_HAS_LOCK) | 1198 | if (status & FE_HAS_LOCK) |
1199 | break; | 1199 | break; |
1200 | 1200 | ||
1201 | msleep(10); | 1201 | msleep(10); |
diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb/frontends/mb86a20s.c index 7fa3e472cdca..fade566927c3 100644 --- a/drivers/media/dvb/frontends/mb86a20s.c +++ b/drivers/media/dvb/frontends/mb86a20s.c | |||
@@ -402,7 +402,7 @@ static int mb86a20s_get_modulation(struct mb86a20s_state *state, | |||
402 | [2] = 0x8e, /* Layer C */ | 402 | [2] = 0x8e, /* Layer C */ |
403 | }; | 403 | }; |
404 | 404 | ||
405 | if (layer > ARRAY_SIZE(reg)) | 405 | if (layer >= ARRAY_SIZE(reg)) |
406 | return -EINVAL; | 406 | return -EINVAL; |
407 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); | 407 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); |
408 | if (rc < 0) | 408 | if (rc < 0) |
@@ -435,7 +435,7 @@ static int mb86a20s_get_fec(struct mb86a20s_state *state, | |||
435 | [2] = 0x8f, /* Layer C */ | 435 | [2] = 0x8f, /* Layer C */ |
436 | }; | 436 | }; |
437 | 437 | ||
438 | if (layer > ARRAY_SIZE(reg)) | 438 | if (layer >= ARRAY_SIZE(reg)) |
439 | return -EINVAL; | 439 | return -EINVAL; |
440 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); | 440 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); |
441 | if (rc < 0) | 441 | if (rc < 0) |
@@ -470,7 +470,7 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state, | |||
470 | [2] = 0x90, /* Layer C */ | 470 | [2] = 0x90, /* Layer C */ |
471 | }; | 471 | }; |
472 | 472 | ||
473 | if (layer > ARRAY_SIZE(reg)) | 473 | if (layer >= ARRAY_SIZE(reg)) |
474 | return -EINVAL; | 474 | return -EINVAL; |
475 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); | 475 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); |
476 | if (rc < 0) | 476 | if (rc < 0) |
@@ -494,7 +494,7 @@ static int mb86a20s_get_segment_count(struct mb86a20s_state *state, | |||
494 | [2] = 0x91, /* Layer C */ | 494 | [2] = 0x91, /* Layer C */ |
495 | }; | 495 | }; |
496 | 496 | ||
497 | if (layer > ARRAY_SIZE(reg)) | 497 | if (layer >= ARRAY_SIZE(reg)) |
498 | return -EINVAL; | 498 | return -EINVAL; |
499 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); | 499 | rc = mb86a20s_writereg(state, 0x6d, reg[layer]); |
500 | if (rc < 0) | 500 | if (rc < 0) |
diff --git a/drivers/media/dvb/frontends/tda18271c2dd.c b/drivers/media/dvb/frontends/tda18271c2dd.c index 86da3d816498..ad7c72e8f517 100644 --- a/drivers/media/dvb/frontends/tda18271c2dd.c +++ b/drivers/media/dvb/frontends/tda18271c2dd.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/firmware.h> | 30 | #include <linux/firmware.h> |
31 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
32 | #include <linux/version.h> | ||
33 | #include <asm/div64.h> | 32 | #include <asm/div64.h> |
34 | 33 | ||
35 | #include "dvb_frontend.h" | 34 | #include "dvb_frontend.h" |
diff --git a/drivers/media/video/as3645a.c b/drivers/media/video/as3645a.c index ec859a580651..f241702a0f36 100644 --- a/drivers/media/video/as3645a.c +++ b/drivers/media/video/as3645a.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
32 | #include <linux/slab.h> | ||
32 | 33 | ||
33 | #include <media/as3645a.h> | 34 | #include <media/as3645a.h> |
34 | #include <media/v4l2-ctrls.h> | 35 | #include <media/v4l2-ctrls.h> |
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 14cb961c22bd..4bfd865a4106 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
@@ -751,20 +751,10 @@ int cx18_v4l2_close(struct file *filp) | |||
751 | 751 | ||
752 | CX18_DEBUG_IOCTL("close() of %s\n", s->name); | 752 | CX18_DEBUG_IOCTL("close() of %s\n", s->name); |
753 | 753 | ||
754 | v4l2_fh_del(fh); | ||
755 | v4l2_fh_exit(fh); | ||
756 | |||
757 | /* Easy case first: this stream was never claimed by us */ | ||
758 | if (s->id != id->open_id) { | ||
759 | kfree(id); | ||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | /* 'Unclaim' this stream */ | ||
764 | |||
765 | /* Stop radio */ | ||
766 | mutex_lock(&cx->serialize_lock); | 754 | mutex_lock(&cx->serialize_lock); |
767 | if (id->type == CX18_ENC_STREAM_TYPE_RAD) { | 755 | /* Stop radio */ |
756 | if (id->type == CX18_ENC_STREAM_TYPE_RAD && | ||
757 | v4l2_fh_is_singular_file(filp)) { | ||
768 | /* Closing radio device, return to TV mode */ | 758 | /* Closing radio device, return to TV mode */ |
769 | cx18_mute(cx); | 759 | cx18_mute(cx); |
770 | /* Mark that the radio is no longer in use */ | 760 | /* Mark that the radio is no longer in use */ |
@@ -781,10 +771,14 @@ int cx18_v4l2_close(struct file *filp) | |||
781 | } | 771 | } |
782 | /* Done! Unmute and continue. */ | 772 | /* Done! Unmute and continue. */ |
783 | cx18_unmute(cx); | 773 | cx18_unmute(cx); |
784 | cx18_release_stream(s); | ||
785 | } else { | ||
786 | cx18_stop_capture(id, 0); | ||
787 | } | 774 | } |
775 | |||
776 | v4l2_fh_del(fh); | ||
777 | v4l2_fh_exit(fh); | ||
778 | |||
779 | /* 'Unclaim' this stream */ | ||
780 | if (s->id == id->open_id) | ||
781 | cx18_stop_capture(id, 0); | ||
788 | kfree(id); | 782 | kfree(id); |
789 | mutex_unlock(&cx->serialize_lock); | 783 | mutex_unlock(&cx->serialize_lock); |
790 | return 0; | 784 | return 0; |
@@ -810,21 +804,15 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) | |||
810 | 804 | ||
811 | item->open_id = cx->open_id++; | 805 | item->open_id = cx->open_id++; |
812 | filp->private_data = &item->fh; | 806 | filp->private_data = &item->fh; |
807 | v4l2_fh_add(&item->fh); | ||
813 | 808 | ||
814 | if (item->type == CX18_ENC_STREAM_TYPE_RAD) { | 809 | if (item->type == CX18_ENC_STREAM_TYPE_RAD && |
815 | /* Try to claim this stream */ | 810 | v4l2_fh_is_singular_file(filp)) { |
816 | if (cx18_claim_stream(item, item->type)) { | ||
817 | /* No, it's already in use */ | ||
818 | v4l2_fh_exit(&item->fh); | ||
819 | kfree(item); | ||
820 | return -EBUSY; | ||
821 | } | ||
822 | |||
823 | if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { | 811 | if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { |
824 | if (atomic_read(&cx->ana_capturing) > 0) { | 812 | if (atomic_read(&cx->ana_capturing) > 0) { |
825 | /* switching to radio while capture is | 813 | /* switching to radio while capture is |
826 | in progress is not polite */ | 814 | in progress is not polite */ |
827 | cx18_release_stream(s); | 815 | v4l2_fh_del(&item->fh); |
828 | v4l2_fh_exit(&item->fh); | 816 | v4l2_fh_exit(&item->fh); |
829 | kfree(item); | 817 | kfree(item); |
830 | return -EBUSY; | 818 | return -EBUSY; |
@@ -842,7 +830,6 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) | |||
842 | /* Done! Unmute and continue. */ | 830 | /* Done! Unmute and continue. */ |
843 | cx18_unmute(cx); | 831 | cx18_unmute(cx); |
844 | } | 832 | } |
845 | v4l2_fh_add(&item->fh); | ||
846 | return 0; | 833 | return 0; |
847 | } | 834 | } |
848 | 835 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 919ed77b32f2..875a7ce94736 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c | |||
@@ -1052,7 +1052,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1052 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1052 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
1053 | if (dev == NULL) { | 1053 | if (dev == NULL) { |
1054 | cx231xx_err(DRIVER_NAME ": out of memory!\n"); | 1054 | cx231xx_err(DRIVER_NAME ": out of memory!\n"); |
1055 | clear_bit(dev->devno, &cx231xx_devused); | 1055 | clear_bit(nr, &cx231xx_devused); |
1056 | return -ENOMEM; | 1056 | return -ENOMEM; |
1057 | } | 1057 | } |
1058 | 1058 | ||
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 3c01be999e35..19b5499d2624 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c | |||
@@ -213,8 +213,8 @@ struct cx23885_board cx23885_boards[] = { | |||
213 | .portc = CX23885_MPEG_DVB, | 213 | .portc = CX23885_MPEG_DVB, |
214 | .tuner_type = TUNER_XC4000, | 214 | .tuner_type = TUNER_XC4000, |
215 | .tuner_addr = 0x61, | 215 | .tuner_addr = 0x61, |
216 | .radio_type = TUNER_XC4000, | 216 | .radio_type = UNSET, |
217 | .radio_addr = 0x61, | 217 | .radio_addr = ADDR_UNSET, |
218 | .input = {{ | 218 | .input = {{ |
219 | .type = CX23885_VMUX_TELEVISION, | 219 | .type = CX23885_VMUX_TELEVISION, |
220 | .vmux = CX25840_VIN2_CH1 | | 220 | .vmux = CX25840_VIN2_CH1 | |
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index af8a225763d3..6835eb1fc093 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c | |||
@@ -943,6 +943,11 @@ static int dvb_register(struct cx23885_tsport *port) | |||
943 | 943 | ||
944 | fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, | 944 | fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, |
945 | &dev->i2c_bus[1].i2c_adap, &cfg); | 945 | &dev->i2c_bus[1].i2c_adap, &cfg); |
946 | if (!fe) { | ||
947 | printk(KERN_ERR "%s/2: xc4000 attach failed\n", | ||
948 | dev->name); | ||
949 | goto frontend_detach; | ||
950 | } | ||
946 | } | 951 | } |
947 | break; | 952 | break; |
948 | case CX23885_BOARD_TBS_6920: | 953 | case CX23885_BOARD_TBS_6920: |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 4bbf9bb97bde..c654bdc7ccb2 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -1550,7 +1550,6 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, | |||
1550 | struct v4l2_control ctrl; | 1550 | struct v4l2_control ctrl; |
1551 | struct videobuf_dvb_frontend *vfe; | 1551 | struct videobuf_dvb_frontend *vfe; |
1552 | struct dvb_frontend *fe; | 1552 | struct dvb_frontend *fe; |
1553 | int err = 0; | ||
1554 | 1553 | ||
1555 | struct analog_parameters params = { | 1554 | struct analog_parameters params = { |
1556 | .mode = V4L2_TUNER_ANALOG_TV, | 1555 | .mode = V4L2_TUNER_ANALOG_TV, |
@@ -1572,8 +1571,10 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, | |||
1572 | params.frequency, f->tuner, params.std); | 1571 | params.frequency, f->tuner, params.std); |
1573 | 1572 | ||
1574 | vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1); | 1573 | vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1); |
1575 | if (!vfe) | 1574 | if (!vfe) { |
1576 | err = -EINVAL; | 1575 | mutex_unlock(&dev->lock); |
1576 | return -EINVAL; | ||
1577 | } | ||
1577 | 1578 | ||
1578 | fe = vfe->dvb.frontend; | 1579 | fe = vfe->dvb.frontend; |
1579 | 1580 | ||
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 62c7ad050f9b..cbd5d119a2c6 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1573,8 +1573,8 @@ static const struct cx88_board cx88_boards[] = { | |||
1573 | .name = "Pinnacle Hybrid PCTV", | 1573 | .name = "Pinnacle Hybrid PCTV", |
1574 | .tuner_type = TUNER_XC2028, | 1574 | .tuner_type = TUNER_XC2028, |
1575 | .tuner_addr = 0x61, | 1575 | .tuner_addr = 0x61, |
1576 | .radio_type = TUNER_XC2028, | 1576 | .radio_type = UNSET, |
1577 | .radio_addr = 0x61, | 1577 | .radio_addr = ADDR_UNSET, |
1578 | .input = { { | 1578 | .input = { { |
1579 | .type = CX88_VMUX_TELEVISION, | 1579 | .type = CX88_VMUX_TELEVISION, |
1580 | .vmux = 0, | 1580 | .vmux = 0, |
@@ -1611,8 +1611,8 @@ static const struct cx88_board cx88_boards[] = { | |||
1611 | .name = "Leadtek TV2000 XP Global", | 1611 | .name = "Leadtek TV2000 XP Global", |
1612 | .tuner_type = TUNER_XC2028, | 1612 | .tuner_type = TUNER_XC2028, |
1613 | .tuner_addr = 0x61, | 1613 | .tuner_addr = 0x61, |
1614 | .radio_type = TUNER_XC2028, | 1614 | .radio_type = UNSET, |
1615 | .radio_addr = 0x61, | 1615 | .radio_addr = ADDR_UNSET, |
1616 | .input = { { | 1616 | .input = { { |
1617 | .type = CX88_VMUX_TELEVISION, | 1617 | .type = CX88_VMUX_TELEVISION, |
1618 | .vmux = 0, | 1618 | .vmux = 0, |
@@ -2115,8 +2115,8 @@ static const struct cx88_board cx88_boards[] = { | |||
2115 | .name = "Terratec Cinergy HT PCI MKII", | 2115 | .name = "Terratec Cinergy HT PCI MKII", |
2116 | .tuner_type = TUNER_XC2028, | 2116 | .tuner_type = TUNER_XC2028, |
2117 | .tuner_addr = 0x61, | 2117 | .tuner_addr = 0x61, |
2118 | .radio_type = TUNER_XC2028, | 2118 | .radio_type = UNSET, |
2119 | .radio_addr = 0x61, | 2119 | .radio_addr = ADDR_UNSET, |
2120 | .input = { { | 2120 | .input = { { |
2121 | .type = CX88_VMUX_TELEVISION, | 2121 | .type = CX88_VMUX_TELEVISION, |
2122 | .vmux = 0, | 2122 | .vmux = 0, |
@@ -2154,9 +2154,9 @@ static const struct cx88_board cx88_boards[] = { | |||
2154 | [CX88_BOARD_WINFAST_DTV1800H] = { | 2154 | [CX88_BOARD_WINFAST_DTV1800H] = { |
2155 | .name = "Leadtek WinFast DTV1800 Hybrid", | 2155 | .name = "Leadtek WinFast DTV1800 Hybrid", |
2156 | .tuner_type = TUNER_XC2028, | 2156 | .tuner_type = TUNER_XC2028, |
2157 | .radio_type = TUNER_XC2028, | 2157 | .radio_type = UNSET, |
2158 | .tuner_addr = 0x61, | 2158 | .tuner_addr = 0x61, |
2159 | .radio_addr = 0x61, | 2159 | .radio_addr = ADDR_UNSET, |
2160 | /* | 2160 | /* |
2161 | * GPIO setting | 2161 | * GPIO setting |
2162 | * | 2162 | * |
@@ -2195,9 +2195,9 @@ static const struct cx88_board cx88_boards[] = { | |||
2195 | [CX88_BOARD_WINFAST_DTV1800H_XC4000] = { | 2195 | [CX88_BOARD_WINFAST_DTV1800H_XC4000] = { |
2196 | .name = "Leadtek WinFast DTV1800 H (XC4000)", | 2196 | .name = "Leadtek WinFast DTV1800 H (XC4000)", |
2197 | .tuner_type = TUNER_XC4000, | 2197 | .tuner_type = TUNER_XC4000, |
2198 | .radio_type = TUNER_XC4000, | 2198 | .radio_type = UNSET, |
2199 | .tuner_addr = 0x61, | 2199 | .tuner_addr = 0x61, |
2200 | .radio_addr = 0x61, | 2200 | .radio_addr = ADDR_UNSET, |
2201 | /* | 2201 | /* |
2202 | * GPIO setting | 2202 | * GPIO setting |
2203 | * | 2203 | * |
@@ -2236,9 +2236,9 @@ static const struct cx88_board cx88_boards[] = { | |||
2236 | [CX88_BOARD_WINFAST_DTV2000H_PLUS] = { | 2236 | [CX88_BOARD_WINFAST_DTV2000H_PLUS] = { |
2237 | .name = "Leadtek WinFast DTV2000 H PLUS", | 2237 | .name = "Leadtek WinFast DTV2000 H PLUS", |
2238 | .tuner_type = TUNER_XC4000, | 2238 | .tuner_type = TUNER_XC4000, |
2239 | .radio_type = TUNER_XC4000, | 2239 | .radio_type = UNSET, |
2240 | .tuner_addr = 0x61, | 2240 | .tuner_addr = 0x61, |
2241 | .radio_addr = 0x61, | 2241 | .radio_addr = ADDR_UNSET, |
2242 | /* | 2242 | /* |
2243 | * GPIO | 2243 | * GPIO |
2244 | * 2: 1: mute audio | 2244 | * 2: 1: mute audio |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 544af91cbdc1..3949b7dc2368 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -731,9 +731,6 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) | |||
731 | 731 | ||
732 | init_kthread_work(&itv->irq_work, ivtv_irq_work_handler); | 732 | init_kthread_work(&itv->irq_work, ivtv_irq_work_handler); |
733 | 733 | ||
734 | /* start counting open_id at 1 */ | ||
735 | itv->open_id = 1; | ||
736 | |||
737 | /* Initial settings */ | 734 | /* Initial settings */ |
738 | itv->cxhdl.port = CX2341X_PORT_MEMORY; | 735 | itv->cxhdl.port = CX2341X_PORT_MEMORY; |
739 | itv->cxhdl.capabilities = CX2341X_CAP_HAS_SLICED_VBI; | 736 | itv->cxhdl.capabilities = CX2341X_CAP_HAS_SLICED_VBI; |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 8f9cc17b518e..06f3d78389bf 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -332,7 +332,7 @@ struct ivtv_stream { | |||
332 | const char *name; /* name of the stream */ | 332 | const char *name; /* name of the stream */ |
333 | int type; /* stream type */ | 333 | int type; /* stream type */ |
334 | 334 | ||
335 | u32 id; | 335 | struct v4l2_fh *fh; /* pointer to the streaming filehandle */ |
336 | spinlock_t qlock; /* locks access to the queues */ | 336 | spinlock_t qlock; /* locks access to the queues */ |
337 | unsigned long s_flags; /* status flags, see above */ | 337 | unsigned long s_flags; /* status flags, see above */ |
338 | int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */ | 338 | int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */ |
@@ -379,7 +379,6 @@ struct ivtv_stream { | |||
379 | 379 | ||
380 | struct ivtv_open_id { | 380 | struct ivtv_open_id { |
381 | struct v4l2_fh fh; | 381 | struct v4l2_fh fh; |
382 | u32 open_id; /* unique ID for this file descriptor */ | ||
383 | int type; /* stream type */ | 382 | int type; /* stream type */ |
384 | int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ | 383 | int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ |
385 | struct ivtv *itv; | 384 | struct ivtv *itv; |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 38f052257f46..2cd6c89b7d91 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -50,16 +50,16 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type) | |||
50 | 50 | ||
51 | if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) { | 51 | if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) { |
52 | /* someone already claimed this stream */ | 52 | /* someone already claimed this stream */ |
53 | if (s->id == id->open_id) { | 53 | if (s->fh == &id->fh) { |
54 | /* yes, this file descriptor did. So that's OK. */ | 54 | /* yes, this file descriptor did. So that's OK. */ |
55 | return 0; | 55 | return 0; |
56 | } | 56 | } |
57 | if (s->id == -1 && (type == IVTV_DEC_STREAM_TYPE_VBI || | 57 | if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI || |
58 | type == IVTV_ENC_STREAM_TYPE_VBI)) { | 58 | type == IVTV_ENC_STREAM_TYPE_VBI)) { |
59 | /* VBI is handled already internally, now also assign | 59 | /* VBI is handled already internally, now also assign |
60 | the file descriptor to this stream for external | 60 | the file descriptor to this stream for external |
61 | reading of the stream. */ | 61 | reading of the stream. */ |
62 | s->id = id->open_id; | 62 | s->fh = &id->fh; |
63 | IVTV_DEBUG_INFO("Start Read VBI\n"); | 63 | IVTV_DEBUG_INFO("Start Read VBI\n"); |
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
@@ -67,7 +67,7 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type) | |||
67 | IVTV_DEBUG_INFO("Stream %d is busy\n", type); | 67 | IVTV_DEBUG_INFO("Stream %d is busy\n", type); |
68 | return -EBUSY; | 68 | return -EBUSY; |
69 | } | 69 | } |
70 | s->id = id->open_id; | 70 | s->fh = &id->fh; |
71 | if (type == IVTV_DEC_STREAM_TYPE_VBI) { | 71 | if (type == IVTV_DEC_STREAM_TYPE_VBI) { |
72 | /* Enable reinsertion interrupt */ | 72 | /* Enable reinsertion interrupt */ |
73 | ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); | 73 | ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); |
@@ -104,7 +104,7 @@ void ivtv_release_stream(struct ivtv_stream *s) | |||
104 | struct ivtv *itv = s->itv; | 104 | struct ivtv *itv = s->itv; |
105 | struct ivtv_stream *s_vbi; | 105 | struct ivtv_stream *s_vbi; |
106 | 106 | ||
107 | s->id = -1; | 107 | s->fh = NULL; |
108 | if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) && | 108 | if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) && |
109 | test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { | 109 | test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { |
110 | /* this stream is still in use internally */ | 110 | /* this stream is still in use internally */ |
@@ -136,7 +136,7 @@ void ivtv_release_stream(struct ivtv_stream *s) | |||
136 | /* was already cleared */ | 136 | /* was already cleared */ |
137 | return; | 137 | return; |
138 | } | 138 | } |
139 | if (s_vbi->id != -1) { | 139 | if (s_vbi->fh) { |
140 | /* VBI stream still claimed by a file descriptor */ | 140 | /* VBI stream still claimed by a file descriptor */ |
141 | return; | 141 | return; |
142 | } | 142 | } |
@@ -268,11 +268,13 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, | |||
268 | } | 268 | } |
269 | 269 | ||
270 | /* wait for more data to arrive */ | 270 | /* wait for more data to arrive */ |
271 | mutex_unlock(&itv->serialize_lock); | ||
271 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); | 272 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); |
272 | /* New buffers might have become available before we were added to the waitqueue */ | 273 | /* New buffers might have become available before we were added to the waitqueue */ |
273 | if (!s->q_full.buffers) | 274 | if (!s->q_full.buffers) |
274 | schedule(); | 275 | schedule(); |
275 | finish_wait(&s->waitq, &wait); | 276 | finish_wait(&s->waitq, &wait); |
277 | mutex_lock(&itv->serialize_lock); | ||
276 | if (signal_pending(current)) { | 278 | if (signal_pending(current)) { |
277 | /* return if a signal was received */ | 279 | /* return if a signal was received */ |
278 | IVTV_DEBUG_INFO("User stopped %s\n", s->name); | 280 | IVTV_DEBUG_INFO("User stopped %s\n", s->name); |
@@ -357,7 +359,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co | |||
357 | size_t tot_written = 0; | 359 | size_t tot_written = 0; |
358 | int single_frame = 0; | 360 | int single_frame = 0; |
359 | 361 | ||
360 | if (atomic_read(&itv->capturing) == 0 && s->id == -1) { | 362 | if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) { |
361 | /* shouldn't happen */ | 363 | /* shouldn't happen */ |
362 | IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name); | 364 | IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name); |
363 | return -EIO; | 365 | return -EIO; |
@@ -507,9 +509,7 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_ | |||
507 | 509 | ||
508 | IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); | 510 | IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); |
509 | 511 | ||
510 | mutex_lock(&itv->serialize_lock); | ||
511 | rc = ivtv_start_capture(id); | 512 | rc = ivtv_start_capture(id); |
512 | mutex_unlock(&itv->serialize_lock); | ||
513 | if (rc) | 513 | if (rc) |
514 | return rc; | 514 | return rc; |
515 | return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); | 515 | return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); |
@@ -584,9 +584,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c | |||
584 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); | 584 | set_bit(IVTV_F_S_APPL_IO, &s->s_flags); |
585 | 585 | ||
586 | /* Start decoder (returns 0 if already started) */ | 586 | /* Start decoder (returns 0 if already started) */ |
587 | mutex_lock(&itv->serialize_lock); | ||
588 | rc = ivtv_start_decoding(id, itv->speed); | 587 | rc = ivtv_start_decoding(id, itv->speed); |
589 | mutex_unlock(&itv->serialize_lock); | ||
590 | if (rc) { | 588 | if (rc) { |
591 | IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); | 589 | IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); |
592 | 590 | ||
@@ -627,11 +625,13 @@ retry: | |||
627 | break; | 625 | break; |
628 | if (filp->f_flags & O_NONBLOCK) | 626 | if (filp->f_flags & O_NONBLOCK) |
629 | return -EAGAIN; | 627 | return -EAGAIN; |
628 | mutex_unlock(&itv->serialize_lock); | ||
630 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); | 629 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); |
631 | /* New buffers might have become free before we were added to the waitqueue */ | 630 | /* New buffers might have become free before we were added to the waitqueue */ |
632 | if (!s->q_free.buffers) | 631 | if (!s->q_free.buffers) |
633 | schedule(); | 632 | schedule(); |
634 | finish_wait(&s->waitq, &wait); | 633 | finish_wait(&s->waitq, &wait); |
634 | mutex_lock(&itv->serialize_lock); | ||
635 | if (signal_pending(current)) { | 635 | if (signal_pending(current)) { |
636 | IVTV_DEBUG_INFO("User stopped %s\n", s->name); | 636 | IVTV_DEBUG_INFO("User stopped %s\n", s->name); |
637 | return -EINTR; | 637 | return -EINTR; |
@@ -686,12 +686,14 @@ retry: | |||
686 | if (mode == OUT_YUV) | 686 | if (mode == OUT_YUV) |
687 | ivtv_yuv_setup_stream_frame(itv); | 687 | ivtv_yuv_setup_stream_frame(itv); |
688 | 688 | ||
689 | mutex_unlock(&itv->serialize_lock); | ||
689 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); | 690 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); |
690 | while (!(got_sig = signal_pending(current)) && | 691 | while (!(got_sig = signal_pending(current)) && |
691 | test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) { | 692 | test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) { |
692 | schedule(); | 693 | schedule(); |
693 | } | 694 | } |
694 | finish_wait(&itv->dma_waitq, &wait); | 695 | finish_wait(&itv->dma_waitq, &wait); |
696 | mutex_lock(&itv->serialize_lock); | ||
695 | if (got_sig) { | 697 | if (got_sig) { |
696 | IVTV_DEBUG_INFO("User interrupted %s\n", s->name); | 698 | IVTV_DEBUG_INFO("User interrupted %s\n", s->name); |
697 | return -EINTR; | 699 | return -EINTR; |
@@ -756,9 +758,7 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) | |||
756 | if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | 758 | if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { |
757 | int rc; | 759 | int rc; |
758 | 760 | ||
759 | mutex_lock(&itv->serialize_lock); | ||
760 | rc = ivtv_start_capture(id); | 761 | rc = ivtv_start_capture(id); |
761 | mutex_unlock(&itv->serialize_lock); | ||
762 | if (rc) { | 762 | if (rc) { |
763 | IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", | 763 | IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", |
764 | s->name, rc); | 764 | s->name, rc); |
@@ -808,7 +808,7 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end) | |||
808 | id->type == IVTV_ENC_STREAM_TYPE_VBI) && | 808 | id->type == IVTV_ENC_STREAM_TYPE_VBI) && |
809 | test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { | 809 | test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { |
810 | /* Also used internally, don't stop capturing */ | 810 | /* Also used internally, don't stop capturing */ |
811 | s->id = -1; | 811 | s->fh = NULL; |
812 | } | 812 | } |
813 | else { | 813 | else { |
814 | ivtv_stop_v4l2_encode_stream(s, gop_end); | 814 | ivtv_stop_v4l2_encode_stream(s, gop_end); |
@@ -861,20 +861,9 @@ int ivtv_v4l2_close(struct file *filp) | |||
861 | 861 | ||
862 | IVTV_DEBUG_FILE("close %s\n", s->name); | 862 | IVTV_DEBUG_FILE("close %s\n", s->name); |
863 | 863 | ||
864 | v4l2_fh_del(fh); | ||
865 | v4l2_fh_exit(fh); | ||
866 | |||
867 | /* Easy case first: this stream was never claimed by us */ | ||
868 | if (s->id != id->open_id) { | ||
869 | kfree(id); | ||
870 | return 0; | ||
871 | } | ||
872 | |||
873 | /* 'Unclaim' this stream */ | ||
874 | |||
875 | /* Stop radio */ | 864 | /* Stop radio */ |
876 | mutex_lock(&itv->serialize_lock); | 865 | if (id->type == IVTV_ENC_STREAM_TYPE_RAD && |
877 | if (id->type == IVTV_ENC_STREAM_TYPE_RAD) { | 866 | v4l2_fh_is_singular_file(filp)) { |
878 | /* Closing radio device, return to TV mode */ | 867 | /* Closing radio device, return to TV mode */ |
879 | ivtv_mute(itv); | 868 | ivtv_mute(itv); |
880 | /* Mark that the radio is no longer in use */ | 869 | /* Mark that the radio is no longer in use */ |
@@ -890,13 +879,25 @@ int ivtv_v4l2_close(struct file *filp) | |||
890 | if (atomic_read(&itv->capturing) > 0) { | 879 | if (atomic_read(&itv->capturing) > 0) { |
891 | /* Undo video mute */ | 880 | /* Undo video mute */ |
892 | ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, | 881 | ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, |
893 | v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) | | 882 | v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) | |
894 | (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8)); | 883 | (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8)); |
895 | } | 884 | } |
896 | /* Done! Unmute and continue. */ | 885 | /* Done! Unmute and continue. */ |
897 | ivtv_unmute(itv); | 886 | ivtv_unmute(itv); |
898 | ivtv_release_stream(s); | 887 | } |
899 | } else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { | 888 | |
889 | v4l2_fh_del(fh); | ||
890 | v4l2_fh_exit(fh); | ||
891 | |||
892 | /* Easy case first: this stream was never claimed by us */ | ||
893 | if (s->fh != &id->fh) { | ||
894 | kfree(id); | ||
895 | return 0; | ||
896 | } | ||
897 | |||
898 | /* 'Unclaim' this stream */ | ||
899 | |||
900 | if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { | ||
900 | struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; | 901 | struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; |
901 | 902 | ||
902 | ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); | 903 | ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); |
@@ -911,21 +912,25 @@ int ivtv_v4l2_close(struct file *filp) | |||
911 | ivtv_stop_capture(id, 0); | 912 | ivtv_stop_capture(id, 0); |
912 | } | 913 | } |
913 | kfree(id); | 914 | kfree(id); |
914 | mutex_unlock(&itv->serialize_lock); | ||
915 | return 0; | 915 | return 0; |
916 | } | 916 | } |
917 | 917 | ||
918 | static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | 918 | int ivtv_v4l2_open(struct file *filp) |
919 | { | 919 | { |
920 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
921 | struct video_device *vdev = video_devdata(filp); | 920 | struct video_device *vdev = video_devdata(filp); |
922 | #endif | 921 | struct ivtv_stream *s = video_get_drvdata(vdev); |
923 | struct ivtv *itv = s->itv; | 922 | struct ivtv *itv = s->itv; |
924 | struct ivtv_open_id *item; | 923 | struct ivtv_open_id *item; |
925 | int res = 0; | 924 | int res = 0; |
926 | 925 | ||
927 | IVTV_DEBUG_FILE("open %s\n", s->name); | 926 | IVTV_DEBUG_FILE("open %s\n", s->name); |
928 | 927 | ||
928 | if (ivtv_init_on_first_open(itv)) { | ||
929 | IVTV_ERR("Failed to initialize on device %s\n", | ||
930 | video_device_node_name(vdev)); | ||
931 | return -ENXIO; | ||
932 | } | ||
933 | |||
929 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 934 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
930 | /* Unless ivtv_fw_debug is set, error out if firmware dead. */ | 935 | /* Unless ivtv_fw_debug is set, error out if firmware dead. */ |
931 | if (ivtv_fw_debug) { | 936 | if (ivtv_fw_debug) { |
@@ -966,31 +971,19 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
966 | return -ENOMEM; | 971 | return -ENOMEM; |
967 | } | 972 | } |
968 | v4l2_fh_init(&item->fh, s->vdev); | 973 | v4l2_fh_init(&item->fh, s->vdev); |
969 | if (res < 0) { | ||
970 | v4l2_fh_exit(&item->fh); | ||
971 | kfree(item); | ||
972 | return res; | ||
973 | } | ||
974 | item->itv = itv; | 974 | item->itv = itv; |
975 | item->type = s->type; | 975 | item->type = s->type; |
976 | 976 | ||
977 | item->open_id = itv->open_id++; | ||
978 | filp->private_data = &item->fh; | 977 | filp->private_data = &item->fh; |
978 | v4l2_fh_add(&item->fh); | ||
979 | 979 | ||
980 | if (item->type == IVTV_ENC_STREAM_TYPE_RAD) { | 980 | if (item->type == IVTV_ENC_STREAM_TYPE_RAD && |
981 | /* Try to claim this stream */ | 981 | v4l2_fh_is_singular_file(filp)) { |
982 | if (ivtv_claim_stream(item, item->type)) { | ||
983 | /* No, it's already in use */ | ||
984 | v4l2_fh_exit(&item->fh); | ||
985 | kfree(item); | ||
986 | return -EBUSY; | ||
987 | } | ||
988 | |||
989 | if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { | 982 | if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { |
990 | if (atomic_read(&itv->capturing) > 0) { | 983 | if (atomic_read(&itv->capturing) > 0) { |
991 | /* switching to radio while capture is | 984 | /* switching to radio while capture is |
992 | in progress is not polite */ | 985 | in progress is not polite */ |
993 | ivtv_release_stream(s); | 986 | v4l2_fh_del(&item->fh); |
994 | v4l2_fh_exit(&item->fh); | 987 | v4l2_fh_exit(&item->fh); |
995 | kfree(item); | 988 | kfree(item); |
996 | return -EBUSY; | 989 | return -EBUSY; |
@@ -1022,32 +1015,9 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
1022 | 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); | 1015 | 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); |
1023 | itv->yuv_info.stream_size = 0; | 1016 | itv->yuv_info.stream_size = 0; |
1024 | } | 1017 | } |
1025 | v4l2_fh_add(&item->fh); | ||
1026 | return 0; | 1018 | return 0; |
1027 | } | 1019 | } |
1028 | 1020 | ||
1029 | int ivtv_v4l2_open(struct file *filp) | ||
1030 | { | ||
1031 | int res; | ||
1032 | struct ivtv *itv = NULL; | ||
1033 | struct ivtv_stream *s = NULL; | ||
1034 | struct video_device *vdev = video_devdata(filp); | ||
1035 | |||
1036 | s = video_get_drvdata(vdev); | ||
1037 | itv = s->itv; | ||
1038 | |||
1039 | mutex_lock(&itv->serialize_lock); | ||
1040 | if (ivtv_init_on_first_open(itv)) { | ||
1041 | IVTV_ERR("Failed to initialize on device %s\n", | ||
1042 | video_device_node_name(vdev)); | ||
1043 | mutex_unlock(&itv->serialize_lock); | ||
1044 | return -ENXIO; | ||
1045 | } | ||
1046 | res = ivtv_serialized_open(s, filp); | ||
1047 | mutex_unlock(&itv->serialize_lock); | ||
1048 | return res; | ||
1049 | } | ||
1050 | |||
1051 | void ivtv_mute(struct ivtv *itv) | 1021 | void ivtv_mute(struct ivtv *itv) |
1052 | { | 1022 | { |
1053 | if (atomic_read(&itv->capturing)) | 1023 | if (atomic_read(&itv->capturing)) |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index ecafa697326e..c4bc48143098 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -179,6 +179,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed) | |||
179 | ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0); | 179 | ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0); |
180 | 180 | ||
181 | /* Wait for any DMA to finish */ | 181 | /* Wait for any DMA to finish */ |
182 | mutex_unlock(&itv->serialize_lock); | ||
182 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); | 183 | prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); |
183 | while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) { | 184 | while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) { |
184 | got_sig = signal_pending(current); | 185 | got_sig = signal_pending(current); |
@@ -188,6 +189,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed) | |||
188 | schedule(); | 189 | schedule(); |
189 | } | 190 | } |
190 | finish_wait(&itv->dma_waitq, &wait); | 191 | finish_wait(&itv->dma_waitq, &wait); |
192 | mutex_lock(&itv->serialize_lock); | ||
191 | if (got_sig) | 193 | if (got_sig) |
192 | return -EINTR; | 194 | return -EINTR; |
193 | 195 | ||
@@ -1107,6 +1109,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std) | |||
1107 | * happens within the first 100 lines of the top field. | 1109 | * happens within the first 100 lines of the top field. |
1108 | * Make 4 attempts to sync to the decoder before giving up. | 1110 | * Make 4 attempts to sync to the decoder before giving up. |
1109 | */ | 1111 | */ |
1112 | mutex_unlock(&itv->serialize_lock); | ||
1110 | for (f = 0; f < 4; f++) { | 1113 | for (f = 0; f < 4; f++) { |
1111 | prepare_to_wait(&itv->vsync_waitq, &wait, | 1114 | prepare_to_wait(&itv->vsync_waitq, &wait, |
1112 | TASK_UNINTERRUPTIBLE); | 1115 | TASK_UNINTERRUPTIBLE); |
@@ -1115,6 +1118,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std) | |||
1115 | schedule_timeout(msecs_to_jiffies(25)); | 1118 | schedule_timeout(msecs_to_jiffies(25)); |
1116 | } | 1119 | } |
1117 | finish_wait(&itv->vsync_waitq, &wait); | 1120 | finish_wait(&itv->vsync_waitq, &wait); |
1121 | mutex_lock(&itv->serialize_lock); | ||
1118 | 1122 | ||
1119 | if (f == 4) | 1123 | if (f == 4) |
1120 | IVTV_WARN("Mode change failed to sync to decoder\n"); | 1124 | IVTV_WARN("Mode change failed to sync to decoder\n"); |
@@ -1842,8 +1846,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio, | |||
1842 | return 0; | 1846 | return 0; |
1843 | } | 1847 | } |
1844 | 1848 | ||
1845 | static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | 1849 | long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1846 | unsigned int cmd, unsigned long arg) | ||
1847 | { | 1850 | { |
1848 | struct video_device *vfd = video_devdata(filp); | 1851 | struct video_device *vfd = video_devdata(filp); |
1849 | long ret; | 1852 | long ret; |
@@ -1855,21 +1858,6 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | |||
1855 | return ret; | 1858 | return ret; |
1856 | } | 1859 | } |
1857 | 1860 | ||
1858 | long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
1859 | { | ||
1860 | struct ivtv_open_id *id = fh2id(filp->private_data); | ||
1861 | struct ivtv *itv = id->itv; | ||
1862 | long res; | ||
1863 | |||
1864 | /* DQEVENT can block, so this should not run with the serialize lock */ | ||
1865 | if (cmd == VIDIOC_DQEVENT) | ||
1866 | return ivtv_serialized_ioctl(itv, filp, cmd, arg); | ||
1867 | mutex_lock(&itv->serialize_lock); | ||
1868 | res = ivtv_serialized_ioctl(itv, filp, cmd, arg); | ||
1869 | mutex_unlock(&itv->serialize_lock); | ||
1870 | return res; | ||
1871 | } | ||
1872 | |||
1873 | static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { | 1861 | static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { |
1874 | .vidioc_querycap = ivtv_querycap, | 1862 | .vidioc_querycap = ivtv_querycap, |
1875 | .vidioc_s_audio = ivtv_s_audio, | 1863 | .vidioc_s_audio = ivtv_s_audio, |
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 9c29e964d400..1b3b9578bf47 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c | |||
@@ -288,13 +288,13 @@ static void dma_post(struct ivtv_stream *s) | |||
288 | ivtv_process_vbi_data(itv, buf, 0, s->type); | 288 | ivtv_process_vbi_data(itv, buf, 0, s->type); |
289 | s->q_dma.bytesused += buf->bytesused; | 289 | s->q_dma.bytesused += buf->bytesused; |
290 | } | 290 | } |
291 | if (s->id == -1) { | 291 | if (s->fh == NULL) { |
292 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0); | 292 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0); |
293 | return; | 293 | return; |
294 | } | 294 | } |
295 | } | 295 | } |
296 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused); | 296 | ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused); |
297 | if (s->id != -1) | 297 | if (s->fh) |
298 | wake_up(&s->waitq); | 298 | wake_up(&s->waitq); |
299 | } | 299 | } |
300 | 300 | ||
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index e7794dc1330e..c6e28b4ebbed 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -159,7 +159,6 @@ static void ivtv_stream_init(struct ivtv *itv, int type) | |||
159 | s->buffers = (itv->options.kilobytes[type] * 1024 + s->buf_size - 1) / s->buf_size; | 159 | s->buffers = (itv->options.kilobytes[type] * 1024 + s->buf_size - 1) / s->buf_size; |
160 | spin_lock_init(&s->qlock); | 160 | spin_lock_init(&s->qlock); |
161 | init_waitqueue_head(&s->waitq); | 161 | init_waitqueue_head(&s->waitq); |
162 | s->id = -1; | ||
163 | s->sg_handle = IVTV_DMA_UNMAPPED; | 162 | s->sg_handle = IVTV_DMA_UNMAPPED; |
164 | ivtv_queue_init(&s->q_free); | 163 | ivtv_queue_init(&s->q_free); |
165 | ivtv_queue_init(&s->q_full); | 164 | ivtv_queue_init(&s->q_full); |
@@ -214,6 +213,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) | |||
214 | s->vdev->fops = ivtv_stream_info[type].fops; | 213 | s->vdev->fops = ivtv_stream_info[type].fops; |
215 | s->vdev->release = video_device_release; | 214 | s->vdev->release = video_device_release; |
216 | s->vdev->tvnorms = V4L2_STD_ALL; | 215 | s->vdev->tvnorms = V4L2_STD_ALL; |
216 | s->vdev->lock = &itv->serialize_lock; | ||
217 | set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags); | 217 | set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags); |
218 | ivtv_set_funcs(s->vdev); | 218 | ivtv_set_funcs(s->vdev); |
219 | return 0; | 219 | return 0; |
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index dcbab6ad4c26..2ad65eb29832 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c | |||
@@ -1149,23 +1149,37 @@ int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src) | |||
1149 | { | 1149 | { |
1150 | struct yuv_playback_info *yi = &itv->yuv_info; | 1150 | struct yuv_playback_info *yi = &itv->yuv_info; |
1151 | struct ivtv_dma_frame dma_args; | 1151 | struct ivtv_dma_frame dma_args; |
1152 | int res; | ||
1152 | 1153 | ||
1153 | ivtv_yuv_setup_stream_frame(itv); | 1154 | ivtv_yuv_setup_stream_frame(itv); |
1154 | 1155 | ||
1155 | /* We only need to supply source addresses for this */ | 1156 | /* We only need to supply source addresses for this */ |
1156 | dma_args.y_source = src; | 1157 | dma_args.y_source = src; |
1157 | dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31); | 1158 | dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31); |
1158 | return ivtv_yuv_udma_frame(itv, &dma_args); | 1159 | /* Wait for frame DMA. Note that serialize_lock is locked, |
1160 | so to allow other processes to access the driver while | ||
1161 | we are waiting unlock first and later lock again. */ | ||
1162 | mutex_unlock(&itv->serialize_lock); | ||
1163 | res = ivtv_yuv_udma_frame(itv, &dma_args); | ||
1164 | mutex_lock(&itv->serialize_lock); | ||
1165 | return res; | ||
1159 | } | 1166 | } |
1160 | 1167 | ||
1161 | /* IVTV_IOC_DMA_FRAME ioctl handler */ | 1168 | /* IVTV_IOC_DMA_FRAME ioctl handler */ |
1162 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | 1169 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) |
1163 | { | 1170 | { |
1164 | /* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */ | 1171 | int res; |
1165 | 1172 | ||
1173 | /* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */ | ||
1166 | ivtv_yuv_next_free(itv); | 1174 | ivtv_yuv_next_free(itv); |
1167 | ivtv_yuv_setup_frame(itv, args); | 1175 | ivtv_yuv_setup_frame(itv, args); |
1168 | return ivtv_yuv_udma_frame(itv, args); | 1176 | /* Wait for frame DMA. Note that serialize_lock is locked, |
1177 | so to allow other processes to access the driver while | ||
1178 | we are waiting unlock first and later lock again. */ | ||
1179 | mutex_unlock(&itv->serialize_lock); | ||
1180 | res = ivtv_yuv_udma_frame(itv, args); | ||
1181 | mutex_lock(&itv->serialize_lock); | ||
1182 | return res; | ||
1169 | } | 1183 | } |
1170 | 1184 | ||
1171 | void ivtv_yuv_close(struct ivtv *itv) | 1185 | void ivtv_yuv_close(struct ivtv *itv) |
@@ -1174,7 +1188,9 @@ void ivtv_yuv_close(struct ivtv *itv) | |||
1174 | int h_filter, v_filter_1, v_filter_2; | 1188 | int h_filter, v_filter_1, v_filter_2; |
1175 | 1189 | ||
1176 | IVTV_DEBUG_YUV("ivtv_yuv_close\n"); | 1190 | IVTV_DEBUG_YUV("ivtv_yuv_close\n"); |
1191 | mutex_unlock(&itv->serialize_lock); | ||
1177 | ivtv_waitq(&itv->vsync_waitq); | 1192 | ivtv_waitq(&itv->vsync_waitq); |
1193 | mutex_lock(&itv->serialize_lock); | ||
1178 | 1194 | ||
1179 | yi->running = 0; | 1195 | yi->running = 0; |
1180 | atomic_set(&yi->next_dma_frame, -1); | 1196 | atomic_set(&yi->next_dma_frame, -1); |
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index a277f95091ef..1fb7d5bd5ec2 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
@@ -1042,7 +1042,8 @@ static int vidioc_querycap(struct file *file, void *fh, | |||
1042 | strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver)); | 1042 | strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver)); |
1043 | strlcpy(cap->card, vout->vfd->name, sizeof(cap->card)); | 1043 | strlcpy(cap->card, vout->vfd->name, sizeof(cap->card)); |
1044 | cap->bus_info[0] = '\0'; | 1044 | cap->bus_info[0] = '\0'; |
1045 | cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT; | 1045 | cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT | |
1046 | V4L2_CAP_VIDEO_OUTPUT_OVERLAY; | ||
1046 | 1047 | ||
1047 | return 0; | 1048 | return 0; |
1048 | } | 1049 | } |
@@ -1825,7 +1826,9 @@ static int vidioc_g_fbuf(struct file *file, void *fh, | |||
1825 | ovid = &vout->vid_info; | 1826 | ovid = &vout->vid_info; |
1826 | ovl = ovid->overlays[0]; | 1827 | ovl = ovid->overlays[0]; |
1827 | 1828 | ||
1828 | a->flags = 0x0; | 1829 | /* The video overlay must stay within the framebuffer and can't be |
1830 | positioned independently. */ | ||
1831 | a->flags = V4L2_FBUF_FLAG_OVERLAY; | ||
1829 | a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY | 1832 | a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY |
1830 | | V4L2_FBUF_CAP_SRC_CHROMAKEY; | 1833 | | V4L2_FBUF_CAP_SRC_CHROMAKEY; |
1831 | 1834 | ||
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 905d41d90c6a..1f506fde97d0 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -104,47 +104,16 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] = | |||
104 | 104 | ||
105 | /****************************************************************************/ | 105 | /****************************************************************************/ |
106 | 106 | ||
107 | static int _send_control_msg(struct pwc_device *pdev, | ||
108 | u8 request, u16 value, int index, void *buf, int buflen) | ||
109 | { | ||
110 | int rc; | ||
111 | void *kbuf = NULL; | ||
112 | |||
113 | if (buflen) { | ||
114 | kbuf = kmemdup(buf, buflen, GFP_KERNEL); /* not allowed on stack */ | ||
115 | if (kbuf == NULL) | ||
116 | return -ENOMEM; | ||
117 | } | ||
118 | |||
119 | rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | ||
120 | request, | ||
121 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
122 | value, | ||
123 | index, | ||
124 | kbuf, buflen, USB_CTRL_SET_TIMEOUT); | ||
125 | |||
126 | kfree(kbuf); | ||
127 | return rc; | ||
128 | } | ||
129 | |||
130 | static int recv_control_msg(struct pwc_device *pdev, | 107 | static int recv_control_msg(struct pwc_device *pdev, |
131 | u8 request, u16 value, void *buf, int buflen) | 108 | u8 request, u16 value, int recv_count) |
132 | { | 109 | { |
133 | int rc; | 110 | int rc; |
134 | void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */ | ||
135 | |||
136 | if (kbuf == NULL) | ||
137 | return -ENOMEM; | ||
138 | 111 | ||
139 | rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | 112 | rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), |
140 | request, | 113 | request, |
141 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 114 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
142 | value, | 115 | value, pdev->vcinterface, |
143 | pdev->vcinterface, | 116 | pdev->ctrl_buf, recv_count, USB_CTRL_GET_TIMEOUT); |
144 | kbuf, buflen, USB_CTRL_GET_TIMEOUT); | ||
145 | memcpy(buf, kbuf, buflen); | ||
146 | kfree(kbuf); | ||
147 | |||
148 | if (rc < 0) | 117 | if (rc < 0) |
149 | PWC_ERROR("recv_control_msg error %d req %02x val %04x\n", | 118 | PWC_ERROR("recv_control_msg error %d req %02x val %04x\n", |
150 | rc, request, value); | 119 | rc, request, value); |
@@ -152,27 +121,39 @@ static int recv_control_msg(struct pwc_device *pdev, | |||
152 | } | 121 | } |
153 | 122 | ||
154 | static inline int send_video_command(struct pwc_device *pdev, | 123 | static inline int send_video_command(struct pwc_device *pdev, |
155 | int index, void *buf, int buflen) | 124 | int index, const unsigned char *buf, int buflen) |
156 | { | 125 | { |
157 | return _send_control_msg(pdev, | 126 | int rc; |
158 | SET_EP_STREAM_CTL, | 127 | |
159 | VIDEO_OUTPUT_CONTROL_FORMATTER, | 128 | memcpy(pdev->ctrl_buf, buf, buflen); |
160 | index, | 129 | |
161 | buf, buflen); | 130 | rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), |
131 | SET_EP_STREAM_CTL, | ||
132 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
133 | VIDEO_OUTPUT_CONTROL_FORMATTER, index, | ||
134 | pdev->ctrl_buf, buflen, USB_CTRL_SET_TIMEOUT); | ||
135 | if (rc >= 0) | ||
136 | memcpy(pdev->cmd_buf, buf, buflen); | ||
137 | else | ||
138 | PWC_ERROR("send_video_command error %d\n", rc); | ||
139 | |||
140 | return rc; | ||
162 | } | 141 | } |
163 | 142 | ||
164 | int send_control_msg(struct pwc_device *pdev, | 143 | int send_control_msg(struct pwc_device *pdev, |
165 | u8 request, u16 value, void *buf, int buflen) | 144 | u8 request, u16 value, void *buf, int buflen) |
166 | { | 145 | { |
167 | return _send_control_msg(pdev, | 146 | return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), |
168 | request, value, pdev->vcinterface, buf, buflen); | 147 | request, |
148 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
149 | value, pdev->vcinterface, | ||
150 | buf, buflen, USB_CTRL_SET_TIMEOUT); | ||
169 | } | 151 | } |
170 | 152 | ||
171 | static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames, | 153 | static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt, |
172 | int *compression) | 154 | int frames, int *compression, int send_to_cam) |
173 | { | 155 | { |
174 | unsigned char buf[3]; | 156 | int fps, ret = 0; |
175 | int ret, fps; | ||
176 | struct Nala_table_entry *pEntry; | 157 | struct Nala_table_entry *pEntry; |
177 | int frames2frames[31] = | 158 | int frames2frames[31] = |
178 | { /* closest match of framerate */ | 159 | { /* closest match of framerate */ |
@@ -194,30 +175,29 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames, | |||
194 | 7 /* 30 */ | 175 | 7 /* 30 */ |
195 | }; | 176 | }; |
196 | 177 | ||
197 | if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25) | 178 | if (size < 0 || size > PSZ_CIF) |
198 | return -EINVAL; | 179 | return -EINVAL; |
180 | if (frames < 4) | ||
181 | frames = 4; | ||
182 | else if (frames > 25) | ||
183 | frames = 25; | ||
199 | frames = frames2frames[frames]; | 184 | frames = frames2frames[frames]; |
200 | fps = frames2table[frames]; | 185 | fps = frames2table[frames]; |
201 | pEntry = &Nala_table[size][fps]; | 186 | pEntry = &Nala_table[size][fps]; |
202 | if (pEntry->alternate == 0) | 187 | if (pEntry->alternate == 0) |
203 | return -EINVAL; | 188 | return -EINVAL; |
204 | 189 | ||
205 | memcpy(buf, pEntry->mode, 3); | 190 | if (send_to_cam) |
206 | ret = send_video_command(pdev, pdev->vendpoint, buf, 3); | 191 | ret = send_video_command(pdev, pdev->vendpoint, |
207 | if (ret < 0) { | 192 | pEntry->mode, 3); |
208 | PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); | 193 | if (ret < 0) |
209 | return ret; | 194 | return ret; |
210 | } | ||
211 | if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) { | ||
212 | ret = pwc_dec1_init(pdev, pdev->type, pdev->release, buf); | ||
213 | if (ret < 0) | ||
214 | return ret; | ||
215 | } | ||
216 | 195 | ||
217 | pdev->cmd_len = 3; | 196 | if (pEntry->compressed && pixfmt == V4L2_PIX_FMT_YUV420) |
218 | memcpy(pdev->cmd_buf, buf, 3); | 197 | pwc_dec1_init(pdev, pEntry->mode); |
219 | 198 | ||
220 | /* Set various parameters */ | 199 | /* Set various parameters */ |
200 | pdev->pixfmt = pixfmt; | ||
221 | pdev->vframes = frames; | 201 | pdev->vframes = frames; |
222 | pdev->valternate = pEntry->alternate; | 202 | pdev->valternate = pEntry->alternate; |
223 | pdev->width = pwc_image_sizes[size][0]; | 203 | pdev->width = pwc_image_sizes[size][0]; |
@@ -243,18 +223,20 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames, | |||
243 | } | 223 | } |
244 | 224 | ||
245 | 225 | ||
246 | static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, | 226 | static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt, |
247 | int *compression) | 227 | int frames, int *compression, int send_to_cam) |
248 | { | 228 | { |
249 | unsigned char buf[13]; | ||
250 | const struct Timon_table_entry *pChoose; | 229 | const struct Timon_table_entry *pChoose; |
251 | int ret, fps; | 230 | int fps, ret = 0; |
252 | 231 | ||
253 | if (size >= PSZ_MAX || frames < 5 || frames > 30 || | 232 | if (size >= PSZ_MAX || *compression < 0 || *compression > 3) |
254 | *compression < 0 || *compression > 3) | ||
255 | return -EINVAL; | ||
256 | if (size == PSZ_VGA && frames > 15) | ||
257 | return -EINVAL; | 233 | return -EINVAL; |
234 | if (frames < 5) | ||
235 | frames = 5; | ||
236 | else if (size == PSZ_VGA && frames > 15) | ||
237 | frames = 15; | ||
238 | else if (frames > 30) | ||
239 | frames = 30; | ||
258 | fps = (frames / 5) - 1; | 240 | fps = (frames / 5) - 1; |
259 | 241 | ||
260 | /* Find a supported framerate with progressively higher compression */ | 242 | /* Find a supported framerate with progressively higher compression */ |
@@ -268,22 +250,18 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, | |||
268 | if (pChoose == NULL || pChoose->alternate == 0) | 250 | if (pChoose == NULL || pChoose->alternate == 0) |
269 | return -ENOENT; /* Not supported. */ | 251 | return -ENOENT; /* Not supported. */ |
270 | 252 | ||
271 | memcpy(buf, pChoose->mode, 13); | 253 | if (send_to_cam) |
272 | ret = send_video_command(pdev, pdev->vendpoint, buf, 13); | 254 | ret = send_video_command(pdev, pdev->vendpoint, |
255 | pChoose->mode, 13); | ||
273 | if (ret < 0) | 256 | if (ret < 0) |
274 | return ret; | 257 | return ret; |
275 | 258 | ||
276 | if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) { | 259 | if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420) |
277 | ret = pwc_dec23_init(pdev, pdev->type, buf); | 260 | pwc_dec23_init(pdev, pChoose->mode); |
278 | if (ret < 0) | ||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | pdev->cmd_len = 13; | ||
283 | memcpy(pdev->cmd_buf, buf, 13); | ||
284 | 261 | ||
285 | /* Set various parameters */ | 262 | /* Set various parameters */ |
286 | pdev->vframes = frames; | 263 | pdev->pixfmt = pixfmt; |
264 | pdev->vframes = (fps + 1) * 5; | ||
287 | pdev->valternate = pChoose->alternate; | 265 | pdev->valternate = pChoose->alternate; |
288 | pdev->width = pwc_image_sizes[size][0]; | 266 | pdev->width = pwc_image_sizes[size][0]; |
289 | pdev->height = pwc_image_sizes[size][1]; | 267 | pdev->height = pwc_image_sizes[size][1]; |
@@ -296,18 +274,20 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, | |||
296 | } | 274 | } |
297 | 275 | ||
298 | 276 | ||
299 | static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, | 277 | static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt, |
300 | int *compression) | 278 | int frames, int *compression, int send_to_cam) |
301 | { | 279 | { |
302 | const struct Kiara_table_entry *pChoose = NULL; | 280 | const struct Kiara_table_entry *pChoose = NULL; |
303 | int fps, ret; | 281 | int fps, ret = 0; |
304 | unsigned char buf[12]; | ||
305 | 282 | ||
306 | if (size >= PSZ_MAX || frames < 5 || frames > 30 || | 283 | if (size >= PSZ_MAX || *compression < 0 || *compression > 3) |
307 | *compression < 0 || *compression > 3) | ||
308 | return -EINVAL; | ||
309 | if (size == PSZ_VGA && frames > 15) | ||
310 | return -EINVAL; | 284 | return -EINVAL; |
285 | if (frames < 5) | ||
286 | frames = 5; | ||
287 | else if (size == PSZ_VGA && frames > 15) | ||
288 | frames = 15; | ||
289 | else if (frames > 30) | ||
290 | frames = 30; | ||
311 | fps = (frames / 5) - 1; | 291 | fps = (frames / 5) - 1; |
312 | 292 | ||
313 | /* Find a supported framerate with progressively higher compression */ | 293 | /* Find a supported framerate with progressively higher compression */ |
@@ -320,26 +300,18 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, | |||
320 | if (pChoose == NULL || pChoose->alternate == 0) | 300 | if (pChoose == NULL || pChoose->alternate == 0) |
321 | return -ENOENT; /* Not supported. */ | 301 | return -ENOENT; /* Not supported. */ |
322 | 302 | ||
323 | PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate); | ||
324 | |||
325 | /* usb_control_msg won't take staticly allocated arrays as argument?? */ | ||
326 | memcpy(buf, pChoose->mode, 12); | ||
327 | |||
328 | /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */ | 303 | /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */ |
329 | ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12); | 304 | if (send_to_cam) |
305 | ret = send_video_command(pdev, 4, pChoose->mode, 12); | ||
330 | if (ret < 0) | 306 | if (ret < 0) |
331 | return ret; | 307 | return ret; |
332 | 308 | ||
333 | if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) { | 309 | if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420) |
334 | ret = pwc_dec23_init(pdev, pdev->type, buf); | 310 | pwc_dec23_init(pdev, pChoose->mode); |
335 | if (ret < 0) | ||
336 | return ret; | ||
337 | } | ||
338 | 311 | ||
339 | pdev->cmd_len = 12; | ||
340 | memcpy(pdev->cmd_buf, buf, 12); | ||
341 | /* All set and go */ | 312 | /* All set and go */ |
342 | pdev->vframes = frames; | 313 | pdev->pixfmt = pixfmt; |
314 | pdev->vframes = (fps + 1) * 5; | ||
343 | pdev->valternate = pChoose->alternate; | 315 | pdev->valternate = pChoose->alternate; |
344 | pdev->width = pwc_image_sizes[size][0]; | 316 | pdev->width = pwc_image_sizes[size][0]; |
345 | pdev->height = pwc_image_sizes[size][1]; | 317 | pdev->height = pwc_image_sizes[size][1]; |
@@ -354,22 +326,24 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, | |||
354 | } | 326 | } |
355 | 327 | ||
356 | int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, | 328 | int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, |
357 | int frames, int *compression) | 329 | int pixfmt, int frames, int *compression, int send_to_cam) |
358 | { | 330 | { |
359 | int ret, size; | 331 | int ret, size; |
360 | 332 | ||
361 | PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt); | 333 | PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", |
334 | width, height, frames, pixfmt); | ||
362 | size = pwc_get_size(pdev, width, height); | 335 | size = pwc_get_size(pdev, width, height); |
363 | PWC_TRACE("decode_size = %d.\n", size); | 336 | PWC_TRACE("decode_size = %d.\n", size); |
364 | 337 | ||
365 | if (DEVICE_USE_CODEC1(pdev->type)) { | 338 | if (DEVICE_USE_CODEC1(pdev->type)) { |
366 | ret = set_video_mode_Nala(pdev, size, frames, compression); | 339 | ret = set_video_mode_Nala(pdev, size, pixfmt, frames, |
367 | 340 | compression, send_to_cam); | |
368 | } else if (DEVICE_USE_CODEC3(pdev->type)) { | 341 | } else if (DEVICE_USE_CODEC3(pdev->type)) { |
369 | ret = set_video_mode_Kiara(pdev, size, frames, compression); | 342 | ret = set_video_mode_Kiara(pdev, size, pixfmt, frames, |
370 | 343 | compression, send_to_cam); | |
371 | } else { | 344 | } else { |
372 | ret = set_video_mode_Timon(pdev, size, frames, compression); | 345 | ret = set_video_mode_Timon(pdev, size, pixfmt, frames, |
346 | compression, send_to_cam); | ||
373 | } | 347 | } |
374 | if (ret < 0) { | 348 | if (ret < 0) { |
375 | PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); | 349 | PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); |
@@ -436,13 +410,12 @@ unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned i | |||
436 | int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) | 410 | int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) |
437 | { | 411 | { |
438 | int ret; | 412 | int ret; |
439 | u8 buf; | ||
440 | 413 | ||
441 | ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf)); | 414 | ret = recv_control_msg(pdev, request, value, 1); |
442 | if (ret < 0) | 415 | if (ret < 0) |
443 | return ret; | 416 | return ret; |
444 | 417 | ||
445 | *data = buf; | 418 | *data = pdev->ctrl_buf[0]; |
446 | return 0; | 419 | return 0; |
447 | } | 420 | } |
448 | 421 | ||
@@ -450,7 +423,8 @@ int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data) | |||
450 | { | 423 | { |
451 | int ret; | 424 | int ret; |
452 | 425 | ||
453 | ret = send_control_msg(pdev, request, value, &data, sizeof(data)); | 426 | pdev->ctrl_buf[0] = data; |
427 | ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 1); | ||
454 | if (ret < 0) | 428 | if (ret < 0) |
455 | return ret; | 429 | return ret; |
456 | 430 | ||
@@ -460,37 +434,34 @@ int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data) | |||
460 | int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) | 434 | int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) |
461 | { | 435 | { |
462 | int ret; | 436 | int ret; |
463 | s8 buf; | ||
464 | 437 | ||
465 | ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf)); | 438 | ret = recv_control_msg(pdev, request, value, 1); |
466 | if (ret < 0) | 439 | if (ret < 0) |
467 | return ret; | 440 | return ret; |
468 | 441 | ||
469 | *data = buf; | 442 | *data = ((s8 *)pdev->ctrl_buf)[0]; |
470 | return 0; | 443 | return 0; |
471 | } | 444 | } |
472 | 445 | ||
473 | int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) | 446 | int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) |
474 | { | 447 | { |
475 | int ret; | 448 | int ret; |
476 | u8 buf[2]; | ||
477 | 449 | ||
478 | ret = recv_control_msg(pdev, request, value, buf, sizeof(buf)); | 450 | ret = recv_control_msg(pdev, request, value, 2); |
479 | if (ret < 0) | 451 | if (ret < 0) |
480 | return ret; | 452 | return ret; |
481 | 453 | ||
482 | *data = (buf[1] << 8) | buf[0]; | 454 | *data = (pdev->ctrl_buf[1] << 8) | pdev->ctrl_buf[0]; |
483 | return 0; | 455 | return 0; |
484 | } | 456 | } |
485 | 457 | ||
486 | int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data) | 458 | int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data) |
487 | { | 459 | { |
488 | int ret; | 460 | int ret; |
489 | u8 buf[2]; | ||
490 | 461 | ||
491 | buf[0] = data & 0xff; | 462 | pdev->ctrl_buf[0] = data & 0xff; |
492 | buf[1] = data >> 8; | 463 | pdev->ctrl_buf[1] = data >> 8; |
493 | ret = send_control_msg(pdev, request, value, buf, sizeof(buf)); | 464 | ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 2); |
494 | if (ret < 0) | 465 | if (ret < 0) |
495 | return ret; | 466 | return ret; |
496 | 467 | ||
@@ -511,7 +482,6 @@ int pwc_button_ctrl(struct pwc_device *pdev, u16 value) | |||
511 | /* POWER */ | 482 | /* POWER */ |
512 | void pwc_camera_power(struct pwc_device *pdev, int power) | 483 | void pwc_camera_power(struct pwc_device *pdev, int power) |
513 | { | 484 | { |
514 | char buf; | ||
515 | int r; | 485 | int r; |
516 | 486 | ||
517 | if (!pdev->power_save) | 487 | if (!pdev->power_save) |
@@ -521,13 +491,11 @@ void pwc_camera_power(struct pwc_device *pdev, int power) | |||
521 | return; /* Not supported by Nala or Timon < release 6 */ | 491 | return; /* Not supported by Nala or Timon < release 6 */ |
522 | 492 | ||
523 | if (power) | 493 | if (power) |
524 | buf = 0x00; /* active */ | 494 | pdev->ctrl_buf[0] = 0x00; /* active */ |
525 | else | 495 | else |
526 | buf = 0xFF; /* power save */ | 496 | pdev->ctrl_buf[0] = 0xFF; /* power save */ |
527 | r = send_control_msg(pdev, | 497 | r = send_control_msg(pdev, SET_STATUS_CTL, |
528 | SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, | 498 | SET_POWER_SAVE_MODE_FORMATTER, pdev->ctrl_buf, 1); |
529 | &buf, sizeof(buf)); | ||
530 | |||
531 | if (r < 0) | 499 | if (r < 0) |
532 | PWC_ERROR("Failed to power %s camera (%d)\n", | 500 | PWC_ERROR("Failed to power %s camera (%d)\n", |
533 | power ? "on" : "off", r); | 501 | power ? "on" : "off", r); |
@@ -535,7 +503,6 @@ void pwc_camera_power(struct pwc_device *pdev, int power) | |||
535 | 503 | ||
536 | int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) | 504 | int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) |
537 | { | 505 | { |
538 | unsigned char buf[2]; | ||
539 | int r; | 506 | int r; |
540 | 507 | ||
541 | if (pdev->type < 730) | 508 | if (pdev->type < 730) |
@@ -551,11 +518,11 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) | |||
551 | if (off_value > 0xff) | 518 | if (off_value > 0xff) |
552 | off_value = 0xff; | 519 | off_value = 0xff; |
553 | 520 | ||
554 | buf[0] = on_value; | 521 | pdev->ctrl_buf[0] = on_value; |
555 | buf[1] = off_value; | 522 | pdev->ctrl_buf[1] = off_value; |
556 | 523 | ||
557 | r = send_control_msg(pdev, | 524 | r = send_control_msg(pdev, |
558 | SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf)); | 525 | SET_STATUS_CTL, LED_FORMATTER, pdev->ctrl_buf, 2); |
559 | if (r < 0) | 526 | if (r < 0) |
560 | PWC_ERROR("Failed to set LED on/off time (%d)\n", r); | 527 | PWC_ERROR("Failed to set LED on/off time (%d)\n", r); |
561 | 528 | ||
@@ -565,7 +532,6 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) | |||
565 | #ifdef CONFIG_USB_PWC_DEBUG | 532 | #ifdef CONFIG_USB_PWC_DEBUG |
566 | int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) | 533 | int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) |
567 | { | 534 | { |
568 | unsigned char buf; | ||
569 | int ret = -1, request; | 535 | int ret = -1, request; |
570 | 536 | ||
571 | if (pdev->type < 675) | 537 | if (pdev->type < 675) |
@@ -575,14 +541,13 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) | |||
575 | else | 541 | else |
576 | request = SENSOR_TYPE_FORMATTER2; | 542 | request = SENSOR_TYPE_FORMATTER2; |
577 | 543 | ||
578 | ret = recv_control_msg(pdev, | 544 | ret = recv_control_msg(pdev, GET_STATUS_CTL, request, 1); |
579 | GET_STATUS_CTL, request, &buf, sizeof(buf)); | ||
580 | if (ret < 0) | 545 | if (ret < 0) |
581 | return ret; | 546 | return ret; |
582 | if (pdev->type < 675) | 547 | if (pdev->type < 675) |
583 | *sensor = buf | 0x100; | 548 | *sensor = pdev->ctrl_buf[0] | 0x100; |
584 | else | 549 | else |
585 | *sensor = buf; | 550 | *sensor = pdev->ctrl_buf[0]; |
586 | return 0; | 551 | return 0; |
587 | } | 552 | } |
588 | #endif | 553 | #endif |
diff --git a/drivers/media/video/pwc/pwc-dec1.c b/drivers/media/video/pwc/pwc-dec1.c index be0e02cb487f..e899036aadf4 100644 --- a/drivers/media/video/pwc/pwc-dec1.c +++ b/drivers/media/video/pwc/pwc-dec1.c | |||
@@ -22,19 +22,11 @@ | |||
22 | along with this program; if not, write to the Free Software | 22 | along with this program; if not, write to the Free Software |
23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 | */ | 24 | */ |
25 | #include "pwc-dec1.h" | 25 | #include "pwc.h" |
26 | 26 | ||
27 | int pwc_dec1_init(struct pwc_device *pwc, int type, int release, void *buffer) | 27 | void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd) |
28 | { | 28 | { |
29 | struct pwc_dec1_private *pdec; | 29 | struct pwc_dec1_private *pdec = &pdev->dec1; |
30 | 30 | ||
31 | if (pwc->decompress_data == NULL) { | 31 | pdec->version = pdev->release; |
32 | pdec = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL); | ||
33 | if (pdec == NULL) | ||
34 | return -ENOMEM; | ||
35 | pwc->decompress_data = pdec; | ||
36 | } | ||
37 | pdec = pwc->decompress_data; | ||
38 | |||
39 | return 0; | ||
40 | } | 32 | } |
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/video/pwc/pwc-dec1.h index a57d8601080b..c565ef8f52fb 100644 --- a/drivers/media/video/pwc/pwc-dec1.h +++ b/drivers/media/video/pwc/pwc-dec1.h | |||
@@ -25,13 +25,15 @@ | |||
25 | #ifndef PWC_DEC1_H | 25 | #ifndef PWC_DEC1_H |
26 | #define PWC_DEC1_H | 26 | #define PWC_DEC1_H |
27 | 27 | ||
28 | #include "pwc.h" | 28 | #include <linux/mutex.h> |
29 | |||
30 | struct pwc_device; | ||
29 | 31 | ||
30 | struct pwc_dec1_private | 32 | struct pwc_dec1_private |
31 | { | 33 | { |
32 | int version; | 34 | int version; |
33 | }; | 35 | }; |
34 | 36 | ||
35 | int pwc_dec1_init(struct pwc_device *pwc, int type, int release, void *buffer); | 37 | void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd); |
36 | 38 | ||
37 | #endif | 39 | #endif |
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c index 2c6709112b2f..3792fedff951 100644 --- a/drivers/media/video/pwc/pwc-dec23.c +++ b/drivers/media/video/pwc/pwc-dec23.c | |||
@@ -294,22 +294,17 @@ static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE]; | |||
294 | 294 | ||
295 | 295 | ||
296 | /* If the type or the command change, we rebuild the lookup table */ | 296 | /* If the type or the command change, we rebuild the lookup table */ |
297 | int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd) | 297 | void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd) |
298 | { | 298 | { |
299 | int flags, version, shift, i; | 299 | int flags, version, shift, i; |
300 | struct pwc_dec23_private *pdec; | 300 | struct pwc_dec23_private *pdec = &pdev->dec23; |
301 | |||
302 | if (pwc->decompress_data == NULL) { | ||
303 | pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); | ||
304 | if (pdec == NULL) | ||
305 | return -ENOMEM; | ||
306 | pwc->decompress_data = pdec; | ||
307 | } | ||
308 | pdec = pwc->decompress_data; | ||
309 | 301 | ||
310 | mutex_init(&pdec->lock); | 302 | mutex_init(&pdec->lock); |
311 | 303 | ||
312 | if (DEVICE_USE_CODEC3(type)) { | 304 | if (pdec->last_cmd_valid && pdec->last_cmd == cmd[2]) |
305 | return; | ||
306 | |||
307 | if (DEVICE_USE_CODEC3(pdev->type)) { | ||
313 | flags = cmd[2] & 0x18; | 308 | flags = cmd[2] & 0x18; |
314 | if (flags == 8) | 309 | if (flags == 8) |
315 | pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */ | 310 | pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */ |
@@ -356,7 +351,8 @@ int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd) | |||
356 | pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255; | 351 | pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255; |
357 | #endif | 352 | #endif |
358 | 353 | ||
359 | return 0; | 354 | pdec->last_cmd = cmd[2]; |
355 | pdec->last_cmd_valid = 1; | ||
360 | } | 356 | } |
361 | 357 | ||
362 | /* | 358 | /* |
@@ -659,12 +655,12 @@ static void DecompressBand23(struct pwc_dec23_private *pdec, | |||
659 | * src: raw data | 655 | * src: raw data |
660 | * dst: image output | 656 | * dst: image output |
661 | */ | 657 | */ |
662 | void pwc_dec23_decompress(const struct pwc_device *pwc, | 658 | void pwc_dec23_decompress(struct pwc_device *pdev, |
663 | const void *src, | 659 | const void *src, |
664 | void *dst) | 660 | void *dst) |
665 | { | 661 | { |
666 | int bandlines_left, bytes_per_block; | 662 | int bandlines_left, bytes_per_block; |
667 | struct pwc_dec23_private *pdec = pwc->decompress_data; | 663 | struct pwc_dec23_private *pdec = &pdev->dec23; |
668 | 664 | ||
669 | /* YUV420P image format */ | 665 | /* YUV420P image format */ |
670 | unsigned char *pout_planar_y; | 666 | unsigned char *pout_planar_y; |
@@ -674,23 +670,22 @@ void pwc_dec23_decompress(const struct pwc_device *pwc, | |||
674 | 670 | ||
675 | mutex_lock(&pdec->lock); | 671 | mutex_lock(&pdec->lock); |
676 | 672 | ||
677 | bandlines_left = pwc->height / 4; | 673 | bandlines_left = pdev->height / 4; |
678 | bytes_per_block = pwc->width * 4; | 674 | bytes_per_block = pdev->width * 4; |
679 | plane_size = pwc->height * pwc->width; | 675 | plane_size = pdev->height * pdev->width; |
680 | 676 | ||
681 | pout_planar_y = dst; | 677 | pout_planar_y = dst; |
682 | pout_planar_u = dst + plane_size; | 678 | pout_planar_u = dst + plane_size; |
683 | pout_planar_v = dst + plane_size + plane_size / 4; | 679 | pout_planar_v = dst + plane_size + plane_size / 4; |
684 | 680 | ||
685 | while (bandlines_left--) { | 681 | while (bandlines_left--) { |
686 | DecompressBand23(pwc->decompress_data, | 682 | DecompressBand23(pdec, src, |
687 | src, | ||
688 | pout_planar_y, pout_planar_u, pout_planar_v, | 683 | pout_planar_y, pout_planar_u, pout_planar_v, |
689 | pwc->width, pwc->width); | 684 | pdev->width, pdev->width); |
690 | src += pwc->vbandlength; | 685 | src += pdev->vbandlength; |
691 | pout_planar_y += bytes_per_block; | 686 | pout_planar_y += bytes_per_block; |
692 | pout_planar_u += pwc->width; | 687 | pout_planar_u += pdev->width; |
693 | pout_planar_v += pwc->width; | 688 | pout_planar_v += pdev->width; |
694 | } | 689 | } |
695 | mutex_unlock(&pdec->lock); | 690 | mutex_unlock(&pdec->lock); |
696 | } | 691 | } |
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/video/pwc/pwc-dec23.h index d64a3c281af6..c655b1c1e6a9 100644 --- a/drivers/media/video/pwc/pwc-dec23.h +++ b/drivers/media/video/pwc/pwc-dec23.h | |||
@@ -25,17 +25,20 @@ | |||
25 | #ifndef PWC_DEC23_H | 25 | #ifndef PWC_DEC23_H |
26 | #define PWC_DEC23_H | 26 | #define PWC_DEC23_H |
27 | 27 | ||
28 | #include "pwc.h" | 28 | struct pwc_device; |
29 | 29 | ||
30 | struct pwc_dec23_private | 30 | struct pwc_dec23_private |
31 | { | 31 | { |
32 | struct mutex lock; | 32 | struct mutex lock; |
33 | 33 | ||
34 | unsigned char last_cmd, last_cmd_valid; | ||
35 | |||
34 | unsigned int scalebits; | 36 | unsigned int scalebits; |
35 | unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */ | 37 | unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */ |
36 | 38 | ||
37 | unsigned int reservoir; | 39 | unsigned int reservoir; |
38 | unsigned int nbits_in_reservoir; | 40 | unsigned int nbits_in_reservoir; |
41 | |||
39 | const unsigned char *stream; | 42 | const unsigned char *stream; |
40 | int temp_colors[16]; | 43 | int temp_colors[16]; |
41 | 44 | ||
@@ -51,8 +54,8 @@ struct pwc_dec23_private | |||
51 | 54 | ||
52 | }; | 55 | }; |
53 | 56 | ||
54 | int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd); | 57 | void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd); |
55 | void pwc_dec23_decompress(const struct pwc_device *pwc, | 58 | void pwc_dec23_decompress(struct pwc_device *pdev, |
56 | const void *src, | 59 | const void *src, |
57 | void *dst); | 60 | void *dst); |
58 | #endif | 61 | #endif |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 943d37ad0d33..122fbd0081eb 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -128,18 +128,11 @@ static struct usb_driver pwc_driver = { | |||
128 | #define MAX_DEV_HINTS 20 | 128 | #define MAX_DEV_HINTS 20 |
129 | #define MAX_ISOC_ERRORS 20 | 129 | #define MAX_ISOC_ERRORS 20 |
130 | 130 | ||
131 | static int default_fps = 10; | ||
132 | #ifdef CONFIG_USB_PWC_DEBUG | 131 | #ifdef CONFIG_USB_PWC_DEBUG |
133 | int pwc_trace = PWC_DEBUG_LEVEL; | 132 | int pwc_trace = PWC_DEBUG_LEVEL; |
134 | #endif | 133 | #endif |
135 | static int power_save = -1; | 134 | static int power_save = -1; |
136 | static int led_on = 100, led_off; /* defaults to LED that is on while in use */ | 135 | static int leds[2] = { 100, 0 }; |
137 | static struct { | ||
138 | int type; | ||
139 | char serial_number[30]; | ||
140 | int device_node; | ||
141 | struct pwc_device *pdev; | ||
142 | } device_hint[MAX_DEV_HINTS]; | ||
143 | 136 | ||
144 | /***/ | 137 | /***/ |
145 | 138 | ||
@@ -386,8 +379,8 @@ static int pwc_isoc_init(struct pwc_device *pdev) | |||
386 | retry: | 379 | retry: |
387 | /* We first try with low compression and then retry with a higher | 380 | /* We first try with low compression and then retry with a higher |
388 | compression setting if there is not enough bandwidth. */ | 381 | compression setting if there is not enough bandwidth. */ |
389 | ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, | 382 | ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt, |
390 | pdev->vframes, &compression); | 383 | pdev->vframes, &compression, 1); |
391 | 384 | ||
392 | /* Get the current alternate interface, adjust packet size */ | 385 | /* Get the current alternate interface, adjust packet size */ |
393 | intf = usb_ifnum_to_if(udev, 0); | 386 | intf = usb_ifnum_to_if(udev, 0); |
@@ -597,23 +590,9 @@ leave: | |||
597 | static void pwc_video_release(struct v4l2_device *v) | 590 | static void pwc_video_release(struct v4l2_device *v) |
598 | { | 591 | { |
599 | struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); | 592 | struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); |
600 | int hint; | ||
601 | |||
602 | /* search device_hint[] table if we occupy a slot, by any chance */ | ||
603 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) | ||
604 | if (device_hint[hint].pdev == pdev) | ||
605 | device_hint[hint].pdev = NULL; | ||
606 | |||
607 | /* Free intermediate decompression buffer & tables */ | ||
608 | if (pdev->decompress_data != NULL) { | ||
609 | PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n", | ||
610 | pdev->decompress_data); | ||
611 | kfree(pdev->decompress_data); | ||
612 | pdev->decompress_data = NULL; | ||
613 | } | ||
614 | 593 | ||
615 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); | 594 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); |
616 | 595 | kfree(pdev->ctrl_buf); | |
617 | kfree(pdev); | 596 | kfree(pdev); |
618 | } | 597 | } |
619 | 598 | ||
@@ -758,7 +737,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) | |||
758 | 737 | ||
759 | /* Turn on camera and set LEDS on */ | 738 | /* Turn on camera and set LEDS on */ |
760 | pwc_camera_power(pdev, 1); | 739 | pwc_camera_power(pdev, 1); |
761 | pwc_set_leds(pdev, led_on, led_off); | 740 | pwc_set_leds(pdev, leds[0], leds[1]); |
762 | 741 | ||
763 | r = pwc_isoc_init(pdev); | 742 | r = pwc_isoc_init(pdev); |
764 | if (r) { | 743 | if (r) { |
@@ -813,10 +792,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
813 | struct usb_device *udev = interface_to_usbdev(intf); | 792 | struct usb_device *udev = interface_to_usbdev(intf); |
814 | struct pwc_device *pdev = NULL; | 793 | struct pwc_device *pdev = NULL; |
815 | int vendor_id, product_id, type_id; | 794 | int vendor_id, product_id, type_id; |
816 | int hint, rc; | 795 | int rc; |
817 | int features = 0; | 796 | int features = 0; |
818 | int compression = 0; | 797 | int compression = 0; |
819 | int video_nr = -1; /* default: use next available device */ | ||
820 | int my_power_save = power_save; | 798 | int my_power_save = power_save; |
821 | char serial_number[30], *name; | 799 | char serial_number[30], *name; |
822 | 800 | ||
@@ -1076,7 +1054,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1076 | return -ENOMEM; | 1054 | return -ENOMEM; |
1077 | } | 1055 | } |
1078 | pdev->type = type_id; | 1056 | pdev->type = type_id; |
1079 | pdev->vframes = default_fps; | ||
1080 | pdev->features = features; | 1057 | pdev->features = features; |
1081 | pwc_construct(pdev); /* set min/max sizes correct */ | 1058 | pwc_construct(pdev); /* set min/max sizes correct */ |
1082 | 1059 | ||
@@ -1107,24 +1084,14 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1107 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); | 1084 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); |
1108 | PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); | 1085 | PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); |
1109 | 1086 | ||
1110 | /* Now search device_hint[] table for a match, so we can hint a node number. */ | 1087 | /* Allocate USB command buffers */ |
1111 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) { | 1088 | pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL); |
1112 | if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) && | 1089 | if (!pdev->ctrl_buf) { |
1113 | (device_hint[hint].pdev == NULL)) { | 1090 | PWC_ERROR("Oops, could not allocate memory for pwc_device.\n"); |
1114 | /* so far, so good... try serial number */ | 1091 | rc = -ENOMEM; |
1115 | if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) { | 1092 | goto err_free_mem; |
1116 | /* match! */ | ||
1117 | video_nr = device_hint[hint].device_node; | ||
1118 | PWC_DEBUG_PROBE("Found hint, will try to register as /dev/video%d\n", video_nr); | ||
1119 | break; | ||
1120 | } | ||
1121 | } | ||
1122 | } | 1093 | } |
1123 | 1094 | ||
1124 | /* occupy slot */ | ||
1125 | if (hint < MAX_DEV_HINTS) | ||
1126 | device_hint[hint].pdev = pdev; | ||
1127 | |||
1128 | #ifdef CONFIG_USB_PWC_DEBUG | 1095 | #ifdef CONFIG_USB_PWC_DEBUG |
1129 | /* Query sensor type */ | 1096 | /* Query sensor type */ |
1130 | if (pwc_get_cmos_sensor(pdev, &rc) >= 0) { | 1097 | if (pwc_get_cmos_sensor(pdev, &rc) >= 0) { |
@@ -1138,8 +1105,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1138 | pwc_set_leds(pdev, 0, 0); | 1105 | pwc_set_leds(pdev, 0, 0); |
1139 | 1106 | ||
1140 | /* Setup intial videomode */ | 1107 | /* Setup intial videomode */ |
1141 | rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, pdev->vframes, | 1108 | rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, |
1142 | &compression); | 1109 | V4L2_PIX_FMT_YUV420, 30, &compression, 1); |
1143 | if (rc) | 1110 | if (rc) |
1144 | goto err_free_mem; | 1111 | goto err_free_mem; |
1145 | 1112 | ||
@@ -1164,7 +1131,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1164 | pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler; | 1131 | pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler; |
1165 | pdev->vdev.v4l2_dev = &pdev->v4l2_dev; | 1132 | pdev->vdev.v4l2_dev = &pdev->v4l2_dev; |
1166 | 1133 | ||
1167 | rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr); | 1134 | rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1); |
1168 | if (rc < 0) { | 1135 | if (rc < 0) { |
1169 | PWC_ERROR("Failed to register as video device (%d).\n", rc); | 1136 | PWC_ERROR("Failed to register as video device (%d).\n", rc); |
1170 | goto err_unregister_v4l2_dev; | 1137 | goto err_unregister_v4l2_dev; |
@@ -1207,8 +1174,7 @@ err_unregister_v4l2_dev: | |||
1207 | err_free_controls: | 1174 | err_free_controls: |
1208 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); | 1175 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); |
1209 | err_free_mem: | 1176 | err_free_mem: |
1210 | if (hint < MAX_DEV_HINTS) | 1177 | kfree(pdev->ctrl_buf); |
1211 | device_hint[hint].pdev = NULL; | ||
1212 | kfree(pdev); | 1178 | kfree(pdev); |
1213 | return rc; | 1179 | return rc; |
1214 | } | 1180 | } |
@@ -1243,27 +1209,19 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
1243 | * Initialization code & module stuff | 1209 | * Initialization code & module stuff |
1244 | */ | 1210 | */ |
1245 | 1211 | ||
1246 | static int fps; | ||
1247 | static int leds[2] = { -1, -1 }; | ||
1248 | static unsigned int leds_nargs; | 1212 | static unsigned int leds_nargs; |
1249 | static char *dev_hint[MAX_DEV_HINTS]; | ||
1250 | static unsigned int dev_hint_nargs; | ||
1251 | 1213 | ||
1252 | module_param(fps, int, 0444); | ||
1253 | #ifdef CONFIG_USB_PWC_DEBUG | 1214 | #ifdef CONFIG_USB_PWC_DEBUG |
1254 | module_param_named(trace, pwc_trace, int, 0644); | 1215 | module_param_named(trace, pwc_trace, int, 0644); |
1255 | #endif | 1216 | #endif |
1256 | module_param(power_save, int, 0644); | 1217 | module_param(power_save, int, 0644); |
1257 | module_param_array(leds, int, &leds_nargs, 0444); | 1218 | module_param_array(leds, int, &leds_nargs, 0444); |
1258 | module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); | ||
1259 | 1219 | ||
1260 | MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); | ||
1261 | #ifdef CONFIG_USB_PWC_DEBUG | 1220 | #ifdef CONFIG_USB_PWC_DEBUG |
1262 | MODULE_PARM_DESC(trace, "For debugging purposes"); | 1221 | MODULE_PARM_DESC(trace, "For debugging purposes"); |
1263 | #endif | 1222 | #endif |
1264 | MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off"); | 1223 | MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off"); |
1265 | MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); | 1224 | MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); |
1266 | MODULE_PARM_DESC(dev_hint, "Device node hints"); | ||
1267 | 1225 | ||
1268 | MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); | 1226 | MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); |
1269 | MODULE_AUTHOR("Luc Saillard <luc@saillard.org>"); | 1227 | MODULE_AUTHOR("Luc Saillard <luc@saillard.org>"); |
@@ -1273,114 +1231,13 @@ MODULE_VERSION( PWC_VERSION ); | |||
1273 | 1231 | ||
1274 | static int __init usb_pwc_init(void) | 1232 | static int __init usb_pwc_init(void) |
1275 | { | 1233 | { |
1276 | int i; | ||
1277 | |||
1278 | #ifdef CONFIG_USB_PWC_DEBUG | ||
1279 | PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n"); | ||
1280 | PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); | ||
1281 | PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); | ||
1282 | PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); | ||
1283 | |||
1284 | if (pwc_trace >= 0) { | ||
1285 | PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace); | ||
1286 | } | ||
1287 | #endif | ||
1288 | |||
1289 | if (fps) { | ||
1290 | if (fps < 4 || fps > 30) { | ||
1291 | PWC_ERROR("Framerate out of bounds (4-30).\n"); | ||
1292 | return -EINVAL; | ||
1293 | } | ||
1294 | default_fps = fps; | ||
1295 | PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps); | ||
1296 | } | ||
1297 | |||
1298 | if (leds[0] >= 0) | ||
1299 | led_on = leds[0]; | ||
1300 | if (leds[1] >= 0) | ||
1301 | led_off = leds[1]; | ||
1302 | |||
1303 | /* Big device node whoopla. Basically, it allows you to assign a | ||
1304 | device node (/dev/videoX) to a camera, based on its type | ||
1305 | & serial number. The format is [type[.serialnumber]:]node. | ||
1306 | |||
1307 | Any camera that isn't matched by these rules gets the next | ||
1308 | available free device node. | ||
1309 | */ | ||
1310 | for (i = 0; i < MAX_DEV_HINTS; i++) { | ||
1311 | char *s, *colon, *dot; | ||
1312 | |||
1313 | /* This loop also initializes the array */ | ||
1314 | device_hint[i].pdev = NULL; | ||
1315 | s = dev_hint[i]; | ||
1316 | if (s != NULL && *s != '\0') { | ||
1317 | device_hint[i].type = -1; /* wildcard */ | ||
1318 | strcpy(device_hint[i].serial_number, "*"); | ||
1319 | |||
1320 | /* parse string: chop at ':' & '/' */ | ||
1321 | colon = dot = s; | ||
1322 | while (*colon != '\0' && *colon != ':') | ||
1323 | colon++; | ||
1324 | while (*dot != '\0' && *dot != '.') | ||
1325 | dot++; | ||
1326 | /* Few sanity checks */ | ||
1327 | if (*dot != '\0' && dot > colon) { | ||
1328 | PWC_ERROR("Malformed camera hint: the colon must be after the dot.\n"); | ||
1329 | return -EINVAL; | ||
1330 | } | ||
1331 | |||
1332 | if (*colon == '\0') { | ||
1333 | /* No colon */ | ||
1334 | if (*dot != '\0') { | ||
1335 | PWC_ERROR("Malformed camera hint: no colon + device node given.\n"); | ||
1336 | return -EINVAL; | ||
1337 | } | ||
1338 | else { | ||
1339 | /* No type or serial number specified, just a number. */ | ||
1340 | device_hint[i].device_node = | ||
1341 | simple_strtol(s, NULL, 10); | ||
1342 | } | ||
1343 | } | ||
1344 | else { | ||
1345 | /* There's a colon, so we have at least a type and a device node */ | ||
1346 | device_hint[i].type = | ||
1347 | simple_strtol(s, NULL, 10); | ||
1348 | device_hint[i].device_node = | ||
1349 | simple_strtol(colon + 1, NULL, 10); | ||
1350 | if (*dot != '\0') { | ||
1351 | /* There's a serial number as well */ | ||
1352 | int k; | ||
1353 | |||
1354 | dot++; | ||
1355 | k = 0; | ||
1356 | while (*dot != ':' && k < 29) { | ||
1357 | device_hint[i].serial_number[k++] = *dot; | ||
1358 | dot++; | ||
1359 | } | ||
1360 | device_hint[i].serial_number[k] = '\0'; | ||
1361 | } | ||
1362 | } | ||
1363 | PWC_TRACE("device_hint[%d]:\n", i); | ||
1364 | PWC_TRACE(" type : %d\n", device_hint[i].type); | ||
1365 | PWC_TRACE(" serial# : %s\n", device_hint[i].serial_number); | ||
1366 | PWC_TRACE(" node : %d\n", device_hint[i].device_node); | ||
1367 | } | ||
1368 | else | ||
1369 | device_hint[i].type = 0; /* not filled */ | ||
1370 | } /* ..for MAX_DEV_HINTS */ | ||
1371 | |||
1372 | PWC_DEBUG_PROBE("Registering driver at address 0x%p.\n", &pwc_driver); | ||
1373 | return usb_register(&pwc_driver); | 1234 | return usb_register(&pwc_driver); |
1374 | } | 1235 | } |
1375 | 1236 | ||
1376 | static void __exit usb_pwc_exit(void) | 1237 | static void __exit usb_pwc_exit(void) |
1377 | { | 1238 | { |
1378 | PWC_DEBUG_MODULE("Deregistering driver.\n"); | ||
1379 | usb_deregister(&pwc_driver); | 1239 | usb_deregister(&pwc_driver); |
1380 | PWC_INFO("Philips webcam module removed.\n"); | ||
1381 | } | 1240 | } |
1382 | 1241 | ||
1383 | module_init(usb_pwc_init); | 1242 | module_init(usb_pwc_init); |
1384 | module_exit(usb_pwc_exit); | 1243 | module_exit(usb_pwc_exit); |
1385 | |||
1386 | /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ | ||
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c index 23a55b5814fc..9be5adffa874 100644 --- a/drivers/media/video/pwc/pwc-misc.c +++ b/drivers/media/video/pwc/pwc-misc.c | |||
@@ -90,5 +90,4 @@ void pwc_construct(struct pwc_device *pdev) | |||
90 | pdev->frame_header_size = 0; | 90 | pdev->frame_header_size = 0; |
91 | pdev->frame_trailer_size = 0; | 91 | pdev->frame_trailer_size = 0; |
92 | } | 92 | } |
93 | pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */ | ||
94 | } | 93 | } |
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 80e25842e84a..f495eeb5403a 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -493,16 +493,11 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) | |||
493 | (pixelformat>>24)&255); | 493 | (pixelformat>>24)&255); |
494 | 494 | ||
495 | ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height, | 495 | ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height, |
496 | pdev->vframes, &compression); | 496 | pixelformat, 30, &compression, 0); |
497 | 497 | ||
498 | PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); | 498 | PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); |
499 | 499 | ||
500 | if (ret == 0) { | 500 | pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt); |
501 | pdev->pixfmt = pixelformat; | ||
502 | pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, | ||
503 | pdev->pixfmt); | ||
504 | } | ||
505 | |||
506 | leave: | 501 | leave: |
507 | mutex_unlock(&pdev->udevlock); | 502 | mutex_unlock(&pdev->udevlock); |
508 | return ret; | 503 | return ret; |
@@ -777,33 +772,33 @@ static int pwc_set_autogain_expo(struct pwc_device *pdev) | |||
777 | static int pwc_set_motor(struct pwc_device *pdev) | 772 | static int pwc_set_motor(struct pwc_device *pdev) |
778 | { | 773 | { |
779 | int ret; | 774 | int ret; |
780 | u8 buf[4]; | ||
781 | 775 | ||
782 | buf[0] = 0; | 776 | pdev->ctrl_buf[0] = 0; |
783 | if (pdev->motor_pan_reset->is_new) | 777 | if (pdev->motor_pan_reset->is_new) |
784 | buf[0] |= 0x01; | 778 | pdev->ctrl_buf[0] |= 0x01; |
785 | if (pdev->motor_tilt_reset->is_new) | 779 | if (pdev->motor_tilt_reset->is_new) |
786 | buf[0] |= 0x02; | 780 | pdev->ctrl_buf[0] |= 0x02; |
787 | if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) { | 781 | if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) { |
788 | ret = send_control_msg(pdev, SET_MPT_CTL, | 782 | ret = send_control_msg(pdev, SET_MPT_CTL, |
789 | PT_RESET_CONTROL_FORMATTER, buf, 1); | 783 | PT_RESET_CONTROL_FORMATTER, |
784 | pdev->ctrl_buf, 1); | ||
790 | if (ret < 0) | 785 | if (ret < 0) |
791 | return ret; | 786 | return ret; |
792 | } | 787 | } |
793 | 788 | ||
794 | memset(buf, 0, sizeof(buf)); | 789 | memset(pdev->ctrl_buf, 0, 4); |
795 | if (pdev->motor_pan->is_new) { | 790 | if (pdev->motor_pan->is_new) { |
796 | buf[0] = pdev->motor_pan->val & 0xFF; | 791 | pdev->ctrl_buf[0] = pdev->motor_pan->val & 0xFF; |
797 | buf[1] = (pdev->motor_pan->val >> 8); | 792 | pdev->ctrl_buf[1] = (pdev->motor_pan->val >> 8); |
798 | } | 793 | } |
799 | if (pdev->motor_tilt->is_new) { | 794 | if (pdev->motor_tilt->is_new) { |
800 | buf[2] = pdev->motor_tilt->val & 0xFF; | 795 | pdev->ctrl_buf[2] = pdev->motor_tilt->val & 0xFF; |
801 | buf[3] = (pdev->motor_tilt->val >> 8); | 796 | pdev->ctrl_buf[3] = (pdev->motor_tilt->val >> 8); |
802 | } | 797 | } |
803 | if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) { | 798 | if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) { |
804 | ret = send_control_msg(pdev, SET_MPT_CTL, | 799 | ret = send_control_msg(pdev, SET_MPT_CTL, |
805 | PT_RELATIVE_CONTROL_FORMATTER, | 800 | PT_RELATIVE_CONTROL_FORMATTER, |
806 | buf, sizeof(buf)); | 801 | pdev->ctrl_buf, 4); |
807 | if (ret < 0) | 802 | if (ret < 0) |
808 | return ret; | 803 | return ret; |
809 | } | 804 | } |
@@ -1094,6 +1089,63 @@ static int pwc_enum_frameintervals(struct file *file, void *fh, | |||
1094 | return 0; | 1089 | return 0; |
1095 | } | 1090 | } |
1096 | 1091 | ||
1092 | static int pwc_g_parm(struct file *file, void *fh, | ||
1093 | struct v4l2_streamparm *parm) | ||
1094 | { | ||
1095 | struct pwc_device *pdev = video_drvdata(file); | ||
1096 | |||
1097 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1098 | return -EINVAL; | ||
1099 | |||
1100 | memset(parm, 0, sizeof(*parm)); | ||
1101 | |||
1102 | parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1103 | parm->parm.capture.readbuffers = MIN_FRAMES; | ||
1104 | parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME; | ||
1105 | parm->parm.capture.timeperframe.denominator = pdev->vframes; | ||
1106 | parm->parm.capture.timeperframe.numerator = 1; | ||
1107 | |||
1108 | return 0; | ||
1109 | } | ||
1110 | |||
1111 | static int pwc_s_parm(struct file *file, void *fh, | ||
1112 | struct v4l2_streamparm *parm) | ||
1113 | { | ||
1114 | struct pwc_device *pdev = video_drvdata(file); | ||
1115 | int compression = 0; | ||
1116 | int ret, fps; | ||
1117 | |||
1118 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
1119 | parm->parm.capture.timeperframe.numerator == 0) | ||
1120 | return -EINVAL; | ||
1121 | |||
1122 | if (pwc_test_n_set_capt_file(pdev, file)) | ||
1123 | return -EBUSY; | ||
1124 | |||
1125 | fps = parm->parm.capture.timeperframe.denominator / | ||
1126 | parm->parm.capture.timeperframe.numerator; | ||
1127 | |||
1128 | mutex_lock(&pdev->udevlock); | ||
1129 | if (!pdev->udev) { | ||
1130 | ret = -ENODEV; | ||
1131 | goto leave; | ||
1132 | } | ||
1133 | |||
1134 | if (pdev->iso_init) { | ||
1135 | ret = -EBUSY; | ||
1136 | goto leave; | ||
1137 | } | ||
1138 | |||
1139 | ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt, | ||
1140 | fps, &compression, 0); | ||
1141 | |||
1142 | pwc_g_parm(file, fh, parm); | ||
1143 | |||
1144 | leave: | ||
1145 | mutex_unlock(&pdev->udevlock); | ||
1146 | return ret; | ||
1147 | } | ||
1148 | |||
1097 | static int pwc_log_status(struct file *file, void *priv) | 1149 | static int pwc_log_status(struct file *file, void *priv) |
1098 | { | 1150 | { |
1099 | struct pwc_device *pdev = video_drvdata(file); | 1151 | struct pwc_device *pdev = video_drvdata(file); |
@@ -1120,4 +1172,6 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = { | |||
1120 | .vidioc_log_status = pwc_log_status, | 1172 | .vidioc_log_status = pwc_log_status, |
1121 | .vidioc_enum_framesizes = pwc_enum_framesizes, | 1173 | .vidioc_enum_framesizes = pwc_enum_framesizes, |
1122 | .vidioc_enum_frameintervals = pwc_enum_frameintervals, | 1174 | .vidioc_enum_frameintervals = pwc_enum_frameintervals, |
1175 | .vidioc_g_parm = pwc_g_parm, | ||
1176 | .vidioc_s_parm = pwc_s_parm, | ||
1123 | }; | 1177 | }; |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 47c518fef179..e4d4d711dd1f 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -44,6 +44,8 @@ | |||
44 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 44 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
45 | #include <linux/input.h> | 45 | #include <linux/input.h> |
46 | #endif | 46 | #endif |
47 | #include "pwc-dec1.h" | ||
48 | #include "pwc-dec23.h" | ||
47 | 49 | ||
48 | /* Version block */ | 50 | /* Version block */ |
49 | #define PWC_VERSION "10.0.15" | 51 | #define PWC_VERSION "10.0.15" |
@@ -132,9 +134,6 @@ | |||
132 | #define DEVICE_USE_CODEC3(x) ((x)>=700) | 134 | #define DEVICE_USE_CODEC3(x) ((x)>=700) |
133 | #define DEVICE_USE_CODEC23(x) ((x)>=675) | 135 | #define DEVICE_USE_CODEC23(x) ((x)>=675) |
134 | 136 | ||
135 | /* from pwc-dec.h */ | ||
136 | #define PWCX_FLAG_PLANAR 0x0001 | ||
137 | |||
138 | /* Request types: video */ | 137 | /* Request types: video */ |
139 | #define SET_LUM_CTL 0x01 | 138 | #define SET_LUM_CTL 0x01 |
140 | #define GET_LUM_CTL 0x02 | 139 | #define GET_LUM_CTL 0x02 |
@@ -248,8 +247,8 @@ struct pwc_device | |||
248 | char vmirror; /* for ToUCaM series */ | 247 | char vmirror; /* for ToUCaM series */ |
249 | char power_save; /* Do powersaving for this cam */ | 248 | char power_save; /* Do powersaving for this cam */ |
250 | 249 | ||
251 | int cmd_len; | ||
252 | unsigned char cmd_buf[13]; | 250 | unsigned char cmd_buf[13]; |
251 | unsigned char *ctrl_buf; | ||
253 | 252 | ||
254 | struct urb *urbs[MAX_ISO_BUFS]; | 253 | struct urb *urbs[MAX_ISO_BUFS]; |
255 | char iso_init; | 254 | char iso_init; |
@@ -272,7 +271,10 @@ struct pwc_device | |||
272 | int frame_total_size; /* including header & trailer */ | 271 | int frame_total_size; /* including header & trailer */ |
273 | int drop_frames; | 272 | int drop_frames; |
274 | 273 | ||
275 | void *decompress_data; /* private data for decompression engine */ | 274 | union { /* private data for decompression engine */ |
275 | struct pwc_dec1_private dec1; | ||
276 | struct pwc_dec23_private dec23; | ||
277 | }; | ||
276 | 278 | ||
277 | /* | 279 | /* |
278 | * We have an 'image' and a 'view', where 'image' is the fixed-size img | 280 | * We have an 'image' and a 'view', where 'image' is the fixed-size img |
@@ -364,7 +366,7 @@ void pwc_construct(struct pwc_device *pdev); | |||
364 | /** Functions in pwc-ctrl.c */ | 366 | /** Functions in pwc-ctrl.c */ |
365 | /* Request a certain video mode. Returns < 0 if not possible */ | 367 | /* Request a certain video mode. Returns < 0 if not possible */ |
366 | extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, | 368 | extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, |
367 | int frames, int *compression); | 369 | int pixfmt, int frames, int *compression, int send_to_cam); |
368 | extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size); | 370 | extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size); |
369 | extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); | 371 | extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); |
370 | extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); | 372 | extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); |
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 510cfab477ff..a9e9653beeb4 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -693,7 +693,7 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, | |||
693 | mf->code = 0; | 693 | mf->code = 0; |
694 | continue; | 694 | continue; |
695 | } | 695 | } |
696 | if (mf->width != tfmt->width || mf->width != tfmt->width) { | 696 | if (mf->width != tfmt->width || mf->height != tfmt->height) { |
697 | u32 fcc = ffmt->fourcc; | 697 | u32 fcc = ffmt->fourcc; |
698 | tfmt->width = mf->width; | 698 | tfmt->width = mf->width; |
699 | tfmt->height = mf->height; | 699 | tfmt->height = mf->height; |
@@ -702,7 +702,8 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, | |||
702 | NULL, &fcc, FIMC_SD_PAD_SOURCE); | 702 | NULL, &fcc, FIMC_SD_PAD_SOURCE); |
703 | if (ffmt && ffmt->mbus_code) | 703 | if (ffmt && ffmt->mbus_code) |
704 | mf->code = ffmt->mbus_code; | 704 | mf->code = ffmt->mbus_code; |
705 | if (mf->width != tfmt->width || mf->width != tfmt->width) | 705 | if (mf->width != tfmt->width || |
706 | mf->height != tfmt->height) | ||
706 | continue; | 707 | continue; |
707 | tfmt->code = mf->code; | 708 | tfmt->code = mf->code; |
708 | } | 709 | } |
@@ -710,7 +711,7 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, | |||
710 | ret = v4l2_subdev_call(csis, pad, set_fmt, NULL, &sfmt); | 711 | ret = v4l2_subdev_call(csis, pad, set_fmt, NULL, &sfmt); |
711 | 712 | ||
712 | if (mf->code == tfmt->code && | 713 | if (mf->code == tfmt->code && |
713 | mf->width == tfmt->width && mf->width == tfmt->width) | 714 | mf->width == tfmt->width && mf->height == tfmt->height) |
714 | break; | 715 | break; |
715 | } | 716 | } |
716 | 717 | ||
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index f5cbb8a4c540..81bcbb9492ea 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -848,11 +848,11 @@ int fimc_ctrls_create(struct fimc_ctx *ctx) | |||
848 | v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4); | 848 | v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4); |
849 | 849 | ||
850 | ctx->ctrl_rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, | 850 | ctx->ctrl_rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, |
851 | V4L2_CID_HFLIP, 0, 1, 1, 0); | 851 | V4L2_CID_ROTATE, 0, 270, 90, 0); |
852 | ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, | 852 | ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, |
853 | V4L2_CID_VFLIP, 0, 1, 1, 0); | 853 | V4L2_CID_HFLIP, 0, 1, 1, 0); |
854 | ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, | 854 | ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, |
855 | V4L2_CID_ROTATE, 0, 270, 90, 0); | 855 | V4L2_CID_VFLIP, 0, 1, 1, 0); |
856 | if (variant->has_alpha) | 856 | if (variant->has_alpha) |
857 | ctx->ctrl_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler, | 857 | ctx->ctrl_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler, |
858 | &fimc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, | 858 | &fimc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, |
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index 615c862f0360..8ea4ee116e46 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/pm_runtime.h> | 21 | #include <linux/pm_runtime.h> |
22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/version.h> | ||
25 | #include <media/v4l2-ctrls.h> | 24 | #include <media/v4l2-ctrls.h> |
26 | #include <media/media-device.h> | 25 | #include <media/media-device.h> |
27 | 26 | ||
diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c index c40b0dde1883..febaa673d363 100644 --- a/drivers/media/video/s5p-g2d/g2d.c +++ b/drivers/media/video/s5p-g2d/g2d.c | |||
@@ -184,6 +184,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) | |||
184 | ctx->rop = ROP4_INVERT; | 184 | ctx->rop = ROP4_INVERT; |
185 | else | 185 | else |
186 | ctx->rop = ROP4_COPY; | 186 | ctx->rop = ROP4_COPY; |
187 | break; | ||
187 | default: | 188 | default: |
188 | v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n"); | 189 | v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n"); |
189 | return -EINVAL; | 190 | return -EINVAL; |
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.c b/drivers/media/video/s5p-jpeg/jpeg-core.c index f841a3e9845c..1105a8749c8b 100644 --- a/drivers/media/video/s5p-jpeg/jpeg-core.c +++ b/drivers/media/video/s5p-jpeg/jpeg-core.c | |||
@@ -989,9 +989,10 @@ static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = { | |||
989 | * ============================================================================ | 989 | * ============================================================================ |
990 | */ | 990 | */ |
991 | 991 | ||
992 | static int s5p_jpeg_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, | 992 | static int s5p_jpeg_queue_setup(struct vb2_queue *vq, |
993 | unsigned int *nplanes, unsigned int sizes[], | 993 | const struct v4l2_format *fmt, |
994 | void *alloc_ctxs[]) | 994 | unsigned int *nbuffers, unsigned int *nplanes, |
995 | unsigned int sizes[], void *alloc_ctxs[]) | ||
995 | { | 996 | { |
996 | struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq); | 997 | struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq); |
997 | struct s5p_jpeg_q_data *q_data = NULL; | 998 | struct s5p_jpeg_q_data *q_data = NULL; |
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc.c b/drivers/media/video/s5p-mfc/s5p_mfc.c index e43e128baf5f..83fe461af263 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/version.h> | ||
22 | #include <linux/videodev2.h> | 21 | #include <linux/videodev2.h> |
23 | #include <linux/workqueue.h> | 22 | #include <linux/workqueue.h> |
24 | #include <media/videobuf2-core.h> | 23 | #include <media/videobuf2-core.h> |
@@ -475,7 +474,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, | |||
475 | ctx->mv_size = 0; | 474 | ctx->mv_size = 0; |
476 | } | 475 | } |
477 | ctx->dpb_count = s5p_mfc_get_dpb_count(); | 476 | ctx->dpb_count = s5p_mfc_get_dpb_count(); |
478 | if (ctx->img_width == 0 || ctx->img_width == 0) | 477 | if (ctx->img_width == 0 || ctx->img_height == 0) |
479 | ctx->state = MFCINST_ERROR; | 478 | ctx->state = MFCINST_ERROR; |
480 | else | 479 | else |
481 | ctx->state = MFCINST_HEAD_PARSED; | 480 | ctx->state = MFCINST_HEAD_PARSED; |
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index 844a4d7797bc..c25ec022d267 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c | |||
@@ -165,7 +165,7 @@ static struct mfc_control controls[] = { | |||
165 | .maximum = 32, | 165 | .maximum = 32, |
166 | .step = 1, | 166 | .step = 1, |
167 | .default_value = 1, | 167 | .default_value = 1, |
168 | .flags = V4L2_CTRL_FLAG_VOLATILE, | 168 | .is_volatile = 1, |
169 | }, | 169 | }, |
170 | }; | 170 | }; |
171 | 171 | ||
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c index 971591d6450f..5b72da5ce418 100644 --- a/drivers/media/video/saa7164/saa7164-cards.c +++ b/drivers/media/video/saa7164/saa7164-cards.c | |||
@@ -269,8 +269,6 @@ struct saa7164_board saa7164_boards[] = { | |||
269 | .portb = SAA7164_MPEG_DVB, | 269 | .portb = SAA7164_MPEG_DVB, |
270 | .portc = SAA7164_MPEG_ENCODER, | 270 | .portc = SAA7164_MPEG_ENCODER, |
271 | .portd = SAA7164_MPEG_ENCODER, | 271 | .portd = SAA7164_MPEG_ENCODER, |
272 | .portc = SAA7164_MPEG_ENCODER, | ||
273 | .portd = SAA7164_MPEG_ENCODER, | ||
274 | .porte = SAA7164_MPEG_VBI, | 272 | .porte = SAA7164_MPEG_VBI, |
275 | .portf = SAA7164_MPEG_VBI, | 273 | .portf = SAA7164_MPEG_VBI, |
276 | .chiprev = SAA7164_CHIP_REV3, | 274 | .chiprev = SAA7164_CHIP_REV3, |
@@ -333,8 +331,6 @@ struct saa7164_board saa7164_boards[] = { | |||
333 | .portd = SAA7164_MPEG_ENCODER, | 331 | .portd = SAA7164_MPEG_ENCODER, |
334 | .porte = SAA7164_MPEG_VBI, | 332 | .porte = SAA7164_MPEG_VBI, |
335 | .portf = SAA7164_MPEG_VBI, | 333 | .portf = SAA7164_MPEG_VBI, |
336 | .porte = SAA7164_MPEG_VBI, | ||
337 | .portf = SAA7164_MPEG_VBI, | ||
338 | .chiprev = SAA7164_CHIP_REV3, | 334 | .chiprev = SAA7164_CHIP_REV3, |
339 | .unit = {{ | 335 | .unit = {{ |
340 | .id = 0x28, | 336 | .id = 0x28, |
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c index 129f135d5a5f..c096b3f74200 100644 --- a/drivers/media/video/tlg2300/pd-main.c +++ b/drivers/media/video/tlg2300/pd-main.c | |||
@@ -374,7 +374,7 @@ static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev) | |||
374 | } | 374 | } |
375 | #endif | 375 | #endif |
376 | 376 | ||
377 | static bool check_firmware(struct usb_device *udev, int *down_firmware) | 377 | static int check_firmware(struct usb_device *udev, int *down_firmware) |
378 | { | 378 | { |
379 | void *buf; | 379 | void *buf; |
380 | int ret; | 380 | int ret; |
@@ -398,7 +398,7 @@ static bool check_firmware(struct usb_device *udev, int *down_firmware) | |||
398 | *down_firmware = 1; | 398 | *down_firmware = 1; |
399 | return firmware_download(udev); | 399 | return firmware_download(udev); |
400 | } | 400 | } |
401 | return ret; | 401 | return 0; |
402 | } | 402 | } |
403 | 403 | ||
404 | static int poseidon_probe(struct usb_interface *interface, | 404 | static int poseidon_probe(struct usb_interface *interface, |
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index da1f4c2d2d4b..cccd42be718a 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c | |||
@@ -465,8 +465,8 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
465 | case V4L2_CID_CHROMA_GAIN: return "Chroma Gain"; | 465 | case V4L2_CID_CHROMA_GAIN: return "Chroma Gain"; |
466 | case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1"; | 466 | case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1"; |
467 | case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2"; | 467 | case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2"; |
468 | case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Minimum Number of Capture Buffers"; | 468 | case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers"; |
469 | case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Minimum Number of Output Buffers"; | 469 | case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers"; |
470 | case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component"; | 470 | case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component"; |
471 | 471 | ||
472 | /* MPEG controls */ | 472 | /* MPEG controls */ |
@@ -506,25 +506,25 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
506 | case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV"; | 506 | case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV"; |
507 | case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface"; | 507 | case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface"; |
508 | case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable"; | 508 | case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable"; |
509 | case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "The Number of Intra Refresh MBs"; | 509 | case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs"; |
510 | case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable"; | 510 | case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable"; |
511 | case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control"; | 511 | case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control"; |
512 | case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode"; | 512 | case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode"; |
513 | case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "The Max Number of Reference Picture"; | 513 | case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics"; |
514 | case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value"; | 514 | case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value"; |
515 | case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P frame QP Value"; | 515 | case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value"; |
516 | case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B frame QP Value"; | 516 | case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value"; |
517 | case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value"; | 517 | case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value"; |
518 | case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value"; | 518 | case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value"; |
519 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value"; | 519 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value"; |
520 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P frame QP Value"; | 520 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P-Frame QP Value"; |
521 | case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B frame QP Value"; | 521 | case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B-Frame QP Value"; |
522 | case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value"; | 522 | case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value"; |
523 | case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value"; | 523 | case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value"; |
524 | case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable"; | 524 | case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable"; |
525 | case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size"; | 525 | case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size"; |
526 | case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entorpy Mode"; | 526 | case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entropy Mode"; |
527 | case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I Period"; | 527 | case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I-Frame Period"; |
528 | case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level"; | 528 | case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level"; |
529 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset"; | 529 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset"; |
530 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset"; | 530 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset"; |
@@ -535,16 +535,16 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
535 | case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable"; | 535 | case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable"; |
536 | case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC"; | 536 | case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC"; |
537 | case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; | 537 | case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; |
538 | case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P frame QP Value"; | 538 | case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value"; |
539 | case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B frame QP Value"; | 539 | case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value"; |
540 | case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value"; | 540 | case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value"; |
541 | case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value"; | 541 | case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value"; |
542 | case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level"; | 542 | case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level"; |
543 | case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile"; | 543 | case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile"; |
544 | case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable"; | 544 | case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable"; |
545 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "The Maximum Bytes Per Slice"; | 545 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "Maximum Bytes in a Slice"; |
546 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "The Number of MB in a Slice"; | 546 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice"; |
547 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "The Slice Partitioning Method"; | 547 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method"; |
548 | case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size"; | 548 | case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size"; |
549 | 549 | ||
550 | /* CAMERA controls */ | 550 | /* CAMERA controls */ |
@@ -580,7 +580,7 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
580 | case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled"; | 580 | case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled"; |
581 | case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time"; | 581 | case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time"; |
582 | case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation"; | 582 | case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation"; |
583 | case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Feature Enabled"; | 583 | case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Enabled"; |
584 | case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain"; | 584 | case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain"; |
585 | case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold"; | 585 | case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold"; |
586 | case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time"; | 586 | case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time"; |
@@ -588,24 +588,24 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
588 | case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled"; | 588 | case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled"; |
589 | case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation"; | 589 | case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation"; |
590 | case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency"; | 590 | case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency"; |
591 | case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-emphasis settings"; | 591 | case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-Emphasis"; |
592 | case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level"; | 592 | case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level"; |
593 | case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor"; | 593 | case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor"; |
594 | 594 | ||
595 | /* Flash controls */ | 595 | /* Flash controls */ |
596 | case V4L2_CID_FLASH_CLASS: return "Flash controls"; | 596 | case V4L2_CID_FLASH_CLASS: return "Flash Controls"; |
597 | case V4L2_CID_FLASH_LED_MODE: return "LED mode"; | 597 | case V4L2_CID_FLASH_LED_MODE: return "LED Mode"; |
598 | case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe source"; | 598 | case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source"; |
599 | case V4L2_CID_FLASH_STROBE: return "Strobe"; | 599 | case V4L2_CID_FLASH_STROBE: return "Strobe"; |
600 | case V4L2_CID_FLASH_STROBE_STOP: return "Stop strobe"; | 600 | case V4L2_CID_FLASH_STROBE_STOP: return "Stop Strobe"; |
601 | case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe status"; | 601 | case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe Status"; |
602 | case V4L2_CID_FLASH_TIMEOUT: return "Strobe timeout"; | 602 | case V4L2_CID_FLASH_TIMEOUT: return "Strobe Timeout"; |
603 | case V4L2_CID_FLASH_INTENSITY: return "Intensity, flash mode"; | 603 | case V4L2_CID_FLASH_INTENSITY: return "Intensity, Flash Mode"; |
604 | case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, torch mode"; | 604 | case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, Torch Mode"; |
605 | case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, indicator"; | 605 | case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, Indicator"; |
606 | case V4L2_CID_FLASH_FAULT: return "Faults"; | 606 | case V4L2_CID_FLASH_FAULT: return "Faults"; |
607 | case V4L2_CID_FLASH_CHARGE: return "Charge"; | 607 | case V4L2_CID_FLASH_CHARGE: return "Charge"; |
608 | case V4L2_CID_FLASH_READY: return "Ready to strobe"; | 608 | case V4L2_CID_FLASH_READY: return "Ready to Strobe"; |
609 | 609 | ||
610 | default: | 610 | default: |
611 | return NULL; | 611 | return NULL; |
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 77feeb67e2db..3f623859a337 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -1871,6 +1871,7 @@ static long __video_do_ioctl(struct file *file, | |||
1871 | case VIDIOC_S_FREQUENCY: | 1871 | case VIDIOC_S_FREQUENCY: |
1872 | { | 1872 | { |
1873 | struct v4l2_frequency *p = arg; | 1873 | struct v4l2_frequency *p = arg; |
1874 | enum v4l2_tuner_type type; | ||
1874 | 1875 | ||
1875 | if (!ops->vidioc_s_frequency) | 1876 | if (!ops->vidioc_s_frequency) |
1876 | break; | 1877 | break; |
@@ -1878,9 +1879,14 @@ static long __video_do_ioctl(struct file *file, | |||
1878 | ret = ret_prio; | 1879 | ret = ret_prio; |
1879 | break; | 1880 | break; |
1880 | } | 1881 | } |
1882 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1883 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1881 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", | 1884 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", |
1882 | p->tuner, p->type, p->frequency); | 1885 | p->tuner, p->type, p->frequency); |
1883 | ret = ops->vidioc_s_frequency(file, fh, p); | 1886 | if (p->type != type) |
1887 | ret = -EINVAL; | ||
1888 | else | ||
1889 | ret = ops->vidioc_s_frequency(file, fh, p); | ||
1884 | break; | 1890 | break; |
1885 | } | 1891 | } |
1886 | case VIDIOC_G_SLICED_VBI_CAP: | 1892 | case VIDIOC_G_SLICED_VBI_CAP: |
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index f6d26419445e..4c09ab781ec3 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c | |||
@@ -1958,7 +1958,6 @@ static int zoran_g_fbuf(struct file *file, void *__fh, | |||
1958 | mutex_unlock(&zr->resource_lock); | 1958 | mutex_unlock(&zr->resource_lock); |
1959 | fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; | 1959 | fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; |
1960 | fb->fmt.field = V4L2_FIELD_INTERLACED; | 1960 | fb->fmt.field = V4L2_FIELD_INTERLACED; |
1961 | fb->flags = V4L2_FBUF_FLAG_OVERLAY; | ||
1962 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; | 1961 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; |
1963 | 1962 | ||
1964 | return 0; | 1963 | return 0; |