dvbdev.c 24.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * dvbdev.c
 *
 * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de>
 *                  & Marcus Metzler <marcus@convergence.de>
 *                    for convergence integrated media GmbH
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

20 21
#define pr_fmt(fmt) "dvbdev: " fmt

L
Linus Torvalds 已提交
22 23 24 25 26
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/kernel.h>
27
#include <linux/i2c.h>
L
Linus Torvalds 已提交
28 29 30 31 32
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/cdev.h>
33
#include <linux/mutex.h>
34
#include <media/dvbdev.h>
L
Linus Torvalds 已提交
35

36 37 38
/* Due to enum tuner_pad_index */
#include <media/tuner.h>

A
Arnd Bergmann 已提交
39
static DEFINE_MUTEX(dvbdev_mutex);
L
Linus Torvalds 已提交
40 41 42 43 44
static int dvbdev_debug;

module_param(dvbdev_debug, int, 0644);
MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off).");

45 46 47 48 49
#define dprintk(fmt, arg...) do {					\
	if (dvbdev_debug)						\
		printk(KERN_DEBUG pr_fmt("%s: " fmt),			\
		       __func__, ##arg);				\
} while (0)
L
Linus Torvalds 已提交
50 51

static LIST_HEAD(dvb_adapter_list);
52
static DEFINE_MUTEX(dvbdev_register_lock);
L
Linus Torvalds 已提交
53 54

static const char * const dnames[] = {
55 56 57 58 59 60 61 62 63
	[DVB_DEVICE_VIDEO] =		"video",
	[DVB_DEVICE_AUDIO] =		"audio",
	[DVB_DEVICE_SEC] =		"sec",
	[DVB_DEVICE_FRONTEND] =		"frontend",
	[DVB_DEVICE_DEMUX] =		"demux",
	[DVB_DEVICE_DVR] =		"dvr",
	[DVB_DEVICE_CA] =		"ca",
	[DVB_DEVICE_NET] =		"net",
	[DVB_DEVICE_OSD] =		"osd"
L
Linus Torvalds 已提交
64 65
};

66 67 68 69
#ifdef CONFIG_DVB_DYNAMIC_MINORS
#define MAX_DVB_MINORS		256
#define DVB_MAX_IDS		MAX_DVB_MINORS
#else
L
Linus Torvalds 已提交
70
#define DVB_MAX_IDS		4
71

72 73 74 75 76 77 78 79 80 81 82 83 84 85
static const u8 minor_type[] = {
       [DVB_DEVICE_VIDEO]      = 0,
       [DVB_DEVICE_AUDIO]      = 1,
       [DVB_DEVICE_SEC]        = 2,
       [DVB_DEVICE_FRONTEND]   = 3,
       [DVB_DEVICE_DEMUX]      = 4,
       [DVB_DEVICE_DVR]        = 5,
       [DVB_DEVICE_CA]         = 6,
       [DVB_DEVICE_NET]        = 7,
       [DVB_DEVICE_OSD]        = 8,
};

#define nums2minor(num, type, id) \
       (((num) << 6) | ((id) << 4) | minor_type[type])
86

L
Linus Torvalds 已提交
87
#define MAX_DVB_MINORS		(DVB_MAX_ADAPTERS*64)
88
#endif
L
Linus Torvalds 已提交
89

90
static struct class *dvb_class;
L
Linus Torvalds 已提交
91

92 93
static struct dvb_device *dvb_minors[MAX_DVB_MINORS];
static DECLARE_RWSEM(minor_rwsem);
L
Linus Torvalds 已提交
94 95 96 97 98

static int dvb_device_open(struct inode *inode, struct file *file)
{
	struct dvb_device *dvbdev;

A
Arnd Bergmann 已提交
99
	mutex_lock(&dvbdev_mutex);
100 101
	down_read(&minor_rwsem);
	dvbdev = dvb_minors[iminor(inode)];
L
Linus Torvalds 已提交
102 103 104

	if (dvbdev && dvbdev->fops) {
		int err = 0;
105
		const struct file_operations *new_fops;
L
Linus Torvalds 已提交
106

107 108
		new_fops = fops_get(dvbdev->fops);
		if (!new_fops)
L
Laurent Pinchart 已提交
109
			goto fail;
110 111 112
		file->private_data = dvbdev;
		replace_fops(file, new_fops);
		if (file->f_op->open)
113
			err = file->f_op->open(inode, file);
114
		up_read(&minor_rwsem);
A
Arnd Bergmann 已提交
115
		mutex_unlock(&dvbdev_mutex);
116
		return err;
L
Linus Torvalds 已提交
117
	}
L
Laurent Pinchart 已提交
118
fail:
119
	up_read(&minor_rwsem);
A
Arnd Bergmann 已提交
120
	mutex_unlock(&dvbdev_mutex);
L
Linus Torvalds 已提交
121 122 123 124
	return -ENODEV;
}


