aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@s-opensource.com>2016-12-26 11:09:28 -0500
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2016-12-26 11:09:28 -0500
commit0e0694ff1a7791274946b7f51bae692da0001a08 (patch)
tree53d28f58d793c151aa870f17d38ddec6ac01ec7a
parent65390ea01ce678379da32b01f39fcfac4903f256 (diff)
parentc739c0a7c3c2472d7562b8f802cdce44d2597c8b (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.c103
-rw-r--r--drivers/media/dvb-core/dvb_net.c15
-rw-r--r--drivers/media/i2c/Kconfig1
-rw-r--r--drivers/media/i2c/smiapp/smiapp-core.c33
-rw-r--r--drivers/media/i2c/tvp5150.c56
-rw-r--r--drivers/media/i2c/tvp5150_reg.h9
-rw-r--r--drivers/media/pci/cobalt/cobalt-driver.c8
-rw-r--r--drivers/media/pci/cobalt/cobalt-driver.h2
-rw-r--r--drivers/media/usb/dvb-usb/pctv452e.c133
-rw-r--r--include/uapi/linux/cec-funcs.h10
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
33static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx); 33static void cec_fill_msg_report_features(struct cec_adapter *adap,
34static 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
1279unconfigure: 1299unconfigure:
@@ -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 */
1530static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx) 1550static 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 */
1562static 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
655config VIDEO_S5K4ECGX 655config 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 2744static int __maybe_unused smiapp_suspend(struct device *dev)
2745
2746static 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
2771static int smiapp_resume(struct device *dev) 2769static 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
2793static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) 2784static 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
3115out_power_off: 3105out_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 = {
1051static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable) 1058static 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)
308static void cobalt_free_msi(struct cobalt *cobalt, struct pci_dev *pci_dev) 308static 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
316static int cobalt_setup_pci(struct cobalt *cobalt, struct pci_dev *pci_dev, 314static 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
104static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, 102static 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
142failed: 144failed:
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
454failed: 460failed:
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)
505static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i) 511static 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
550ret: 557ret:
551 mutex_unlock(&state->ca_mutex); 558 kfree(b0);
552 kfree(rx);
553 return ret; 559 return ret;
554} 560}
555 561
556static int pctv452e_rc_query(struct dvb_usb_device *d) 562static 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 }
597ret: 608ret:
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
1678static inline void cec_ops_report_current_latency(const struct cec_msg *msg, 1679static 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
1692static inline void cec_msg_request_current_latency(struct cec_msg *msg, 1696static inline void cec_msg_request_current_latency(struct cec_msg *msg,