[PATCH] DVB core update
[linux-2.6/history.git] / drivers / media / dvb / dvb-core / dvb_frontend.c
blobfc4c01309c80f1b04bd4cfd38840ac1e09faa726
1 /*
2 * dvb-core.c: DVB core driver
4 * Copyright (C) 1999-2001 Ralph Metzler
5 * Marcus Metzler
6 * Holger Waechtler
7 * for convergence integrated media GmbH
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
25 #include <linux/string.h>
26 #include <linux/kernel.h>
27 #include <linux/sched.h>
28 #include <linux/wait.h>
29 #include <linux/slab.h>
30 #include <linux/poll.h>
31 #include <linux/module.h>
32 #include <linux/list.h>
33 #include <asm/processor.h>
34 #include <asm/semaphore.h>
36 #include "dvb_frontend.h"
37 #include "dvbdev.h"
38 #include "dvb_functions.h"
41 static int dvb_frontend_debug = 0;
42 static int dvb_shutdown_timeout = 5;
44 #define dprintk if (dvb_frontend_debug) printk
46 #define MAX_EVENT 8
48 struct dvb_fe_events {
49 struct dvb_frontend_event events[MAX_EVENT];
50 int eventw;
51 int eventr;
52 int overflow;
53 wait_queue_head_t wait_queue;
54 struct semaphore sem;
58 struct dvb_frontend_data {
59 struct dvb_frontend_info *info;
60 struct dvb_frontend frontend;
61 struct dvb_device *dvbdev;
62 struct dvb_frontend_parameters parameters;
63 struct dvb_fe_events events;
64 struct semaphore sem;
65 struct list_head list_head;
66 wait_queue_head_t wait_queue;
67 pid_t thread_pid;
68 unsigned long release_jiffies;
69 unsigned long lost_sync_jiffies;
70 int bending;
71 int lnb_drift;
72 int timeout_count;
73 int lost_sync_count;
74 int exit;
75 fe_status_t status;
79 struct dvb_frontend_ioctl_data {
80 struct list_head list_head;
81 struct dvb_adapter *adapter;
82 int (*before_ioctl) (struct dvb_frontend *frontend,
83 unsigned int cmd, void *arg);
84 int (*after_ioctl) (struct dvb_frontend *frontend,
85 unsigned int cmd, void *arg);
86 void *before_after_data;
90 struct dvb_frontend_notifier_data {
91 struct list_head list_head;
92 struct dvb_adapter *adapter;
93 void (*callback) (fe_status_t s, void *data);
94 void *data;
98 static LIST_HEAD(frontend_list);
99 static LIST_HEAD(frontend_ioctl_list);
100 static LIST_HEAD(frontend_notifier_list);
102 static DECLARE_MUTEX(frontend_mutex);
105 static int dvb_frontend_internal_ioctl (struct dvb_frontend *frontend,
106 unsigned int cmd, void *arg)
108 int err = -EOPNOTSUPP;
110 dprintk ("%s\n", __FUNCTION__);
112 if (frontend->before_ioctl)
113 err = frontend->before_ioctl (frontend, cmd, arg);
115 if (err == -EOPNOTSUPP) {
116 err = frontend->ioctl (frontend, cmd, arg);
118 if ((err == -EOPNOTSUPP) && frontend->after_ioctl)
119 err = frontend->after_ioctl (frontend, cmd, arg);
122 return err;
127 * if 2 tuners are located side by side you can get interferences when
128 * they try to tune to the same frequency, so both lose sync.
129 * We will slightly mistune in this case. The AFC of the demodulator
130 * should make it still possible to receive the requested transponder
131 * on both tuners...
133 static void dvb_bend_frequency (struct dvb_frontend_data *this_fe, int recursive)
135 struct list_head *entry;
136 int stepsize = this_fe->info->frequency_stepsize;
137 int this_fe_adap_num = this_fe->frontend.i2c->adapter->num;
138 int frequency;
140 if (!stepsize || recursive > 10) {
141 printk ("%s: too deep recursion, check frequency_stepsize "
142 "in your frontend code!\n", __FUNCTION__);
143 return;
146 dprintk ("%s\n", __FUNCTION__);
148 if (!recursive) {
149 if (down_interruptible (&frontend_mutex))
150 return;
152 this_fe->bending = 0;
155 list_for_each (entry, &frontend_list) {
156 struct dvb_frontend_data *fe;
157 int f;
159 fe = list_entry (entry, struct dvb_frontend_data, list_head);
161 if (fe->frontend.i2c->adapter->num != this_fe_adap_num)
162 continue;
164 f = fe->parameters.frequency;
165 f += fe->lnb_drift;
166 f += fe->bending;
168 frequency = this_fe->parameters.frequency;
169 frequency += this_fe->lnb_drift;
170 frequency += this_fe->bending;
172 if (this_fe != fe && fe->lost_sync_count != -1 &&
173 frequency > f - stepsize && frequency < f + stepsize)
175 if (recursive % 2)
176 this_fe->bending += stepsize;
177 else
178 this_fe->bending = -this_fe->bending;
180 dvb_bend_frequency (this_fe, recursive + 1);
181 goto done;
184 done:
185 if (!recursive)
186 up (&frontend_mutex);
190 static void dvb_call_frontend_notifiers (struct dvb_frontend_data *fe,
191 fe_status_t s)
193 dprintk ("%s\n", __FUNCTION__);
195 if ((fe->status & FE_HAS_LOCK) && !(s & FE_HAS_LOCK))
196 fe->lost_sync_jiffies = jiffies;
198 if (((s ^ fe->status) & FE_HAS_LOCK) && (s & FE_HAS_LOCK))
199 dvb_delay (fe->info->notifier_delay);
201 fe->status = s;
203 if (!(s & FE_HAS_LOCK) && (fe->info->caps & FE_CAN_MUTE_TS))
204 return;
207 * now tell the Demux about the TS status changes...
209 if (fe->frontend.notifier_callback)
210 fe->frontend.notifier_callback(fe->status, fe->frontend.notifier_data);
214 static void dvb_frontend_add_event (struct dvb_frontend_data *fe, fe_status_t status)
216 struct dvb_fe_events *events = &fe->events;
217 struct dvb_frontend_event *e;
218 int wp;
220 dprintk ("%s\n", __FUNCTION__);
222 if (down_interruptible (&events->sem))
223 return;
225 wp = (events->eventw + 1) % MAX_EVENT;
227 if (wp == events->eventr) {
228 events->overflow = 1;
229 events->eventr = (events->eventr + 1) % MAX_EVENT;
232 e = &events->events[events->eventw];
234 memcpy (&e->parameters, &fe->parameters,
235 sizeof (struct dvb_frontend_parameters));
237 if (status & FE_HAS_LOCK)
238 dvb_frontend_internal_ioctl (&fe->frontend,
239 FE_GET_FRONTEND,
240 &e->parameters);
241 events->eventw = wp;
243 up (&events->sem);
245 e->status = status;
246 dvb_call_frontend_notifiers (fe, status);
248 wake_up_interruptible (&events->wait_queue);
252 static int dvb_frontend_get_event (struct dvb_frontend_data *fe,
253 struct dvb_frontend_event *event, int flags)
255 struct dvb_fe_events *events = &fe->events;
257 dprintk ("%s\n", __FUNCTION__);
259 if (events->overflow) {
260 events->overflow = 0;
261 return -EOVERFLOW;
264 if (events->eventw == events->eventr) {
265 int ret;
267 if (flags & O_NONBLOCK)
268 return -EWOULDBLOCK;
270 up(&fe->sem);
272 ret = wait_event_interruptible (events->wait_queue,
273 events->eventw != events->eventr);
275 if (down_interruptible (&fe->sem))
276 return -ERESTARTSYS;
278 if (ret < 0)
279 return ret;
282 if (down_interruptible (&events->sem))
283 return -ERESTARTSYS;
285 memcpy (event, &events->events[events->eventr],
286 sizeof(struct dvb_frontend_event));
288 events->eventr = (events->eventr + 1) % MAX_EVENT;
290 up (&events->sem);
292 return 0;
296 static int dvb_frontend_set_parameters (struct dvb_frontend_data *fe,
297 struct dvb_frontend_parameters *param,
298 int first_trial)
300 struct dvb_frontend *frontend = &fe->frontend;
301 int err;
303 if (first_trial) {
304 fe->timeout_count = 0;
305 fe->lost_sync_count = 0;
306 fe->lost_sync_jiffies = jiffies;
307 fe->lnb_drift = 0;
308 if (fe->status & ~FE_TIMEDOUT)
309 dvb_frontend_add_event (fe, 0);
310 memcpy (&fe->parameters, param,
311 sizeof (struct dvb_frontend_parameters));
314 dvb_bend_frequency (fe, 0);
316 dprintk ("%s: f == %i, drift == %i\n",
317 __FUNCTION__, (int) param->frequency, (int) fe->lnb_drift);
319 param->frequency += fe->lnb_drift + fe->bending;
320 err = dvb_frontend_internal_ioctl (frontend, FE_SET_FRONTEND, param);
321 param->frequency -= fe->lnb_drift + fe->bending;
323 wake_up_interruptible (&fe->wait_queue);
325 return err;
328 static void dvb_frontend_init (struct dvb_frontend_data *fe)
330 struct dvb_frontend *frontend = &fe->frontend;
332 dprintk ("DVB: initialising frontend %i:%i (%s)...\n",
333 frontend->i2c->adapter->num, frontend->i2c->id,
334 fe->info->name);
336 dvb_frontend_internal_ioctl (frontend, FE_INIT, NULL);
340 static void update_delay (int *quality, int *delay, int locked)
342 int q2;
344 dprintk ("%s\n", __FUNCTION__);
346 if (locked)
347 (*quality) = (*quality * 220 + 36*256) / 256;
348 else
349 (*quality) = (*quality * 220 + 0) / 256;
351 q2 = *quality - 128;
352 q2 *= q2;
354 *delay = HZ/20 + q2 * HZ / (128*128);
358 #define LNB_DRIFT 1024 /* max. tolerated LNB drift, XXX FIXME: adjust! */
359 #define TIMEOUT 2*HZ
362 * here we only come when we have lost the lock bit,
363 * let's try to do something useful...
365 static void dvb_frontend_recover (struct dvb_frontend_data *fe)
367 dprintk ("%s\n", __FUNCTION__);
369 #if 0
370 if (fe->timeout_count > 3) {
371 printk ("%s: frontend seems dead, reinitializing...\n",
372 __FUNCTION__);
373 dvb_call_frontend_notifiers (fe, 0);
374 dvb_frontend_internal_ioctl (&fe->frontend, FE_INIT, NULL);
375 dvb_frontend_set_parameters (fe, &fe->parameters, 1);
376 dvb_frontend_add_event (fe, FE_REINIT);
377 fe->lost_sync_jiffies = jiffies;
378 fe->timeout_count = 0;
379 return;
381 #endif
384 * let's start a zigzag scan to compensate LNB drift...
387 int j = fe->lost_sync_count;
388 int stepsize;
390 if (fe->info->type == FE_QPSK)
391 stepsize = fe->parameters.u.qpsk.symbol_rate / 16000;
392 else if (fe->info->type == FE_QAM)
393 stepsize = 0;
394 else
395 stepsize = fe->info->frequency_stepsize * 2;
397 if (j % 32 == 0) {
398 fe->lnb_drift = 0;
399 } else {
400 fe->lnb_drift = -fe->lnb_drift;
401 if (j % 2)
402 fe->lnb_drift += stepsize;
405 dvb_frontend_set_parameters (fe, &fe->parameters, 0);
408 dvb_frontend_internal_ioctl (&fe->frontend, FE_RESET, NULL);
413 static int dvb_frontend_is_exiting (struct dvb_frontend_data *fe)
415 if (fe->exit)
416 return 1;
418 if (fe->dvbdev->writers == 1)
419 if (jiffies - fe->release_jiffies > dvb_shutdown_timeout * HZ)
420 return 1;
422 return 0;
426 static int dvb_frontend_thread (void *data)
428 struct dvb_frontend_data *fe = (struct dvb_frontend_data *) data;
429 char name [15];
430 int quality = 0, delay = 3*HZ;
431 fe_status_t s;
433 dprintk ("%s\n", __FUNCTION__);
435 snprintf (name, sizeof(name), "kdvb-fe-%i:%i",
436 fe->frontend.i2c->adapter->num, fe->frontend.i2c->id);
438 dvb_kernel_thread_setup (name);
440 fe->lost_sync_count = -1;
442 dvb_call_frontend_notifiers (fe, 0);
443 dvb_frontend_init (fe);
445 while (!dvb_frontend_is_exiting (fe)) {
446 up (&fe->sem); /* is locked when we enter the thread... */
448 interruptible_sleep_on_timeout (&fe->wait_queue, delay);
449 if (signal_pending(current))
450 break;
452 if (down_interruptible (&fe->sem))
453 break;
455 if (fe->lost_sync_count == -1)
456 continue;
458 if (dvb_frontend_is_exiting (fe))
459 break;
461 dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s);
463 update_delay (&quality, &delay, s & FE_HAS_LOCK);
465 s &= ~FE_TIMEDOUT;
467 if (s & FE_HAS_LOCK) {
468 fe->timeout_count = 0;
469 fe->lost_sync_count = 0;
470 } else {
471 fe->lost_sync_count++;
472 if (!(fe->info->caps & FE_CAN_RECOVER)) {
473 if (!(fe->info->caps & FE_CAN_CLEAN_SETUP)) {
474 if (fe->lost_sync_count < 10)
475 continue;
477 dvb_frontend_recover (fe);
478 delay = HZ/5;
480 if (jiffies - fe->lost_sync_jiffies > TIMEOUT) {
481 s |= FE_TIMEDOUT;
482 if ((fe->status & FE_TIMEDOUT) == 0)
483 fe->timeout_count++;
487 if (s != fe->status)
488 dvb_frontend_add_event (fe, s);
491 if (dvb_shutdown_timeout)
492 dvb_frontend_internal_ioctl (&fe->frontend, FE_SLEEP, NULL);
494 up (&fe->sem);
496 fe->thread_pid = 0;
497 mb();
499 wake_up_interruptible (&fe->wait_queue);
500 return 0;
504 static void dvb_frontend_stop (struct dvb_frontend_data *fe)
506 dprintk ("%s\n", __FUNCTION__);
508 fe->exit = 1;
509 mb();
511 if (!fe->thread_pid)
512 return;
514 /* check if the thread is really alive */
515 if (kill_proc(fe->thread_pid, 0, 1) == -ESRCH) {
516 printk("dvb_frontend_stop: thread PID %d already died\n",
517 fe->thread_pid);
518 /* make sure the mutex was not held by the thread */
519 init_MUTEX (&fe->sem);
520 return;
523 wake_up_interruptible (&fe->wait_queue);
524 interruptible_sleep_on(&fe->wait_queue);
526 /* paranoia check */
527 if (fe->thread_pid)
528 printk("dvb_frontend_stop: warning: thread PID %d won't exit\n",
529 fe->thread_pid);
533 static int dvb_frontend_start (struct dvb_frontend_data *fe)
535 int ret;
537 dprintk ("%s\n", __FUNCTION__);
539 if (fe->thread_pid) {
540 if (!fe->exit)
541 return 0;
542 else
543 dvb_frontend_stop (fe);
546 if (signal_pending(current))
547 return -EINTR;
548 if (down_interruptible (&fe->sem))
549 return -EINTR;
551 fe->exit = 0;
552 fe->thread_pid = 0;
553 mb();
555 ret = kernel_thread (dvb_frontend_thread, fe, 0);
556 if (ret < 0) {
557 printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret);
558 up(&fe->sem);
559 return ret;
561 fe->thread_pid = ret;
563 return 0;
567 static int dvb_frontend_ioctl (struct inode *inode, struct file *file,
568 unsigned int cmd, void *parg)
570 struct dvb_device *dvbdev = file->private_data;
571 struct dvb_frontend_data *fe = dvbdev->priv;
572 int err = 0;
574 dprintk ("%s\n", __FUNCTION__);
576 if (!fe || !fe->frontend.ioctl || fe->exit)
577 return -ENODEV;
579 if (down_interruptible (&fe->sem))
580 return -ERESTARTSYS;
582 switch (cmd) {
583 case FE_DISEQC_SEND_MASTER_CMD:
584 case FE_DISEQC_SEND_BURST:
585 case FE_SET_TONE:
586 if (fe->status)
587 dvb_call_frontend_notifiers (fe, 0);
588 dvb_frontend_internal_ioctl (&fe->frontend, cmd, parg);
589 break;
590 case FE_SET_FRONTEND:
591 err = dvb_frontend_set_parameters (fe, parg, 1);
592 break;
593 case FE_GET_EVENT:
594 err = dvb_frontend_get_event (fe, parg, file->f_flags);
595 break;
596 case FE_GET_FRONTEND:
597 memcpy (parg, &fe->parameters,
598 sizeof (struct dvb_frontend_parameters));
599 /* fall-through... */
600 default:
601 dvb_frontend_internal_ioctl (&fe->frontend, cmd, parg);
604 up (&fe->sem);
606 return err;
610 static unsigned int dvb_frontend_poll (struct file *file, struct poll_table_struct *wait)
612 struct dvb_device *dvbdev = file->private_data;
613 struct dvb_frontend_data *fe = dvbdev->priv;
615 dprintk ("%s\n", __FUNCTION__);
617 poll_wait (file, &fe->events.wait_queue, wait);
619 if (fe->events.eventw != fe->events.eventr)
620 return (POLLIN | POLLRDNORM | POLLPRI);
622 return 0;
626 static int dvb_frontend_open (struct inode *inode, struct file *file)
628 struct dvb_device *dvbdev = file->private_data;
629 struct dvb_frontend_data *fe = dvbdev->priv;
630 int ret;
632 dprintk ("%s\n", __FUNCTION__);
634 if ((ret = dvb_generic_open (inode, file)) < 0)
635 return ret;
637 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
638 ret = dvb_frontend_start (fe);
639 if (ret)
640 dvb_generic_release (inode, file);
642 /* empty event queue */
643 fe->events.eventr = fe->events.eventw = 0;
646 return ret;
650 static int dvb_frontend_release (struct inode *inode, struct file *file)
652 struct dvb_device *dvbdev = file->private_data;
653 struct dvb_frontend_data *fe = dvbdev->priv;
655 dprintk ("%s\n", __FUNCTION__);
657 if ((file->f_flags & O_ACCMODE) != O_RDONLY)
658 fe->release_jiffies = jiffies;
660 return dvb_generic_release (inode, file);
666 dvb_add_frontend_ioctls (struct dvb_adapter *adapter,
667 int (*before_ioctl) (struct dvb_frontend *frontend,
668 unsigned int cmd, void *arg),
669 int (*after_ioctl) (struct dvb_frontend *frontend,
670 unsigned int cmd, void *arg),
671 void *before_after_data)
673 struct dvb_frontend_ioctl_data *ioctl;
674 struct list_head *entry;
676 dprintk ("%s\n", __FUNCTION__);
678 if (down_interruptible (&frontend_mutex))
679 return -ERESTARTSYS;
681 ioctl = kmalloc (sizeof(struct dvb_frontend_ioctl_data), GFP_KERNEL);
683 if (!ioctl) {
684 up (&frontend_mutex);
685 return -ENOMEM;
688 ioctl->adapter = adapter;
689 ioctl->before_ioctl = before_ioctl;
690 ioctl->after_ioctl = after_ioctl;
691 ioctl->before_after_data = before_after_data;
693 list_add_tail (&ioctl->list_head, &frontend_ioctl_list);
695 list_for_each (entry, &frontend_list) {
696 struct dvb_frontend_data *fe;
698 fe = list_entry (entry, struct dvb_frontend_data, list_head);
700 if (fe->frontend.i2c->adapter == adapter &&
701 fe->frontend.before_ioctl == NULL &&
702 fe->frontend.after_ioctl == NULL)
704 fe->frontend.before_ioctl = before_ioctl;
705 fe->frontend.after_ioctl = after_ioctl;
706 fe->frontend.before_after_data = before_after_data;
710 up (&frontend_mutex);
712 return 0;
716 void
717 dvb_remove_frontend_ioctls (struct dvb_adapter *adapter,
718 int (*before_ioctl) (struct dvb_frontend *frontend,
719 unsigned int cmd, void *arg),
720 int (*after_ioctl) (struct dvb_frontend *frontend,
721 unsigned int cmd, void *arg))
723 struct list_head *entry, *n;
725 dprintk ("%s\n", __FUNCTION__);
727 down (&frontend_mutex);
729 list_for_each (entry, &frontend_list) {
730 struct dvb_frontend_data *fe;
732 fe = list_entry (entry, struct dvb_frontend_data, list_head);
734 if (fe->frontend.i2c->adapter == adapter &&
735 fe->frontend.before_ioctl == before_ioctl &&
736 fe->frontend.after_ioctl == after_ioctl)
738 fe->frontend.before_ioctl = NULL;
739 fe->frontend.after_ioctl = NULL;
744 list_for_each_safe (entry, n, &frontend_ioctl_list) {
745 struct dvb_frontend_ioctl_data *ioctl;
747 ioctl = list_entry (entry, struct dvb_frontend_ioctl_data, list_head);
749 if (ioctl->adapter == adapter &&
750 ioctl->before_ioctl == before_ioctl &&
751 ioctl->after_ioctl == after_ioctl)
753 list_del (&ioctl->list_head);
754 kfree (ioctl);
756 break;
760 up (&frontend_mutex);
765 dvb_add_frontend_notifier (struct dvb_adapter *adapter,
766 void (*callback) (fe_status_t s, void *data),
767 void *data)
769 struct dvb_frontend_notifier_data *notifier;
770 struct list_head *entry;
772 dprintk ("%s\n", __FUNCTION__);
774 if (down_interruptible (&frontend_mutex))
775 return -ERESTARTSYS;
777 notifier = kmalloc (sizeof(struct dvb_frontend_notifier_data), GFP_KERNEL);
779 if (!notifier) {
780 up (&frontend_mutex);
781 return -ENOMEM;
784 notifier->adapter = adapter;
785 notifier->callback = callback;
786 notifier->data = data;
788 list_add_tail (&notifier->list_head, &frontend_notifier_list);
790 list_for_each (entry, &frontend_list) {
791 struct dvb_frontend_data *fe;
793 fe = list_entry (entry, struct dvb_frontend_data, list_head);
795 if (fe->frontend.i2c->adapter == adapter &&
796 fe->frontend.notifier_callback == NULL)
798 fe->frontend.notifier_callback = callback;
799 fe->frontend.notifier_data = data;
803 up (&frontend_mutex);
805 return 0;
809 void
810 dvb_remove_frontend_notifier (struct dvb_adapter *adapter,
811 void (*callback) (fe_status_t s, void *data))
813 struct list_head *entry, *n;
815 dprintk ("%s\n", __FUNCTION__);
817 down (&frontend_mutex);
819 list_for_each (entry, &frontend_list) {
820 struct dvb_frontend_data *fe;
822 fe = list_entry (entry, struct dvb_frontend_data, list_head);
824 if (fe->frontend.i2c->adapter == adapter &&
825 fe->frontend.notifier_callback == callback)
827 fe->frontend.notifier_callback = NULL;
832 list_for_each_safe (entry, n, &frontend_notifier_list) {
833 struct dvb_frontend_notifier_data *notifier;
835 notifier = list_entry (entry, struct dvb_frontend_notifier_data, list_head);
837 if (notifier->adapter == adapter &&
838 notifier->callback == callback)
840 list_del (&notifier->list_head);
841 kfree (notifier);
843 break;
847 up (&frontend_mutex);
851 static struct file_operations dvb_frontend_fops = {
852 .owner = THIS_MODULE,
853 .ioctl = dvb_generic_ioctl,
854 .poll = dvb_frontend_poll,
855 .open = dvb_frontend_open,
856 .release = dvb_frontend_release
862 dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,
863 unsigned int cmd, void *arg),
864 struct dvb_i2c_bus *i2c,
865 void *data,
866 struct dvb_frontend_info *info)
868 struct list_head *entry;
869 struct dvb_frontend_data *fe;
870 static const struct dvb_device dvbdev_template = {
871 .users = ~0,
872 .writers = 1,
873 .fops = &dvb_frontend_fops,
874 .kernel_ioctl = dvb_frontend_ioctl
877 dprintk ("%s\n", __FUNCTION__);
879 if (down_interruptible (&frontend_mutex))
880 return -ERESTARTSYS;
882 if (!(fe = kmalloc (sizeof (struct dvb_frontend_data), GFP_KERNEL))) {
883 up (&frontend_mutex);
884 return -ENOMEM;
887 memset (fe, 0, sizeof (struct dvb_frontend_data));
889 init_MUTEX (&fe->sem);
890 init_waitqueue_head (&fe->wait_queue);
891 init_waitqueue_head (&fe->events.wait_queue);
892 init_MUTEX (&fe->events.sem);
893 fe->events.eventw = fe->events.eventr = 0;
894 fe->events.overflow = 0;
896 fe->frontend.ioctl = ioctl;
897 fe->frontend.i2c = i2c;
898 fe->frontend.data = data;
899 fe->info = info;
901 list_for_each (entry, &frontend_ioctl_list) {
902 struct dvb_frontend_ioctl_data *ioctl;
904 ioctl = list_entry (entry,
905 struct dvb_frontend_ioctl_data,
906 list_head);
908 if (ioctl->adapter == i2c->adapter) {
909 fe->frontend.before_ioctl = ioctl->before_ioctl;
910 fe->frontend.after_ioctl = ioctl->after_ioctl;
911 fe->frontend.before_after_data = ioctl->before_after_data;
912 break;
916 list_for_each (entry, &frontend_notifier_list) {
917 struct dvb_frontend_notifier_data *notifier;
919 notifier = list_entry (entry,
920 struct dvb_frontend_notifier_data,
921 list_head);
923 if (notifier->adapter == i2c->adapter) {
924 fe->frontend.notifier_callback = notifier->callback;
925 fe->frontend.notifier_data = notifier->data;
926 break;
930 list_add_tail (&fe->list_head, &frontend_list);
932 printk ("DVB: registering frontend %i:%i (%s)...\n",
933 fe->frontend.i2c->adapter->num, fe->frontend.i2c->id,
934 fe->info->name);
936 dvb_register_device (i2c->adapter, &fe->dvbdev, &dvbdev_template,
937 fe, DVB_DEVICE_FRONTEND);
939 up (&frontend_mutex);
941 return 0;
945 int dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend,
946 unsigned int cmd, void *arg),
947 struct dvb_i2c_bus *i2c)
949 struct list_head *entry, *n;
951 dprintk ("%s\n", __FUNCTION__);
953 down (&frontend_mutex);
955 list_for_each_safe (entry, n, &frontend_list) {
956 struct dvb_frontend_data *fe;
958 fe = list_entry (entry, struct dvb_frontend_data, list_head);
960 if (fe->frontend.ioctl == ioctl && fe->frontend.i2c == i2c) {
961 dvb_unregister_device (fe->dvbdev);
962 list_del (entry);
963 up (&frontend_mutex);
964 dvb_frontend_stop (fe);
965 kfree (fe);
966 return 0;
970 up (&frontend_mutex);
971 return -EINVAL;
974 MODULE_PARM(dvb_frontend_debug,"i");
975 MODULE_PARM(dvb_shutdown_timeout,"i");
976 MODULE_PARM_DESC(dvb_frontend_debug, "enable verbose debug messages");
977 MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");