125
static const struct file_operations dvb_device_fops =
L
Linus Torvalds 已提交
126 127 128
{
	.owner =	THIS_MODULE,
	.open =		dvb_device_open,
129
	.llseek =	noop_llseek,
L
Linus Torvalds 已提交
130 131
};

132
static struct cdev dvb_device_cdev;
L
Linus Torvalds 已提交
133 134 135

int dvb_generic_open(struct inode *inode, struct file *file)
{
136
	struct dvb_device *dvbdev = file->private_data;
L
Linus Torvalds 已提交
137

138 139
	if (!dvbdev)
		return -ENODEV;
L
Linus Torvalds 已提交
140 141

	if (!dvbdev->users)
142
		return -EBUSY;
L
Linus Torvalds 已提交
143 144

	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
145 146
		if (!dvbdev->readers)
			return -EBUSY;
L
Linus Torvalds 已提交
147 148
		dvbdev->readers--;
	} else {
149 150
		if (!dvbdev->writers)
			return -EBUSY;
L
Linus Torvalds 已提交
151 152 153 154 155 156 157 158 159 160 161
		dvbdev->writers--;
	}

	dvbdev->users--;
	return 0;
}
EXPORT_SYMBOL(dvb_generic_open);


int dvb_generic_release(struct inode *inode, struct file *file)
{
162
	struct dvb_device *dvbdev = file->private_data;
L
Linus Torvalds 已提交
163 164

	if (!dvbdev)
165
		return -ENODEV;
L
Linus Torvalds 已提交
166 167 168 169 170 171 172 173 174 175 176 177 178

	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
		dvbdev->readers++;
	} else {
		dvbdev->writers++;
	}

	dvbdev->users++;
	return 0;
}
EXPORT_SYMBOL(dvb_generic_release);


179 180
long dvb_generic_ioctl(struct file *file,
		       unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
181
{
182
	struct dvb_device *dvbdev = file->private_data;
L
Linus Torvalds 已提交
183

184 185
	if (!dvbdev)
		return -ENODEV;
L
Linus Torvalds 已提交
186 187 188 189

	if (!dvbdev->kernel_ioctl)
		return -EINVAL;

A
Arnd Bergmann 已提交
190
	return dvb_usercopy(file, cmd, arg, dvbdev->kernel_ioctl);
L
Linus Torvalds 已提交
191 192 193 194 195 196 197 198 199
}
EXPORT_SYMBOL(dvb_generic_ioctl);


static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
{
	u32 id = 0;

	while (id < DVB_MAX_IDS) {
200 201
		struct dvb_device *dev;
		list_for_each_entry(dev, &adap->device_list, list_head)
L
Linus Torvalds 已提交
202 203 204 205 206 207 208 209 210
			if (dev->type == type && dev->id == id)
				goto skip;
		return id;
skip:
		id++;
	}
	return -ENFILE;
}

211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
static void dvb_media_device_free(struct dvb_device *dvbdev)
{
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
	if (dvbdev->entity) {
		media_device_unregister_entity(dvbdev->entity);
		kfree(dvbdev->entity);
		kfree(dvbdev->pads);
		dvbdev->entity = NULL;
		dvbdev->pads = NULL;
	}

	if (dvbdev->tsout_entity) {
		int i;

		for (i = 0; i < dvbdev->tsout_num_entities; i++) {
			media_device_unregister_entity(&dvbdev->tsout_entity[i]);
			kfree(dvbdev->tsout_entity[i].name);
		}
		kfree(dvbdev->tsout_entity);
		kfree(dvbdev->tsout_pads);
		dvbdev->tsout_entity = NULL;
		dvbdev->tsout_pads = NULL;

		dvbdev->tsout_num_entities = 0;
	}

	if (dvbdev->intf_devnode) {
		media_devnode_remove(dvbdev->intf_devnode);
		dvbdev->intf_devnode = NULL;
	}
241 242 243 244 245 246 247

	if (dvbdev->adapter->conn) {
		media_device_unregister_entity(dvbdev->adapter->conn);
		dvbdev->adapter->conn = NULL;
		kfree(dvbdev->adapter->conn_pads);
		dvbdev->adapter->conn_pads = NULL;
	}
248 249 250
#endif
}

251
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
252
static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
253 254 255 256 257 258 259
				    const char *name, int npads)
{
	int i, ret = 0;

	dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
				     GFP_KERNEL);
	if (!dvbdev->tsout_pads)
