3 * @brief Linux DVB API version 5
5 /*****************************************************************************
6 * Copyright © 2011 Rémi Denis-Courmont
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
27 #include <vlc_common.h>
29 #include <vlc_interrupt.h>
36 #include <sys/ioctl.h>
37 #include <linux/dvb/version.h>
38 #include <linux/dvb/frontend.h>
39 #include <linux/dvb/dmx.h>
42 #include "dtv/en50221.h"
45 # define O_SEARCH O_RDONLY
48 #define DVBv5(minor) \
49 (DVB_API_VERSION > 5 \
50 || (DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= (minor)))
58 static int icmp (const void *a
, const void *b
)
61 const dvb_int_map_t
*entry
= b
;
62 return *key
- entry
->vlc
;
65 /** Maps a VLC config integer to a Linux DVB enum value */
66 static int dvb_parse_int (int i
, const dvb_int_map_t
*map
, size_t n
, int def
)
68 const dvb_int_map_t
*p
= bsearch(&i
, map
, n
, sizeof (*map
), icmp
);
69 return (p
!= NULL
) ? p
->linux_
: def
;
78 static int scmp (const void *a
, const void *b
)
81 dvb_str_map_t
*entry
= b
;
82 return strcmp (key
, entry
->vlc
);
85 /** Maps a VLC config string to a Linux DVB enum value */
86 static int dvb_parse_str (const char *str
, const dvb_str_map_t
*map
, size_t n
,
91 const dvb_str_map_t
*p
= bsearch (str
, map
, n
, sizeof (*map
), scmp
);
99 static int dvb_parse_modulation (const char *str
, int def
)
101 static const dvb_str_map_t mods
[] =
103 { "128QAM", QAM_128
},
104 { "16APSK", APSK_16
},
107 { "256QAM", QAM_256
},
108 { "32APSK", APSK_32
},
117 return dvb_parse_str (str
, mods
, sizeof (mods
) / sizeof (*mods
), def
);
120 static int dvb_parse_fec (uint32_t fec
)
122 static const dvb_int_map_t rates
[] =
125 { VLC_FEC(1,2), FEC_1_2
},
128 { VLC_FEC(2,3), FEC_2_3
},
129 { VLC_FEC(3,4), FEC_3_4
},
130 { VLC_FEC(3,5), FEC_3_5
},
131 { VLC_FEC(4,5), FEC_4_5
},
132 { VLC_FEC(5,6), FEC_5_6
},
133 { VLC_FEC(6,7), FEC_6_7
},
134 { VLC_FEC(7,8), FEC_7_8
},
135 { VLC_FEC(8,9), FEC_8_9
},
136 { VLC_FEC(9,10), FEC_9_10
},
137 { VLC_FEC_AUTO
, FEC_AUTO
},
139 return dvb_parse_int (fec
, rates
, sizeof (rates
) / sizeof (*rates
),
151 # define MAX_PIDS 256
161 //size_t buffer_size;
164 /** Opens the device directory for the specified DVB adapter */
165 static int dvb_open_adapter (uint8_t adapter
)
169 snprintf (dir
, sizeof (dir
), "/dev/dvb/adapter%"PRIu8
, adapter
);
170 return vlc_open (dir
, O_SEARCH
|O_DIRECTORY
);
173 /** Opens the DVB device node of the specified type */
174 static int dvb_open_node (dvb_device_t
*d
, const char *type
, int flags
)
176 char path
[strlen (type
) + 4];
178 snprintf (path
, sizeof (path
), "%s%u", type
, d
->device
);
179 return vlc_openat (d
->dir
, path
, flags
| O_NONBLOCK
);
183 * Opens the DVB tuner
185 dvb_device_t
*dvb_open (vlc_object_t
*obj
)
187 dvb_device_t
*d
= malloc (sizeof (*d
));
188 if (unlikely(d
== NULL
))
193 uint8_t adapter
= var_InheritInteger (obj
, "dvb-adapter");
194 d
->device
= var_InheritInteger (obj
, "dvb-device");
196 d
->dir
= dvb_open_adapter (adapter
);
199 msg_Err (obj
, "cannot access adapter %"PRIu8
": %s", adapter
,
200 vlc_strerror_c(errno
));
206 d
->budget
= var_InheritBool (obj
, "dvb-budget-mode");
212 d
->demux
= dvb_open_node (d
, "demux", O_RDONLY
);
215 msg_Err (obj
, "cannot access demultiplexer: %s",
216 vlc_strerror_c(errno
));
222 if (ioctl (d
->demux
, DMX_SET_BUFFER_SIZE
, 1 << 20) < 0)
223 msg_Warn (obj
, "cannot expand demultiplexing buffer: %s",
224 vlc_strerror_c(errno
));
226 /* We need to filter at least one PID. The tap for TS demultiplexing
227 * cannot be configured otherwise. So add the PAT. */
228 struct dmx_pes_filter_params param
;
230 param
.pid
= d
->budget
? 0x2000 : 0x000;
231 param
.input
= DMX_IN_FRONTEND
;
232 param
.output
= DMX_OUT_TSDEMUX_TAP
;
233 param
.pes_type
= DMX_PES_OTHER
;
234 param
.flags
= DMX_IMMEDIATE_START
;
235 if (ioctl (d
->demux
, DMX_SET_PES_FILTER
, ¶m
) < 0)
237 msg_Err (obj
, "cannot setup TS demultiplexer: %s",
238 vlc_strerror_c(errno
));
245 for (size_t i
= 0; i
< MAX_PIDS
; i
++)
246 d
->pids
[i
].pid
= d
->pids
[i
].fd
= -1;
247 d
->demux
= dvb_open_node (d
, "dvr", O_RDONLY
);
250 msg_Err (obj
, "cannot access DVR: %s", vlc_strerror_c(errno
));
258 int ca
= dvb_open_node (d
, "ca", O_RDWR
);
261 d
->cam
= en50221_Init (obj
, ca
);
266 msg_Dbg (obj
, "conditional access module not available: %s",
267 vlc_strerror_c(errno
));
275 void dvb_close (dvb_device_t
*d
)
280 for (size_t i
= 0; i
< MAX_PIDS
; i
++)
281 if (d
->pids
[i
].fd
!= -1)
282 vlc_close (d
->pids
[i
].fd
);
286 en50221_End (d
->cam
);
287 if (d
->frontend
!= -1)
288 vlc_close (d
->frontend
);
289 vlc_close (d
->demux
);
294 static void dvb_frontend_status(vlc_object_t
*obj
, fe_status_t s
)
296 msg_Dbg(obj
, "frontend status:");
299 msg_Dbg(obj, "\t%s", #f);
312 * Reads TS data from the tuner.
313 * @return number of bytes read, 0 on EOF, -1 if no data (yet).
315 ssize_t
dvb_read (dvb_device_t
*d
, void *buf
, size_t len
, int ms
)
317 struct pollfd ufd
[2];
321 en50221_Poll (d
->cam
);
323 ufd
[0].fd
= d
->demux
;
324 ufd
[0].events
= POLLIN
;
325 if (d
->frontend
!= -1)
327 ufd
[1].fd
= d
->frontend
;
328 ufd
[1].events
= POLLPRI
;
335 n
= vlc_poll_i11e (ufd
, n
, ms
);
341 if (d
->frontend
!= -1 && ufd
[1].revents
)
343 struct dvb_frontend_event ev
;
345 if (ioctl (d
->frontend
, FE_GET_EVENT
, &ev
) < 0)
347 if (errno
== EOVERFLOW
)
349 msg_Err (d
->obj
, "cannot dequeue events fast enough!");
352 msg_Err (d
->obj
, "cannot dequeue frontend event: %s",
353 vlc_strerror_c(errno
));
357 dvb_frontend_status(d
->obj
, ev
.status
);
362 ssize_t val
= read (d
->demux
, buf
, len
);
363 if (val
== -1 && (errno
!= EAGAIN
&& errno
!= EINTR
))
365 if (errno
== EOVERFLOW
)
367 msg_Err (d
->obj
, "cannot demux data fast enough!");
370 msg_Err (d
->obj
, "cannot demux: %s", vlc_strerror_c(errno
));
379 int dvb_add_pid (dvb_device_t
*d
, uint16_t pid
)
384 if (pid
== 0 || ioctl (d
->demux
, DMX_ADD_PID
, &pid
) >= 0)
387 for (size_t i
= 0; i
< MAX_PIDS
; i
++)
389 if (d
->pids
[i
].pid
== pid
)
391 if (d
->pids
[i
].fd
!= -1)
394 int fd
= dvb_open_node (d
, "demux", O_RDONLY
);
398 /* We need to filter at least one PID. The tap for TS demultiplexing
399 * cannot be configured otherwise. So add the PAT. */
400 struct dmx_pes_filter_params param
;
403 param
.input
= DMX_IN_FRONTEND
;
404 param
.output
= DMX_OUT_TS_TAP
;
405 param
.pes_type
= DMX_PES_OTHER
;
406 param
.flags
= DMX_IMMEDIATE_START
;
407 if (ioctl (fd
, DMX_SET_PES_FILTER
, ¶m
) < 0)
413 d
->pids
[i
].pid
= pid
;
419 msg_Err (d
->obj
, "cannot add PID 0x%04"PRIu16
": %s", pid
,
420 vlc_strerror_c(errno
));
424 void dvb_remove_pid (dvb_device_t
*d
, uint16_t pid
)
430 ioctl (d
->demux
, DMX_REMOVE_PID
, &pid
);
432 for (size_t i
= 0; i
< MAX_PIDS
; i
++)
434 if (d
->pids
[i
].pid
== pid
)
436 vlc_close (d
->pids
[i
].fd
);
437 d
->pids
[i
].pid
= d
->pids
[i
].fd
= -1;
444 bool dvb_get_pid_state (const dvb_device_t
*d
, uint16_t pid
)
449 for (size_t i
= 0; i
< MAX_PIDS
; i
++)
450 if (d
->pids
[i
].pid
== pid
)
456 /** Finds a frontend of the correct type */
457 static int dvb_open_frontend (dvb_device_t
*d
)
459 if (d
->frontend
!= -1)
461 int fd
= dvb_open_node (d
, "frontend", O_RDWR
);
464 msg_Err (d
->obj
, "cannot access frontend: %s", vlc_strerror_c(errno
));
471 #define dvb_find_frontend(d, sys) (dvb_open_frontend(d))
474 * Detects supported delivery systems.
475 * @return a bit mask of supported systems (zero on failure)
477 unsigned dvb_enum_systems (dvb_device_t
*d
)
479 if (dvb_open_frontend (d
))
482 struct dtv_property prop
[2] = {
483 { .cmd
= DTV_API_VERSION
},
484 { .cmd
= DTV_ENUM_DELSYS
},
486 struct dtv_properties props
= {
491 if (ioctl (d
->frontend
, FE_GET_PROPERTY
, &props
) < 0)
493 msg_Err (d
->obj
, "cannot enumerate frontend systems: %s",
494 vlc_strerror_c(errno
));
498 static const unsigned systab
[] = {
500 [SYS_DVBC_ANNEX_A
] = DTV_DELIVERY_DVB_C
,
501 [SYS_DVBC_ANNEX_B
] = DTV_DELIVERY_CQAM
,
502 [SYS_DVBT
] = DTV_DELIVERY_DVB_T
,
504 [SYS_DVBS
] = DTV_DELIVERY_DVB_S
,
505 [SYS_DVBS2
] = DTV_DELIVERY_DVB_S2
,
507 [SYS_ISDBT
] = DTV_DELIVERY_ISDB_T
,
508 [SYS_ISDBS
] = DTV_DELIVERY_ISDB_S
,
509 [SYS_ISDBC
] = DTV_DELIVERY_ISDB_C
, // no drivers exist (as of 3.3-rc6)
510 [SYS_ATSC
] = DTV_DELIVERY_ATSC
,
515 [SYS_DVBT2
] = DTV_DELIVERY_DVB_T2
,
517 [SYS_DVBC_ANNEX_C
] = DTV_DELIVERY_ISDB_C
, // another name for ISDB-C?
519 unsigned systems
= 0;
521 msg_Dbg (d
->obj
, "probing frontend (kernel API v%u.%u, user API v%u.%u)",
522 prop
[0].u
.data
>> 8, prop
[0].u
.data
& 0xFF,
523 DVB_API_VERSION
, DVB_API_VERSION_MINOR
);
525 for (size_t i
= 0; i
< prop
[1].u
.buffer
.len
; i
++)
527 unsigned sys
= prop
[1].u
.buffer
.data
[i
];
529 if (sys
>= (sizeof (systab
) / sizeof (systab
[0])) || !systab
[sys
])
531 msg_Warn (d
->obj
, "unknown delivery system %u", sys
);
534 msg_Dbg (d
->obj
, " system %u", sys
);
535 systems
|= systab
[sys
];
542 struct dtv_property prop
[1] = {
543 { .cmd
= DTV_API_VERSION
},
545 struct dtv_properties props
= {
549 unsigned systems
= 0;
551 if (ioctl (d
->frontend
, FE_GET_PROPERTY
, &props
) < 0)
553 msg_Err (d
->obj
, "unsupported kernel DVB version 3 or older (%s)",
554 vlc_strerror_c(errno
));
558 msg_Dbg (d
->obj
, "probing frontend (kernel API v%u.%u, user API v%u.%u)",
559 prop
[0].u
.data
>> 8, prop
[0].u
.data
& 0xFF,
560 DVB_API_VERSION
, DVB_API_VERSION_MINOR
);
562 /* Some delivery systems cannot be detected without the DVB API v5.5.
563 * To run correctly on recent kernels (Linux >= 3.3),
564 * VLC needs to be compiled with up-to-date kernel headers. */
565 if ((prop
[0].u
.data
>> 8) > 5
566 || ((prop
[0].u
.data
>> 8) == 5 && (prop
[0].u
.data
& 0xFF) >= 5))
567 msg_Err (d
->obj
, "obsolete user API version running on a new kernel");
568 msg_Info (d
->obj
, "please recompile "PACKAGE_NAME
" "PACKAGE_VERSION
);
570 struct dvb_frontend_info info
;
571 if (ioctl (d
->frontend
, FE_GET_INFO
, &info
) < 0)
573 msg_Err (d
->obj
, "cannot get frontend info: %s",
574 vlc_strerror_c(errno
));
577 msg_Dbg (d
->obj
, " name %s", info
.name
);
578 msg_Dbg (d
->obj
, " type %u, capabilities 0x%08X", info
.type
, info
.caps
);
579 msg_Dbg (d
->obj
, " frequencies %10"PRIu32
" to %10"PRIu32
,
580 info
.frequency_min
, info
.frequency_max
);
581 msg_Dbg (d
->obj
, " (%"PRIu32
" tolerance, %"PRIu32
" per step)",
582 info
.frequency_tolerance
, info
.frequency_stepsize
);
583 msg_Dbg (d
->obj
, " bauds rates %10"PRIu32
" to %10"PRIu32
,
584 info
.symbol_rate_min
, info
.symbol_rate_max
);
585 msg_Dbg (d
->obj
, " (%"PRIu32
" tolerance)", info
.symbol_rate_tolerance
);
587 /* DVB first generation and ATSC */
590 case FE_QPSK
: systems
= DTV_DELIVERY_DVB_S
; break;
591 case FE_QAM
: systems
= DTV_DELIVERY_DVB_C
; break;
592 case FE_OFDM
: systems
= DTV_DELIVERY_DVB_T
; break;
593 case FE_ATSC
: systems
= DTV_DELIVERY_ATSC
| DTV_DELIVERY_CQAM
; break;
595 msg_Err (d
->obj
, "unknown frontend type %u", info
.type
);
598 /* DVB 2nd generation */
604 if (info
.caps
& FE_CAN_2G_MODULATION
)
605 systems
|= systems
<< 1; /* DVB_foo -> DVB_foo|DVB_foo2 */
610 /* ISDB (only terrestrial before DVBv5.5) */
611 if (info
.type
== FE_OFDM
)
612 systems
|= DTV_DELIVERY_ISDB_T
;
617 float dvb_get_signal_strength (dvb_device_t
*d
)
621 if (d
->frontend
== -1
622 || ioctl (d
->frontend
, FE_READ_SIGNAL_STRENGTH
, &strength
) < 0)
624 return strength
/ 65535.;
627 float dvb_get_snr (dvb_device_t
*d
)
631 if (d
->frontend
== -1 || ioctl (d
->frontend
, FE_READ_SNR
, &snr
) < 0)
636 bool dvb_set_ca_pmt (dvb_device_t
*d
, en50221_capmt_info_t
*p_capmtinfo
)
640 en50221_SetCAPMT (d
->cam
, p_capmtinfo
);
646 static int dvb_vset_props (dvb_device_t
*d
, size_t n
, va_list ap
)
648 assert (n
<= DTV_IOCTL_MAX_MSGS
);
650 struct dtv_property buf
[n
], *prop
= buf
;
651 struct dtv_properties props
= { .num
= n
, .props
= buf
};
653 memset (buf
, 0, sizeof (buf
));
657 prop
->cmd
= va_arg (ap
, uint32_t);
658 prop
->u
.data
= va_arg (ap
, uint32_t);
659 msg_Dbg (d
->obj
, "setting property %2"PRIu32
" to %"PRIu32
,
660 prop
->cmd
, prop
->u
.data
);
665 if (ioctl (d
->frontend
, FE_SET_PROPERTY
, &props
) < 0)
667 msg_Err (d
->obj
, "cannot set frontend tuning parameters: %s",
668 vlc_strerror_c(errno
));
674 static int dvb_set_props (dvb_device_t
*d
, size_t n
, ...)
680 ret
= dvb_vset_props (d
, n
, ap
);
685 static int dvb_set_prop (dvb_device_t
*d
, uint32_t prop
, uint32_t val
)
687 return dvb_set_props (d
, 1, prop
, val
);
690 int dvb_set_inversion (dvb_device_t
*d
, int v
)
694 case 0: v
= INVERSION_OFF
; break;
695 case 1: v
= INVERSION_ON
; break;
696 default: v
= INVERSION_AUTO
; break;
698 return dvb_set_prop (d
, DTV_INVERSION
, v
);
701 int dvb_tune (dvb_device_t
*d
)
703 return dvb_set_prop (d
, DTV_TUNE
, 0 /* dummy */);
706 int dvb_fill_device_caps(dvb_device_t
*d
, dvb_device_caps_t
*caps
)
708 struct dvb_frontend_info info
;
709 if (ioctl (d
->frontend
, FE_GET_INFO
, &info
) < 0)
711 msg_Err (d
->obj
, "cannot get frontend info: %s",
712 vlc_strerror_c(errno
));
716 caps
->frequency
.min
= info
.frequency_min
;
717 caps
->frequency
.max
= info
.frequency_max
;
718 caps
->symbolrate
.min
= info
.symbol_rate_min
;
719 caps
->symbolrate
.max
= info
.symbol_rate_max
;
720 caps
->b_can_cam_auto
= ( info
.caps
& FE_CAN_QAM_AUTO
);
726 int dvb_set_dvbc (dvb_device_t
*d
, uint32_t freq
, const char *modstr
,
727 uint32_t srate
, uint32_t fec
)
729 unsigned mod
= dvb_parse_modulation (modstr
, QAM_AUTO
);
730 fec
= dvb_parse_fec (fec
);
732 if (dvb_find_frontend (d
, DTV_DELIVERY_DVB_C
))
734 return dvb_set_props (d
, 6, DTV_CLEAR
, 0,
736 DTV_DELIVERY_SYSTEM
, SYS_DVBC_ANNEX_A
,
738 DTV_DELIVERY_SYSTEM
, SYS_DVBC_ANNEX_AC
,
740 DTV_FREQUENCY
, freq
, DTV_MODULATION
, mod
,
741 DTV_SYMBOL_RATE
, srate
, DTV_INNER_FEC
, fec
);
746 static unsigned dvb_parse_polarization (char pol
)
748 static const dvb_int_map_t tab
[5] = {
749 { 0, SEC_VOLTAGE_OFF
},
750 { 'H', SEC_VOLTAGE_18
},
751 { 'L', SEC_VOLTAGE_18
},
752 { 'R', SEC_VOLTAGE_13
},
753 { 'V', SEC_VOLTAGE_13
},
755 return dvb_parse_int (pol
, tab
, 5, SEC_VOLTAGE_OFF
);
758 int dvb_set_sec (dvb_device_t
*d
, uint64_t freq_Hz
, char pol
,
759 uint32_t lowf
, uint32_t highf
, uint32_t switchf
)
761 uint32_t freq
= freq_Hz
/ 1000;
763 /* Always try to configure high voltage, but only warn on enable failure */
764 int val
= var_InheritBool (d
->obj
, "dvb-high-voltage");
765 if (ioctl (d
->frontend
, FE_ENABLE_HIGH_LNB_VOLTAGE
, &val
) < 0 && val
)
766 msg_Err (d
->obj
, "cannot enable high LNB voltage: %s",
767 vlc_strerror_c(errno
));
769 /* Windows BDA exposes a higher-level API covering LNB oscillators.
770 * So lets pretend this is platform-specific stuff and do it here. */
772 { /* Default oscillator frequencies */
775 uint16_t min
, max
, low
, high
;
777 { /* min max low high */
778 { 10700, 13250, 9750, 10600 }, /* Ku band */
779 { 4500, 4800, 5950, 0 }, /* C band (high) */
780 { 3400, 4200, 5150, 0 }, /* C band (low) */
781 { 2500, 2700, 3650, 0 }, /* S band */
782 { 950, 2150, 0, 0 }, /* adjusted IF (L band) */
784 uint_fast16_t mHz
= freq
/ 1000;
786 for (size_t i
= 0; i
< sizeof (tab
) / sizeof (tab
[0]); i
++)
787 if (mHz
>= tab
[i
].min
&& mHz
<= tab
[i
].max
)
789 lowf
= tab
[i
].low
* 1000;
790 highf
= tab
[i
].high
* 1000;
794 msg_Err (d
->obj
, "no known band for frequency %u kHz", freq
);
796 msg_Dbg (d
->obj
, "selected LNB low: %u kHz, LNB high: %u kHz",
800 /* Use high oscillator frequency? */
801 bool high
= highf
!= 0 && freq
> switchf
;
803 freq
-= high
? highf
: lowf
;
804 if ((int32_t)freq
< 0)
806 assert (freq
< 0x7fffffff);
809 switch (var_InheritInteger (d
->obj
, "dvb-tone"))
811 case 0: tone
= SEC_TONE_OFF
; break;
812 case 1: tone
= SEC_TONE_ON
; break;
813 default: tone
= high
? SEC_TONE_ON
: SEC_TONE_OFF
;
816 /*** LNB selection / DiSEqC ***/
817 unsigned voltage
= dvb_parse_polarization (pol
);
818 if (dvb_set_props (d
, 2, DTV_TONE
, SEC_TONE_OFF
, DTV_VOLTAGE
, voltage
))
821 unsigned satno
= var_InheritInteger (d
->obj
, "dvb-satno");
824 #undef vlc_tick_sleep /* we know what we are doing! */
826 /* DiSEqC Bus Specification:
827 http://www.eutelsat.com/satellites/pdf/Diseqc/Reference%20docs/bus_spec.pdf */
830 struct dvb_diseqc_master_cmd uncmd
;
833 struct dvb_diseqc_master_cmd cmd
;
835 satno
= (satno
- 1) & 3;
836 cmd
.msg
[0] = 0xE0; /* framing: master, no reply, 1st TX */
837 cmd
.msg
[1] = 0x10; /* address: all LNB/switch */
838 cmd
.msg
[2] = 0x38; /* command: Write Port Group 0 (committed) */
839 cmd
.msg
[3] = 0xF0 /* data[0]: clear all bits */
840 | (satno
<< 2) /* LNB (A, B, C or D) */
841 | ((voltage
== SEC_VOLTAGE_18
) << 1) /* polarization */
842 | (tone
== SEC_TONE_ON
); /* option */
843 cmd
.msg
[4] = cmd
.msg
[5] = 0; /* unused */
844 cmd
.msg_len
= 4; /* length */
846 vlc_tick_sleep (VLC_TICK_FROM_MS(15)); /* wait 15 ms before DiSEqC command */
847 unsigned uncommitted
= var_InheritInteger (d
->obj
, "dvb-uncommitted");
850 uncommitted
= (uncommitted
- 1) & 3;
851 uncmd
.msg
[0] = 0xE0; /* framing: master, no reply, 1st TX */
852 uncmd
.msg
[1] = 0x10; /* address: all LNB/switch */
853 uncmd
.msg
[2] = 0x39; /* command: Write Port Group 1 (uncommitted) */
854 uncmd
.msg
[3] = 0xF0 /* data[0]: clear all bits */
855 | (uncommitted
<< 2) /* LNB (A, B, C or D) */
856 | ((voltage
== SEC_VOLTAGE_18
) << 1) /* polarization */
857 | (tone
== SEC_TONE_ON
); /* option */
858 uncmd
.msg
[4] = uncmd
.msg
[5] = 0; /* unused */
859 uncmd
.msg_len
= 4; /* length */
860 if (ioctl (d
->frontend
, FE_DISEQC_SEND_MASTER_CMD
, &uncmd
) < 0)
862 msg_Err (d
->obj
, "cannot send uncommitted DiSEqC command: %s",
863 vlc_strerror_c(errno
));
866 /* Repeat uncommitted command */
867 uncmd
.msg
[0] = 0xE1; /* framing: master, no reply, repeated TX */
868 if (ioctl (d
->frontend
, FE_DISEQC_SEND_MASTER_CMD
, &uncmd
) < 0)
871 "cannot send repeated uncommitted DiSEqC command: %s",
872 vlc_strerror_c(errno
));
875 vlc_tick_sleep(VLC_TICK_FROM_MS(125)); /* wait 125 ms before committed DiSEqC command */
877 if (ioctl (d
->frontend
, FE_DISEQC_SEND_MASTER_CMD
, &cmd
) < 0)
879 msg_Err (d
->obj
, "cannot send committed DiSEqC command: %s",
880 vlc_strerror_c(errno
));
883 vlc_tick_sleep (VLC_TICK_FROM_MS(54 + 15));
887 if (ioctl (d
->frontend
, FE_DISEQC_SEND_BURST
,
888 satno
? SEC_MINI_B
: SEC_MINI_A
) < 0)
890 msg_Err (d
->obj
, "cannot send Mini-DiSEqC tone burst: %s",
891 vlc_strerror_c(errno
));
894 vlc_tick_sleep (VLC_TICK_FROM_MS(15));
897 /* Continuous tone (to select high oscillator frequency) */
898 return dvb_set_props (d
, 2, DTV_FREQUENCY
, freq
, DTV_TONE
, tone
);
901 int dvb_set_dvbs (dvb_device_t
*d
, uint64_t freq_Hz
,
902 uint32_t srate
, uint32_t fec
)
904 uint32_t freq
= freq_Hz
/ 1000;
905 fec
= dvb_parse_fec (fec
);
907 if (dvb_find_frontend (d
, DTV_DELIVERY_DVB_S
))
909 return dvb_set_props (d
, 5, DTV_CLEAR
, 0, DTV_DELIVERY_SYSTEM
, SYS_DVBS
,
910 DTV_FREQUENCY
, freq
, DTV_SYMBOL_RATE
, srate
,
914 int dvb_set_dvbs2 (dvb_device_t
*d
, uint64_t freq_Hz
, const char *modstr
,
915 uint32_t srate
, uint32_t fec
, int pilot
, int rolloff
,
918 uint32_t freq
= freq_Hz
/ 1000;
919 unsigned mod
= dvb_parse_modulation (modstr
, QPSK
);
920 fec
= dvb_parse_fec (fec
);
924 case 0: pilot
= PILOT_OFF
; break;
925 case 1: pilot
= PILOT_ON
; break;
926 default: pilot
= PILOT_AUTO
; break;
931 case 20: rolloff
= ROLLOFF_20
; break;
932 case 25: rolloff
= ROLLOFF_25
; break;
933 case 35: rolloff
= ROLLOFF_35
; break;
934 default: rolloff
= PILOT_AUTO
; break;
937 if (dvb_find_frontend (d
, DTV_DELIVERY_DVB_S2
))
940 return dvb_set_props (d
, 9, DTV_CLEAR
, 0, DTV_DELIVERY_SYSTEM
, SYS_DVBS2
,
941 DTV_FREQUENCY
, freq
, DTV_MODULATION
, mod
,
942 DTV_SYMBOL_RATE
, srate
, DTV_INNER_FEC
, fec
,
943 DTV_PILOT
, pilot
, DTV_ROLLOFF
, rolloff
,
944 DTV_STREAM_ID
, (uint32_t)sid
);
946 # warning DVB-S2 needs Linux DVB version 5.8 or later.
949 msg_Err (d
->obj
, "DVB-S2 stream ID support not compiled-in");
952 return dvb_set_props (d
, 8, DTV_CLEAR
, 0, DTV_DELIVERY_SYSTEM
, SYS_DVBS2
,
953 DTV_FREQUENCY
, freq
, DTV_MODULATION
, mod
,
954 DTV_SYMBOL_RATE
, srate
, DTV_INNER_FEC
, fec
,
955 DTV_PILOT
, pilot
, DTV_ROLLOFF
, rolloff
);
961 static uint32_t dvb_parse_bandwidth (uint32_t i
)
966 case 2: return 1712000;
967 default: return i
* 1000000;
971 static int dvb_parse_transmit_mode (int i
)
973 static const dvb_int_map_t tab
[] = {
974 { -1, TRANSMISSION_MODE_AUTO
},
976 { 1, TRANSMISSION_MODE_1K
},
978 { 2, TRANSMISSION_MODE_2K
},
979 { 4, TRANSMISSION_MODE_4K
},
980 { 8, TRANSMISSION_MODE_8K
},
982 { 16, TRANSMISSION_MODE_16K
},
983 { 32, TRANSMISSION_MODE_32K
},
986 return dvb_parse_int (i
, tab
, sizeof (tab
) / sizeof (*tab
),
987 TRANSMISSION_MODE_AUTO
);
990 static int dvb_parse_guard (uint32_t guard
)
992 static const dvb_int_map_t tab
[] = {
993 { VLC_GUARD(1,4), GUARD_INTERVAL_1_4
},
994 { VLC_GUARD(1,8), GUARD_INTERVAL_1_8
},
995 { VLC_GUARD(1,16), GUARD_INTERVAL_1_16
},
996 { VLC_GUARD(1,32), GUARD_INTERVAL_1_32
},
998 { VLC_GUARD(1,128), GUARD_INTERVAL_1_128
},
999 { VLC_GUARD(19,128), GUARD_INTERVAL_19_128
},
1000 { VLC_GUARD(19,256), GUARD_INTERVAL_19_256
},
1002 { VLC_GUARD_AUTO
, GUARD_INTERVAL_AUTO
},
1004 return dvb_parse_int (guard
, tab
, sizeof (tab
) / sizeof (*tab
),
1005 GUARD_INTERVAL_AUTO
);
1008 static int dvb_parse_hierarchy (int i
)
1010 static const dvb_int_map_t tab
[] = {
1011 { HIERARCHY_AUTO
, -1 },
1012 { HIERARCHY_NONE
, 0 },
1017 return dvb_parse_int (i
, tab
, sizeof (tab
) / sizeof (*tab
),
1021 int dvb_set_dvbt (dvb_device_t
*d
, uint32_t freq
, const char *modstr
,
1022 uint32_t fec_hp
, uint32_t fec_lp
, uint32_t bandwidth
,
1023 int transmit_mode
, uint32_t guard
, int hierarchy
)
1025 uint32_t mod
= dvb_parse_modulation (modstr
, QAM_AUTO
);
1026 fec_hp
= dvb_parse_fec (fec_hp
);
1027 fec_lp
= dvb_parse_fec (fec_lp
);
1028 bandwidth
= dvb_parse_bandwidth (bandwidth
);
1029 transmit_mode
= dvb_parse_transmit_mode (transmit_mode
);
1030 guard
= dvb_parse_guard (guard
);
1031 hierarchy
= dvb_parse_hierarchy (hierarchy
);
1033 if (dvb_find_frontend (d
, DTV_DELIVERY_DVB_T
))
1035 return dvb_set_props (d
, 10, DTV_CLEAR
, 0, DTV_DELIVERY_SYSTEM
, SYS_DVBT
,
1036 DTV_FREQUENCY
, freq
, DTV_MODULATION
, mod
,
1037 DTV_CODE_RATE_HP
, fec_hp
, DTV_CODE_RATE_LP
, fec_lp
,
1038 DTV_BANDWIDTH_HZ
, bandwidth
,
1039 DTV_TRANSMISSION_MODE
, transmit_mode
,
1040 DTV_GUARD_INTERVAL
, guard
,
1041 DTV_HIERARCHY
, hierarchy
);
1044 int dvb_set_dvbt2 (dvb_device_t
*d
, uint32_t freq
, const char *modstr
,
1045 uint32_t fec
, uint32_t bandwidth
,
1046 int transmit_mode
, uint32_t guard
, uint8_t plp
)
1049 uint32_t mod
= dvb_parse_modulation (modstr
, QAM_AUTO
);
1050 fec
= dvb_parse_fec (fec
);
1051 bandwidth
= dvb_parse_bandwidth (bandwidth
);
1052 transmit_mode
= dvb_parse_transmit_mode (transmit_mode
);
1053 guard
= dvb_parse_guard (guard
);
1055 if (dvb_find_frontend (d
, DVB_T2
))
1057 return dvb_set_props (d
, 9, DTV_CLEAR
, 0, DTV_DELIVERY_SYSTEM
, SYS_DVBT2
,
1058 DTV_FREQUENCY
, freq
, DTV_MODULATION
, mod
,
1059 DTV_INNER_FEC
, fec
, DTV_BANDWIDTH_HZ
, bandwidth
,
1060 DTV_TRANSMISSION_MODE
, transmit_mode
,
1061 DTV_GUARD_INTERVAL
, guard
,
1069 # warning DVB-T2 needs Linux DVB version 5.3 or later.
1070 msg_Err (d
->obj
, "DVB-T2 support not compiled-in");
1071 (void) freq
; (void) modstr
; (void) fec
; (void) bandwidth
;
1072 (void) transmit_mode
; (void) guard
;
1079 int dvb_set_isdbc (dvb_device_t
*d
, uint32_t freq
, const char *modstr
,
1080 uint32_t srate
, uint32_t fec
)
1082 unsigned mod
= dvb_parse_modulation (modstr
, QAM_AUTO
);
1083 fec
= dvb_parse_fec (fec
);
1085 if (dvb_find_frontend (d
, DTV_DELIVERY_ISDB_C
))
1087 return dvb_set_props (d
, 6, DTV_CLEAR
, 0,
1089 DTV_DELIVERY_SYSTEM
, SYS_DVBC_ANNEX_C
,
1091 # warning ISDB-C might need Linux DVB version 5.5 or later.
1092 DTV_DELIVERY_SYSTEM
, SYS_DVBC_ANNEX_AC
,
1094 DTV_FREQUENCY
, freq
, DTV_MODULATION
, mod
,
1095 DTV_SYMBOL_RATE
, srate
, DTV_INNER_FEC
, fec
);
1100 int dvb_set_isdbs (dvb_device_t
*d
, uint64_t freq_Hz
, uint16_t ts_id
)
1102 uint32_t freq
= freq_Hz
/ 1000;
1104 if (dvb_find_frontend (d
, DTV_DELIVERY_ISDB_S
))
1106 return dvb_set_props (d
, 4, DTV_CLEAR
, 0, DTV_DELIVERY_SYSTEM
, SYS_ISDBS
,
1107 DTV_FREQUENCY
, freq
,
1118 static int dvb_set_isdbt_layer (dvb_device_t
*d
, unsigned num
,
1119 const isdbt_layer_t
*l
)
1121 uint32_t mod
= dvb_parse_modulation (l
->modulation
, QAM_AUTO
);
1122 uint32_t fec
= dvb_parse_fec (l
->code_rate
);
1123 uint32_t count
= l
->segment_count
;
1124 uint32_t ti
= l
->time_interleaving
;
1126 num
*= DTV_ISDBT_LAYERB_FEC
- DTV_ISDBT_LAYERA_FEC
;
1128 return dvb_set_props (d
, 5, DTV_DELIVERY_SYSTEM
, SYS_ISDBT
,
1129 DTV_ISDBT_LAYERA_FEC
+ num
, fec
,
1130 DTV_ISDBT_LAYERA_MODULATION
+ num
, mod
,
1131 DTV_ISDBT_LAYERA_SEGMENT_COUNT
+ num
, count
,
1132 DTV_ISDBT_LAYERA_TIME_INTERLEAVING
+ num
, ti
);
1135 int dvb_set_isdbt (dvb_device_t
*d
, uint32_t freq
, uint32_t bandwidth
,
1136 int transmit_mode
, uint32_t guard
,
1137 const isdbt_layer_t layers
[3])
1139 bandwidth
= dvb_parse_bandwidth (bandwidth
);
1140 transmit_mode
= dvb_parse_transmit_mode (transmit_mode
);
1141 guard
= dvb_parse_guard (guard
);
1143 if (dvb_find_frontend (d
, DTV_DELIVERY_ISDB_T
))
1145 if (dvb_set_props (d
, 6, DTV_CLEAR
, 0, DTV_DELIVERY_SYSTEM
, SYS_ISDBT
,
1146 DTV_FREQUENCY
, freq
, DTV_BANDWIDTH_HZ
, bandwidth
,
1147 DTV_GUARD_INTERVAL
, guard
,
1148 DTV_ISDBT_LAYER_ENABLED
, 0x7 /* all layers enabled */))
1150 for (unsigned i
= 0; i
< 3; i
++)
1151 if (dvb_set_isdbt_layer (d
, i
, layers
+ i
))
1158 int dvb_set_atsc (dvb_device_t
*d
, uint32_t freq
, const char *modstr
)
1160 unsigned mod
= dvb_parse_modulation (modstr
, VSB_8
);
1162 if (dvb_find_frontend (d
, DTV_DELIVERY_ATSC
))
1164 return dvb_set_props (d
, 4, DTV_CLEAR
, 0, DTV_DELIVERY_SYSTEM
, SYS_ATSC
,
1165 DTV_FREQUENCY
, freq
, DTV_MODULATION
, mod
);
1168 int dvb_set_cqam (dvb_device_t
*d
, uint32_t freq
, const char *modstr
)
1170 unsigned mod
= dvb_parse_modulation (modstr
, QAM_AUTO
);
1172 if (dvb_find_frontend (d
, DTV_DELIVERY_CQAM
))
1174 return dvb_set_props (d
, 4, DTV_CLEAR
, 0,
1175 DTV_DELIVERY_SYSTEM
, SYS_DVBC_ANNEX_B
,
1176 DTV_FREQUENCY
, freq
, DTV_MODULATION
, mod
);