|
58 | 58 | #define CEC_TX_INPROGRESS -1
|
59 | 59 | #define CEC_TX_AVAIL 0
|
60 | 60 |
|
| 61 | +#define CEC_TX_RETRIES 3 |
| 62 | + |
| 63 | + |
61 | 64 | /* These flags must not collide with HDMI_IH_CEC_STAT0_xxxx */
|
62 | 65 | #define CEC_STAT0_EX_CONNECTED 0x0100
|
63 | 66 | #define CEC_STAT0_EX_DISCONNECTED 0x0200
|
@@ -213,6 +216,7 @@ static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
|
213 | 216 | static void mxc_hdmi_cec_handle(struct hdmi_cec_priv *priv, u32 cec_stat)
|
214 | 217 | {
|
215 | 218 | int i;
|
| 219 | + u8 val; |
216 | 220 | struct hdmi_cec_event *event;
|
217 | 221 |
|
218 | 222 | if (!priv->open_count)
|
@@ -269,19 +273,18 @@ static void mxc_hdmi_cec_handle(struct hdmi_cec_priv *priv, u32 cec_stat)
|
269 | 273 | }
|
270 | 274 |
|
271 | 275 | /* An error is detected on cec line (for initiator only). */
|
272 |
| - if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_INIT) { |
273 |
| - priv->tx_answer = cec_stat; |
274 |
| - wake_up(&tx_queue); |
275 |
| - return; |
276 |
| - } |
277 | 276 | /* A frame is not acknowledged in a directly addressed message.
|
278 | 277 | * Or a frame is negatively acknowledged in
|
279 | 278 | * a broadcast message (for initiator only).
|
280 | 279 | */
|
281 |
| - if (cec_stat & HDMI_IH_CEC_STAT0_NACK) { |
282 |
| - priv->send_error++; |
283 |
| - priv->tx_answer = cec_stat; |
284 |
| - wake_up(&tx_queue); |
| 280 | + if (cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK)) { |
| 281 | + if (++priv->send_error < CEC_TX_RETRIES) { |
| 282 | + val = hdmi_readb(HDMI_CEC_CTRL) & ~0x07; |
| 283 | + hdmi_writeb(val | 0x01, HDMI_CEC_CTRL); |
| 284 | + } else { |
| 285 | + priv->tx_answer = cec_stat; |
| 286 | + wake_up(&tx_queue); |
| 287 | + } |
285 | 288 | }
|
286 | 289 |
|
287 | 290 | /* An error is notified by a follower.
|
@@ -426,10 +429,9 @@ static ssize_t hdmi_cec_write(struct file *file, const char __user *buf,
|
426 | 429 | msg_len = count;
|
427 | 430 | hdmi_writeb(msg_len, HDMI_CEC_TX_CNT);
|
428 | 431 | for (i = 0; i < msg_len; i++)
|
429 |
| - hdmi_writeb(msg[i], HDMI_CEC_TX_DATA0+i); |
430 |
| - val = hdmi_readb(HDMI_CEC_CTRL); |
431 |
| - val |= 0x01; |
432 |
| - hdmi_writeb(val, HDMI_CEC_CTRL); |
| 432 | + hdmi_writeb(msg[i], HDMI_CEC_TX_DATA0 + i); |
| 433 | + val = hdmi_readb(HDMI_CEC_CTRL) & ~0x07; |
| 434 | + hdmi_writeb(val | 0x03, HDMI_CEC_CTRL); |
433 | 435 |
|
434 | 436 | mutex_unlock(&priv->lock);
|
435 | 437 |
|
|
0 commit comments