260 261
		return -ENOMEM;

262 263
	dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity),
				       GFP_KERNEL);
264 265 266 267 268
	if (!dvbdev->tsout_entity)
		return -ENOMEM;

	dvbdev->tsout_num_entities = npads;

269 270 271 272 273
	for (i = 0; i < npads; i++) {
		struct media_pad *pads = &dvbdev->tsout_pads[i];
		struct media_entity *entity = &dvbdev->tsout_entity[i];

		entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
274 275
		if (!entity->name)
			return -ENOMEM;
276

277
		entity->function = MEDIA_ENT_F_IO_DTV;
278 279
		pads->flags = MEDIA_PAD_FL_SINK;

280
		ret = media_entity_pads_init(entity, 1, pads);
281
		if (ret < 0)
282
			return ret;
283 284 285 286

		ret = media_device_register_entity(dvbdev->adapter->mdev,
						   entity);
		if (ret < 0)
287
			return ret;
288
	}
289
	return 0;
290 291 292 293 294
}

#define DEMUX_TSOUT	"demux-tsout"
#define DVR_TSOUT	"dvr-tsout"

295 296
static int dvb_create_media_entity(struct dvb_device *dvbdev,
				   int type, int demux_sink_pads)
297
{
298
	int i, ret, npads;
299

300 301 302 303
	switch (type) {
	case DVB_DEVICE_FRONTEND:
		npads = 2;
		break;
304
	case DVB_DEVICE_DVR:
305 306 307
		ret = dvb_create_tsout_entity(dvbdev, DVR_TSOUT,
					      demux_sink_pads);
		return ret;
308
	case DVB_DEVICE_DEMUX:
309
		npads = 1 + demux_sink_pads;
310 311 312 313
		ret = dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT,
					      demux_sink_pads);
		if (ret < 0)
			return ret;
314 315 316 317 318 319 320 321 322 323 324 325 326 327
		break;
	case DVB_DEVICE_CA:
		npads = 2;
		break;
	case DVB_DEVICE_NET:
		/*
		 * We should be creating entities for the MPE/ULE
		 * decapsulation hardware (or software implementation).
		 *
		 * However, the number of for the MPE/ULE decaps may not be
		 * fixed. As we don't have yet dynamic support for PADs at
		 * the Media Controller, let's not create the decap
		 * entities yet.
		 */
328
		return 0;
329
	default:
330
		return 0;
331
	}
332 333 334

	dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL);
	if (!dvbdev->entity)
335
		return -ENOMEM;
336 337

	dvbdev->entity->name = dvbdev->name;
338 339 340 341

	if (npads) {
		dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
				       GFP_KERNEL);
342 343
		if (!dvbdev->pads)
			return -ENOMEM;
344 345
	}

346 347
	switch (type) {
	case DVB_DEVICE_FRONTEND:
348
		dvbdev->entity->function = MEDIA_ENT_F_DTV_DEMOD;
349 350
		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
351 352
		break;
	case DVB_DEVICE_DEMUX:
353
		dvbdev->entity->function = MEDIA_ENT_F_TS_DEMUX;
354
		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
355 356
		for (i = 1; i < npads; i++)
			dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE;
357 358
		break;
	case DVB_DEVICE_CA:
359
		dvbdev->entity->function = MEDIA_ENT_F_DTV_CA;
360 361
		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
362 363
		break;
	default:
364
		/* Should never happen, as the first switch prevents it */
365
		kfree(dvbdev->entity);
366
		kfree(dvbdev->pads);
367
		dvbdev->entity = NULL;
368 369
		dvbdev->pads = NULL;
		return 0;
370 371
	}

372
	if (npads) {
373
		ret = media_entity_pads_init(dvbdev->entity, npads, dvbdev->pads);
374 375
		if (ret)
			return ret;
376
	}
377 378 379
	ret = media_device_register_entity(dvbdev->adapter->mdev,
					   dvbdev->entity);
	if (ret)
380
		return ret;
381

382
	pr_info("%s: media entity '%s' registered.\n",
383
		__func__, dvbdev->entity->name);
384 385

	return 0;
386
}
387
#endif
L
Linus Torvalds 已提交
388

389 390 391
static int dvb_register_media_device(struct dvb_device *dvbdev,
				     int type, int minor,
				     unsigned demux_sink_pads)
