drivers/media/cec/usb/pulse8/pulse8-cec.c

Source file repositories/reference/linux-study-clean/drivers/media/cec/usb/pulse8/pulse8-cec.c

File Facts

System
Linux kernel
Corpus path
drivers/media/cec/usb/pulse8/pulse8-cec.c
Extension
.c
Size
25048 bytes
Lines
932
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct pulse8 {
	struct device *dev;
	struct serio *serio;
	struct cec_adapter *adap;
	unsigned int vers;

	struct delayed_work ping_eeprom_work;

	struct work_struct irq_work;
	struct cec_msg rx_msg[NUM_MSGS];
	unsigned int rx_msg_cur_idx, rx_msg_num;
	/* protect rx_msg_cur_idx and rx_msg_num */
	spinlock_t msg_lock;
	u8 new_rx_msg[CEC_MAX_MSG_SIZE];
	u8 new_rx_msg_len;

	struct work_struct tx_work;
	u32 tx_done_status;
	u32 tx_signal_free_time;
	struct cec_msg tx_msg;
	bool tx_msg_is_bcast;

	struct completion cmd_done;
	u8 data[DATA_SIZE];
	unsigned int len;
	u8 buf[DATA_SIZE];
	unsigned int idx;
	bool escape;
	bool started;

	/* locks access to the adapter */
	struct mutex lock;
	bool config_pending;
	bool restoring_config;
	bool autonomous;
};

static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len)
{
	int err = 0;

	err = serio_write(serio, MSGSTART);
	if (err)
		return err;
	for (; !err && cmd_len; command++, cmd_len--) {
		if (*command >= MSGESC) {
			err = serio_write(serio, MSGESC);
			if (!err)
				err = serio_write(serio, *command - MSGOFFSET);
		} else {
			err = serio_write(serio, *command);
		}
	}
	if (!err)
		err = serio_write(serio, MSGEND);

	return err;
}

static int pulse8_send_and_wait_once(struct pulse8 *pulse8,
				     const u8 *cmd, u8 cmd_len,
				     u8 response, u8 size)
{
	int err;

	if (!pulse8->serio)
		return -ENODEV;

	if (debug > 1)
		dev_info(pulse8->dev, "transmit %s: %*ph\n",
			 pulse8_msgname(cmd[0]), cmd_len, cmd);
	init_completion(&pulse8->cmd_done);

	err = pulse8_send(pulse8->serio, cmd, cmd_len);
	if (err)
		return err;

	if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ))
		return -ETIMEDOUT;
	if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED &&
	    cmd[0] != MSGCODE_SET_CONTROLLED &&
	    cmd[0] != MSGCODE_SET_AUTO_ENABLED &&
	    cmd[0] != MSGCODE_GET_BUILDDATE)
		return -ENOTTY;
	if (response &&
	    ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) {
		dev_info(pulse8->dev, "transmit %s failed with %s\n",
			 pulse8_msgname(cmd[0]),
			 pulse8_msgname(pulse8->data[0]));
		return -EIO;

Annotation

Implementation Notes