drivers/media/pci/mantis/mantis_i2c.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/mantis/mantis_i2c.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/mantis/mantis_i2c.c
Extension
.c
Size
6037 bytes
Lines
253
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 (stat & MANTIS_INT_I2CDONE) {
				/* check xfer was acknowledged */
				if (stat & MANTIS_INT_I2CRACK) {
					data = mmread(MANTIS_I2CDATA_CTL);
					msgs[i + 1].buf[0] = (data >> 8) & 0xff;
					dprintk(MANTIS_DEBUG, 0, "        Byte <%d> RXD=0x%02x  [%02x]\n", 0x0, data, msgs[i + 1].buf[0]);
				} else {
					/* I/O error */
					dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
					ret = -EIO;
					break;
				}
			} else {
				/* I/O error */
				dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
				ret = -EIO;
				break;
			}
			i += 2; /* Write/Read operation in one go */
		}

		if (i < num) {
			if (msgs[i].flags & I2C_M_RD)
				ret = mantis_i2c_read(mantis, &msgs[i]);
			else
				ret = mantis_i2c_write(mantis, &msgs[i]);

			i++;
			if (ret < 0)
				goto bail_out;
		}

	}

	mutex_unlock(&mantis->i2c_lock);

	return num;

bail_out:
	mutex_unlock(&mantis->i2c_lock);
	return ret;
}

static u32 mantis_i2c_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_SMBUS_EMUL;
}

static const struct i2c_algorithm mantis_algo = {
	.master_xfer		= mantis_i2c_xfer,
	.functionality		= mantis_i2c_func,
};

int mantis_i2c_init(struct mantis_pci *mantis)
{
	u32 intstat;
	struct i2c_adapter *i2c_adapter = &mantis->adapter;
	struct pci_dev *pdev		= mantis->pdev;

	init_waitqueue_head(&mantis->i2c_wq);
	mutex_init(&mantis->i2c_lock);
	strscpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name));
	i2c_set_adapdata(i2c_adapter, mantis);

	i2c_adapter->owner	= THIS_MODULE;
	i2c_adapter->algo	= &mantis_algo;
	i2c_adapter->algo_data	= NULL;
	i2c_adapter->timeout	= 500;
	i2c_adapter->retries	= 3;
	i2c_adapter->dev.parent	= &pdev->dev;

	mantis->i2c_rc		= i2c_add_adapter(i2c_adapter);
	if (mantis->i2c_rc < 0)
		return mantis->i2c_rc;

	dprintk(MANTIS_DEBUG, 1, "Initializing I2C ..");

	intstat = mmread(MANTIS_INT_STAT);
	mmread(MANTIS_INT_MASK);
	mmwrite(intstat, MANTIS_INT_STAT);
	dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
	mantis_mask_ints(mantis, MANTIS_INT_I2CDONE);

	return 0;
}
EXPORT_SYMBOL_GPL(mantis_i2c_init);

int mantis_i2c_exit(struct mantis_pci *mantis)
{
	dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");

Annotation

Implementation Notes