392 393
{
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
394
	struct media_link *link;
395
	u32 intf_type;
396
	int ret;
397 398

	if (!dvbdev->adapter->mdev)
399
		return 0;
400

401 402 403
	ret = dvb_create_media_entity(dvbdev, type, demux_sink_pads);
	if (ret)
		return ret;
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421

	switch (type) {
	case DVB_DEVICE_FRONTEND:
		intf_type = MEDIA_INTF_T_DVB_FE;
		break;
	case DVB_DEVICE_DEMUX:
		intf_type = MEDIA_INTF_T_DVB_DEMUX;
		break;
	case DVB_DEVICE_DVR:
		intf_type = MEDIA_INTF_T_DVB_DVR;
		break;
	case DVB_DEVICE_CA:
		intf_type = MEDIA_INTF_T_DVB_CA;
		break;
	case DVB_DEVICE_NET:
		intf_type = MEDIA_INTF_T_DVB_NET;
		break;
	default:
422
		return 0;
423 424 425
	}

	dvbdev->intf_devnode = media_devnode_create(dvbdev->adapter->mdev,
426
						    intf_type, 0,
427
						    DVB_MAJOR, minor);
428 429 430

	if (!dvbdev->intf_devnode)
		return -ENOMEM;
431 432 433 434 435 436 437 438 439

	/*
	 * Create the "obvious" link, e. g. the ones that represent
	 * a direct association between an interface and an entity.
	 * Other links should be created elsewhere, like:
	 *		DVB FE intf    -> tuner
	 *		DVB demux intf -> dvr
	 */

440 441
	if (!dvbdev->entity)
		return 0;
442

443 444 445 446
	link = media_create_intf_link(dvbdev->entity,
				      &dvbdev->intf_devnode->intf,
				      MEDIA_LNK_FL_ENABLED |
				      MEDIA_LNK_FL_IMMUTABLE);
447 448
	if (!link)
		return -ENOMEM;
449
#endif
450
	return 0;
451 452
}

L
Linus Torvalds 已提交
453
int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
454 455
			const struct dvb_device *template, void *priv,
			enum dvb_device_type type, int demux_sink_pads)
L
Linus Torvalds 已提交
456 457
{
	struct dvb_device *dvbdev;
458
	struct file_operations *dvbdevfops;
459
	struct device *clsdev;
460
	int minor;
461
	int id, ret;
L
Linus Torvalds 已提交
462

463
	mutex_lock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
464

465
	if ((id = dvbdev_get_free_id (adap, type)) < 0){
466
		mutex_unlock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
467
		*pdvbdev = NULL;
468
		pr_err("%s: couldn't find free device id\n", __func__);
L
Linus Torvalds 已提交
469 470 471
		return -ENFILE;
	}

472
	*pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL);
L
Linus Torvalds 已提交
473

474 475 476 477 478 479 480 481 482
	if (!dvbdev){
		mutex_unlock(&dvbdev_register_lock);
		return -ENOMEM;
	}

	dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);

	if (!dvbdevfops){
		kfree (dvbdev);
483
		mutex_unlock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
484 485 486 487 488 489 490 491
		return -ENOMEM;
	}

	memcpy(dvbdev, template, sizeof(struct dvb_device));
	dvbdev->type = type;
	dvbdev->id = id;
	dvbdev->adapter = adap;
	dvbdev->priv = priv;
492
	dvbdev->fops = dvbdevfops;
493
	init_waitqueue_head (&dvbdev->wait_queue);
L
Linus Torvalds 已提交
494

495 496
	memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
	dvbdevfops->owner = adap->module;
L
Linus Torvalds 已提交
497 498 499

	list_add_tail (&dvbdev->list_head, &adap->device_list);

500 501 502 503 504 505 506 507 508
	down_write(&minor_rwsem);
#ifdef CONFIG_DVB_DYNAMIC_MINORS
	for (minor = 0; minor < MAX_DVB_MINORS; minor++)
		if (dvb_minors[minor] == NULL)
			break;

	if (minor == MAX_DVB_MINORS) {
		kfree(dvbdevfops);
		kfree(dvbdev);
509
		up_write(&minor_rwsem);
510 511 512 513 514 515 516 517 518 519 520
		mutex_unlock(&dvbdev_register_lock);
		return -EINVAL;
	}
#else
	minor = nums2minor(adap->num, type, id);
#endif

	dvbdev->minor = minor;
	dvb_minors[minor] = dvbdev;
	up_write(&minor_rwsem);

521 522
	ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
	if (ret) {
523
		pr_err("%s: dvb_register_media_device failed to create the mediagraph\n",
524 525 526 527 528 529 530 531 532 533
		      __func__);

		dvb_media_device_free(dvbdev);
		kfree(dvbdevfops);
		kfree(dvbdev);
		up_write(&minor_rwsem);
		mutex_unlock(&dvbdev_register_lock);
		return ret;
	}

