drivers/iio/chemical/sps30_serial.c

Source file repositories/reference/linux-study-clean/drivers/iio/chemical/sps30_serial.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/chemical/sps30_serial.c
Extension
.c
Size
10716 bytes
Lines
433
Domain
Driver Families
Bucket
drivers/iio
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 sps30_serial_priv {
	struct completion new_frame;
	unsigned char buf[SPS30_SERIAL_MAX_BUF_SIZE];
	size_t num;
	bool escaped;
	bool done;
};

static int sps30_serial_xfer(struct sps30_state *state, const unsigned char *buf, size_t size)
{
	struct serdev_device *serdev = to_serdev_device(state->dev);
	struct sps30_serial_priv *priv = state->priv;
	int ret;

	priv->num = 0;
	priv->escaped = false;
	priv->done = false;

	ret = serdev_device_write(serdev, buf, size, SPS30_SERIAL_TIMEOUT);
	if (ret < 0)
		return ret;
	if (ret != size)
		return -EIO;

	ret = wait_for_completion_interruptible_timeout(&priv->new_frame, SPS30_SERIAL_TIMEOUT);
	if (ret < 0)
		return ret;
	if (!ret)
		return -ETIMEDOUT;

	return 0;
}

static const struct {
	u8 byte;
	u8 byte2;
} sps30_serial_bytes[] = {
	{ 0x11, 0x31 },
	{ 0x13, 0x33 },
	{ 0x7e, 0x5e },
	{ 0x7d, 0x5d },
};

static int sps30_serial_put_byte(u8 *buf, u8 byte)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(sps30_serial_bytes); i++) {
		if (sps30_serial_bytes[i].byte != byte)
			continue;

		buf[0] = SPS30_SERIAL_ESCAPE_CHAR;
		buf[1] = sps30_serial_bytes[i].byte2;

		return 2;
	}

	buf[0] = byte;

	return 1;
}

static u8 sps30_serial_get_byte(bool escaped, u8 byte2)
{
	int i;

	if (!escaped)
		return byte2;

	for (i = 0; i < ARRAY_SIZE(sps30_serial_bytes); i++) {
		if (sps30_serial_bytes[i].byte2 != byte2)
			continue;

		return sps30_serial_bytes[i].byte;
	}

	return 0;
}

static unsigned char sps30_serial_calc_chksum(const unsigned char *buf, size_t num)
{
	unsigned int chksum = 0;
	size_t i;

	for (i = 0; i < num; i++)
		chksum += buf[i];

	return ~chksum;
}

Annotation

Implementation Notes