drivers/iio/chemical/scd30_serial.c
Source file repositories/reference/linux-study-clean/drivers/iio/chemical/scd30_serial.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/chemical/scd30_serial.c- Extension
.c- Size
- 7126 bytes
- Lines
- 265
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/crc16.hlinux/device.hlinux/errno.hlinux/iio/iio.hlinux/jiffies.hlinux/mod_devicetable.hlinux/module.hlinux/property.hlinux/serdev.hlinux/string.hlinux/types.hlinux/unaligned.hscd30.h
Detected Declarations
struct scd30_serdev_privfunction scd30_serdev_calc_crcfunction scd30_serdev_xferfunction scd30_serdev_commandfunction scd30_serdev_receive_buffunction scd30_serdev_probe
Annotated Snippet
struct scd30_serdev_priv {
struct completion meas_ready;
char *buf;
int num_expected;
int num;
};
static u16 scd30_serdev_cmd_lookup_tbl[] = {
[CMD_START_MEAS] = 0x0036,
[CMD_STOP_MEAS] = 0x0037,
[CMD_MEAS_INTERVAL] = 0x0025,
[CMD_MEAS_READY] = 0x0027,
[CMD_READ_MEAS] = 0x0028,
[CMD_ASC] = 0x003a,
[CMD_FRC] = 0x0039,
[CMD_TEMP_OFFSET] = 0x003b,
[CMD_FW_VERSION] = 0x0020,
[CMD_RESET] = 0x0034,
};
static u16 scd30_serdev_calc_crc(const char *buf, int size)
{
return crc16(0xffff, buf, size);
}
static int scd30_serdev_xfer(struct scd30_state *state, char *txbuf, int txsize,
char *rxbuf, int rxsize)
{
struct serdev_device *serdev = to_serdev_device(state->dev);
struct scd30_serdev_priv *priv = state->priv;
int ret;
priv->buf = rxbuf;
priv->num_expected = rxsize;
priv->num = 0;
ret = serdev_device_write(serdev, txbuf, txsize, SCD30_SERDEV_TIMEOUT);
if (ret < 0)
return ret;
if (ret != txsize)
return -EIO;
ret = wait_for_completion_interruptible_timeout(&priv->meas_ready, SCD30_SERDEV_TIMEOUT);
if (ret < 0)
return ret;
if (!ret)
return -ETIMEDOUT;
return 0;
}
static int scd30_serdev_command(struct scd30_state *state, enum scd30_cmd cmd, u16 arg,
void *response, int size)
{
/*
* Communication over serial line is based on modbus protocol (or rather
* its variation called modbus over serial to be precise). Upon
* receiving a request device should reply with response.
*
* Frame below represents a request message. Each field takes
* exactly one byte.
*
* +------+------+-----+-----+-------+-------+-----+-----+
* | dev | op | reg | reg | byte1 | byte0 | crc | crc |
* | addr | code | msb | lsb | | | lsb | msb |
* +------+------+-----+-----+-------+-------+-----+-----+
*
* The message device replies with depends on the 'op code' field from
* the request. In case it was set to SCD30_SERDEV_WRITE sensor should
* reply with unchanged request. Otherwise 'op code' was set to
* SCD30_SERDEV_READ and response looks like the one below. As with
* request, each field takes one byte.
*
* +------+------+--------+-------+-----+-------+-----+-----+
* | dev | op | num of | byte0 | ... | byteN | crc | crc |
* | addr | code | bytes | | | | lsb | msb |
* +------+------+--------+-------+-----+-------+-----+-----+
*/
char txbuf[SCD30_SERDEV_MAX_BUF_SIZE] = { SCD30_SERDEV_ADDR },
rxbuf[SCD30_SERDEV_MAX_BUF_SIZE];
int ret, rxsize, txsize = 2;
char *rsp = response;
u16 crc;
put_unaligned_be16(scd30_serdev_cmd_lookup_tbl[cmd], txbuf + txsize);
txsize += 2;
if (rsp) {
txbuf[1] = SCD30_SERDEV_READ;
if (cmd == CMD_READ_MEAS)
Annotation
- Immediate include surface: `linux/crc16.h`, `linux/device.h`, `linux/errno.h`, `linux/iio/iio.h`, `linux/jiffies.h`, `linux/mod_devicetable.h`, `linux/module.h`, `linux/property.h`.
- Detected declarations: `struct scd30_serdev_priv`, `function scd30_serdev_calc_crc`, `function scd30_serdev_xfer`, `function scd30_serdev_command`, `function scd30_serdev_receive_buf`, `function scd30_serdev_probe`.
- Atlas domain: Driver Families / drivers/iio.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.