534 535
	mutex_unlock(&dvbdev_register_lock);

536
	clsdev = device_create(dvb_class, adap->device,
537
			       MKDEV(DVB_MAJOR, minor),
538
			       dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
539
	if (IS_ERR(clsdev)) {
540
		pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
541
		       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
542 543
		return PTR_ERR(clsdev);
	}
544
	dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
545
		adap->num, dnames[type], id, minor, minor);
L
Linus Torvalds 已提交
546 547 548 549 550 551

	return 0;
}
EXPORT_SYMBOL(dvb_register_device);


552
void dvb_remove_device(struct dvb_device *dvbdev)
L
Linus Torvalds 已提交
553 554 555 556
{
	if (!dvbdev)
		return;

557 558 559 560
	down_write(&minor_rwsem);
	dvb_minors[dvbdev->minor] = NULL;
	up_write(&minor_rwsem);

561
	dvb_media_device_free(dvbdev);
562

563
	device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
564

L
Linus Torvalds 已提交
565
	list_del (&dvbdev->list_head);
566 567 568 569 570 571 572 573 574
}
EXPORT_SYMBOL(dvb_remove_device);


void dvb_free_device(struct dvb_device *dvbdev)
{
	if (!dvbdev)
		return;

575
	kfree (dvbdev->fops);
L
Linus Torvalds 已提交
576 577
	kfree (dvbdev);
}
578 579 580 581 582 583 584 585
EXPORT_SYMBOL(dvb_free_device);


void dvb_unregister_device(struct dvb_device *dvbdev)
{
	dvb_remove_device(dvbdev);
	dvb_free_device(dvbdev);
}
L
Linus Torvalds 已提交
586 587
EXPORT_SYMBOL(dvb_unregister_device);

588 589

#ifdef CONFIG_MEDIA_CONTROLLER_DVB
590 591 592 593 594 595 596 597 598 599 600 601 602 603

static int dvb_create_io_intf_links(struct dvb_adapter *adap,
				    struct media_interface *intf,
				    char *name)
{
	struct media_device *mdev = adap->mdev;
	struct media_entity *entity;
	struct media_link *link;

	media_device_for_each_entity(entity, mdev) {
		if (entity->function == MEDIA_ENT_F_IO_DTV) {
			if (strncmp(entity->name, name, strlen(name)))
				continue;
			link = media_create_intf_link(entity, intf,
604 605
						      MEDIA_LNK_FL_ENABLED |
						      MEDIA_LNK_FL_IMMUTABLE);
606 607 608 609 610 611 612
			if (!link)
				return -ENOMEM;
		}
	}
	return 0;
}

613 614
int dvb_create_media_graph(struct dvb_adapter *adap,
			   bool create_rf_connector)
