drivers/media/dvb-core/dvb_frontend.c

Source file repositories/reference/linux-study-clean/drivers/media/dvb-core/dvb_frontend.c

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-core/dvb_frontend.c
Extension
.c
Size
83754 bytes
Lines
3108
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations dvb_frontend_fops = {
	.owner		= THIS_MODULE,
	.unlocked_ioctl	= dvb_frontend_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= dvb_frontend_compat_ioctl,
#endif
	.poll		= dvb_frontend_poll,
	.open		= dvb_frontend_open,
	.release	= dvb_frontend_release,
	.llseek		= noop_llseek,
};

int dvb_frontend_suspend(struct dvb_frontend *fe)
{
	int ret = 0;

	dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
		fe->id);

	if (fe->ops.tuner_ops.suspend)
		ret = fe->ops.tuner_ops.suspend(fe);
	else if (fe->ops.tuner_ops.sleep)
		ret = fe->ops.tuner_ops.sleep(fe);

	if (fe->ops.suspend)
		ret = fe->ops.suspend(fe);
	else if (fe->ops.sleep)
		ret = fe->ops.sleep(fe);

	return ret;
}
EXPORT_SYMBOL(dvb_frontend_suspend);

int dvb_frontend_resume(struct dvb_frontend *fe)
{
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
	int ret = 0;

	dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
		fe->id);

	fe->exit = DVB_FE_DEVICE_RESUME;
	if (fe->ops.resume)
		ret = fe->ops.resume(fe);
	else if (fe->ops.init)
		ret = fe->ops.init(fe);

	if (fe->ops.tuner_ops.resume)
		ret = fe->ops.tuner_ops.resume(fe);
	else if (fe->ops.tuner_ops.init)
		ret = fe->ops.tuner_ops.init(fe);

	if (fe->ops.set_tone && fepriv->tone != -1)
		fe->ops.set_tone(fe, fepriv->tone);
	if (fe->ops.set_voltage && fepriv->voltage != -1)
		fe->ops.set_voltage(fe, fepriv->voltage);

	fe->exit = DVB_FE_NO_EXIT;
	fepriv->state = FESTATE_RETUNE;
	dvb_frontend_wakeup(fe);

	return ret;
}
EXPORT_SYMBOL(dvb_frontend_resume);

int dvb_register_frontend(struct dvb_adapter *dvb,
			  struct dvb_frontend *fe)
{
	struct dvb_frontend_private *fepriv;
	const struct dvb_device dvbdev_template = {
		.users = ~0,
		.writers = 1,
		.readers = (~0) - 1,
		.fops = &dvb_frontend_fops,
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
		.name = fe->ops.info.name,
#endif
	};
	int ret;

	dev_dbg(dvb->device, "%s:\n", __func__);

	if (mutex_lock_interruptible(&frontend_mutex))
		return -ERESTARTSYS;

	fe->frontend_priv = kzalloc_obj(struct dvb_frontend_private);
	if (!fe->frontend_priv) {
		mutex_unlock(&frontend_mutex);
		return -ENOMEM;
	}

Annotation

Implementation Notes