sound/i2c/i2c.c

Source file repositories/reference/linux-study-clean/sound/i2c/i2c.c

File Facts

System
Linux kernel
Corpus path
sound/i2c/i2c.c
Extension
.c
Size
7647 bytes
Lines
327
Domain
Driver Families
Bucket
sound/i2c
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

while (!list_empty(&bus->buses)) {
			slave = snd_i2c_slave_bus(bus->buses.next);
			snd_device_free(bus->card, slave);
		}
	}
	if (bus->private_free)
		bus->private_free(bus);
	kfree(bus);
	return 0;
}

static int snd_i2c_bus_dev_free(struct snd_device *device)
{
	struct snd_i2c_bus *bus = device->device_data;
	return snd_i2c_bus_free(bus);
}

int snd_i2c_bus_create(struct snd_card *card, const char *name,
		       struct snd_i2c_bus *master, struct snd_i2c_bus **ri2c)
{
	struct snd_i2c_bus *bus;
	int err;
	static const struct snd_device_ops ops = {
		.dev_free =	snd_i2c_bus_dev_free,
	};

	*ri2c = NULL;
	bus = kzalloc_obj(*bus);
	if (bus == NULL)
		return -ENOMEM;
	mutex_init(&bus->lock_mutex);
	INIT_LIST_HEAD(&bus->devices);
	INIT_LIST_HEAD(&bus->buses);
	bus->card = card;
	bus->ops = &snd_i2c_bit_ops;
	if (master) {
		list_add_tail(&bus->buses, &master->buses);
		bus->master = master;
	}
	strscpy(bus->name, name, sizeof(bus->name));
	err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops);
	if (err < 0) {
		snd_i2c_bus_free(bus);
		return err;
	}
	*ri2c = bus;
	return 0;
}

EXPORT_SYMBOL(snd_i2c_bus_create);

int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
			  unsigned char addr, struct snd_i2c_device **rdevice)
{
	struct snd_i2c_device *device;

	*rdevice = NULL;
	if (snd_BUG_ON(!bus))
		return -EINVAL;
	device = kzalloc_obj(*device);
	if (device == NULL)
		return -ENOMEM;
	device->addr = addr;
	strscpy(device->name, name, sizeof(device->name));
	list_add_tail(&device->list, &bus->devices);
	device->bus = bus;
	*rdevice = device;
	return 0;
}

EXPORT_SYMBOL(snd_i2c_device_create);

int snd_i2c_device_free(struct snd_i2c_device *device)
{
	if (device->bus)
		list_del(&device->list);
	if (device->private_free)
		device->private_free(device);
	kfree(device);
	return 0;
}

EXPORT_SYMBOL(snd_i2c_device_free);

int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
{
	return device->bus->ops->sendbytes(device, bytes, count);
}

EXPORT_SYMBOL(snd_i2c_sendbytes);

Annotation

Implementation Notes