615 616
{
	struct media_device *mdev = adap->mdev;
617
	struct media_entity *entity, *tuner = NULL, *demod = NULL, *conn;
618
	struct media_entity *demux = NULL, *ca = NULL;
619
	struct media_link *link;
620
	struct media_interface *intf;
621 622
	unsigned demux_pad = 0;
	unsigned dvr_pad = 0;
623
	unsigned ntuner = 0, ndemod = 0;
624
	int ret;
625
	static const char *connector_name = "Television";
626 627

	if (!mdev)
628
		return 0;
629 630

	media_device_for_each_entity(entity, mdev) {
631
		switch (entity->function) {
632
		case MEDIA_ENT_F_TUNER:
633
			tuner = entity;
634
			ntuner++;
635
			break;
636
		case MEDIA_ENT_F_DTV_DEMOD:
637
			demod = entity;
638
			ndemod++;
639
			break;
640
		case MEDIA_ENT_F_TS_DEMUX:
641 642
			demux = entity;
			break;
643
		case MEDIA_ENT_F_DTV_CA:
644 645 646 647 648
			ca = entity;
			break;
		}
	}

649 650 651 652 653 654 655 656 657 658 659 660
	/*
	 * Prepare to signalize to media_create_pad_links() that multiple
	 * entities of the same type exists and a 1:n or n:1 links need to be
	 * created.
	 * NOTE: if both tuner and demod have multiple instances, it is up
	 * to the caller driver to create such links.
	 */
	if (ntuner > 1)
		tuner = NULL;
	if (ndemod > 1)
		demod = NULL;

661 662 663 664 665 666
	if (create_rf_connector) {
		conn = kzalloc(sizeof(*conn), GFP_KERNEL);
		if (!conn)
			return -ENOMEM;
		adap->conn = conn;

667
		adap->conn_pads = kzalloc(sizeof(*adap->conn_pads), GFP_KERNEL);
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
		if (!adap->conn_pads)
			return -ENOMEM;

		conn->flags = MEDIA_ENT_FL_CONNECTOR;
		conn->function = MEDIA_ENT_F_CONN_RF;
		conn->name = connector_name;
		adap->conn_pads->flags = MEDIA_PAD_FL_SOURCE;

		ret = media_entity_pads_init(conn, 1, adap->conn_pads);
		if (ret)
			return ret;

		ret = media_device_register_entity(mdev, conn);
		if (ret)
			return ret;

684 685 686 687 688 689 690 691
		if (!ntuner)
			ret = media_create_pad_links(mdev,
						     MEDIA_ENT_F_CONN_RF,
						     conn, 0,
						     MEDIA_ENT_F_DTV_DEMOD,
						     demod, 0,
						     MEDIA_LNK_FL_ENABLED,
						     false);
692
		else
693 694 695 696 697 698 699
			ret = media_create_pad_links(mdev,
						     MEDIA_ENT_F_CONN_RF,
						     conn, 0,
						     MEDIA_ENT_F_TUNER,
						     tuner, TUNER_PAD_RF_INPUT,
						     MEDIA_LNK_FL_ENABLED,
						     false);
700 701 702 703
		if (ret)
			return ret;
	}

704 705 706
	if (ntuner && ndemod) {
		ret = media_create_pad_links(mdev,
					     MEDIA_ENT_F_TUNER,
707
					     tuner, TUNER_PAD_OUTPUT,
708 709 710
					     MEDIA_ENT_F_DTV_DEMOD,
					     demod, 0, MEDIA_LNK_FL_ENABLED,
					     false);
711 712 713
		if (ret)
			return ret;
	}
714

715 716 717 718 719 720 721
	if (ndemod && demux) {
		ret = media_create_pad_links(mdev,
					     MEDIA_ENT_F_DTV_DEMOD,
					     demod, 1,
					     MEDIA_ENT_F_TS_DEMUX,
					     demux, 0, MEDIA_LNK_FL_ENABLED,
					     false);
722
		if (ret)
723
			return ret;
724 725 726 727
	}
	if (demux && ca) {
		ret = media_create_pad_link(demux, 1, ca,
					    0, MEDIA_LNK_FL_ENABLED);
728
		if (ret)
729
			return ret;
730
	}
731

732 733 734
	/* Create demux links for each ringbuffer/pad */
	if (demux) {
		media_device_for_each_entity(entity, mdev) {
735
			if (entity->function == MEDIA_ENT_F_IO_DTV) {
736
				if (!strncmp(entity->name, DVR_TSOUT,
737 738 739 740 741 742 743
				    strlen(DVR_TSOUT))) {
					ret = media_create_pad_link(demux,
								++dvr_pad,
							    entity, 0, 0);
					if (ret)
						return ret;
				}
744
				if (!strncmp(entity->name, DEMUX_TSOUT,
745 746
				    strlen(DEMUX_TSOUT))) {
					ret = media_create_pad_link(demux,
747
							      ++demux_pad,
748 749 750 751
							    entity, 0, 0);
					if (ret)
						return ret;
				}
752 753 754 755
			}
		}
	}

756
	/* Create interface links for FE->tuner, DVR->demux and CA->ca */
757
	media_device_for_each_intf(intf, mdev) {
758 759
		if (intf->type == MEDIA_INTF_T_DVB_CA && ca) {
			link = media_create_intf_link(ca, intf,
760 761
						      MEDIA_LNK_FL_ENABLED |
						      MEDIA_LNK_FL_IMMUTABLE);
762 763 764
			if (!link)
				return -ENOMEM;
		}
765

766 767
		if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) {
			link = media_create_intf_link(tuner, intf,
768 769
						      MEDIA_LNK_FL_ENABLED |
						      MEDIA_LNK_FL_IMMUTABLE);
770 771 772
			if (!link)
				return -ENOMEM;
		}
773 774 775 776 777 778
#if 0
		/*
		 * Indirect link - let's not create yet, as we don't know how
		 *		   to handle indirect links, nor if this will
		 *		   actually be needed.
		 */
779 780
		if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) {
			link = media_create_intf_link(demux, intf,
781 782
						      MEDIA_LNK_FL_ENABLED |
						      MEDIA_LNK_FL_IMMUTABLE);
783 784 785
			if (!link)
				return -ENOMEM;
		}
