Example #1
0
static int rain_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
				    u32 signal_free_time, struct cec_msg *msg)
{
	struct rain *rain = cec_get_drvdata(adap);
	char cmd[2 * CEC_MAX_MSG_SIZE + 16];
	unsigned int i;
	int err;

	if (msg->len == 1) {
		snprintf(cmd, sizeof(cmd), "x%x", cec_msg_destination(msg));
	} else {
		char hex[3];

		snprintf(cmd, sizeof(cmd), "x%x %02x ",
			 cec_msg_destination(msg), msg->msg[1]);
		for (i = 2; i < msg->len; i++) {
			snprintf(hex, sizeof(hex), "%02x", msg->msg[i]);
			strlcat(cmd, hex, sizeof(cmd));
		}
	}
	mutex_lock(&rain->write_lock);
	err = rain_send(rain, cmd);
	mutex_unlock(&rain->write_lock);
	return err;
}
Example #2
0
static void vivid_cec_xfer_done_worker(struct work_struct *work)
{
	struct vivid_cec_work *cw =
		container_of(work, struct vivid_cec_work, work.work);
	struct vivid_dev *dev = cw->dev;
	struct cec_adapter *adap = cw->adap;
	u8 dest = cec_msg_destination(&cw->msg);
	bool valid_dest;
	unsigned int i;

	valid_dest = cec_msg_is_broadcast(&cw->msg);
	if (!valid_dest)
		valid_dest = vivid_cec_find_dest_adap(dev, adap, dest);

	cw->tx_status = valid_dest ? CEC_TX_STATUS_OK : CEC_TX_STATUS_NACK;
	spin_lock(&dev->cec_slock);
	dev->cec_xfer_time_jiffies = 0;
	dev->cec_xfer_start_jiffies = 0;
	list_del(&cw->list);
	spin_unlock(&dev->cec_slock);
	cec_transmit_done(cw->adap, cw->tx_status, 0, valid_dest ? 0 : 1, 0, 0);

	/* Broadcast message */
	if (adap != dev->cec_rx_adap)
		cec_received_msg(dev->cec_rx_adap, &cw->msg);
	for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++)
		if (adap != dev->cec_tx_adap[i])
			cec_received_msg(dev->cec_tx_adap[i], &cw->msg);
	kfree(cw);
}
Example #3
0
static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg)
{
	struct vivid_dev *dev = adap->priv;
	struct cec_msg reply;
	u8 dest = cec_msg_destination(msg);
	u16 pa;
	u8 disp_ctl;
	char osd[14];

	if (cec_msg_is_broadcast(msg))
		dest = adap->log_addrs.log_addr[0];
	cec_msg_init(&reply, dest, cec_msg_initiator(msg));

	switch (cec_msg_opcode(msg)) {
	case CEC_MSG_SET_STREAM_PATH:
		if (cec_is_sink(adap))
			return -ENOMSG;
		cec_ops_set_stream_path(msg, &pa);
		if (pa != adap->phys_addr)
			return -ENOMSG;
		cec_msg_active_source(&reply, adap->phys_addr);
		cec_transmit_msg(adap, &reply, false);
		break;
	case CEC_MSG_SET_OSD_STRING:
		if (!cec_is_sink(adap))
			return -ENOMSG;
		cec_ops_set_osd_string(msg, &disp_ctl, osd);
		switch (disp_ctl) {
		case CEC_OP_DISP_CTL_DEFAULT:
			strcpy(dev->osd, osd);
			dev->osd_jiffies = jiffies;
			break;
		case CEC_OP_DISP_CTL_UNTIL_CLEARED:
			strcpy(dev->osd, osd);
			dev->osd_jiffies = 0;
			break;
		case CEC_OP_DISP_CTL_CLEAR:
			dev->osd[0] = 0;
			dev->osd_jiffies = 0;
			break;
		default:
			cec_msg_feature_abort(&reply, cec_msg_opcode(msg),
					      CEC_OP_ABORT_INVALID_OP);
			cec_transmit_msg(adap, &reply, false);
			break;
		}
		break;
	default:
		return -ENOMSG;
	}
	return 0;
}
static void vivid_cec_xfer_done_worker(struct work_struct *work)
{
	struct vivid_cec_work *cw =
		container_of(work, struct vivid_cec_work, work.work);
	struct vivid_dev *dev = cw->dev;
	struct cec_adapter *adap = cw->adap;
	bool is_poll = cw->msg.len == 1;
	u8 dest = cec_msg_destination(&cw->msg);
	struct cec_adapter *dest_adap = NULL;
	bool valid_dest;
	unsigned int i;

	valid_dest = cec_msg_is_broadcast(&cw->msg);
	if (!valid_dest) {
		dest_adap = vivid_cec_find_dest_adap(dev, adap, dest);
		if (dest_adap)
			valid_dest = true;
	}
	cw->tx_status = valid_dest ? CEC_TX_STATUS_OK : CEC_TX_STATUS_NACK;
	spin_lock(&dev->cec_slock);
	dev->cec_xfer_time_jiffies = 0;
	dev->cec_xfer_start_jiffies = 0;
	list_del(&cw->list);
	spin_unlock(&dev->cec_slock);
	cec_transmit_done(cw->adap, cw->tx_status, 0, valid_dest ? 0 : 1, 0, 0);

	if (!is_poll && dest_adap) {
		/* Directed message */
		cec_received_msg(dest_adap, &cw->msg);
	} else if (!is_poll && valid_dest) {
		/* Broadcast message */
		if (adap != dev->cec_rx_adap &&
		    dev->cec_rx_adap->log_addrs.log_addr_mask)
			cec_received_msg(dev->cec_rx_adap, &cw->msg);
		for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) {
			if (adap == dev->cec_tx_adap[i] ||
			    !dev->cec_tx_adap[i]->log_addrs.log_addr_mask)
				continue;
			cec_received_msg(dev->cec_tx_adap[i], &cw->msg);
		}
	}
	kfree(cw);
}