提交 4f88b0de 编写于 作者: H Hans Verkuil 提交者: Mauro Carvalho Chehab

media: vivid: add CEC pin monitoring emulation

Add support to emulate CEC pin monitoring. There are few hardware devices
that support this, so being able to emulate it here helps developing
software for this.
Signed-off-by: NHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: NMauro Carvalho Chehab <mchehab@s-opensource.com>
上级 28e11b15
......@@ -22,6 +22,15 @@
#include "vivid-core.h"
#include "vivid-cec.h"
#define CEC_TIM_START_BIT_TOTAL 4500
#define CEC_TIM_START_BIT_LOW 3700
#define CEC_TIM_START_BIT_HIGH 800
#define CEC_TIM_DATA_BIT_TOTAL 2400
#define CEC_TIM_DATA_BIT_0_LOW 1500
#define CEC_TIM_DATA_BIT_0_HIGH 900
#define CEC_TIM_DATA_BIT_1_LOW 600
#define CEC_TIM_DATA_BIT_1_HIGH 1800
void vivid_cec_bus_free_work(struct vivid_dev *dev)
{
spin_lock(&dev->cec_slock);
......@@ -64,6 +73,58 @@ static bool vivid_cec_find_dest_adap(struct vivid_dev *dev,
return false;
}
static void vivid_cec_pin_adap_events(struct cec_adapter *adap, ktime_t ts,
const struct cec_msg *msg, bool nacked)
{
unsigned int len = nacked ? 1 : msg->len;
unsigned int i;
bool bit;
if (adap == NULL)
return;
ts = ktime_sub_us(ts, (CEC_TIM_START_BIT_TOTAL +
len * 10 * CEC_TIM_DATA_BIT_TOTAL));
cec_queue_pin_cec_event(adap, false, ts);
ts = ktime_add_us(ts, CEC_TIM_START_BIT_LOW);
cec_queue_pin_cec_event(adap, true, ts);
ts = ktime_add_us(ts, CEC_TIM_START_BIT_HIGH);
for (i = 0; i < 10 * len; i++) {
switch (i % 10) {
case 0 ... 7:
bit = msg->msg[i / 10] & (0x80 >> (i % 10));
break;
case 8: /* EOM */
bit = i / 10 == msg->len - 1;
break;
case 9: /* ACK */
bit = cec_msg_is_broadcast(msg) ^ nacked;
break;
}
cec_queue_pin_cec_event(adap, false, ts);
if (bit)
ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_LOW);
else
ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_LOW);
cec_queue_pin_cec_event(adap, true, ts);
if (bit)
ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_HIGH);
else
ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_HIGH);
}
}
static void vivid_cec_pin_events(struct vivid_dev *dev,
const struct cec_msg *msg, bool nacked)
{
ktime_t ts = ktime_get();
unsigned int i;
vivid_cec_pin_adap_events(dev->cec_rx_adap, ts, msg, nacked);
for (i = 0; i < MAX_OUTPUTS; i++)
vivid_cec_pin_adap_events(dev->cec_tx_adap[i], ts, msg, nacked);
}
static void vivid_cec_xfer_done_worker(struct work_struct *work)
{
struct vivid_cec_work *cw =
......@@ -84,6 +145,7 @@ static void vivid_cec_xfer_done_worker(struct work_struct *work)
dev->cec_xfer_start_jiffies = 0;
list_del(&cw->list);
spin_unlock(&dev->cec_slock);
vivid_cec_pin_events(dev, &cw->msg, !valid_dest);
cec_transmit_attempt_done(cw->adap, cw->tx_status);
/* Broadcast message */
......@@ -118,6 +180,7 @@ static void vivid_cec_xfer_try_worker(struct work_struct *work)
static int vivid_cec_adap_enable(struct cec_adapter *adap, bool enable)
{
adap->cec_pin_is_high = true;
return 0;
}
......@@ -219,7 +282,7 @@ struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev,
bool is_source)
{
char name[sizeof(dev->vid_out_dev.name) + 2];
u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL;
u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN;
snprintf(name, sizeof(name), "%s%d",
is_source ? dev->vid_out_dev.name : dev->vid_cap_dev.name,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册