drivers/media/pci/solo6x10/solo6x10-i2c.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/solo6x10/solo6x10-i2c.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/solo6x10/solo6x10-i2c.c
Extension
.c
Size
6988 bytes
Lines
324
Domain
Driver Families
Bucket
drivers/media
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (solo_dev->i2c_msg->flags & I2C_M_RD) {
			solo_dev->i2c_state = IIC_STATE_READ;
			ret = solo_i2c_handle_read(solo_dev);
			break;
		}

		solo_dev->i2c_state = IIC_STATE_WRITE;
		fallthrough;
	case IIC_STATE_WRITE:
		ret = solo_i2c_handle_write(solo_dev);
		break;

	case IIC_STATE_READ:
		solo_dev->i2c_msg->buf[solo_dev->i2c_msg_ptr] =
			solo_reg_read(solo_dev, SOLO_IIC_RXD);
		solo_dev->i2c_msg_ptr++;

		ret = solo_i2c_handle_read(solo_dev);
		break;

	default:
		solo_i2c_stop(solo_dev);
	}

	return ret;
}

static int solo_i2c_master_xfer(struct i2c_adapter *adap,
				struct i2c_msg msgs[], int num)
{
	struct solo_dev *solo_dev = adap->algo_data;
	unsigned long timeout;
	int ret;
	int i;
	DEFINE_WAIT(wait);

	for (i = 0; i < SOLO_I2C_ADAPTERS; i++) {
		if (&solo_dev->i2c_adap[i] == adap)
			break;
	}

	if (i == SOLO_I2C_ADAPTERS)
		return num; /* XXX Right return value for failure? */

	mutex_lock(&solo_dev->i2c_mutex);
	solo_dev->i2c_id = i;
	solo_dev->i2c_msg = msgs;
	solo_dev->i2c_msg_num = num;
	solo_dev->i2c_msg_ptr = 0;

	solo_reg_write(solo_dev, SOLO_IIC_CTRL, 0);
	solo_irq_on(solo_dev, SOLO_IRQ_IIC);
	solo_i2c_start(solo_dev);

	timeout = HZ / 2;

	for (;;) {
		prepare_to_wait(&solo_dev->i2c_wait, &wait,
				TASK_INTERRUPTIBLE);

		if (solo_dev->i2c_state == IIC_STATE_STOP)
			break;

		timeout = schedule_timeout(timeout);
		if (!timeout)
			break;

		if (signal_pending(current))
			break;
	}

	finish_wait(&solo_dev->i2c_wait, &wait);
	ret = num - solo_dev->i2c_msg_num;
	solo_dev->i2c_state = IIC_STATE_IDLE;
	solo_dev->i2c_id = -1;

	mutex_unlock(&solo_dev->i2c_mutex);

	return ret;
}

static u32 solo_i2c_functionality(struct i2c_adapter *adap)
{
	return I2C_FUNC_I2C;
}

static const struct i2c_algorithm solo_i2c_algo = {
	.master_xfer	= solo_i2c_master_xfer,
	.functionality	= solo_i2c_functionality,
};

Annotation

Implementation Notes