786
#endif
787 788 789 790 791 792 793 794 795
		if (intf->type == MEDIA_INTF_T_DVB_DVR) {
			ret = dvb_create_io_intf_links(adap, intf, DVR_TSOUT);
			if (ret)
				return ret;
		}
		if (intf->type == MEDIA_INTF_T_DVB_DEMUX) {
			ret = dvb_create_io_intf_links(adap, intf, DEMUX_TSOUT);
			if (ret)
				return ret;
796
		}
797
	}
798
	return 0;
799 800
}
EXPORT_SYMBOL_GPL(dvb_create_media_graph);
801
#endif
802

803 804 805 806 807 808 809 810 811 812 813
static int dvbdev_check_free_adapter_num(int num)
{
	struct list_head *entry;
	list_for_each(entry, &dvb_adapter_list) {
		struct dvb_adapter *adap;
		adap = list_entry(entry, struct dvb_adapter, list_head);
		if (adap->num == num)
			return 0;
	}
	return 1;
}
L
Linus Torvalds 已提交
814 815 816 817 818 819

static int dvbdev_get_free_adapter_num (void)
{
	int num = 0;

	while (num < DVB_MAX_ADAPTERS) {
820 821
		if (dvbdev_check_free_adapter_num(num))
			return num;
L
Linus Torvalds 已提交
822 823 824 825 826 827 828
		num++;
	}

	return -ENFILE;
}


829 830 831
int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
			 struct module *module, struct device *device,
			 short *adapter_nums)
L
Linus Torvalds 已提交
832
{
833
	int i, num;
L
Linus Torvalds 已提交
834

835
	mutex_lock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
836

837 838 839 840 841 842 843 844 845 846 847 848 849 850
	for (i = 0; i < DVB_MAX_ADAPTERS; ++i) {
		num = adapter_nums[i];
		if (num >= 0  &&  num < DVB_MAX_ADAPTERS) {
		/* use the one the driver asked for */
			if (dvbdev_check_free_adapter_num(num))
				break;
		} else {
			num = dvbdev_get_free_adapter_num();
			break;
		}
		num = -1;
	}

	if (num < 0) {
851
		mutex_unlock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
852 853 854 855 856 857
		return -ENFILE;
	}

	memset (adap, 0, sizeof(struct dvb_adapter));
	INIT_LIST_HEAD (&adap->device_list);

858
	pr_info("DVB: registering new adapter (%s)\n", name);
L
Linus Torvalds 已提交
859 860 861 862

	adap->num = num;
	adap->name = name;
	adap->module = module;
863
	adap->device = device;
864 865 866
	adap->mfe_shared = 0;
	adap->mfe_dvbdev = NULL;
	mutex_init (&adap->mfe_lock);
L
Linus Torvalds 已提交
867

868 869 870 871
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
	mutex_init(&adap->mdev_lock);
#endif

L
Linus Torvalds 已提交
872 873
	list_add_tail (&adap->list_head, &dvb_adapter_list);

874
	mutex_unlock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
875 876 877 878 879 880 881 882

	return num;
}
EXPORT_SYMBOL(dvb_register_adapter);


int dvb_unregister_adapter(struct dvb_adapter *adap)
{
883
	mutex_lock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
884
	list_del (&adap->list_head);
885
	mutex_unlock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
886 887 888 889 890 891 892 893 894
	return 0;
}
EXPORT_SYMBOL(dvb_unregister_adapter);

/* if the miracle happens and "generic_usercopy()" is included into
   the kernel, then this can vanish. please don't make the mistake and
   define this as video_usercopy(). this will introduce a dependecy
   to the v4l "videodev.o" module, which is unnecessary for some
   cards (ie. the budget dvb-cards don't need the v4l module...) */
895
int dvb_usercopy(struct file *file,
896
		     unsigned int cmd, unsigned long arg,
897
		     int (*func)(struct file *file,
L
Linus Torvalds 已提交
898 899
		     unsigned int cmd, void *arg))
{
900 901 902 903 904 905 906 907
	char    sbuf[128];
	void    *mbuf = NULL;
	void    *parg = NULL;
	int     err  = -EINVAL;

	/*  Copy arguments into temp kernel buffer  */
	switch (_IOC_DIR(cmd)) {
	case _IOC_NONE:
L
Linus Torvalds 已提交
908 909 910 911 912 913
		/*
		 * For this command, the pointer is actually an integer
		 * argument.
		 */
		parg = (void *) arg;
		break;
914 915 916 917
	case _IOC_READ: /* some v4l ioctls are marked wrong ... */
	case _IOC_WRITE:
	case (_IOC_WRITE | _IOC_READ):
		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
918
			parg = sbuf;
919
		} else {
920
			/* too big to allocate from stack */
921
			mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
922 923 924
			if (NULL == mbuf)
				return -ENOMEM;
			parg = mbuf;
925 926 927 928
		}

		err = -EFAULT;
		if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
929
			goto out;
930 931 932 933
		break;
	}

	/* call driver */
