diff options
author | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-12-26 11:09:28 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-12-26 11:09:28 -0500 |
commit | 0e0694ff1a7791274946b7f51bae692da0001a08 (patch) | |
tree | 53d28f58d793c151aa870f17d38ddec6ac01ec7a | |
parent | 65390ea01ce678379da32b01f39fcfac4903f256 (diff) | |
parent | c739c0a7c3c2472d7562b8f802cdce44d2597c8b (diff) |
Merge branch 'patchwork' into v4l_for_linus
* patchwork:
[media] s5k4ecgx: select CRC32 helper
[media] dvb: avoid warning in dvb_net
[media] v4l: tvp5150: Don't override output pinmuxing at stream on/off time
[media] v4l: tvp5150: Fix comment regarding output pin muxing
[media] v4l: tvp5150: Reset device at probe time, not in get/set format handlers
[media] pctv452e: move buffer to heap, no mutex
[media] media/cobalt: use pci_irq_allocate_vectors
[media] cec: fix race between configuring and unconfiguring
[media] cec: move cec_report_phys_addr into cec_config_thread_func
[media] cec: replace cec_report_features by cec_fill_msg_report_features
[media] cec: update log_addr[] before finishing configuration
[media] cec: CEC_MSG_GIVE_FEATURES should abort for CEC version < 2
[media] cec: when canceling a message, don't overwrite old status info
[media] cec: fix report_current_latency
[media] smiapp: Make suspend and resume functions __maybe_unused
[media] smiapp: Implement power-on and power-off sequences without runtime PM
-rw-r--r-- | drivers/media/cec/cec-adap.c | 103 | ||||
-rw-r--r-- | drivers/media/dvb-core/dvb_net.c | 15 | ||||
-rw-r--r-- | drivers/media/i2c/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/i2c/smiapp/smiapp-core.c | 33 | ||||
-rw-r--r-- | drivers/media/i2c/tvp5150.c | 56 | ||||
-rw-r--r-- | drivers/media/i2c/tvp5150_reg.h | 9 | ||||
-rw-r--r-- | drivers/media/pci/cobalt/cobalt-driver.c | 8 | ||||
-rw-r--r-- | drivers/media/pci/cobalt/cobalt-driver.h | 2 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/pctv452e.c | 133 | ||||
-rw-r--r-- | include/uapi/linux/cec-funcs.h | 10 |
10 files changed, 195 insertions, 175 deletions
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 0ea4efb3de66..ebb5e391b800 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c | |||
@@ -30,8 +30,9 @@ | |||
30 | 30 | ||
31 | #include "cec-priv.h" | 31 | #include "cec-priv.h" |
32 | 32 | ||
33 | static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx); | 33 | static void cec_fill_msg_report_features(struct cec_adapter *adap, |
34 | static int cec_report_phys_addr(struct cec_adapter *adap, unsigned int la_idx); | 34 | struct cec_msg *msg, |
35 | unsigned int la_idx); | ||
35 | 36 | ||
36 | /* | 37 | /* |
37 | * 400 ms is the time it takes for one 16 byte message to be | 38 | * 400 ms is the time it takes for one 16 byte message to be |
@@ -288,10 +289,10 @@ static void cec_data_cancel(struct cec_data *data) | |||
288 | 289 | ||
289 | /* Mark it as an error */ | 290 | /* Mark it as an error */ |
290 | data->msg.tx_ts = ktime_get_ns(); | 291 | data->msg.tx_ts = ktime_get_ns(); |
291 | data->msg.tx_status = CEC_TX_STATUS_ERROR | | 292 | data->msg.tx_status |= CEC_TX_STATUS_ERROR | |
292 | CEC_TX_STATUS_MAX_RETRIES; | 293 | CEC_TX_STATUS_MAX_RETRIES; |
294 | data->msg.tx_error_cnt++; | ||
293 | data->attempts = 0; | 295 | data->attempts = 0; |
294 | data->msg.tx_error_cnt = 1; | ||
295 | /* Queue transmitted message for monitoring purposes */ | 296 | /* Queue transmitted message for monitoring purposes */ |
296 | cec_queue_msg_monitor(data->adap, &data->msg, 1); | 297 | cec_queue_msg_monitor(data->adap, &data->msg, 1); |
297 | 298 | ||
@@ -851,7 +852,7 @@ static const u8 cec_msg_size[256] = { | |||
851 | [CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED, | 852 | [CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED, |
852 | [CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED, | 853 | [CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED, |
853 | [CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST, | 854 | [CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST, |
854 | [CEC_MSG_REPORT_CURRENT_LATENCY] = 7 | BCAST, | 855 | [CEC_MSG_REPORT_CURRENT_LATENCY] = 6 | BCAST, |
855 | [CEC_MSG_CDC_MESSAGE] = 2 | BCAST, | 856 | [CEC_MSG_CDC_MESSAGE] = 2 | BCAST, |
856 | }; | 857 | }; |
857 | 858 | ||
@@ -1250,30 +1251,49 @@ configured: | |||
1250 | for (i = 1; i < las->num_log_addrs; i++) | 1251 | for (i = 1; i < las->num_log_addrs; i++) |
1251 | las->log_addr[i] = CEC_LOG_ADDR_INVALID; | 1252 | las->log_addr[i] = CEC_LOG_ADDR_INVALID; |
1252 | } | 1253 | } |
1254 | for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) | ||
1255 | las->log_addr[i] = CEC_LOG_ADDR_INVALID; | ||
1253 | adap->is_configured = true; | 1256 | adap->is_configured = true; |
1254 | adap->is_configuring = false; | 1257 | adap->is_configuring = false; |
1255 | cec_post_state_event(adap); | 1258 | cec_post_state_event(adap); |
1256 | mutex_unlock(&adap->lock); | ||
1257 | 1259 | ||
1260 | /* | ||
1261 | * Now post the Report Features and Report Physical Address broadcast | ||
1262 | * messages. Note that these are non-blocking transmits, meaning that | ||
1263 | * they are just queued up and once adap->lock is unlocked the main | ||
1264 | * thread will kick in and start transmitting these. | ||
1265 | * | ||
1266 | * If after this function is done (but before one or more of these | ||
1267 | * messages are actually transmitted) the CEC adapter is unconfigured, | ||
1268 | * then any remaining messages will be dropped by the main thread. | ||
1269 | */ | ||
1258 | for (i = 0; i < las->num_log_addrs; i++) { | 1270 | for (i = 0; i < las->num_log_addrs; i++) { |
1271 | struct cec_msg msg = {}; | ||
1272 | |||
1259 | if (las->log_addr[i] == CEC_LOG_ADDR_INVALID || | 1273 | if (las->log_addr[i] == CEC_LOG_ADDR_INVALID || |
1260 | (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY)) | 1274 | (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY)) |
1261 | continue; | 1275 | continue; |
1262 | 1276 | ||
1263 | /* | 1277 | msg.msg[0] = (las->log_addr[i] << 4) | 0x0f; |
1264 | * Report Features must come first according | 1278 | |
1265 | * to CEC 2.0 | 1279 | /* Report Features must come first according to CEC 2.0 */ |
1266 | */ | 1280 | if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED && |
1267 | if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED) | 1281 | adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) { |
1268 | cec_report_features(adap, i); | 1282 | cec_fill_msg_report_features(adap, &msg, i); |
1269 | cec_report_phys_addr(adap, i); | 1283 | cec_transmit_msg_fh(adap, &msg, NULL, false); |
1284 | } | ||
1285 | |||
1286 | /* Report Physical Address */ | ||
1287 | cec_msg_report_physical_addr(&msg, adap->phys_addr, | ||
1288 | las->primary_device_type[i]); | ||
1289 | dprintk(2, "config: la %d pa %x.%x.%x.%x\n", | ||
1290 | las->log_addr[i], | ||
1291 | cec_phys_addr_exp(adap->phys_addr)); | ||
1292 | cec_transmit_msg_fh(adap, &msg, NULL, false); | ||
1270 | } | 1293 | } |
1271 | for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) | ||
1272 | las->log_addr[i] = CEC_LOG_ADDR_INVALID; | ||
1273 | mutex_lock(&adap->lock); | ||
1274 | adap->kthread_config = NULL; | 1294 | adap->kthread_config = NULL; |
1275 | mutex_unlock(&adap->lock); | ||
1276 | complete(&adap->config_completion); | 1295 | complete(&adap->config_completion); |
1296 | mutex_unlock(&adap->lock); | ||
1277 | return 0; | 1297 | return 0; |
1278 | 1298 | ||
1279 | unconfigure: | 1299 | unconfigure: |
@@ -1526,52 +1546,32 @@ EXPORT_SYMBOL_GPL(cec_s_log_addrs); | |||
1526 | 1546 | ||
1527 | /* High-level core CEC message handling */ | 1547 | /* High-level core CEC message handling */ |
1528 | 1548 | ||
1529 | /* Transmit the Report Features message */ | 1549 | /* Fill in the Report Features message */ |
1530 | static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx) | 1550 | static void cec_fill_msg_report_features(struct cec_adapter *adap, |
1551 | struct cec_msg *msg, | ||
1552 | unsigned int la_idx) | ||
1531 | { | 1553 | { |
1532 | struct cec_msg msg = { }; | ||
1533 | const struct cec_log_addrs *las = &adap->log_addrs; | 1554 | const struct cec_log_addrs *las = &adap->log_addrs; |
1534 | const u8 *features = las->features[la_idx]; | 1555 | const u8 *features = las->features[la_idx]; |
1535 | bool op_is_dev_features = false; | 1556 | bool op_is_dev_features = false; |
1536 | unsigned int idx; | 1557 | unsigned int idx; |
1537 | 1558 | ||
1538 | /* This is 2.0 and up only */ | ||
1539 | if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0) | ||
1540 | return 0; | ||
1541 | |||
1542 | /* Report Features */ | 1559 | /* Report Features */ |
1543 | msg.msg[0] = (las->log_addr[la_idx] << 4) | 0x0f; | 1560 | msg->msg[0] = (las->log_addr[la_idx] << 4) | 0x0f; |
1544 | msg.len = 4; | 1561 | msg->len = 4; |
1545 | msg.msg[1] = CEC_MSG_REPORT_FEATURES; | 1562 | msg->msg[1] = CEC_MSG_REPORT_FEATURES; |
1546 | msg.msg[2] = adap->log_addrs.cec_version; | 1563 | msg->msg[2] = adap->log_addrs.cec_version; |
1547 | msg.msg[3] = las->all_device_types[la_idx]; | 1564 | msg->msg[3] = las->all_device_types[la_idx]; |
1548 | 1565 | ||
1549 | /* Write RC Profiles first, then Device Features */ | 1566 | /* Write RC Profiles first, then Device Features */ |
1550 | for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) { | 1567 | for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) { |
1551 | msg.msg[msg.len++] = features[idx]; | 1568 | msg->msg[msg->len++] = features[idx]; |
1552 | if ((features[idx] & CEC_OP_FEAT_EXT) == 0) { | 1569 | if ((features[idx] & CEC_OP_FEAT_EXT) == 0) { |
1553 | if (op_is_dev_features) | 1570 | if (op_is_dev_features) |
1554 | break; | 1571 | break; |
1555 | op_is_dev_features = true; | 1572 | op_is_dev_features = true; |
1556 | } | 1573 | } |
1557 | } | 1574 | } |
1558 | return cec_transmit_msg(adap, &msg, false); | ||
1559 | } | ||
1560 | |||
1561 | /* Transmit the Report Physical Address message */ | ||
1562 | static int cec_report_phys_addr(struct cec_adapter *adap, unsigned int la_idx) | ||
1563 | { | ||
1564 | const struct cec_log_addrs *las = &adap->log_addrs; | ||
1565 | struct cec_msg msg = { }; | ||
1566 | |||
1567 | /* Report Physical Address */ | ||
1568 | msg.msg[0] = (las->log_addr[la_idx] << 4) | 0x0f; | ||
1569 | cec_msg_report_physical_addr(&msg, adap->phys_addr, | ||
1570 | las->primary_device_type[la_idx]); | ||
1571 | dprintk(2, "config: la %d pa %x.%x.%x.%x\n", | ||
1572 | las->log_addr[la_idx], | ||
1573 | cec_phys_addr_exp(adap->phys_addr)); | ||
1574 | return cec_transmit_msg(adap, &msg, false); | ||
1575 | } | 1575 | } |
1576 | 1576 | ||
1577 | /* Transmit the Feature Abort message */ | 1577 | /* Transmit the Feature Abort message */ |
@@ -1777,9 +1777,10 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, | |||
1777 | } | 1777 | } |
1778 | 1778 | ||
1779 | case CEC_MSG_GIVE_FEATURES: | 1779 | case CEC_MSG_GIVE_FEATURES: |
1780 | if (adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) | 1780 | if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0) |
1781 | return cec_report_features(adap, la_idx); | 1781 | return cec_feature_abort(adap, msg); |
1782 | return 0; | 1782 | cec_fill_msg_report_features(adap, &tx_cec_msg, la_idx); |
1783 | return cec_transmit_msg(adap, &tx_cec_msg, false); | ||
1783 | 1784 | ||
1784 | default: | 1785 | default: |
1785 | /* | 1786 | /* |
diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index dfc03a95df71..f06e0488aa2c 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c | |||
@@ -719,6 +719,9 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h, | |||
719 | skb_copy_from_linear_data(h->priv->ule_skb, dest_addr, | 719 | skb_copy_from_linear_data(h->priv->ule_skb, dest_addr, |
720 | ETH_ALEN); | 720 | ETH_ALEN); |
721 | skb_pull(h->priv->ule_skb, ETH_ALEN); | 721 | skb_pull(h->priv->ule_skb, ETH_ALEN); |
722 | } else { | ||
723 | /* dest_addr buffer is only valid if h->priv->ule_dbit == 0 */ | ||
724 | eth_zero_addr(dest_addr); | ||
722 | } | 725 | } |
723 | 726 | ||
724 | /* Handle ULE Extension Headers. */ | 727 | /* Handle ULE Extension Headers. */ |
@@ -750,16 +753,8 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h, | |||
750 | if (!h->priv->ule_bridged) { | 753 | if (!h->priv->ule_bridged) { |
751 | skb_push(h->priv->ule_skb, ETH_HLEN); | 754 | skb_push(h->priv->ule_skb, ETH_HLEN); |
752 | h->ethh = (struct ethhdr *)h->priv->ule_skb->data; | 755 | h->ethh = (struct ethhdr *)h->priv->ule_skb->data; |
753 | if (!h->priv->ule_dbit) { | 756 | memcpy(h->ethh->h_dest, dest_addr, ETH_ALEN); |
754 | /* | 757 | eth_zero_addr(h->ethh->h_source); |
755 | * dest_addr buffer is only valid if | ||
756 | * h->priv->ule_dbit == 0 | ||
757 | */ | ||
758 | memcpy(h->ethh->h_dest, dest_addr, ETH_ALEN); | ||
759 | eth_zero_addr(h->ethh->h_source); | ||
760 | } else /* zeroize source and dest */ | ||
761 | memset(h->ethh, 0, ETH_ALEN * 2); | ||
762 | |||
763 | h->ethh->h_proto = htons(h->priv->ule_sndu_type); | 758 | h->ethh->h_proto = htons(h->priv->ule_sndu_type); |
764 | } | 759 | } |
765 | /* else: skb is in correct state; nothing to do. */ | 760 | /* else: skb is in correct state; nothing to do. */ |
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index b31fa6fae009..b979ea148251 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig | |||
@@ -655,6 +655,7 @@ config VIDEO_S5K6A3 | |||
655 | config VIDEO_S5K4ECGX | 655 | config VIDEO_S5K4ECGX |
656 | tristate "Samsung S5K4ECGX sensor support" | 656 | tristate "Samsung S5K4ECGX sensor support" |
657 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 657 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
658 | select CRC32 | ||
658 | ---help--- | 659 | ---help--- |
659 | This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M | 660 | This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M |
660 | camera sensor with an embedded SoC image signal processor. | 661 | camera sensor with an embedded SoC image signal processor. |
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 59872b31f832..f4e92bdfe192 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c | |||
@@ -2741,9 +2741,7 @@ static const struct v4l2_subdev_internal_ops smiapp_internal_ops = { | |||
2741 | * I2C Driver | 2741 | * I2C Driver |
2742 | */ | 2742 | */ |
2743 | 2743 | ||
2744 | #ifdef CONFIG_PM | 2744 | static int __maybe_unused smiapp_suspend(struct device *dev) |
2745 | |||
2746 | static int smiapp_suspend(struct device *dev) | ||
2747 | { | 2745 | { |
2748 | struct i2c_client *client = to_i2c_client(dev); | 2746 | struct i2c_client *client = to_i2c_client(dev); |
2749 | struct v4l2_subdev *subdev = i2c_get_clientdata(client); | 2747 | struct v4l2_subdev *subdev = i2c_get_clientdata(client); |
@@ -2768,7 +2766,7 @@ static int smiapp_suspend(struct device *dev) | |||
2768 | return 0; | 2766 | return 0; |
2769 | } | 2767 | } |
2770 | 2768 | ||
2771 | static int smiapp_resume(struct device *dev) | 2769 | static int __maybe_unused smiapp_resume(struct device *dev) |
2772 | { | 2770 | { |
2773 | struct i2c_client *client = to_i2c_client(dev); | 2771 | struct i2c_client *client = to_i2c_client(dev); |
2774 | struct v4l2_subdev *subdev = i2c_get_clientdata(client); | 2772 | struct v4l2_subdev *subdev = i2c_get_clientdata(client); |
@@ -2783,13 +2781,6 @@ static int smiapp_resume(struct device *dev) | |||
2783 | return rval; | 2781 | return rval; |
2784 | } | 2782 | } |
2785 | 2783 | ||
2786 | #else | ||
2787 | |||
2788 | #define smiapp_suspend NULL | ||
2789 | #define smiapp_resume NULL | ||
2790 | |||
2791 | #endif /* CONFIG_PM */ | ||
2792 | |||
2793 | static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) | 2784 | static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) |
2794 | { | 2785 | { |
2795 | struct smiapp_hwconfig *hwcfg; | 2786 | struct smiapp_hwconfig *hwcfg; |
@@ -2913,13 +2904,9 @@ static int smiapp_probe(struct i2c_client *client, | |||
2913 | if (IS_ERR(sensor->xshutdown)) | 2904 | if (IS_ERR(sensor->xshutdown)) |
2914 | return PTR_ERR(sensor->xshutdown); | 2905 | return PTR_ERR(sensor->xshutdown); |
2915 | 2906 | ||
2916 | pm_runtime_enable(&client->dev); | 2907 | rval = smiapp_power_on(&client->dev); |
2917 | 2908 | if (rval < 0) | |
2918 | rval = pm_runtime_get_sync(&client->dev); | 2909 | return rval; |
2919 | if (rval < 0) { | ||
2920 | rval = -ENODEV; | ||
2921 | goto out_power_off; | ||
2922 | } | ||
2923 | 2910 | ||
2924 | rval = smiapp_identify_module(sensor); | 2911 | rval = smiapp_identify_module(sensor); |
2925 | if (rval) { | 2912 | if (rval) { |
@@ -3100,6 +3087,9 @@ static int smiapp_probe(struct i2c_client *client, | |||
3100 | if (rval < 0) | 3087 | if (rval < 0) |
3101 | goto out_media_entity_cleanup; | 3088 | goto out_media_entity_cleanup; |
3102 | 3089 | ||
3090 | pm_runtime_set_active(&client->dev); | ||
3091 | pm_runtime_get_noresume(&client->dev); | ||
3092 | pm_runtime_enable(&client->dev); | ||
3103 | pm_runtime_set_autosuspend_delay(&client->dev, 1000); | 3093 | pm_runtime_set_autosuspend_delay(&client->dev, 1000); |
3104 | pm_runtime_use_autosuspend(&client->dev); | 3094 | pm_runtime_use_autosuspend(&client->dev); |
3105 | pm_runtime_put_autosuspend(&client->dev); | 3095 | pm_runtime_put_autosuspend(&client->dev); |
@@ -3113,8 +3103,7 @@ out_cleanup: | |||
3113 | smiapp_cleanup(sensor); | 3103 | smiapp_cleanup(sensor); |
3114 | 3104 | ||
3115 | out_power_off: | 3105 | out_power_off: |
3116 | pm_runtime_put(&client->dev); | 3106 | smiapp_power_off(&client->dev); |
3117 | pm_runtime_disable(&client->dev); | ||
3118 | 3107 | ||
3119 | return rval; | 3108 | return rval; |
3120 | } | 3109 | } |
@@ -3127,8 +3116,10 @@ static int smiapp_remove(struct i2c_client *client) | |||
3127 | 3116 | ||
3128 | v4l2_async_unregister_subdev(subdev); | 3117 | v4l2_async_unregister_subdev(subdev); |
3129 | 3118 | ||
3130 | pm_runtime_suspend(&client->dev); | ||
3131 | pm_runtime_disable(&client->dev); | 3119 | pm_runtime_disable(&client->dev); |
3120 | if (!pm_runtime_status_suspended(&client->dev)) | ||
3121 | smiapp_power_off(&client->dev); | ||
3122 | pm_runtime_set_suspended(&client->dev); | ||
3132 | 3123 | ||
3133 | for (i = 0; i < sensor->ssds_used; i++) { | 3124 | for (i = 0; i < sensor->ssds_used; i++) { |
3134 | v4l2_device_unregister_subdev(&sensor->ssds[i].sd); | 3125 | v4l2_device_unregister_subdev(&sensor->ssds[i].sd); |
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 3a0fe8cc64e9..48646a7f3fb0 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c | |||
@@ -291,8 +291,12 @@ static void tvp5150_selmux(struct v4l2_subdev *sd) | |||
291 | tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode); | 291 | tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode); |
292 | tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input); | 292 | tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input); |
293 | 293 | ||
294 | /* Svideo should enable YCrCb output and disable GPCL output | 294 | /* |
295 | * For Composite and TV, it should be the reverse | 295 | * Setup the FID/GLCO/VLK/HVLK and INTREQ/GPCL/VBLK output signals. For |
296 | * S-Video we output the vertical lock (VLK) signal on FID/GLCO/VLK/HVLK | ||
297 | * and set INTREQ/GPCL/VBLK to logic 0. For composite we output the | ||
298 | * field indicator (FID) signal on FID/GLCO/VLK/HVLK and set | ||
299 | * INTREQ/GPCL/VBLK to logic 1. | ||
296 | */ | 300 | */ |
297 | val = tvp5150_read(sd, TVP5150_MISC_CTL); | 301 | val = tvp5150_read(sd, TVP5150_MISC_CTL); |
298 | if (val < 0) { | 302 | if (val < 0) { |
@@ -301,9 +305,9 @@ static void tvp5150_selmux(struct v4l2_subdev *sd) | |||
301 | } | 305 | } |
302 | 306 | ||
303 | if (decoder->input == TVP5150_SVIDEO) | 307 | if (decoder->input == TVP5150_SVIDEO) |
304 | val = (val & ~0x40) | 0x10; | 308 | val = (val & ~TVP5150_MISC_CTL_GPCL) | TVP5150_MISC_CTL_HVLK; |
305 | else | 309 | else |
306 | val = (val & ~0x10) | 0x40; | 310 | val = (val & ~TVP5150_MISC_CTL_HVLK) | TVP5150_MISC_CTL_GPCL; |
307 | tvp5150_write(sd, TVP5150_MISC_CTL, val); | 311 | tvp5150_write(sd, TVP5150_MISC_CTL, val); |
308 | }; | 312 | }; |
309 | 313 | ||
@@ -455,7 +459,12 @@ static const struct i2c_reg_value tvp5150_init_enable[] = { | |||
455 | },{ /* Automatic offset and AGC enabled */ | 459 | },{ /* Automatic offset and AGC enabled */ |
456 | TVP5150_ANAL_CHL_CTL, 0x15 | 460 | TVP5150_ANAL_CHL_CTL, 0x15 |
457 | },{ /* Activate YCrCb output 0x9 or 0xd ? */ | 461 | },{ /* Activate YCrCb output 0x9 or 0xd ? */ |
458 | TVP5150_MISC_CTL, 0x6f | 462 | TVP5150_MISC_CTL, TVP5150_MISC_CTL_GPCL | |
463 | TVP5150_MISC_CTL_INTREQ_OE | | ||
464 | TVP5150_MISC_CTL_YCBCR_OE | | ||
465 | TVP5150_MISC_CTL_SYNC_OE | | ||
466 | TVP5150_MISC_CTL_VBLANK | | ||
467 | TVP5150_MISC_CTL_CLOCK_OE, | ||
459 | },{ /* Activates video std autodetection for all standards */ | 468 | },{ /* Activates video std autodetection for all standards */ |
460 | TVP5150_AUTOSW_MSK, 0x0 | 469 | TVP5150_AUTOSW_MSK, 0x0 |
461 | },{ /* Default format: 0x47. For 4:2:2: 0x40 */ | 470 | },{ /* Default format: 0x47. For 4:2:2: 0x40 */ |
@@ -861,8 +870,6 @@ static int tvp5150_fill_fmt(struct v4l2_subdev *sd, | |||
861 | 870 | ||
862 | f = &format->format; | 871 | f = &format->format; |
863 | 872 | ||
864 | tvp5150_reset(sd, 0); | ||
865 | |||
866 | f->width = decoder->rect.width; | 873 | f->width = decoder->rect.width; |
867 | f->height = decoder->rect.height / 2; | 874 | f->height = decoder->rect.height / 2; |
868 | 875 | ||
@@ -1051,21 +1058,27 @@ static const struct media_entity_operations tvp5150_sd_media_ops = { | |||
1051 | static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable) | 1058 | static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable) |
1052 | { | 1059 | { |
1053 | struct tvp5150 *decoder = to_tvp5150(sd); | 1060 | struct tvp5150 *decoder = to_tvp5150(sd); |
1054 | /* Output format: 8-bit ITU-R BT.656 with embedded syncs */ | 1061 | int val; |
1055 | int val = 0x09; | ||
1056 | |||
1057 | /* Output format: 8-bit 4:2:2 YUV with discrete sync */ | ||
1058 | if (decoder->mbus_type == V4L2_MBUS_PARALLEL) | ||
1059 | val = 0x0d; | ||
1060 | 1062 | ||
1061 | /* Initializes TVP5150 to its default values */ | 1063 | /* Enable or disable the video output signals. */ |
1062 | /* # set PCLK (27MHz) */ | 1064 | val = tvp5150_read(sd, TVP5150_MISC_CTL); |
1063 | tvp5150_write(sd, TVP5150_CONF_SHARED_PIN, 0x00); | 1065 | if (val < 0) |
1066 | return val; | ||
1067 | |||
1068 | val &= ~(TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE | | ||
1069 | TVP5150_MISC_CTL_CLOCK_OE); | ||
1070 | |||
1071 | if (enable) { | ||
1072 | /* | ||
1073 | * Enable the YCbCr and clock outputs. In discrete sync mode | ||
1074 | * (non-BT.656) additionally enable the the sync outputs. | ||
1075 | */ | ||
1076 | val |= TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_CLOCK_OE; | ||
1077 | if (decoder->mbus_type == V4L2_MBUS_PARALLEL) | ||
1078 | val |= TVP5150_MISC_CTL_SYNC_OE; | ||
1079 | } | ||
1064 | 1080 | ||
1065 | if (enable) | 1081 | tvp5150_write(sd, TVP5150_MISC_CTL, val); |
1066 | tvp5150_write(sd, TVP5150_MISC_CTL, val); | ||
1067 | else | ||
1068 | tvp5150_write(sd, TVP5150_MISC_CTL, 0x00); | ||
1069 | 1082 | ||
1070 | return 0; | 1083 | return 0; |
1071 | } | 1084 | } |
@@ -1524,7 +1537,6 @@ static int tvp5150_probe(struct i2c_client *c, | |||
1524 | res = core->hdl.error; | 1537 | res = core->hdl.error; |
1525 | goto err; | 1538 | goto err; |
1526 | } | 1539 | } |
1527 | v4l2_ctrl_handler_setup(&core->hdl); | ||
1528 | 1540 | ||
1529 | /* Default is no cropping */ | 1541 | /* Default is no cropping */ |
1530 | core->rect.top = 0; | 1542 | core->rect.top = 0; |
@@ -1535,6 +1547,8 @@ static int tvp5150_probe(struct i2c_client *c, | |||
1535 | core->rect.left = 0; | 1547 | core->rect.left = 0; |
1536 | core->rect.width = TVP5150_H_MAX; | 1548 | core->rect.width = TVP5150_H_MAX; |
1537 | 1549 | ||
1550 | tvp5150_reset(sd, 0); /* Calls v4l2_ctrl_handler_setup() */ | ||
1551 | |||
1538 | res = v4l2_async_register_subdev(sd); | 1552 | res = v4l2_async_register_subdev(sd); |
1539 | if (res < 0) | 1553 | if (res < 0) |
1540 | goto err; | 1554 | goto err; |
diff --git a/drivers/media/i2c/tvp5150_reg.h b/drivers/media/i2c/tvp5150_reg.h index 25a994944918..30a48c28d05a 100644 --- a/drivers/media/i2c/tvp5150_reg.h +++ b/drivers/media/i2c/tvp5150_reg.h | |||
@@ -9,6 +9,15 @@ | |||
9 | #define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */ | 9 | #define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */ |
10 | #define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */ | 10 | #define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */ |
11 | #define TVP5150_MISC_CTL 0x03 /* Miscellaneous controls */ | 11 | #define TVP5150_MISC_CTL 0x03 /* Miscellaneous controls */ |
12 | #define TVP5150_MISC_CTL_VBLK_GPCL BIT(7) | ||
13 | #define TVP5150_MISC_CTL_GPCL BIT(6) | ||
14 | #define TVP5150_MISC_CTL_INTREQ_OE BIT(5) | ||
15 | #define TVP5150_MISC_CTL_HVLK BIT(4) | ||
16 | #define TVP5150_MISC_CTL_YCBCR_OE BIT(3) | ||
17 | #define TVP5150_MISC_CTL_SYNC_OE BIT(2) | ||
18 | #define TVP5150_MISC_CTL_VBLANK BIT(1) | ||
19 | #define TVP5150_MISC_CTL_CLOCK_OE BIT(0) | ||
20 | |||
12 | #define TVP5150_AUTOSW_MSK 0x04 /* Autoswitch mask: TVP5150A / TVP5150AM */ | 21 | #define TVP5150_AUTOSW_MSK 0x04 /* Autoswitch mask: TVP5150A / TVP5150AM */ |
13 | 22 | ||
14 | /* Reserved 05h */ | 23 | /* Reserved 05h */ |
diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index 979634000597..d5c911c09e2b 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c | |||
@@ -308,9 +308,7 @@ static void cobalt_pci_iounmap(struct cobalt *cobalt, struct pci_dev *pci_dev) | |||
308 | static void cobalt_free_msi(struct cobalt *cobalt, struct pci_dev *pci_dev) | 308 | static void cobalt_free_msi(struct cobalt *cobalt, struct pci_dev *pci_dev) |
309 | { | 309 | { |
310 | free_irq(pci_dev->irq, (void *)cobalt); | 310 | free_irq(pci_dev->irq, (void *)cobalt); |
311 | 311 | pci_free_irq_vectors(pci_dev); | |
312 | if (cobalt->msi_enabled) | ||
313 | pci_disable_msi(pci_dev); | ||
314 | } | 312 | } |
315 | 313 | ||
316 | static int cobalt_setup_pci(struct cobalt *cobalt, struct pci_dev *pci_dev, | 314 | static int cobalt_setup_pci(struct cobalt *cobalt, struct pci_dev *pci_dev, |
@@ -387,14 +385,12 @@ static int cobalt_setup_pci(struct cobalt *cobalt, struct pci_dev *pci_dev, | |||
387 | from being generated. */ | 385 | from being generated. */ |
388 | cobalt_set_interrupt(cobalt, false); | 386 | cobalt_set_interrupt(cobalt, false); |
389 | 387 | ||
390 | if (pci_enable_msi_range(pci_dev, 1, 1) < 1) { | 388 | if (pci_alloc_irq_vectors(pci_dev, 1, 1, PCI_IRQ_MSI) < 1) { |
391 | cobalt_err("Could not enable MSI\n"); | 389 | cobalt_err("Could not enable MSI\n"); |
392 | cobalt->msi_enabled = false; | ||
393 | ret = -EIO; | 390 | ret = -EIO; |
394 | goto err_release; | 391 | goto err_release; |
395 | } | 392 | } |
396 | msi_config_show(cobalt, pci_dev); | 393 | msi_config_show(cobalt, pci_dev); |
397 | cobalt->msi_enabled = true; | ||
398 | 394 | ||
399 | /* Register IRQ */ | 395 | /* Register IRQ */ |
400 | if (request_irq(pci_dev->irq, cobalt_irq_handler, IRQF_SHARED, | 396 | if (request_irq(pci_dev->irq, cobalt_irq_handler, IRQF_SHARED, |
diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h index ed00dc9d9399..00f773ec359a 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.h +++ b/drivers/media/pci/cobalt/cobalt-driver.h | |||
@@ -287,8 +287,6 @@ struct cobalt { | |||
287 | u32 irq_none; | 287 | u32 irq_none; |
288 | u32 irq_full_fifo; | 288 | u32 irq_full_fifo; |
289 | 289 | ||
290 | bool msi_enabled; | ||
291 | |||
292 | /* omnitek dma */ | 290 | /* omnitek dma */ |
293 | int dma_channels; | 291 | int dma_channels; |
294 | int first_fifo_channel; | 292 | int first_fifo_channel; |
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c index 07fa08be9e99..d54ebe7e0215 100644 --- a/drivers/media/usb/dvb-usb/pctv452e.c +++ b/drivers/media/usb/dvb-usb/pctv452e.c | |||
@@ -97,14 +97,13 @@ struct pctv452e_state { | |||
97 | u8 c; /* transaction counter, wraps around... */ | 97 | u8 c; /* transaction counter, wraps around... */ |
98 | u8 initialized; /* set to 1 if 0x15 has been sent */ | 98 | u8 initialized; /* set to 1 if 0x15 has been sent */ |
99 | u16 last_rc_key; | 99 | u16 last_rc_key; |
100 | |||
101 | unsigned char data[80]; | ||
102 | }; | 100 | }; |
103 | 101 | ||
104 | static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, | 102 | static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, |
105 | unsigned int write_len, unsigned int read_len) | 103 | unsigned int write_len, unsigned int read_len) |
106 | { | 104 | { |
107 | struct pctv452e_state *state = (struct pctv452e_state *)d->priv; | 105 | struct pctv452e_state *state = (struct pctv452e_state *)d->priv; |
106 | u8 *buf; | ||
108 | u8 id; | 107 | u8 id; |
109 | unsigned int rlen; | 108 | unsigned int rlen; |
110 | int ret; | 109 | int ret; |
@@ -114,36 +113,39 @@ static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, | |||
114 | return -EIO; | 113 | return -EIO; |
115 | } | 114 | } |
116 | 115 | ||
117 | mutex_lock(&state->ca_mutex); | 116 | buf = kmalloc(64, GFP_KERNEL); |
117 | if (!buf) | ||
118 | return -ENOMEM; | ||
119 | |||
118 | id = state->c++; | 120 | id = state->c++; |
119 | 121 | ||
120 | state->data[0] = SYNC_BYTE_OUT; | 122 | buf[0] = SYNC_BYTE_OUT; |
121 | state->data[1] = id; | 123 | buf[1] = id; |
122 | state->data[2] = cmd; | 124 | buf[2] = cmd; |
123 | state->data[3] = write_len; | 125 | buf[3] = write_len; |
124 | 126 | ||
125 | memcpy(state->data + 4, data, write_len); | 127 | memcpy(buf + 4, data, write_len); |
126 | 128 | ||
127 | rlen = (read_len > 0) ? 64 : 0; | 129 | rlen = (read_len > 0) ? 64 : 0; |
128 | ret = dvb_usb_generic_rw(d, state->data, 4 + write_len, | 130 | ret = dvb_usb_generic_rw(d, buf, 4 + write_len, |
129 | state->data, rlen, /* delay_ms */ 0); | 131 | buf, rlen, /* delay_ms */ 0); |
130 | if (0 != ret) | 132 | if (0 != ret) |
131 | goto failed; | 133 | goto failed; |
132 | 134 | ||
133 | ret = -EIO; | 135 | ret = -EIO; |
134 | if (SYNC_BYTE_IN != state->data[0] || id != state->data[1]) | 136 | if (SYNC_BYTE_IN != buf[0] || id != buf[1]) |
135 | goto failed; | 137 | goto failed; |
136 | 138 | ||
137 | memcpy(data, state->data + 4, read_len); | 139 | memcpy(data, buf + 4, read_len); |
138 | 140 | ||
139 | mutex_unlock(&state->ca_mutex); | 141 | kfree(buf); |
140 | return 0; | 142 | return 0; |
141 | 143 | ||
142 | failed: | 144 | failed: |
143 | err("CI error %d; %02X %02X %02X -> %*ph.", | 145 | err("CI error %d; %02X %02X %02X -> %*ph.", |
144 | ret, SYNC_BYTE_OUT, id, cmd, 3, state->data); | 146 | ret, SYNC_BYTE_OUT, id, cmd, 3, buf); |
145 | 147 | ||
146 | mutex_unlock(&state->ca_mutex); | 148 | kfree(buf); |
147 | return ret; | 149 | return ret; |
148 | } | 150 | } |
149 | 151 | ||
@@ -410,53 +412,57 @@ static int pctv452e_i2c_msg(struct dvb_usb_device *d, u8 addr, | |||
410 | u8 *rcv_buf, u8 rcv_len) | 412 | u8 *rcv_buf, u8 rcv_len) |
411 | { | 413 | { |
412 | struct pctv452e_state *state = (struct pctv452e_state *)d->priv; | 414 | struct pctv452e_state *state = (struct pctv452e_state *)d->priv; |
415 | u8 *buf; | ||
413 | u8 id; | 416 | u8 id; |
414 | int ret; | 417 | int ret; |
415 | 418 | ||
416 | mutex_lock(&state->ca_mutex); | 419 | buf = kmalloc(64, GFP_KERNEL); |
420 | if (!buf) | ||
421 | return -ENOMEM; | ||
422 | |||
417 | id = state->c++; | 423 | id = state->c++; |
418 | 424 | ||
419 | ret = -EINVAL; | 425 | ret = -EINVAL; |
420 | if (snd_len > 64 - 7 || rcv_len > 64 - 7) | 426 | if (snd_len > 64 - 7 || rcv_len > 64 - 7) |
421 | goto failed; | 427 | goto failed; |
422 | 428 | ||
423 | state->data[0] = SYNC_BYTE_OUT; | 429 | buf[0] = SYNC_BYTE_OUT; |
424 | state->data[1] = id; | 430 | buf[1] = id; |
425 | state->data[2] = PCTV_CMD_I2C; | 431 | buf[2] = PCTV_CMD_I2C; |
426 | state->data[3] = snd_len + 3; | 432 | buf[3] = snd_len + 3; |
427 | state->data[4] = addr << 1; | 433 | buf[4] = addr << 1; |
428 | state->data[5] = snd_len; | 434 | buf[5] = snd_len; |
429 | state->data[6] = rcv_len; | 435 | buf[6] = rcv_len; |
430 | 436 | ||
431 | memcpy(state->data + 7, snd_buf, snd_len); | 437 | memcpy(buf + 7, snd_buf, snd_len); |
432 | 438 | ||
433 | ret = dvb_usb_generic_rw(d, state->data, 7 + snd_len, | 439 | ret = dvb_usb_generic_rw(d, buf, 7 + snd_len, |
434 | state->data, /* rcv_len */ 64, | 440 | buf, /* rcv_len */ 64, |
435 | /* delay_ms */ 0); | 441 | /* delay_ms */ 0); |
436 | if (ret < 0) | 442 | if (ret < 0) |
437 | goto failed; | 443 | goto failed; |
438 | 444 | ||
439 | /* TT USB protocol error. */ | 445 | /* TT USB protocol error. */ |
440 | ret = -EIO; | 446 | ret = -EIO; |
441 | if (SYNC_BYTE_IN != state->data[0] || id != state->data[1]) | 447 | if (SYNC_BYTE_IN != buf[0] || id != buf[1]) |
442 | goto failed; | 448 | goto failed; |
443 | 449 | ||
444 | /* I2C device didn't respond as expected. */ | 450 | /* I2C device didn't respond as expected. */ |
445 | ret = -EREMOTEIO; | 451 | ret = -EREMOTEIO; |
446 | if (state->data[5] < snd_len || state->data[6] < rcv_len) | 452 | if (buf[5] < snd_len || buf[6] < rcv_len) |
447 | goto failed; | 453 | goto failed; |
448 | 454 | ||
449 | memcpy(rcv_buf, state->data + 7, rcv_len); | 455 | memcpy(rcv_buf, buf + 7, rcv_len); |
450 | mutex_unlock(&state->ca_mutex); | ||
451 | 456 | ||
457 | kfree(buf); | ||
452 | return rcv_len; | 458 | return rcv_len; |
453 | 459 | ||
454 | failed: | 460 | failed: |
455 | err("I2C error %d; %02X %02X %02X %02X %02X -> %*ph", | 461 | err("I2C error %d; %02X %02X %02X %02X %02X -> %*ph", |
456 | ret, SYNC_BYTE_OUT, id, addr << 1, snd_len, rcv_len, | 462 | ret, SYNC_BYTE_OUT, id, addr << 1, snd_len, rcv_len, |
457 | 7, state->data); | 463 | 7, buf); |
458 | 464 | ||
459 | mutex_unlock(&state->ca_mutex); | 465 | kfree(buf); |
460 | return ret; | 466 | return ret; |
461 | } | 467 | } |
462 | 468 | ||
@@ -505,7 +511,7 @@ static u32 pctv452e_i2c_func(struct i2c_adapter *adapter) | |||
505 | static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i) | 511 | static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i) |
506 | { | 512 | { |
507 | struct pctv452e_state *state = (struct pctv452e_state *)d->priv; | 513 | struct pctv452e_state *state = (struct pctv452e_state *)d->priv; |
508 | u8 *rx; | 514 | u8 *b0, *rx; |
509 | int ret; | 515 | int ret; |
510 | 516 | ||
511 | info("%s: %d\n", __func__, i); | 517 | info("%s: %d\n", __func__, i); |
@@ -516,11 +522,12 @@ static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i) | |||
516 | if (state->initialized) | 522 | if (state->initialized) |
517 | return 0; | 523 | return 0; |
518 | 524 | ||
519 | rx = kmalloc(PCTV_ANSWER_LEN, GFP_KERNEL); | 525 | b0 = kmalloc(5 + PCTV_ANSWER_LEN, GFP_KERNEL); |
520 | if (!rx) | 526 | if (!b0) |
521 | return -ENOMEM; | 527 | return -ENOMEM; |
522 | 528 | ||
523 | mutex_lock(&state->ca_mutex); | 529 | rx = b0 + 5; |
530 | |||
524 | /* hmm where shoud this should go? */ | 531 | /* hmm where shoud this should go? */ |
525 | ret = usb_set_interface(d->udev, 0, ISOC_INTERFACE_ALTERNATIVE); | 532 | ret = usb_set_interface(d->udev, 0, ISOC_INTERFACE_ALTERNATIVE); |
526 | if (ret != 0) | 533 | if (ret != 0) |
@@ -528,66 +535,70 @@ static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i) | |||
528 | __func__, ret); | 535 | __func__, ret); |
529 | 536 | ||
530 | /* this is a one-time initialization, dont know where to put */ | 537 | /* this is a one-time initialization, dont know where to put */ |
531 | state->data[0] = 0xaa; | 538 | b0[0] = 0xaa; |
532 | state->data[1] = state->c++; | 539 | b0[1] = state->c++; |
533 | state->data[2] = PCTV_CMD_RESET; | 540 | b0[2] = PCTV_CMD_RESET; |
534 | state->data[3] = 1; | 541 | b0[3] = 1; |
535 | state->data[4] = 0; | 542 | b0[4] = 0; |
536 | /* reset board */ | 543 | /* reset board */ |
537 | ret = dvb_usb_generic_rw(d, state->data, 5, rx, PCTV_ANSWER_LEN, 0); | 544 | ret = dvb_usb_generic_rw(d, b0, 5, rx, PCTV_ANSWER_LEN, 0); |
538 | if (ret) | 545 | if (ret) |
539 | goto ret; | 546 | goto ret; |
540 | 547 | ||
541 | state->data[1] = state->c++; | 548 | b0[1] = state->c++; |
542 | state->data[4] = 1; | 549 | b0[4] = 1; |
543 | /* reset board (again?) */ | 550 | /* reset board (again?) */ |
544 | ret = dvb_usb_generic_rw(d, state->data, 5, rx, PCTV_ANSWER_LEN, 0); | 551 | ret = dvb_usb_generic_rw(d, b0, 5, rx, PCTV_ANSWER_LEN, 0); |
545 | if (ret) | 552 | if (ret) |
546 | goto ret; | 553 | goto ret; |
547 | 554 | ||
548 | state->initialized = 1; | 555 | state->initialized = 1; |
549 | 556 | ||
550 | ret: | 557 | ret: |
551 | mutex_unlock(&state->ca_mutex); | 558 | kfree(b0); |
552 | kfree(rx); | ||
553 | return ret; | 559 | return ret; |
554 | } | 560 | } |
555 | 561 | ||
556 | static int pctv452e_rc_query(struct dvb_usb_device *d) | 562 | static int pctv452e_rc_query(struct dvb_usb_device *d) |
557 | { | 563 | { |
558 | struct pctv452e_state *state = (struct pctv452e_state *)d->priv; | 564 | struct pctv452e_state *state = (struct pctv452e_state *)d->priv; |
565 | u8 *b, *rx; | ||
559 | int ret, i; | 566 | int ret, i; |
560 | u8 id; | 567 | u8 id; |
561 | 568 | ||
562 | mutex_lock(&state->ca_mutex); | 569 | b = kmalloc(CMD_BUFFER_SIZE + PCTV_ANSWER_LEN, GFP_KERNEL); |
570 | if (!b) | ||
571 | return -ENOMEM; | ||
572 | |||
573 | rx = b + CMD_BUFFER_SIZE; | ||
574 | |||
563 | id = state->c++; | 575 | id = state->c++; |
564 | 576 | ||
565 | /* prepare command header */ | 577 | /* prepare command header */ |
566 | state->data[0] = SYNC_BYTE_OUT; | 578 | b[0] = SYNC_BYTE_OUT; |
567 | state->data[1] = id; | 579 | b[1] = id; |
568 | state->data[2] = PCTV_CMD_IR; | 580 | b[2] = PCTV_CMD_IR; |
569 | state->data[3] = 0; | 581 | b[3] = 0; |
570 | 582 | ||
571 | /* send ir request */ | 583 | /* send ir request */ |
572 | ret = dvb_usb_generic_rw(d, state->data, 4, | 584 | ret = dvb_usb_generic_rw(d, b, 4, rx, PCTV_ANSWER_LEN, 0); |
573 | state->data, PCTV_ANSWER_LEN, 0); | ||
574 | if (ret != 0) | 585 | if (ret != 0) |
575 | goto ret; | 586 | goto ret; |
576 | 587 | ||
577 | if (debug > 3) { | 588 | if (debug > 3) { |
578 | info("%s: read: %2d: %*ph: ", __func__, ret, 3, state->data); | 589 | info("%s: read: %2d: %*ph: ", __func__, ret, 3, rx); |
579 | for (i = 0; (i < state->data[3]) && ((i + 3) < PCTV_ANSWER_LEN); i++) | 590 | for (i = 0; (i < rx[3]) && ((i+3) < PCTV_ANSWER_LEN); i++) |
580 | info(" %02x", state->data[i + 3]); | 591 | info(" %02x", rx[i+3]); |
581 | 592 | ||
582 | info("\n"); | 593 | info("\n"); |
583 | } | 594 | } |
584 | 595 | ||
585 | if ((state->data[3] == 9) && (state->data[12] & 0x01)) { | 596 | if ((rx[3] == 9) && (rx[12] & 0x01)) { |
586 | /* got a "press" event */ | 597 | /* got a "press" event */ |
587 | state->last_rc_key = RC_SCANCODE_RC5(state->data[7], state->data[6]); | 598 | state->last_rc_key = RC_SCANCODE_RC5(rx[7], rx[6]); |
588 | if (debug > 2) | 599 | if (debug > 2) |
589 | info("%s: cmd=0x%02x sys=0x%02x\n", | 600 | info("%s: cmd=0x%02x sys=0x%02x\n", |
590 | __func__, state->data[6], state->data[7]); | 601 | __func__, rx[6], rx[7]); |
591 | 602 | ||
592 | rc_keydown(d->rc_dev, RC_TYPE_RC5, state->last_rc_key, 0); | 603 | rc_keydown(d->rc_dev, RC_TYPE_RC5, state->last_rc_key, 0); |
593 | } else if (state->last_rc_key) { | 604 | } else if (state->last_rc_key) { |
@@ -595,7 +606,7 @@ static int pctv452e_rc_query(struct dvb_usb_device *d) | |||
595 | state->last_rc_key = 0; | 606 | state->last_rc_key = 0; |
596 | } | 607 | } |
597 | ret: | 608 | ret: |
598 | mutex_unlock(&state->ca_mutex); | 609 | kfree(b); |
599 | return ret; | 610 | return ret; |
600 | } | 611 | } |
601 | 612 | ||
diff --git a/include/uapi/linux/cec-funcs.h b/include/uapi/linux/cec-funcs.h index 3cbc327801d6..c451eec42a83 100644 --- a/include/uapi/linux/cec-funcs.h +++ b/include/uapi/linux/cec-funcs.h | |||
@@ -1665,14 +1665,15 @@ static inline void cec_msg_report_current_latency(struct cec_msg *msg, | |||
1665 | __u8 audio_out_compensated, | 1665 | __u8 audio_out_compensated, |
1666 | __u8 audio_out_delay) | 1666 | __u8 audio_out_delay) |
1667 | { | 1667 | { |
1668 | msg->len = 7; | 1668 | msg->len = 6; |
1669 | msg->msg[0] |= 0xf; /* broadcast */ | 1669 | msg->msg[0] |= 0xf; /* broadcast */ |
1670 | msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY; | 1670 | msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY; |
1671 | msg->msg[2] = phys_addr >> 8; | 1671 | msg->msg[2] = phys_addr >> 8; |
1672 | msg->msg[3] = phys_addr & 0xff; | 1672 | msg->msg[3] = phys_addr & 0xff; |
1673 | msg->msg[4] = video_latency; | 1673 | msg->msg[4] = video_latency; |
1674 | msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated; | 1674 | msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated; |
1675 | msg->msg[6] = audio_out_delay; | 1675 | if (audio_out_compensated == 3) |
1676 | msg->msg[msg->len++] = audio_out_delay; | ||
1676 | } | 1677 | } |
1677 | 1678 | ||
1678 | static inline void cec_ops_report_current_latency(const struct cec_msg *msg, | 1679 | static inline void cec_ops_report_current_latency(const struct cec_msg *msg, |
@@ -1686,7 +1687,10 @@ static inline void cec_ops_report_current_latency(const struct cec_msg *msg, | |||
1686 | *video_latency = msg->msg[4]; | 1687 | *video_latency = msg->msg[4]; |
1687 | *low_latency_mode = (msg->msg[5] >> 2) & 1; | 1688 | *low_latency_mode = (msg->msg[5] >> 2) & 1; |
1688 | *audio_out_compensated = msg->msg[5] & 3; | 1689 | *audio_out_compensated = msg->msg[5] & 3; |
1689 | *audio_out_delay = msg->msg[6]; | 1690 | if (*audio_out_compensated == 3 && msg->len >= 7) |
1691 | *audio_out_delay = msg->msg[6]; | ||
1692 | else | ||
1693 | *audio_out_delay = 0; | ||
1690 | } | 1694 | } |
1691 | 1695 | ||
1692 | static inline void cec_msg_request_current_latency(struct cec_msg *msg, | 1696 | static inline void cec_msg_request_current_latency(struct cec_msg *msg, |