2 * dvb-core.c: DVB core driver
4 * Copyright (C) 1999-2001 Ralph Metzler
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"
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
48 struct dvb_fe_events
{
49 struct dvb_frontend_event events
[MAX_EVENT
];
53 wait_queue_head_t wait_queue
;
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
;
65 struct list_head list_head
;
66 wait_queue_head_t wait_queue
;
68 unsigned long release_jiffies
;
69 unsigned long lost_sync_jiffies
;
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
);
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
);
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
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
;
140 if (!stepsize
|| recursive
> 10) {
141 printk ("%s: too deep recursion, check frequency_stepsize "
142 "in your frontend code!\n", __FUNCTION__
);
146 dprintk ("%s\n", __FUNCTION__
);
149 if (down_interruptible (&frontend_mutex
))
152 this_fe
->bending
= 0;
155 list_for_each (entry
, &frontend_list
) {
156 struct dvb_frontend_data
*fe
;
159 fe
= list_entry (entry
, struct dvb_frontend_data
, list_head
);
161 if (fe
->frontend
.i2c
->adapter
->num
!= this_fe_adap_num
)
164 f
= fe
->parameters
.frequency
;
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
)
176 this_fe
->bending
+= stepsize
;
178 this_fe
->bending
= -this_fe
->bending
;
180 dvb_bend_frequency (this_fe
, recursive
+ 1);
186 up (&frontend_mutex
);
190 static void dvb_call_frontend_notifiers (struct dvb_frontend_data
*fe
,
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
);
203 if (!(s
& FE_HAS_LOCK
) && (fe
->info
->caps
& FE_CAN_MUTE_TS
))
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
;
220 dprintk ("%s\n", __FUNCTION__
);
222 if (down_interruptible (&events
->sem
))
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
,
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;
264 if (events
->eventw
== events
->eventr
) {
267 if (flags
& O_NONBLOCK
)
272 ret
= wait_event_interruptible (events
->wait_queue
,
273 events
->eventw
!= events
->eventr
);
275 if (down_interruptible (&fe
->sem
))
282 if (down_interruptible (&events
->sem
))
285 memcpy (event
, &events
->events
[events
->eventr
],
286 sizeof(struct dvb_frontend_event
));
288 events
->eventr
= (events
->eventr
+ 1) % MAX_EVENT
;
296 static int dvb_frontend_set_parameters (struct dvb_frontend_data
*fe
,
297 struct dvb_frontend_parameters
*param
,
300 struct dvb_frontend
*frontend
= &fe
->frontend
;
304 fe
->timeout_count
= 0;
305 fe
->lost_sync_count
= 0;
306 fe
->lost_sync_jiffies
= jiffies
;
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
);
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
,
336 dvb_frontend_internal_ioctl (frontend
, FE_INIT
, NULL
);
340 static void update_delay (int *quality
, int *delay
, int locked
)
344 dprintk ("%s\n", __FUNCTION__
);
347 (*quality
) = (*quality
* 220 + 36*256) / 256;
349 (*quality
) = (*quality
* 220 + 0) / 256;
354 *delay
= HZ
/20 + q2
* HZ
/ (128*128);
358 #define LNB_DRIFT 1024 /* max. tolerated LNB drift, XXX FIXME: adjust! */
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__
);
370 if (fe
->timeout_count
> 3) {
371 printk ("%s: frontend seems dead, reinitializing...\n",
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;
384 * let's start a zigzag scan to compensate LNB drift...
387 int j
= fe
->lost_sync_count
;
390 if (fe
->info
->type
== FE_QPSK
)
391 stepsize
= fe
->parameters
.u
.qpsk
.symbol_rate
/ 16000;
392 else if (fe
->info
->type
== FE_QAM
)
395 stepsize
= fe
->info
->frequency_stepsize
* 2;
400 fe
->lnb_drift
= -fe
->lnb_drift
;
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
)
418 if (fe
->dvbdev
->writers
== 1)
419 if (jiffies
- fe
->release_jiffies
> dvb_shutdown_timeout
* HZ
)
426 static int dvb_frontend_thread (void *data
)
428 struct dvb_frontend_data
*fe
= (struct dvb_frontend_data
*) data
;
430 int quality
= 0, delay
= 3*HZ
;
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
))
452 if (down_interruptible (&fe
->sem
))
455 if (fe
->lost_sync_count
== -1)
458 if (dvb_frontend_is_exiting (fe
))
461 dvb_frontend_internal_ioctl (&fe
->frontend
, FE_READ_STATUS
, &s
);
463 update_delay (&quality
, &delay
, s
& FE_HAS_LOCK
);
467 if (s
& FE_HAS_LOCK
) {
468 fe
->timeout_count
= 0;
469 fe
->lost_sync_count
= 0;
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)
477 dvb_frontend_recover (fe
);
480 if (jiffies
- fe
->lost_sync_jiffies
> TIMEOUT
) {
482 if ((fe
->status
& FE_TIMEDOUT
) == 0)
488 dvb_frontend_add_event (fe
, s
);
491 if (dvb_shutdown_timeout
)
492 dvb_frontend_internal_ioctl (&fe
->frontend
, FE_SLEEP
, NULL
);
499 wake_up_interruptible (&fe
->wait_queue
);
504 static void dvb_frontend_stop (struct dvb_frontend_data
*fe
)
506 dprintk ("%s\n", __FUNCTION__
);
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",
518 /* make sure the mutex was not held by the thread */
519 init_MUTEX (&fe
->sem
);
523 wake_up_interruptible (&fe
->wait_queue
);
524 interruptible_sleep_on(&fe
->wait_queue
);
528 printk("dvb_frontend_stop: warning: thread PID %d won't exit\n",
533 static int dvb_frontend_start (struct dvb_frontend_data
*fe
)
537 dprintk ("%s\n", __FUNCTION__
);
539 if (fe
->thread_pid
) {
543 dvb_frontend_stop (fe
);
546 if (signal_pending(current
))
548 if (down_interruptible (&fe
->sem
))
555 ret
= kernel_thread (dvb_frontend_thread
, fe
, 0);
557 printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret
);
561 fe
->thread_pid
= ret
;
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
;
574 dprintk ("%s\n", __FUNCTION__
);
576 if (!fe
|| !fe
->frontend
.ioctl
|| fe
->exit
)
579 if (down_interruptible (&fe
->sem
))
583 case FE_DISEQC_SEND_MASTER_CMD
:
584 case FE_DISEQC_SEND_BURST
:
587 dvb_call_frontend_notifiers (fe
, 0);
588 dvb_frontend_internal_ioctl (&fe
->frontend
, cmd
, parg
);
590 case FE_SET_FRONTEND
:
591 err
= dvb_frontend_set_parameters (fe
, parg
, 1);
594 err
= dvb_frontend_get_event (fe
, parg
, file
->f_flags
);
596 case FE_GET_FRONTEND
:
597 memcpy (parg
, &fe
->parameters
,
598 sizeof (struct dvb_frontend_parameters
));
599 /* fall-through... */
601 dvb_frontend_internal_ioctl (&fe
->frontend
, cmd
, parg
);
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
);
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
;
632 dprintk ("%s\n", __FUNCTION__
);
634 if ((ret
= dvb_generic_open (inode
, file
)) < 0)
637 if ((file
->f_flags
& O_ACCMODE
) != O_RDONLY
) {
638 ret
= dvb_frontend_start (fe
);
640 dvb_generic_release (inode
, file
);
642 /* empty event queue */
643 fe
->events
.eventr
= fe
->events
.eventw
= 0;
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
))
681 ioctl
= kmalloc (sizeof(struct dvb_frontend_ioctl_data
), GFP_KERNEL
);
684 up (&frontend_mutex
);
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
);
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
);
760 up (&frontend_mutex
);
765 dvb_add_frontend_notifier (struct dvb_adapter
*adapter
,
766 void (*callback
) (fe_status_t s
, 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
))
777 notifier
= kmalloc (sizeof(struct dvb_frontend_notifier_data
), GFP_KERNEL
);
780 up (&frontend_mutex
);
784 notifier
->adapter
= adapter
;
785 notifier
->callback
= callback
;
786 notifier
->data
= data
;
788 list_add_tail (¬ifier
->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
);
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 (¬ifier
->list_head
);
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
,
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
= {
873 .fops
= &dvb_frontend_fops
,
874 .kernel_ioctl
= dvb_frontend_ioctl
877 dprintk ("%s\n", __FUNCTION__
);
879 if (down_interruptible (&frontend_mutex
))
882 if (!(fe
= kmalloc (sizeof (struct dvb_frontend_data
), GFP_KERNEL
))) {
883 up (&frontend_mutex
);
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
;
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
,
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
;
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
,
923 if (notifier
->adapter
== i2c
->adapter
) {
924 fe
->frontend
.notifier_callback
= notifier
->callback
;
925 fe
->frontend
.notifier_data
= notifier
->data
;
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
,
936 dvb_register_device (i2c
->adapter
, &fe
->dvbdev
, &dvbdev_template
,
937 fe
, DVB_DEVICE_FRONTEND
);
939 up (&frontend_mutex
);
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
);
963 up (&frontend_mutex
);
964 dvb_frontend_stop (fe
);
970 up (&frontend_mutex
);
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");