934
	if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
935
		err = -ENOTTY;
936 937 938 939 940 941 942 943 944 945

	if (err < 0)
		goto out;

	/*  Copy results into user buffer  */
	switch (_IOC_DIR(cmd))
	{
	case _IOC_READ:
	case (_IOC_WRITE | _IOC_READ):
		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
946
			err = -EFAULT;
947 948
		break;
	}
L
Linus Torvalds 已提交
949 950

out:
951 952
	kfree(mbuf);
	return err;
L
Linus Torvalds 已提交
953 954
}

955
#if IS_ENABLED(CONFIG_I2C)
956 957 958 959 960 961 962 963 964 965
struct i2c_client *dvb_module_probe(const char *module_name,
				    const char *name,
				    struct i2c_adapter *adap,
				    unsigned char addr,
				    void *platform_data)
{
	struct i2c_client *client;
	struct i2c_board_info *board_info;

	board_info = kzalloc(sizeof(*board_info), GFP_KERNEL);
966 967
	if (!board_info)
		return NULL;
968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003

	if (name)
		strlcpy(board_info->type, name, I2C_NAME_SIZE);
	else
		strlcpy(board_info->type, module_name, I2C_NAME_SIZE);

	board_info->addr = addr;
	board_info->platform_data = platform_data;
	request_module(module_name);
	client = i2c_new_device(adap, board_info);
	if (client == NULL || client->dev.driver == NULL) {
		kfree(board_info);
		return NULL;
	}

	if (!try_module_get(client->dev.driver->owner)) {
		i2c_unregister_device(client);
		client = NULL;
	}

	kfree(board_info);
	return client;
}
EXPORT_SYMBOL_GPL(dvb_module_probe);

void dvb_module_release(struct i2c_client *client)
{
	if (!client)
		return;

	module_put(client->dev.driver->owner);
	i2c_unregister_device(client);
}
EXPORT_SYMBOL_GPL(dvb_module_release);
#endif

1004 1005 1006 1007 1008
static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	struct dvb_device *dvbdev = dev_get_drvdata(dev);

	add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
1009 1010
	add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]);
	add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id);
1011 1012 1013
	return 0;
}

1014
static char *dvb_devnode(struct device *dev, umode_t *mode)
1015 1016 1017 1018 1019 1020 1021 1022
{
	struct dvb_device *dvbdev = dev_get_drvdata(dev);

	return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d",
		dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);
}


L
Linus Torvalds 已提交
1023 1024 1025 1026 1027 1028
static int __init init_dvbdev(void)
{
	int retval;
	dev_t dev = MKDEV(DVB_MAJOR, 0);

	if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
1029
		pr_err("dvb-core: unable to get major %d\n", DVB_MAJOR);
L
Linus Torvalds 已提交
1030 1031 1032 1033 1034
		return retval;
	}

	cdev_init(&dvb_device_cdev, &dvb_device_fops);
	if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
1035
		pr_err("dvb-core: unable register character device\n");
L
Linus Torvalds 已提交
1036 1037 1038
		goto error;
	}

1039
	dvb_class = class_create(THIS_MODULE, "dvb");
L
Linus Torvalds 已提交
1040 1041 1042 1043
	if (IS_ERR(dvb_class)) {
		retval = PTR_ERR(dvb_class);
		goto error;
	}
1044
	dvb_class->dev_uevent = dvb_uevent;
1045
	dvb_class->devnode = dvb_devnode;
L
Linus Torvalds 已提交
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056
	return 0;

error:
	cdev_del(&dvb_device_cdev);
	unregister_chrdev_region(dev, MAX_DVB_MINORS);
	return retval;
}


static void __exit exit_dvbdev(void)
{
1057
	class_destroy(dvb_class);
L
Linus Torvalds 已提交
1058
	cdev_del(&dvb_device_cdev);
1059
	unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
L
Linus Torvalds 已提交
1060 1061
}

1062
subsys_initcall(init_dvbdev);
L
Linus Torvalds 已提交
1063 1064 1065 1066 1067
module_exit(exit_dvbdev);

MODULE_DESCRIPTION("DVB Core Driver");
MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler");
MODULE_LICENSE("GPL");