drivers/media/usb/em28xx/em28xx-camera.c

Source file repositories/reference/linux-study-clean/drivers/media/usb/em28xx/em28xx-camera.c

File Facts

System
Linux kernel
Corpus path
drivers/media/usb/em28xx/em28xx-camera.c
Extension
.c
Size
10294 bytes
Lines
413
Domain
Driver Families
Bucket
drivers/media
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 (ret < 0) {
			if (ret != -ENXIO)
				dev_err(&dev->intf->dev,
					"couldn't read from i2c device 0x%02x: error %i\n",
				       client->addr << 1, ret);
			continue;
		}
		id = swab16(ret); /* LE -> BE */
		/* Read chip ID from register 0xff */
		ret = i2c_smbus_read_word_data(client, 0xff);
		if (ret < 0) {
			dev_err(&dev->intf->dev,
				"couldn't read from i2c device 0x%02x: error %i\n",
				client->addr << 1, ret);
			continue;
		}
		/* Validate chip ID to be sure we have a Micron device */
		if (id != swab16(ret))
			continue;
		/* Check chip ID */
		switch (id) {
		case 0x1222:
			name = "MT9V012"; /* MI370 */ /* 640x480 */
			break;
		case 0x1229:
			name = "MT9V112"; /* 640x480 */
			break;
		case 0x1433:
			name = "MT9M011"; /* 1280x1024 */
			break;
		case 0x143a:    /* found in the ECS G200 */
			name = "MT9M111"; /* MI1310 */ /* 1280x1024 */
			dev->em28xx_sensor = EM28XX_MT9M111;
			break;
		case 0x148c:
			name = "MT9M112"; /* MI1320 */ /* 1280x1024 */
			break;
		case 0x1511:
			name = "MT9D011"; /* MI2010 */ /* 1600x1200 */
			break;
		case 0x8232:
		case 0x8243:	/* rev B */
			name = "MT9V011"; /* MI360 */ /* 640x480 */
			dev->em28xx_sensor = EM28XX_MT9V011;
			break;
		case 0x8431:
			name = "MT9M001"; /* 1280x1024 */
			dev->em28xx_sensor = EM28XX_MT9M001;
			break;
		default:
			dev_info(&dev->intf->dev,
				 "unknown Micron sensor detected: 0x%04x\n",
				 id);
			return 0;
		}

		if (dev->em28xx_sensor == EM28XX_NOSENSOR)
			dev_info(&dev->intf->dev,
				 "unsupported sensor detected: %s\n", name);
		else
			dev_info(&dev->intf->dev,
				 "sensor %s detected\n", name);

		return 0;
	}

	return -ENODEV;
}

/*
 * Probes Omnivision sensors with 8 bit address and register width
 */
static int em28xx_probe_sensor_omnivision(struct em28xx *dev)
{
	int ret, i;
	char *name;
	u8 reg;
	u16 id;
	struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus];

	dev->em28xx_sensor = EM28XX_NOSENSOR;
	/*
	 * NOTE: these devices have the register auto incrementation disabled
	 * by default, so we have to use single byte reads !
	 */
	for (i = 0; omnivision_sensor_addrs[i] != I2C_CLIENT_END; i++) {
		client->addr = omnivision_sensor_addrs[i];
		/* Read manufacturer ID from registers 0x1c-0x1d (BE) */
		reg = 0x1c;
		ret = i2c_smbus_read_byte_data(client, reg);

Annotation

Implementation Notes