3 * @brief Linux DVB API version 5
5 /*****************************************************************************
6 * Copyright © 2011 Rémi Denis-Courmont
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
13 * This library 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 General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 ****************************************************************************/
27 #include <vlc_common.h>
34 #include <sys/ioctl.h>
35 #include <linux/dvb/version.h>
36 #include <linux/dvb/frontend.h>
37 #include <linux/dvb/dmx.h>
41 # 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)))
52 # error Linux DVB kernel headers version 2.6.28 or later required.
55 /** Opens the device directory for the specified DVB adapter */
56 static int dvb_open_adapter (uint8_t adapter)
60 snprintf (dir, sizeof (dir), "/dev/dvb/adapter%"PRIu8, adapter);
61 return open (dir, O_SEARCH|O_DIRECTORY|O_CLOEXEC);
64 /** Opens the DVB device node of the specified type */
65 static int dvb_open_node (int dir, const char *type, unsigned dev, int flags)
68 char path[strlen (type) + 4];
70 snprintf (path, sizeof (path), "%s%"PRIu8, type, dev);
71 fd = openat (dir, path, flags|O_CLOEXEC);
73 fcntl (fd, F_SETFL, fcntl (fd, F_GETFL) | O_NONBLOCK);
83 static int icmp (const void *a, const void *b)
85 int key = (intptr_t)a;
86 const dvb_int_map_t *entry = b;
87 return key - entry->vlc;
90 /** Maps a VLC config integer to a Linux DVB enum value */
91 static int dvb_parse_int (int i, const dvb_int_map_t *map, size_t n, int def)
93 const void *k = (const void *)(intptr_t)i;
94 const dvb_int_map_t *p = bsearch (k, map, n, sizeof (*map), icmp);
95 return (p != NULL) ? p->linux_ : def;
104 static int scmp (const void *a, const void *b)
107 dvb_str_map_t *entry = b;
108 return strcmp (key, entry->vlc);
111 /** Maps a VLC config string to a Linux DVB enum value */
112 static int dvb_parse_str (const char *str, const dvb_str_map_t *map, size_t n,
117 const dvb_str_map_t *p = bsearch (str, map, n, sizeof (*map), scmp);
124 /*** Modulations ***/
125 static int dvb_parse_modulation (const char *str, int def)
127 static const dvb_str_map_t mods[] =
129 { "128QAM", QAM_128 },
130 { "16APSK", APSK_16 },
133 { "256QAM", QAM_256 },
134 { "32APSK", APSK_32 },
143 return dvb_parse_str (str, mods, sizeof (mods) / sizeof (*mods), def);
146 static int dvb_parse_fec (uint32_t fec)
148 static const dvb_int_map_t rates[] =
151 { VLC_FEC(1,2), FEC_1_2 },
154 { VLC_FEC(2,3), FEC_2_3 },
155 { VLC_FEC(3,4), FEC_3_4 },
156 { VLC_FEC(3,5), FEC_3_5 },
157 { VLC_FEC(4,5), FEC_4_5 },
158 { VLC_FEC(5,6), FEC_5_6 },
159 { VLC_FEC(6,7), FEC_6_7 },
160 { VLC_FEC(7,8), FEC_7_8 },
161 { VLC_FEC(8,9), FEC_8_9 },
162 { VLC_FEC(9,10), FEC_9_10 },
163 { VLC_FEC_AUTO, FEC_AUTO },
165 return dvb_parse_int (fec, rates, sizeof (rates) / sizeof (*rates),
177 # define MAX_PIDS 256
187 struct dvb_frontend_info info;
189 //size_t buffer_size;
193 * Opens the DVB tuner
195 dvb_device_t *dvb_open (vlc_object_t *obj)
197 dvb_device_t *d = malloc (sizeof (*d));
198 if (unlikely(d == NULL))
203 uint8_t adapter = var_InheritInteger (obj, "dvb-adapter");
205 d->dir = dvb_open_adapter (adapter);
208 msg_Err (obj, "cannot access adapter %"PRIu8": %m", adapter);
216 d->budget = var_InheritBool (obj, "dvb-budget-mode");
222 d->demux = dvb_open_node (d->dir, "demux", 0, O_RDONLY);
225 msg_Err (obj, "cannot access demultiplexer: %m");
231 if (ioctl (d->demux, DMX_SET_BUFFER_SIZE, 1 << 20) < 0)
232 msg_Warn (obj, "cannot expand demultiplexing buffer: %m");
234 /* We need to filter at least one PID. The tap for TS demultiplexing
235 * cannot be configured otherwise. So add the PAT. */
236 struct dmx_pes_filter_params param;
238 param.pid = d->budget ? 0x2000 : 0x000;
239 param.input = DMX_IN_FRONTEND;
240 param.output = DMX_OUT_TSDEMUX_TAP;
241 param.pes_type = DMX_PES_OTHER;
242 param.flags = DMX_IMMEDIATE_START;
243 if (ioctl (d->demux, DMX_SET_PES_FILTER, ¶m) < 0)
245 msg_Err (obj, "cannot setup TS demultiplexer: %m");
252 for (size_t i = 0; i < MAX_PIDS; i++)
253 d->pids[i].pid = d->pids[i].fd = -1;
254 d->demux = dvb_open_node (d->dir, "dvr", 0, O_RDONLY);
257 msg_Err (obj, "cannot access DVR: %m");
266 int ca = dvb_open_node (d->dir, "ca", 0, O_RDWR);
269 d->cam = en50221_Init (obj, ca);
274 msg_Dbg (obj, "conditional access module not available (%m)");
283 void dvb_close (dvb_device_t *d)
288 for (size_t i = 0; i < MAX_PIDS; i++)
289 if (d->pids[i].fd != -1)
290 close (d->pids[i].fd);
295 en50221_End (d->cam);
297 if (d->frontend != -1)
305 * Reads TS data from the tuner.
306 * @return number of bytes read, 0 on EOF, -1 if no data (yet).
308 ssize_t dvb_read (dvb_device_t *d, void *buf, size_t len)
310 struct pollfd ufd[2];
315 en50221_Poll (d->cam);
318 ufd[0].fd = d->demux;
319 ufd[0].events = POLLIN;
320 if (d->frontend != -1)
322 ufd[1].fd = d->frontend;
323 ufd[1].events = POLLIN;
329 if (poll (ufd, n, 500 /* FIXME */) < 0)
332 if (d->frontend != -1 && ufd[1].revents)
334 struct dvb_frontend_event ev;
336 if (ioctl (d->frontend, FE_GET_EVENT, &ev) < 0)
338 if (errno == EOVERFLOW)
340 msg_Err (d->obj, "cannot dequeue events fast enough!");
343 msg_Err (d->obj, "cannot dequeue frontend event: %m");
347 msg_Dbg (d->obj, "frontend status: 0x%02X", (unsigned)ev.status);
352 ssize_t val = read (d->demux, buf, len);
353 if (val == -1 && (errno != EAGAIN && errno != EINTR))
355 if (errno == EOVERFLOW)
357 msg_Err (d->obj, "cannot demux data fast enough!");
360 msg_Err (d->obj, "cannot demux: %m");
369 int dvb_add_pid (dvb_device_t *d, uint16_t pid)
374 if (pid == 0 || ioctl (d->demux, DMX_ADD_PID, &pid) >= 0)
377 for (size_t i = 0; i < MAX_PIDS; i++)
379 if (d->pids[i].pid == pid)
381 if (d->pids[i].fd != -1)
384 int fd = dvb_open_node (d->dir, "demux", 0, O_RDONLY);
388 /* We need to filter at least one PID. The tap for TS demultiplexing
389 * cannot be configured otherwise. So add the PAT. */
390 struct dmx_pes_filter_params param;
393 param.input = DMX_IN_FRONTEND;
394 param.output = DMX_OUT_TS_TAP;
395 param.pes_type = DMX_PES_OTHER;
396 param.flags = DMX_IMMEDIATE_START;
397 if (ioctl (fd, DMX_SET_PES_FILTER, ¶m) < 0)
403 d->pids[i].pid = pid;
409 msg_Err (d->obj, "cannot add PID 0x%04"PRIu16": %m", pid);
413 void dvb_remove_pid (dvb_device_t *d, uint16_t pid)
419 ioctl (d->demux, DMX_REMOVE_PID, &pid);
421 for (size_t i = 0; i < MAX_PIDS; i++)
423 if (d->pids[i].pid == pid)
425 close (d->pids[i].fd);
426 d->pids[i].pid = d->pids[i].fd = -1;
433 /** Finds a frontend of the correct type */
434 static int dvb_find_frontend (dvb_device_t *d, fe_type_t type, fe_caps_t caps)
436 if (d->frontend != -1)
438 if (d->info.type == type || (d->info.caps & caps) == caps)
439 return 0; /* already got an adequate frontend */
445 for (unsigned n = 0; n < 256; n++)
447 int fd = dvb_open_node (d->dir, "frontend", n, O_RDWR);
451 break; /* all frontends already enumerated */
452 msg_Err (d->obj, "cannot access frontend %u; %m", n);
456 if (ioctl (fd, FE_GET_INFO, &d->info) < 0)
458 msg_Err (d->obj, "cannot get frontend %u info: %m", n);
462 msg_Dbg (d->obj, "probing frontend %u: %s", n, d->info.name);
463 msg_Dbg (d->obj, " type %u, capabilities 0x%08X", d->info.type,
465 msg_Dbg (d->obj, " frequencies %10"PRIu32" to %10"PRIu32,
466 d->info.frequency_min, d->info.frequency_max);
467 msg_Dbg (d->obj, " (%"PRIu32" tolerance, %"PRIu32" per step)",
468 d->info.frequency_tolerance, d->info.frequency_stepsize);
469 msg_Dbg (d->obj, " bauds rates %10"PRIu32" to %10"PRIu32,
470 d->info.symbol_rate_min, d->info.symbol_rate_max);
471 msg_Dbg (d->obj, " (%"PRIu32" tolerance)",
472 d->info.symbol_rate_tolerance);
474 if (d->info.type != type || (d->info.caps & caps) != caps)
476 msg_Dbg (d->obj, "skipping frontend %u: wrong type", n);
480 msg_Dbg (d->obj, "selected frontend %u", n);
488 msg_Err (d->obj, "no suitable frontend found");
493 * Detects supported delivery systems.
494 * @return a bit mask of supported systems (zero on failure)
496 unsigned dvb_enum_systems (dvb_device_t *d)
498 unsigned systems = 0;
500 for (unsigned n = 0; n < 256; n++)
502 int fd = dvb_open_node (d->dir, "frontend", n, O_RDWR);
506 break; /* all frontends already enumerated */
507 msg_Err (d->obj, "cannot access frontend %u; %m", n);
511 struct dvb_frontend_info info;
512 if (ioctl (fd, FE_GET_INFO, &info) < 0)
514 msg_Err (d->obj, "cannot get frontend %u info: %m", n);
520 /* Linux DVB lacks detection for non-DVB/non-ATSC demods */
521 static const unsigned types[] = {
528 if (((unsigned)info.type) >= sizeof (types) / sizeof (types[0]))
530 msg_Err (d->obj, "unknown frontend type %u", info.type);
534 unsigned sys = types[info.type];
535 if (info.caps & FE_CAN_2G_MODULATION)
536 sys |= sys << 1; /* DVB_foo -> DVB_foo|DVB_foo2 */
542 float dvb_get_signal_strength (dvb_device_t *d)
546 if (ioctl (d->frontend, FE_READ_SIGNAL_STRENGTH, &strength) < 0)
548 return strength / 65535.;
551 float dvb_get_snr (dvb_device_t *d)
555 if (ioctl (d->frontend, FE_READ_SNR, &snr) < 0)
561 void dvb_set_ca_pmt (dvb_device_t *d, struct dvbpsi_pmt_s *pmt)
564 en50221_SetCAPMT (d->cam, pmt);
568 static int dvb_vset_props (dvb_device_t *d, size_t n, va_list ap)
570 struct dtv_property buf[n], *prop = buf;
571 struct dtv_properties props = { .num = n, .props = buf };
573 memset (prop, 0, sizeof (prop));
577 prop->cmd = va_arg (ap, uint32_t);
578 prop->u.data = va_arg (ap, uint32_t);
579 msg_Dbg (d->obj, "setting property %2"PRIu32" to %"PRIu32,
580 prop->cmd, prop->u.data);
585 if (ioctl (d->frontend, FE_SET_PROPERTY, &props) < 0)
587 msg_Err (d->obj, "cannot set frontend tuning parameters: %m");
593 static int dvb_set_props (dvb_device_t *d, size_t n, ...)
599 ret = dvb_vset_props (d, n, ap);
604 static int dvb_set_prop (dvb_device_t *d, uint32_t prop, uint32_t val)
606 return dvb_set_props (d, 1, prop, val);
609 int dvb_set_inversion (dvb_device_t *d, int v)
613 case 0: v = INVERSION_OFF; break;
614 case 1: v = INVERSION_ON; break;
615 default: v = INVERSION_AUTO; break;
617 return dvb_set_prop (d, DTV_INVERSION, v);
620 int dvb_tune (dvb_device_t *d)
622 return dvb_set_prop (d, DTV_TUNE, 0 /* dummy */);
627 int dvb_set_dvbc (dvb_device_t *d, uint32_t freq, const char *modstr,
628 uint32_t srate, uint32_t fec)
630 unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
631 fec = dvb_parse_fec (fec);
633 if (dvb_find_frontend (d, FE_QAM, FE_IS_STUPID))
635 return dvb_set_props (d, 6, DTV_CLEAR, 0,
636 DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_AC,
637 DTV_FREQUENCY, freq, DTV_MODULATION, mod,
638 DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec);
643 static unsigned dvb_parse_polarization (char pol)
645 static const dvb_int_map_t tab[5] = {
646 { 0, SEC_VOLTAGE_OFF },
647 { 'H', SEC_VOLTAGE_18 },
648 { 'L', SEC_VOLTAGE_18 },
649 { 'R', SEC_VOLTAGE_13 },
650 { 'V', SEC_VOLTAGE_13 },
652 return dvb_parse_int (pol, tab, 5, SEC_VOLTAGE_OFF);
655 int dvb_set_sec (dvb_device_t *d, uint64_t freq_Hz, char pol,
656 uint32_t lowf, uint32_t highf, uint32_t switchf)
658 uint32_t freq = freq_Hz / 1000;
660 /* Always try to configure high voltage, but only warn on enable failure */
661 int val = var_InheritBool (d->obj, "dvb-high-voltage");
662 if (ioctl (d->frontend, FE_ENABLE_HIGH_LNB_VOLTAGE, &val) < 0 && val)
663 msg_Err (d->obj, "cannot enable high LNB voltage: %m");
665 /* Windows BDA exposes a higher-level API covering LNB oscillators.
666 * So lets pretend this is platform-specific stuff and do it here. */
668 { /* Default oscillator frequencies */
671 uint16_t min, max, low, high;
673 { /* min max low high */
674 { 10700, 13250, 9750, 10600 }, /* Ku band */
675 { 4500, 4800, 5950, 0 }, /* C band (high) */
676 { 3400, 4200, 5150, 0 }, /* C band (low) */
677 { 2500, 2700, 3650, 0 }, /* S band */
678 { 950, 2150, 0, 0 }, /* adjusted IF (L band) */
680 uint_fast16_t mHz = freq / 1000;
682 for (size_t i = 0; i < sizeof (tab) / sizeof (tab[0]); i++)
683 if (mHz >= tab[i].min && mHz <= tab[i].max)
685 lowf = tab[i].low * 1000;
686 highf = tab[i].high * 1000;
690 msg_Err (d->obj, "no known band for frequency %u kHz", freq);
692 msg_Dbg (d->obj, "selected LNB low: %u kHz, LNB high: %u kHz",
696 /* Use high oscillator frequency? */
697 bool high = highf != 0 && freq > switchf;
699 freq -= high ? highf : lowf;
700 if ((int32_t)freq < 0)
702 assert (freq < 0x7fffffff);
705 switch (var_InheritInteger (d->obj, "dvb-tone"))
707 case 0: tone = SEC_TONE_OFF; break;
708 case 1: tone = SEC_TONE_ON; break;
709 default: tone = high ? SEC_TONE_ON : SEC_TONE_OFF;
712 /*** LNB selection / DiSEqC ***/
713 unsigned voltage = dvb_parse_polarization (pol);
714 if (dvb_set_props (d, 2, DTV_TONE, SEC_TONE_OFF, DTV_VOLTAGE, voltage))
717 unsigned satno = var_InheritInteger (d->obj, "dvb-satno");
721 #undef msleep /* we know what we are doing! */
722 struct dvb_diseqc_master_cmd cmd;
724 satno = (satno - 1) & 3;
725 cmd.msg[0] = 0xE0; /* framing: master, no reply, 1st TX */
726 cmd.msg[1] = 0x10; /* address: all LNB/switch */
727 cmd.msg[2] = 0x38; /* command: Write Port Group 0 */
728 cmd.msg[3] = 0xF0 /* data[0]: clear all bits */
729 | (satno << 2) /* LNB (A, B, C or D) */
730 | ((voltage == SEC_VOLTAGE_18) << 1) /* polarization */
731 | (tone == SEC_TONE_ON); /* option */
732 cmd.msg[4] = cmd.msg[5] = 0; /* unused */
733 msleep (15000); /* wait 15 ms before DiSEqC command */
734 if (ioctl (d->frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) < 0)
736 msg_Err (d->obj, "cannot send DiSEqC command: %m");
739 msleep (54000 + 15000);
743 if (ioctl (d->frontend, FE_DISEQC_SEND_BURST,
744 satno ? SEC_MINI_B : SEC_MINI_A) < 0)
746 msg_Err (d->obj, "cannot send Mini-DiSEqC tone burst: %m");
752 /* Continuous tone (to select high oscillator frequency) */
753 return dvb_set_props (d, 2, DTV_FREQUENCY, freq, DTV_TONE, tone);
756 int dvb_set_dvbs (dvb_device_t *d, uint64_t freq_Hz,
757 uint32_t srate, uint32_t fec)
759 uint32_t freq = freq_Hz / 1000;
760 fec = dvb_parse_fec (fec);
762 if (dvb_find_frontend (d, FE_QPSK, FE_IS_STUPID))
764 return dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBS,
765 DTV_FREQUENCY, freq, DTV_SYMBOL_RATE, srate,
769 int dvb_set_dvbs2 (dvb_device_t *d, uint64_t freq_Hz, const char *modstr,
770 uint32_t srate, uint32_t fec, int pilot, int rolloff)
772 uint32_t freq = freq_Hz / 1000;
773 unsigned mod = dvb_parse_modulation (modstr, QPSK);
774 fec = dvb_parse_fec (fec);
778 case 0: pilot = PILOT_OFF; break;
779 case 1: pilot = PILOT_ON; break;
780 default: pilot = PILOT_AUTO; break;
785 case 20: rolloff = ROLLOFF_20; break;
786 case 25: rolloff = ROLLOFF_25; break;
787 case 35: rolloff = ROLLOFF_35; break;
788 default: rolloff = PILOT_AUTO; break;
791 if (dvb_find_frontend (d, FE_QPSK, FE_CAN_2G_MODULATION))
793 return dvb_set_props (d, 8, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBS2,
794 DTV_FREQUENCY, freq, DTV_MODULATION, mod,
795 DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec,
796 DTV_PILOT, pilot, DTV_ROLLOFF, rolloff);
801 static uint32_t dvb_parse_bandwidth (uint32_t i)
806 case 2: return 1712000;
807 default: return i * 1000000;
811 static int dvb_parse_transmit_mode (int i)
813 static const dvb_int_map_t tab[] = {
814 { -1, TRANSMISSION_MODE_AUTO },
816 { 1, TRANSMISSION_MODE_1K },
818 { 2, TRANSMISSION_MODE_2K },
820 { 4, TRANSMISSION_MODE_4K },
822 { 8, TRANSMISSION_MODE_8K },
824 { 16, TRANSMISSION_MODE_16K },
825 { 32, TRANSMISSION_MODE_32K },
828 return dvb_parse_int (i, tab, sizeof (tab) / sizeof (*tab),
829 TRANSMISSION_MODE_AUTO);
832 static int dvb_parse_guard (uint32_t guard)
834 static const dvb_int_map_t tab[] = {
835 { VLC_GUARD(1,4), GUARD_INTERVAL_1_4 },
836 { VLC_GUARD(1,8), GUARD_INTERVAL_1_8 },
837 { VLC_GUARD(1,16), GUARD_INTERVAL_1_16 },
838 { VLC_GUARD(1,32), GUARD_INTERVAL_1_32 },
840 { VLC_GUARD(1,128), GUARD_INTERVAL_1_128 },
841 { VLC_GUARD(19,128), GUARD_INTERVAL_19_128 },
842 { VLC_GUARD(19,256), GUARD_INTERVAL_19_256 },
844 { VLC_GUARD_AUTO, GUARD_INTERVAL_AUTO },
846 return dvb_parse_int (guard, tab, sizeof (tab) / sizeof (*tab),
847 GUARD_INTERVAL_AUTO);
850 static int dvb_parse_hierarchy (int i)
852 static const dvb_int_map_t tab[] = {
853 { HIERARCHY_AUTO, -1 },
854 { HIERARCHY_NONE, 0 },
859 return dvb_parse_int (i, tab, sizeof (tab) / sizeof (*tab),
863 int dvb_set_dvbt (dvb_device_t *d, uint32_t freq, const char *modstr,
864 uint32_t fec_hp, uint32_t fec_lp, uint32_t bandwidth,
865 int transmit_mode, uint32_t guard, int hierarchy)
867 uint32_t mod = dvb_parse_modulation (modstr, QAM_AUTO);
868 fec_hp = dvb_parse_fec (fec_hp);
869 fec_lp = dvb_parse_fec (fec_lp);
870 bandwidth = dvb_parse_bandwidth (bandwidth);
871 transmit_mode = dvb_parse_transmit_mode (transmit_mode);
872 guard = dvb_parse_guard (guard);
873 hierarchy = dvb_parse_hierarchy (hierarchy);
875 if (dvb_find_frontend (d, FE_OFDM, FE_IS_STUPID))
877 return dvb_set_props (d, 10, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBT,
878 DTV_FREQUENCY, freq, DTV_MODULATION, mod,
879 DTV_CODE_RATE_HP, fec_hp, DTV_CODE_RATE_LP, fec_lp,
880 DTV_BANDWIDTH_HZ, bandwidth,
881 DTV_TRANSMISSION_MODE, transmit_mode,
882 DTV_GUARD_INTERVAL, guard,
883 DTV_HIERARCHY, hierarchy);
886 int dvb_set_dvbt2 (dvb_device_t *d, uint32_t freq, const char *modstr,
887 uint32_t fec, uint32_t bandwidth,
888 int transmit_mode, uint32_t guard)
891 uint32_t mod = dvb_parse_modulation (modstr, QAM_AUTO);
892 fec = dvb_parse_fec (fec);
893 bandwidth = dvb_parse_bandwidth (bandwidth);
894 transmit_mode = dvb_parse_transmit_mode (transmit_mode);
895 guard = dvb_parse_guard (guard);
897 if (dvb_find_frontend (d, FE_OFDM, FE_CAN_2G_MODULATION))
899 return dvb_set_props (d, 8, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBT2,
900 DTV_FREQUENCY, freq, DTV_MODULATION, mod,
901 DTV_INNER_FEC, fec, DTV_BANDWIDTH_HZ, bandwidth,
902 DTV_TRANSMISSION_MODE, transmit_mode,
903 DTV_GUARD_INTERVAL, guard);
905 # warning DVB-T2 needs Linux DVB version 5.3 or later.
906 msg_Err (d->obj, "DVB-T2 support not compiled-in");
907 (void) freq; (void) modstr; (void) fec; (void) bandwidth;
908 (void) transmit_mode; (void) guard;
915 int dvb_set_isdbs (dvb_device_t *d, uint64_t freq_Hz, uint16_t ts_id)
918 uint32_t freq = freq_Hz / 1000;
920 if (dvb_find_frontend (d, FE_QPSK, FE_IS_STUPID))
922 return dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ISDBS,
924 DTV_ISDBS_TS_ID, (uint32_t)ts_id);
926 # warning ISDB-S needs Linux DVB version 5.1 or later.
933 static int dvb_set_isdbt_layer (dvb_device_t *d, unsigned num,
934 const isdbt_layer_t *l)
936 uint32_t mod = dvb_parse_modulation (l->modulation, QAM_AUTO);
937 uint32_t fec = dvb_parse_fec (l->code_rate);
938 uint32_t count = l->segment_count;
939 uint32_t ti = l->time_interleaving;
941 num *= DTV_ISDBT_LAYERB_FEC - DTV_ISDBT_LAYERA_FEC;
943 return dvb_set_props (d, 5, DTV_DELIVERY_SYSTEM, SYS_ISDBT,
944 DTV_ISDBT_LAYERA_FEC + num, fec,
945 DTV_ISDBT_LAYERA_MODULATION + num, mod,
946 DTV_ISDBT_LAYERA_SEGMENT_COUNT + num, count,
947 DTV_ISDBT_LAYERA_TIME_INTERLEAVING + num, ti);
951 int dvb_set_isdbt (dvb_device_t *d, uint32_t freq, uint32_t bandwidth,
952 int transmit_mode, uint32_t guard,
953 const isdbt_layer_t layers[3])
956 bandwidth = dvb_parse_bandwidth (bandwidth);
957 transmit_mode = dvb_parse_transmit_mode (transmit_mode);
958 guard = dvb_parse_guard (guard);
960 if (dvb_find_frontend (d, FE_OFDM, FE_IS_STUPID))
962 if (dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ISDBT,
963 DTV_FREQUENCY, freq, DTV_BANDWIDTH_HZ, bandwidth,
964 DTV_GUARD_INTERVAL, guard))
966 for (unsigned i = 0; i < 3; i++)
967 if (dvb_set_isdbt_layer (d, i, layers + i))
971 # warning ISDB-T needs Linux DVB version 5.1 or later.
972 msg_Err (d->obj, "ISDB-T support not compiled-in");
973 (void) freq; (void) bandwidth; (void) transmit_mode; (void) guard;
981 int dvb_set_atsc (dvb_device_t *d, uint32_t freq, const char *modstr)
983 unsigned mod = dvb_parse_modulation (modstr, VSB_8);
985 if (dvb_find_frontend (d, FE_ATSC, FE_IS_STUPID))
987 return dvb_set_props (d, 4, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ATSC,
988 DTV_FREQUENCY, freq, DTV_MODULATION, mod);
991 int dvb_set_cqam (dvb_device_t *d, uint32_t freq, const char *modstr)
993 unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
995 if (dvb_find_frontend (d, FE_QAM, FE_IS_STUPID))
997 return dvb_set_props (d, 4, DTV_CLEAR, 0,
998 DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_B,
999 DTV_FREQUENCY, freq, DTV_MODULATION, mod);