1 /*****************************************************************************
2 * linux_dvb.c : functions to control a DVB card under Linux with v4l2
3 *****************************************************************************
4 * Copyright (C) 1998-2010 VLC authors and VideoLAN
6 * Authors: Damien Lucas <nitrox@via.ecp.fr>
7 * Johan Bilien <jobi@via.ecp.fr>
8 * Jean-Paul Saman <jpsaman _at_ videolan _dot_ org>
9 * Christopher Ross <chris@tebibyte.org>
10 * Christophe Massiot <massiot@via.ecp.fr>
11 * David Kaplan <david@of1.org>
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 2.1 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
26 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_access.h>
37 #include <sys/types.h>
38 #include <sys/ioctl.h>
43 /* DVB Card Drivers */
44 #include <linux/dvb/version.h>
45 #include <linux/dvb/dmx.h>
46 #include <linux/dvb/frontend.h>
51 #define DMX "/dev/dvb/adapter%d/demux%d"
52 #define FRONTEND "/dev/dvb/adapter%d/frontend%d"
53 #define DVR "/dev/dvb/adapter%d/dvr%d"
60 fe_status_t i_last_status;
61 struct dvb_frontend_info info;
64 #define FRONTEND_LOCK_TIMEOUT 10000000 /* 10 s */
66 /* Local prototypes */
67 static int FrontendInfo( access_t * );
68 static int FrontendSetQPSK( access_t * );
69 static int FrontendSetQAM( access_t * );
70 static int FrontendSetOFDM( access_t * );
71 static int FrontendSetATSC( access_t * );
73 /*****************************************************************************
74 * FrontendOpen : Determine frontend device information and capabilities
75 *****************************************************************************/
76 int FrontendOpen( access_t *p_access )
78 access_sys_t *p_sys = p_access->p_sys;
79 frontend_t * p_frontend;
80 unsigned int i_adapter, i_device;
84 i_adapter = var_GetInteger( p_access, "dvb-adapter" );
85 i_device = var_GetInteger( p_access, "dvb-device" );
86 b_probe = var_GetBool( p_access, "dvb-probe" );
88 if( snprintf( frontend, sizeof(frontend), FRONTEND, i_adapter, i_device ) >= (int)sizeof(frontend) )
90 msg_Err( p_access, "snprintf() truncated string for FRONTEND" );
91 frontend[sizeof(frontend) - 1] = '\0';
94 p_sys->p_frontend = p_frontend = malloc( sizeof(frontend_t) );
98 msg_Dbg( p_access, "Opening device %s", frontend );
99 if( (p_sys->i_frontend_handle = vlc_open(frontend, O_RDWR | O_NONBLOCK)) < 0 )
101 msg_Err( p_access, "FrontEndOpen: opening device failed (%m)" );
108 const char * psz_expected = NULL;
109 const char * psz_real;
111 if( FrontendInfo( p_access ) < 0 )
113 close( p_sys->i_frontend_handle );
118 switch( p_frontend->info.type )
133 psz_real = "unknown";
137 if( (!strncmp( p_access->psz_access, "qpsk", 4 ) ||
138 !strncmp( p_access->psz_access, "dvb-s", 5 ) ||
139 !strncmp( p_access->psz_access, "satellite", 9 ) ) &&
140 (p_frontend->info.type != FE_QPSK) )
142 psz_expected = "DVB-S";
144 if( (!strncmp( p_access->psz_access, "cable", 5 ) ||
145 !strncmp( p_access->psz_access, "dvb-c", 5 ) ) &&
146 (p_frontend->info.type != FE_QAM) )
148 psz_expected = "DVB-C";
150 if( (!strncmp( p_access->psz_access, "terrestrial", 11 ) ||
151 !strncmp( p_access->psz_access, "dvb-t", 5 ) ) &&
152 (p_frontend->info.type != FE_OFDM) )
154 psz_expected = "DVB-T";
157 if( (!strncmp( p_access->psz_access, "usdigital", 9 ) ||
158 !strncmp( p_access->psz_access, "atsc", 4 ) ) &&
159 (p_frontend->info.type != FE_ATSC) )
161 psz_expected = "ATSC";
164 if( psz_expected != NULL )
166 msg_Err( p_access, "requested type %s not supported by %s tuner",
167 psz_expected, psz_real );
168 close( p_sys->i_frontend_handle );
173 else /* no frontend probing is done so use default border values. */
175 msg_Dbg( p_access, "using default values for frontend info" );
177 msg_Dbg( p_access, "method of access is %s", p_access->psz_access );
178 p_frontend->info.type = FE_QPSK;
179 if( !strncmp( p_access->psz_access, "qpsk", 4 ) ||
180 !strncmp( p_access->psz_access, "dvb-s", 5 ) )
181 p_frontend->info.type = FE_QPSK;
182 else if( !strncmp( p_access->psz_access, "cable", 5 ) ||
183 !strncmp( p_access->psz_access, "dvb-c", 5 ) )
184 p_frontend->info.type = FE_QAM;
185 else if( !strncmp( p_access->psz_access, "terrestrial", 11 ) ||
186 !strncmp( p_access->psz_access, "dvb-t", 5 ) )
187 p_frontend->info.type = FE_OFDM;
188 else if( !strncmp( p_access->psz_access, "usdigital", 9 ) ||
189 !strncmp( p_access->psz_access, "atsc", 4 ) )
190 p_frontend->info.type = FE_ATSC;
196 /*****************************************************************************
197 * FrontendClose : Close the frontend
198 *****************************************************************************/
199 void FrontendClose( access_t *p_access )
201 access_sys_t *p_sys = p_access->p_sys;
203 if( p_sys->p_frontend )
205 close( p_sys->i_frontend_handle );
206 free( p_sys->p_frontend );
208 p_sys->p_frontend = NULL;
212 /*****************************************************************************
213 * FrontendSet : Tune !
214 *****************************************************************************/
215 int FrontendSet( access_t *p_access )
217 access_sys_t *p_sys = p_access->p_sys;
219 switch( p_sys->p_frontend->info.type )
223 if( FrontendSetQPSK( p_access ) )
225 msg_Err( p_access, "DVB-S tuning error" );
232 if( FrontendSetQAM( p_access ) )
234 msg_Err( p_access, "DVB-C tuning error" );
241 if( FrontendSetOFDM( p_access ) )
243 msg_Err( p_access, "DVB-T tuning error" );
250 if( FrontendSetATSC( p_access ) )
252 msg_Err( p_access, "ATSC tuning error" );
258 msg_Err( p_access, "tuner type %s not supported",
259 p_sys->p_frontend->info.name );
262 p_sys->p_frontend->i_last_status = 0;
263 p_sys->i_frontend_timeout = mdate() + FRONTEND_LOCK_TIMEOUT;
267 /*****************************************************************************
268 * FrontendPoll : Poll for frontend events
269 *****************************************************************************/
270 void FrontendPoll( access_t *p_access )
272 access_sys_t *p_sys = p_access->p_sys;
273 frontend_t * p_frontend = p_sys->p_frontend;
274 struct dvb_frontend_event event;
275 fe_status_t i_status, i_diff;
279 if( ioctl( p_sys->i_frontend_handle, FE_GET_EVENT, &event ) < 0 )
281 if( errno != EWOULDBLOCK )
282 msg_Err( p_access, "frontend event error: %m" );
286 i_status = event.status;
287 i_diff = i_status ^ p_frontend->i_last_status;
288 p_frontend->i_last_status = i_status;
293 if ( i_diff & (x) ) \
295 if ( i_status & (x) )
297 IF_UP( FE_HAS_SIGNAL )
298 msg_Dbg( p_access, "frontend has acquired signal" );
300 msg_Dbg( p_access, "frontend has lost signal" );
302 IF_UP( FE_HAS_CARRIER )
303 msg_Dbg( p_access, "frontend has acquired carrier" );
305 msg_Dbg( p_access, "frontend has lost carrier" );
307 IF_UP( FE_HAS_VITERBI )
308 msg_Dbg( p_access, "frontend has acquired stable FEC" );
310 msg_Dbg( p_access, "frontend has lost FEC" );
313 msg_Dbg( p_access, "frontend has acquired sync" );
315 msg_Dbg( p_access, "frontend has lost sync" );
319 frontend_statistic_t stat;
321 msg_Dbg( p_access, "frontend has acquired lock" );
322 p_sys->i_frontend_timeout = 0;
324 /* Read some statistics */
325 if( !FrontendGetStatistic( p_access, &stat ) )
327 if( stat.i_ber >= 0 )
328 msg_Dbg( p_access, "- Bit error rate: %d", stat.i_ber );
329 if( stat.i_signal_strenth >= 0 )
330 msg_Dbg( p_access, "- Signal strength: %d", stat.i_signal_strenth );
331 if( stat.i_snr >= 0 )
332 msg_Dbg( p_access, "- SNR: %d", stat.i_snr );
337 msg_Dbg( p_access, "frontend has lost lock" );
338 p_sys->i_frontend_timeout = mdate() + FRONTEND_LOCK_TIMEOUT;
343 /* The frontend was reinited. */
344 msg_Warn( p_access, "reiniting frontend");
345 FrontendSet( p_access );
352 int FrontendGetStatistic( access_t *p_access, frontend_statistic_t *p_stat )
354 access_sys_t *p_sys = p_access->p_sys;
355 frontend_t * p_frontend = p_sys->p_frontend;
357 if( (p_frontend->i_last_status & FE_HAS_LOCK) == 0 )
360 memset( p_stat, 0, sizeof(*p_stat) );
361 if( ioctl( p_sys->i_frontend_handle, FE_READ_BER, &p_stat->i_ber ) < 0 )
363 if( ioctl( p_sys->i_frontend_handle, FE_READ_SIGNAL_STRENGTH, &p_stat->i_signal_strenth ) < 0 )
364 p_stat->i_signal_strenth = -1;
365 if( ioctl( p_sys->i_frontend_handle, FE_READ_SNR, &p_stat->i_snr ) < 0 )
371 void FrontendGetStatus( access_t *p_access, frontend_status_t *p_status )
373 access_sys_t *p_sys = p_access->p_sys;
374 frontend_t * p_frontend = p_sys->p_frontend;
376 p_status->b_has_signal = (p_frontend->i_last_status & FE_HAS_SIGNAL) != 0;
377 p_status->b_has_carrier = (p_frontend->i_last_status & FE_HAS_CARRIER) != 0;
378 p_status->b_has_lock = (p_frontend->i_last_status & FE_HAS_LOCK) != 0;
381 static int ScanParametersDvbS( access_t *p_access, scan_parameter_t *p_scan )
383 const frontend_t *p_frontend = p_access->p_sys->p_frontend;
385 memset( p_scan, 0, sizeof(*p_scan) );
386 p_scan->type = SCAN_DVB_S;
388 p_scan->frequency.i_min = p_frontend->info.frequency_min;
389 p_scan->frequency.i_max = p_frontend->info.frequency_max;
390 /* set satellite config file path */
391 p_scan->sat_info.psz_name = var_InheritString( p_access, "dvb-satellite" );
396 static int ScanParametersDvbC( access_t *p_access, scan_parameter_t *p_scan )
398 const frontend_t *p_frontend = p_access->p_sys->p_frontend;
400 memset( p_scan, 0, sizeof(*p_scan) );
401 p_scan->type = SCAN_DVB_C;
402 p_scan->b_exhaustive = false;
405 p_scan->frequency.i_min = p_frontend->info.frequency_min;
406 p_scan->frequency.i_max = p_frontend->info.frequency_max;
407 p_scan->frequency.i_step = p_frontend->info.frequency_stepsize
408 ? p_frontend->info.frequency_stepsize : 166667;
409 p_scan->frequency.i_count = (p_scan->frequency.i_max-p_scan->frequency.i_min)/p_scan->frequency.i_step;
411 /* if user supplies modulation or frontend can do auto, don't scan them */
412 if( var_GetInteger( p_access, "dvb-modulation" ) ||
413 p_frontend->info.caps & FE_CAN_QAM_AUTO )
415 p_scan->b_modulation_set = true;
417 p_scan->b_modulation_set = false;
418 /* our scanning code flips modulation from 16..256 automaticly*/
419 p_scan->i_modulation = 0;
422 /* if user supplies symbolrate, don't scan those */
423 if( var_GetInteger( p_access, "dvb-srate" ) )
424 p_scan->b_symbolrate_set = true;
426 p_scan->b_symbolrate_set = false;
429 p_scan->bandwidth.i_min = 6;
430 p_scan->bandwidth.i_max = 8;
431 p_scan->bandwidth.i_step = 1;
432 p_scan->bandwidth.i_count = 3;
436 static int ScanParametersDvbT( access_t *p_access, scan_parameter_t *p_scan )
438 const frontend_t *p_frontend = p_access->p_sys->p_frontend;
440 memset( p_scan, 0, sizeof(*p_scan) );
441 p_scan->type = SCAN_DVB_T;
442 p_scan->b_exhaustive = false;
445 p_scan->frequency.i_min = p_frontend->info.frequency_min;
446 p_scan->frequency.i_max = p_frontend->info.frequency_max;
447 p_scan->frequency.i_step = p_frontend->info.frequency_stepsize
448 ? p_frontend->info.frequency_stepsize : 166667;
449 p_scan->frequency.i_count = (p_scan->frequency.i_max-p_scan->frequency.i_min)/p_scan->frequency.i_step;
452 p_scan->bandwidth.i_min = 6;
453 p_scan->bandwidth.i_max = 8;
454 p_scan->bandwidth.i_step = 1;
455 p_scan->bandwidth.i_count = 3;
459 int FrontendGetScanParameter( access_t *p_access, scan_parameter_t *p_scan )
461 access_sys_t *p_sys = p_access->p_sys;
462 const frontend_t *p_frontend = p_sys->p_frontend;
464 if( p_frontend->info.type == FE_OFDM ) /* DVB-T */
465 return ScanParametersDvbT( p_access, p_scan );
466 else if( p_frontend->info.type == FE_QAM ) /* DVB-C */
467 return ScanParametersDvbC( p_access, p_scan );
468 else if( p_frontend->info.type == FE_QPSK )
469 return ScanParametersDvbS( p_access, p_scan ); /* DVB-S */
471 msg_Err( p_access, "frontend scanning not supported" );
475 /*****************************************************************************
476 * FrontendInfo : Return information about given frontend
477 *****************************************************************************/
478 static int FrontendInfo( access_t *p_access )
480 access_sys_t *p_sys = p_access->p_sys;
481 frontend_t *p_frontend = p_sys->p_frontend;
483 /* Determine type of frontend */
484 if( ioctl( p_sys->i_frontend_handle, FE_GET_INFO, &p_frontend->info ) < 0 )
486 msg_Err( p_access, "frontend info request error: %m" );
490 /* Print out frontend capabilities. */
491 msg_Dbg(p_access, "Frontend Info:" );
492 msg_Dbg(p_access, " name = %s", p_frontend->info.name );
493 switch( p_frontend->info.type )
496 msg_Dbg( p_access, " type = QPSK (DVB-S)" );
499 msg_Dbg( p_access, " type = QAM (DVB-C)" );
502 msg_Dbg( p_access, " type = OFDM (DVB-T)" );
505 msg_Dbg( p_access, " type = ATSC (USA)" );
507 #if 0 /* DVB_API_VERSION == 3 */
509 msg_Dbg(p_access, " type = MEMORY" );
512 msg_Dbg(p_access, " type = NETWORK" );
516 msg_Err( p_access, " unknown frontend type (%d)",
517 p_frontend->info.type );
520 msg_Dbg(p_access, " frequency_min = %u (kHz)",
521 p_frontend->info.frequency_min);
522 msg_Dbg(p_access, " frequency_max = %u (kHz)",
523 p_frontend->info.frequency_max);
524 msg_Dbg(p_access, " frequency_stepsize = %u",
525 p_frontend->info.frequency_stepsize);
526 msg_Dbg(p_access, " frequency_tolerance = %u",
527 p_frontend->info.frequency_tolerance);
528 msg_Dbg(p_access, " symbol_rate_min = %u (kHz)",
529 p_frontend->info.symbol_rate_min);
530 msg_Dbg(p_access, " symbol_rate_max = %u (kHz)",
531 p_frontend->info.symbol_rate_max);
532 msg_Dbg(p_access, " symbol_rate_tolerance (ppm) = %u",
533 p_frontend->info.symbol_rate_tolerance);
534 msg_Dbg(p_access, " notifier_delay (ms) = %u",
535 p_frontend->info.notifier_delay );
537 msg_Dbg(p_access, "Frontend Info capability list:");
538 if( p_frontend->info.caps == FE_IS_STUPID)
539 msg_Dbg(p_access, " no capabilities - frontend is stupid!");
540 if( p_frontend->info.caps & FE_CAN_INVERSION_AUTO)
541 msg_Dbg(p_access, " inversion auto");
542 if( p_frontend->info.caps & FE_CAN_FEC_1_2)
543 msg_Dbg(p_access, " forward error correction 1/2");
544 if( p_frontend->info.caps & FE_CAN_FEC_2_3)
545 msg_Dbg(p_access, " forward error correction 2/3");
546 if( p_frontend->info.caps & FE_CAN_FEC_3_4)
547 msg_Dbg(p_access, " forward error correction 3/4");
548 if( p_frontend->info.caps & FE_CAN_FEC_4_5)
549 msg_Dbg(p_access, " forward error correction 4/5");
550 if( p_frontend->info.caps & FE_CAN_FEC_5_6)
551 msg_Dbg(p_access, " forward error correction 5/6");
552 if( p_frontend->info.caps & FE_CAN_FEC_6_7)
553 msg_Dbg(p_access, " forward error correction 6/7");
554 if( p_frontend->info.caps & FE_CAN_FEC_7_8)
555 msg_Dbg(p_access, " forward error correction 7/8");
556 if( p_frontend->info.caps & FE_CAN_FEC_8_9)
557 msg_Dbg(p_access, " forward error correction 8/9");
558 if( p_frontend->info.caps & FE_CAN_FEC_AUTO)
559 msg_Dbg(p_access, " forward error correction auto");
560 if( p_frontend->info.caps & FE_CAN_QPSK)
561 msg_Dbg(p_access, " QPSK modulation");
562 if( p_frontend->info.caps & FE_CAN_QAM_16)
563 msg_Dbg(p_access, " QAM 16 modulation");
564 if( p_frontend->info.caps & FE_CAN_QAM_32)
565 msg_Dbg(p_access, " QAM 32 modulation");
566 if( p_frontend->info.caps & FE_CAN_QAM_64)
567 msg_Dbg(p_access, " QAM 64 modulation");
568 if( p_frontend->info.caps & FE_CAN_QAM_128)
569 msg_Dbg(p_access, " QAM 128 modulation");
570 if( p_frontend->info.caps & FE_CAN_QAM_256)
571 msg_Dbg(p_access, " QAM 256 modulation");
572 if( p_frontend->info.caps & FE_CAN_QAM_AUTO)
573 msg_Dbg(p_access, " QAM auto modulation");
574 if( p_frontend->info.caps & FE_CAN_TRANSMISSION_MODE_AUTO)
575 msg_Dbg(p_access, " transmission mode auto");
576 if( p_frontend->info.caps & FE_CAN_BANDWIDTH_AUTO)
577 msg_Dbg(p_access, " bandwidth mode auto");
578 if( p_frontend->info.caps & FE_CAN_GUARD_INTERVAL_AUTO)
579 msg_Dbg(p_access, " guard interval mode auto");
580 if( p_frontend->info.caps & FE_CAN_HIERARCHY_AUTO)
581 msg_Dbg(p_access, " hierarchy mode auto");
582 if( p_frontend->info.caps & FE_CAN_8VSB)
583 msg_Dbg(p_access, " 8-level VSB modulation");
584 if( p_frontend->info.caps & FE_CAN_16VSB)
585 msg_Dbg(p_access, " 16-level VSB modulation");
586 if( p_frontend->info.caps & FE_HAS_EXTENDED_CAPS)
587 msg_Dbg(p_access, " extended capabilities");
588 /* 3 capabilities that don't exist yet HERE */
589 #if (DVB_API_VERSION > 5) \
590 || ((DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 2))
591 if( p_frontend->info.caps & FE_CAN_TURBO_FEC)
592 msg_Dbg(p_access, " Turbo FEC modulation");
594 # warning Please update your Linux kernel headers!
596 if( p_frontend->info.caps & FE_CAN_2G_MODULATION)
597 msg_Dbg(p_access, " 2nd generation modulation (DVB-S2)");
598 /* FE_NEEDS_BENDING is deprecated */
599 if( p_frontend->info.caps & FE_CAN_RECOVER)
600 msg_Dbg(p_access, " cable unplug recovery");
601 if( p_frontend->info.caps & FE_CAN_MUTE_TS)
602 msg_Dbg(p_access, " spurious TS muting");
603 msg_Dbg(p_access, "End of capability list");
608 /*****************************************************************************
609 * Decoding the DVB parameters (common)
610 *****************************************************************************/
611 static fe_spectral_inversion_t DecodeInversion( access_t *p_access )
614 fe_spectral_inversion_t fe_inversion = 0;
616 i_val = var_GetInteger( p_access, "dvb-inversion" );
617 msg_Dbg( p_access, "using inversion=%d", i_val );
621 case 0: fe_inversion = INVERSION_OFF; break;
622 case 1: fe_inversion = INVERSION_ON; break;
623 case 2: fe_inversion = INVERSION_AUTO; break;
625 msg_Dbg( p_access, "dvb has inversion not set, using auto");
626 fe_inversion = INVERSION_AUTO;
632 static fe_code_rate_t DecodeFEC( access_t *p_access, const char *varname )
634 switch( var_GetInteger(p_access, varname) )
636 case 0: return FEC_NONE;
637 case 1: return FEC_1_2;
638 case 2: return FEC_2_3;
639 case 3: return FEC_3_4;
640 case 4: return FEC_4_5;
641 case 5: return FEC_5_6;
642 case 6: return FEC_6_7;
643 case 7: return FEC_7_8;
644 case 8: return FEC_8_9;
645 case 9: return FEC_AUTO;
646 default: return FEC_NONE;
650 static fe_modulation_t DecodeModulation( access_t *p_access,
651 fe_modulation_t def )
653 switch( var_GetInteger( p_access, "dvb-modulation" ) )
655 case -1: return QPSK;
656 case 0: return QAM_AUTO;
657 case 8: return VSB_8;
658 case 16: return QAM_16;
659 case 32: return QAM_32;
660 case 64: return QAM_64;
661 case 128: return QAM_128;
662 case 256: return QAM_256;
667 /*****************************************************************************
668 * FrontendSetQPSK : controls the FE device
669 *****************************************************************************/
670 static fe_sec_voltage_t DecodeVoltage( access_t *p_access )
672 switch( var_GetInteger( p_access, "dvb-voltage" ) )
674 case 0: return SEC_VOLTAGE_OFF;
675 case 13: return SEC_VOLTAGE_13;
676 case 18: return SEC_VOLTAGE_18;
677 default: return SEC_VOLTAGE_OFF;
681 static fe_sec_tone_mode_t DecodeTone( access_t *p_access )
683 switch( var_GetInteger( p_access, "dvb-tone" ) )
685 case 0: return SEC_TONE_OFF;
686 case 1: return SEC_TONE_ON;
687 default: return SEC_TONE_OFF;
693 struct dvb_diseqc_master_cmd cmd;
697 static int DoDiseqc( access_t *p_access )
699 access_sys_t *p_sys = p_access->p_sys;
702 int i_frequency, i_lnb_slof;
703 fe_sec_voltage_t fe_voltage;
704 fe_sec_tone_mode_t fe_tone;
706 i_frequency = var_GetInteger( p_access, "dvb-frequency" );
707 i_lnb_slof = var_GetInteger( p_access, "dvb-lnb-slof" );
709 i_val = var_GetInteger( p_access, "dvb-tone" );
710 if( i_val == -1 /* auto */ )
712 if( i_frequency >= i_lnb_slof )
716 var_SetInteger( p_access, "dvb-tone", i_val );
719 fe_voltage = DecodeVoltage( p_access );
720 fe_tone = DecodeTone( p_access );
722 /* Switch off continuous tone. */
723 if( ioctl( p_sys->i_frontend_handle, FE_SET_TONE, SEC_TONE_OFF ) < 0 )
725 msg_Err( p_access, "switching tone %s error: %m", "off" );
729 /* Configure LNB voltage. */
730 if( ioctl( p_sys->i_frontend_handle, FE_SET_VOLTAGE, fe_voltage ) < 0 )
732 msg_Err( p_access, "voltage error: %m" );
736 b_val = var_GetBool( p_access, "dvb-high-voltage" );
737 if( ioctl( p_sys->i_frontend_handle,
738 FE_ENABLE_HIGH_LNB_VOLTAGE, b_val ) < 0 && b_val )
740 msg_Err( p_access, "high LNB voltage error: %m" );
743 /* Wait for at least 15 ms. */
746 i_val = var_GetInteger( p_access, "dvb-satno" );
747 if( i_val > 0 && i_val < 5 )
749 /* digital satellite equipment control,
750 * specification is available from http://www.eutelsat.com/
753 /* 1.x compatible equipment */
754 struct diseqc_cmd_t cmd = { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
756 /* param: high nibble: reset bits, low nibble set bits,
757 * bits are: option, position, polarization, band
759 cmd.cmd.msg[3] = 0xf0 /* reset bits */
760 | (((i_val - 1) * 4) & 0xc)
761 | (fe_voltage == SEC_VOLTAGE_13 ? 0 : 2)
762 | (fe_tone == SEC_TONE_ON ? 1 : 0);
764 if( ioctl( p_sys->i_frontend_handle, FE_DISEQC_SEND_MASTER_CMD,
767 msg_Err( p_access, "master command sending error: %m" );
771 msleep(15000 + cmd.wait * 1000);
773 /* A or B simple diseqc ("diseqc-compatible") */
774 if( ioctl( p_sys->i_frontend_handle, FE_DISEQC_SEND_BURST,
775 ((i_val - 1) % 2) ? SEC_MINI_B : SEC_MINI_A ) )
777 msg_Err( p_access, "burst sending error: %m" );
784 if( ioctl( p_sys->i_frontend_handle, FE_SET_TONE, fe_tone ) )
786 msg_Err( p_access, "switching tone %s error: %m",
787 (fe_tone == SEC_TONE_ON) ? "on" : "off" );
795 static int FrontendSetQPSK( access_t *p_access )
797 access_sys_t *p_sys = p_access->p_sys;
798 struct dvb_frontend_parameters fep;
800 int i_frequency, i_lnb_slof = 0, i_lnb_lof1, i_lnb_lof2 = 0;
802 /* Prepare the fep structure */
803 i_frequency = var_GetInteger( p_access, "dvb-frequency" );
805 i_val = var_GetInteger( p_access, "dvb-lnb-lof1" );
808 /* Automatic mode. */
809 if ( i_frequency >= 950000 && i_frequency <= 2150000 )
811 msg_Dbg( p_access, "frequency %d is in IF-band", i_frequency );
814 else if ( i_frequency >= 2500000 && i_frequency <= 2700000 )
816 msg_Dbg( p_access, "frequency %d is in S-band", i_frequency );
817 i_lnb_lof1 = 3650000;
819 else if ( i_frequency >= 3400000 && i_frequency <= 4200000 )
821 msg_Dbg( p_access, "frequency %d is in C-band (lower)",
823 i_lnb_lof1 = 5150000;
825 else if ( i_frequency >= 4500000 && i_frequency <= 4800000 )
827 msg_Dbg( p_access, "frequency %d is in C-band (higher)",
829 i_lnb_lof1 = 5950000;
831 else if ( i_frequency >= 10700000 && i_frequency <= 13250000 )
833 msg_Dbg( p_access, "frequency %d is in Ku-band",
835 i_lnb_lof1 = 9750000;
836 i_lnb_lof2 = 10600000;
837 i_lnb_slof = 11700000;
841 msg_Err( p_access, "frequency %d is out of any known band",
843 msg_Err( p_access, "specify dvb-lnb-lof1 manually for the local "
844 "oscillator frequency" );
847 var_SetInteger( p_access, "dvb-lnb-lof1", i_lnb_lof1 );
848 var_SetInteger( p_access, "dvb-lnb-lof2", i_lnb_lof2 );
849 var_SetInteger( p_access, "dvb-lnb-slof", i_lnb_slof );
854 i_lnb_lof2 = var_GetInteger( p_access, "dvb-lnb-lof2" );
855 i_lnb_slof = var_GetInteger( p_access, "dvb-lnb-slof" );
858 if( i_lnb_slof && i_frequency >= i_lnb_slof )
860 i_frequency -= i_lnb_lof2;
864 i_frequency -= i_lnb_lof1;
866 fep.frequency = i_frequency >= 0 ? i_frequency : -i_frequency;
868 fep.inversion = DecodeInversion( p_access );
870 fep.u.qpsk.symbol_rate = var_GetInteger( p_access, "dvb-srate" );
872 fep.u.qpsk.fec_inner = DecodeFEC( p_access, "dvb-fec" );
874 if( DoDiseqc( p_access ) < 0 )
879 /* Empty the event queue */
882 struct dvb_frontend_event event;
883 if ( ioctl( p_sys->i_frontend_handle, FE_GET_EVENT, &event ) < 0
884 && errno == EWOULDBLOCK )
888 /* Now send it all to the frontend device */
889 if( ioctl( p_sys->i_frontend_handle, FE_SET_FRONTEND, &fep ) < 0 )
891 msg_Err( p_access, "frontend error: %m" );
898 /*****************************************************************************
899 * FrontendSetQAM : controls the FE device
900 *****************************************************************************/
901 static int FrontendSetQAM( access_t *p_access )
903 access_sys_t *p_sys = p_access->p_sys;
904 frontend_t *p_frontend = p_sys->p_frontend;
905 struct dvb_frontend_parameters fep;
908 /* Prepare the fep structure */
910 fep.frequency = var_GetInteger( p_access, "dvb-frequency" );
912 fep.inversion = DecodeInversion( p_access );
914 /* Default symbol-rate is for dvb-s, and doesn't fit
915 * for dvb-c, so if it's over the limit of frontend, default to
916 * somewhat common value
918 i_val = var_GetInteger( p_access, "dvb-srate" );
919 if( i_val < p_frontend->info.symbol_rate_max &&
920 i_val > p_frontend->info.symbol_rate_min )
921 fep.u.qam.symbol_rate = i_val;
923 fep.u.qam.fec_inner = DecodeFEC( p_access, "dvb-fec" );
925 fep.u.qam.modulation = DecodeModulation( p_access, QAM_AUTO );
927 /* Empty the event queue */
930 struct dvb_frontend_event event;
931 if ( ioctl( p_sys->i_frontend_handle, FE_GET_EVENT, &event ) < 0
932 && errno == EWOULDBLOCK )
936 /* Now send it all to the frontend device */
937 if( ioctl( p_sys->i_frontend_handle, FE_SET_FRONTEND, &fep ) < 0 )
939 msg_Err( p_access, "frontend error: %m" );
946 /*****************************************************************************
947 * FrontendSetOFDM : controls the FE device
948 *****************************************************************************/
949 static fe_bandwidth_t DecodeBandwidth( access_t *p_access )
951 fe_bandwidth_t fe_bandwidth = 0;
952 int i_bandwidth = var_GetInteger( p_access, "dvb-bandwidth" );
954 msg_Dbg( p_access, "using bandwidth=%d", i_bandwidth );
956 switch( i_bandwidth )
958 case 0: fe_bandwidth = BANDWIDTH_AUTO; break;
959 case 6: fe_bandwidth = BANDWIDTH_6_MHZ; break;
960 case 7: fe_bandwidth = BANDWIDTH_7_MHZ; break;
961 case 8: fe_bandwidth = BANDWIDTH_8_MHZ; break;
963 msg_Dbg( p_access, "terrestrial dvb has bandwidth not set, using auto" );
964 fe_bandwidth = BANDWIDTH_AUTO;
970 static fe_transmit_mode_t DecodeTransmission( access_t *p_access )
972 fe_transmit_mode_t fe_transmission = 0;
973 int i_transmission = var_GetInteger( p_access, "dvb-transmission" );
975 msg_Dbg( p_access, "using transmission=%d", i_transmission );
977 switch( i_transmission )
979 case 0: fe_transmission = TRANSMISSION_MODE_AUTO; break;
980 case 2: fe_transmission = TRANSMISSION_MODE_2K; break;
981 case 8: fe_transmission = TRANSMISSION_MODE_8K; break;
983 msg_Dbg( p_access, "terrestrial dvb has transmission mode not set, using auto");
984 fe_transmission = TRANSMISSION_MODE_AUTO;
987 return fe_transmission;
990 static fe_guard_interval_t DecodeGuardInterval( access_t *p_access )
992 fe_guard_interval_t fe_guard = 0;
993 int i_guard = var_GetInteger( p_access, "dvb-guard" );
995 msg_Dbg( p_access, "using guard=%d", i_guard );
999 case 0: fe_guard = GUARD_INTERVAL_AUTO; break;
1000 case 4: fe_guard = GUARD_INTERVAL_1_4; break;
1001 case 8: fe_guard = GUARD_INTERVAL_1_8; break;
1002 case 16: fe_guard = GUARD_INTERVAL_1_16; break;
1003 case 32: fe_guard = GUARD_INTERVAL_1_32; break;
1005 msg_Dbg( p_access, "terrestrial dvb has guard interval not set, using auto");
1006 fe_guard = GUARD_INTERVAL_AUTO;
1012 static fe_hierarchy_t DecodeHierarchy( access_t *p_access )
1014 fe_hierarchy_t fe_hierarchy = 0;
1015 int i_hierarchy = var_GetInteger( p_access, "dvb-hierarchy" );
1017 msg_Dbg( p_access, "using hierarchy=%d", i_hierarchy );
1019 switch( i_hierarchy )
1021 case -1: fe_hierarchy = HIERARCHY_NONE; break;
1022 case 0: fe_hierarchy = HIERARCHY_AUTO; break;
1023 case 1: fe_hierarchy = HIERARCHY_1; break;
1024 case 2: fe_hierarchy = HIERARCHY_2; break;
1025 case 4: fe_hierarchy = HIERARCHY_4; break;
1027 msg_Dbg( p_access, "terrestrial dvb has hierarchy not set, using auto");
1028 fe_hierarchy = HIERARCHY_AUTO;
1031 return fe_hierarchy;
1034 static int FrontendSetOFDM( access_t * p_access )
1036 access_sys_t *p_sys = p_access->p_sys;
1037 struct dvb_frontend_parameters fep;
1039 /* Prepare the fep structure */
1041 fep.frequency = var_GetInteger( p_access, "dvb-frequency" );
1043 fep.inversion = DecodeInversion( p_access );
1045 fep.u.ofdm.bandwidth = DecodeBandwidth( p_access );
1046 fep.u.ofdm.code_rate_HP = DecodeFEC( p_access, "dvb-code-rate-hp" );
1047 fep.u.ofdm.code_rate_LP = DecodeFEC( p_access, "dvb-code-rate-lp" );
1048 fep.u.ofdm.constellation = DecodeModulation( p_access, QAM_AUTO );
1049 fep.u.ofdm.transmission_mode = DecodeTransmission( p_access );
1050 fep.u.ofdm.guard_interval = DecodeGuardInterval( p_access );
1051 fep.u.ofdm.hierarchy_information = DecodeHierarchy( p_access );
1053 /* Empty the event queue */
1056 struct dvb_frontend_event event;
1057 if ( ioctl( p_sys->i_frontend_handle, FE_GET_EVENT, &event ) < 0
1058 && errno == EWOULDBLOCK )
1062 /* Now send it all to the frontend device */
1063 if( ioctl( p_sys->i_frontend_handle, FE_SET_FRONTEND, &fep ) < 0 )
1065 msg_Err( p_access, "frontend error: %m" );
1066 return VLC_EGENERIC;
1072 /*****************************************************************************
1073 * FrontendSetATSC : controls the FE device
1074 *****************************************************************************/
1075 static int FrontendSetATSC( access_t *p_access )
1077 access_sys_t *p_sys = p_access->p_sys;
1078 struct dvb_frontend_parameters fep;
1080 /* Prepare the fep structure */
1082 fep.frequency = var_GetInteger( p_access, "dvb-frequency" );
1084 fep.u.vsb.modulation = DecodeModulation( p_access, VSB_8 );
1086 /* Empty the event queue */
1089 struct dvb_frontend_event event;
1090 if ( ioctl( p_sys->i_frontend_handle, FE_GET_EVENT, &event ) < 0
1091 && errno == EWOULDBLOCK )
1095 /* Now send it all to the frontend device */
1096 if( ioctl( p_sys->i_frontend_handle, FE_SET_FRONTEND, &fep ) < 0 )
1098 msg_Err( p_access, "frontend error: %m" );
1099 return VLC_EGENERIC;
1110 /*****************************************************************************
1111 * DMXSetFilter : controls the demux to add a filter
1112 *****************************************************************************/
1113 int DMXSetFilter( access_t * p_access, int i_pid, int * pi_fd, int i_type )
1115 struct dmx_pes_filter_params s_filter_params;
1116 unsigned int i_adapter, i_device;
1119 i_adapter = var_GetInteger( p_access, "dvb-adapter" );
1120 i_device = var_GetInteger( p_access, "dvb-device" );
1122 if( snprintf( dmx, sizeof(dmx), DMX, i_adapter, i_device )
1123 >= (int)sizeof(dmx) )
1125 msg_Err( p_access, "snprintf() truncated string for DMX" );
1126 dmx[sizeof(dmx) - 1] = '\0';
1129 msg_Dbg( p_access, "Opening device %s", dmx );
1130 if( (*pi_fd = vlc_open(dmx, O_RDWR)) < 0 )
1132 msg_Err( p_access, "DMXSetFilter: opening device failed (%m)" );
1133 return VLC_EGENERIC;
1136 /* We fill the DEMUX structure : */
1137 s_filter_params.pid = i_pid;
1138 s_filter_params.input = DMX_IN_FRONTEND;
1139 s_filter_params.output = DMX_OUT_TS_TAP;
1140 s_filter_params.flags = DMX_IMMEDIATE_START;
1143 { /* First device */
1145 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_VIDEO0 for PID %d", i_pid);
1146 s_filter_params.pes_type = DMX_PES_VIDEO0;
1149 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_AUDIO0 for PID %d", i_pid);
1150 s_filter_params.pes_type = DMX_PES_AUDIO0;
1153 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_TELETEXT0 for PID %d", i_pid);
1154 s_filter_params.pes_type = DMX_PES_TELETEXT0;
1157 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_SUBTITLE0 for PID %d", i_pid);
1158 s_filter_params.pes_type = DMX_PES_SUBTITLE0;
1161 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_PCR0 for PID %d", i_pid);
1162 s_filter_params.pes_type = DMX_PES_PCR0;
1166 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_VIDEO1 for PID %d", i_pid);
1167 s_filter_params.pes_type = DMX_PES_VIDEO1;
1170 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_AUDIO1 for PID %d", i_pid);
1171 s_filter_params.pes_type = DMX_PES_AUDIO1;
1174 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_TELETEXT1 for PID %d", i_pid);
1175 s_filter_params.pes_type = DMX_PES_TELETEXT1;
1178 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_SUBTITLE1 for PID %d", i_pid);
1179 s_filter_params.pes_type = DMX_PES_SUBTITLE1;
1182 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_PCR1 for PID %d", i_pid);
1183 s_filter_params.pes_type = DMX_PES_PCR1;
1187 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_VIDEO2 for PID %d", i_pid);
1188 s_filter_params.pes_type = DMX_PES_VIDEO2;
1191 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_AUDIO2 for PID %d", i_pid);
1192 s_filter_params.pes_type = DMX_PES_AUDIO2;
1195 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_TELETEXT2 for PID %d", i_pid);
1196 s_filter_params.pes_type = DMX_PES_TELETEXT2;
1199 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_SUBTITLE2 for PID %d", i_pid);
1200 s_filter_params.pes_type = DMX_PES_SUBTITLE2;
1203 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_PCR2 for PID %d", i_pid);
1204 s_filter_params.pes_type = DMX_PES_PCR2;
1208 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_VIDEO3 for PID %d", i_pid);
1209 s_filter_params.pes_type = DMX_PES_VIDEO3;
1212 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_AUDIO3 for PID %d", i_pid);
1213 s_filter_params.pes_type = DMX_PES_AUDIO3;
1216 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_TELETEXT3 for PID %d", i_pid);
1217 s_filter_params.pes_type = DMX_PES_TELETEXT3;
1220 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_SUBTITLE3 for PID %d", i_pid);
1221 s_filter_params.pes_type = DMX_PES_SUBTITLE3;
1224 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_PCR3 for PID %d", i_pid);
1225 s_filter_params.pes_type = DMX_PES_PCR3;
1227 /* Usually used by Nova cards */
1230 msg_Dbg(p_access, "DMXSetFilter: DMX_PES_OTHER for PID %d", i_pid);
1231 s_filter_params.pes_type = DMX_PES_OTHER;
1235 /* We then give the order to the device : */
1236 if( ioctl( *pi_fd, DMX_SET_PES_FILTER, &s_filter_params ) )
1238 msg_Err( p_access, "setting demux PES filter failed: %m" );
1239 return VLC_EGENERIC;
1244 /*****************************************************************************
1245 * DMXUnsetFilter : removes a filter
1246 *****************************************************************************/
1247 int DMXUnsetFilter( access_t * p_access, int i_fd )
1249 if( ioctl( i_fd, DMX_STOP ) < 0 )
1251 msg_Err( p_access, "stopping demux failed: %m" );
1252 return VLC_EGENERIC;
1255 msg_Dbg( p_access, "DMXUnsetFilter: closing demux %d", i_fd );
1265 /*****************************************************************************
1267 *****************************************************************************/
1268 int DVROpen( access_t * p_access )
1270 access_sys_t *p_sys = p_access->p_sys;
1271 unsigned int i_adapter, i_device;
1274 i_adapter = var_GetInteger( p_access, "dvb-adapter" );
1275 i_device = var_GetInteger( p_access, "dvb-device" );
1277 if( snprintf( dvr, sizeof(dvr), DVR, i_adapter, i_device )
1278 >= (int)sizeof(dvr) )
1280 msg_Err( p_access, "snprintf() truncated string for DVR" );
1281 dvr[sizeof(dvr) - 1] = '\0';
1284 msg_Dbg( p_access, "Opening device %s", dvr );
1285 if( (p_sys->i_handle = vlc_open(dvr, O_RDONLY)) < 0 )
1287 msg_Err( p_access, "DVROpen: opening device failed (%m)" );
1288 return VLC_EGENERIC;
1291 if( fcntl( p_sys->i_handle, F_SETFL, O_NONBLOCK ) == -1 )
1293 msg_Warn( p_access, "DVROpen: couldn't set non-blocking mode (%m)" );
1299 /*****************************************************************************
1301 *****************************************************************************/
1302 void DVRClose( access_t * p_access )
1304 access_sys_t *p_sys = p_access->p_sys;
1306 close( p_sys->i_handle );