drivers/platform/cznic/turris-omnia-mcu-base.c

Source file repositories/reference/linux-study-clean/drivers/platform/cznic/turris-omnia-mcu-base.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/cznic/turris-omnia-mcu-base.c
Extension
.c
Size
10340 bytes
Lines
420
Domain
Driver Families
Bucket
drivers/platform
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (err) {
			/* try read 16-bit features */
			u16 features16;

			err = omnia_cmd_read_u16(client, OMNIA_CMD_GET_FEATURES,
						 &features16);
			if (err)
				return err;

			mcu->features = features16;
		} else {
			if (mcu->features & OMNIA_FEAT_FROM_BIT_16_INVALID)
				mcu->features &= GENMASK(15, 0);
		}
	} else {
		dev_info(dev,
			 "Your board's MCU firmware does not support feature reading.\n");
		suggest_fw_upgrade = true;
	}

	mcu->type = omnia_status_to_mcu_type(status);
	dev_info(dev, "MCU type %s%s\n", mcu->type,
		 (mcu->features & OMNIA_FEAT_PERIPH_MCU) ?
			", with peripheral resets wired" : "");

	omnia_mcu_print_version_hash(mcu, true);

	if (mcu->features & OMNIA_FEAT_BOOTLOADER)
		dev_warn(dev,
			 "MCU is running bootloader firmware. Was firmware upgrade interrupted?\n");
	else
		omnia_mcu_print_version_hash(mcu, false);

	for (unsigned int i = 0; i < ARRAY_SIZE(features); i++) {
		if (mcu->features & features[i].mask)
			continue;

		omnia_info_missing_feature(dev, features[i].name);
		suggest_fw_upgrade = true;
	}

	if (suggest_fw_upgrade)
		dev_info(dev,
			 "Consider upgrading MCU firmware with the omnia-mcutool utility.\n");

	return 0;
}

static int omnia_mcu_read_board_info(struct omnia_mcu *mcu)
{
	u8 reply[1 + OMNIA_BOARD_INFO_LEN];
	int err;

	err = omnia_cmd_read(mcu->client, OMNIA_CMD_BOARD_INFO_GET, reply,
			     sizeof(reply));
	if (err)
		return err;

	if (reply[0] != OMNIA_BOARD_INFO_LEN)
		return -EIO;

	mcu->board_serial_number = get_unaligned_le64(&reply[1]);

	/* we can't use ether_addr_copy() because reply is not u16-aligned */
	memcpy(mcu->board_first_mac, &reply[9], sizeof(mcu->board_first_mac));

	mcu->board_revision = reply[15];

	return 0;
}

static int omnia_mcu_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct omnia_mcu *mcu;
	int err;

	if (!client->irq)
		return dev_err_probe(dev, -EINVAL, "IRQ resource not found\n");

	mcu = devm_kzalloc(dev, sizeof(*mcu), GFP_KERNEL);
	if (!mcu)
		return -ENOMEM;

	mcu->client = client;
	i2c_set_clientdata(client, mcu);

	err = omnia_mcu_read_features(mcu);
	if (err)
		return dev_err_probe(dev, err,

Annotation

Implementation Notes