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>
35 #include <sys/ioctl.h>
36 #include <linux/dvb/version.h>
37 #include <linux/dvb/frontend.h>
38 #include <linux/dvb/dmx.h>
42 # include "dtv/en50221.h"
46 # define O_SEARCH O_RDONLY
49 #define DVBv5(minor) \
50 (DVB_API_VERSION > 5 \
51 || (DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= (minor)))
59 static int icmp (const void *a, const void *b)
61 int key = (intptr_t)a;
62 const dvb_int_map_t *entry = b;
63 return key - entry->vlc;
66 /** Maps a VLC config integer to a Linux DVB enum value */
67 static int dvb_parse_int (int i, const dvb_int_map_t *map, size_t n, int def)
69 const void *k = (const void *)(intptr_t)i;
70 const dvb_int_map_t *p = bsearch (k, map, n, sizeof (*map), icmp);
71 return (p != NULL) ? p->linux_ : def;
80 static int scmp (const void *a, const void *b)
83 dvb_str_map_t *entry = b;
84 return strcmp (key, entry->vlc);
87 /** Maps a VLC config string to a Linux DVB enum value */
88 static int dvb_parse_str (const char *str, const dvb_str_map_t *map, size_t n,
93 const dvb_str_map_t *p = bsearch (str, map, n, sizeof (*map), scmp);
100 /*** Modulations ***/
101 static int dvb_parse_modulation (const char *str, int def)
103 static const dvb_str_map_t mods[] =
105 { "128QAM", QAM_128 },
106 { "16APSK", APSK_16 },
109 { "256QAM", QAM_256 },
110 { "32APSK", APSK_32 },
119 return dvb_parse_str (str, mods, sizeof (mods) / sizeof (*mods), def);
122 static int dvb_parse_fec (uint32_t fec)
124 static const dvb_int_map_t rates[] =
127 { VLC_FEC(1,2), FEC_1_2 },
130 { VLC_FEC(2,3), FEC_2_3 },
131 { VLC_FEC(3,4), FEC_3_4 },
132 { VLC_FEC(3,5), FEC_3_5 },
133 { VLC_FEC(4,5), FEC_4_5 },
134 { VLC_FEC(5,6), FEC_5_6 },
135 { VLC_FEC(6,7), FEC_6_7 },
136 { VLC_FEC(7,8), FEC_7_8 },
137 { VLC_FEC(8,9), FEC_8_9 },
138 { VLC_FEC(9,10), FEC_9_10 },
139 { VLC_FEC_AUTO, FEC_AUTO },
141 return dvb_parse_int (fec, rates, sizeof (rates) / sizeof (*rates),
153 # define MAX_PIDS 256
165 //size_t buffer_size;
168 /** Opens the device directory for the specified DVB adapter */
169 static int dvb_open_adapter (uint8_t adapter)
173 snprintf (dir, sizeof (dir), "/dev/dvb/adapter%"PRIu8, adapter);
174 return vlc_open (dir, O_SEARCH|O_DIRECTORY);
177 /** Opens the DVB device node of the specified type */
178 static int dvb_open_node (dvb_device_t *d, const char *type, int flags)
180 char path[strlen (type) + 4];
182 snprintf (path, sizeof (path), "%s%u", type, d->device);
183 return vlc_openat (d->dir, path, flags | O_NONBLOCK);
187 * Opens the DVB tuner
189 dvb_device_t *dvb_open (vlc_object_t *obj)
191 dvb_device_t *d = malloc (sizeof (*d));
192 if (unlikely(d == NULL))
197 uint8_t adapter = var_InheritInteger (obj, "dvb-adapter");
198 d->device = var_InheritInteger (obj, "dvb-device");
200 d->dir = dvb_open_adapter (adapter);
203 msg_Err (obj, "cannot access adapter %"PRIu8": %s", adapter,
204 vlc_strerror_c(errno));
212 d->budget = var_InheritBool (obj, "dvb-budget-mode");
218 d->demux = dvb_open_node (d, "demux", O_RDONLY);
221 msg_Err (obj, "cannot access demultiplexer: %s",
222 vlc_strerror_c(errno));
228 if (ioctl (d->demux, DMX_SET_BUFFER_SIZE, 1 << 20) < 0)
229 msg_Warn (obj, "cannot expand demultiplexing buffer: %s",
230 vlc_strerror_c(errno));
232 /* We need to filter at least one PID. The tap for TS demultiplexing
233 * cannot be configured otherwise. So add the PAT. */
234 struct dmx_pes_filter_params param;
236 param.pid = d->budget ? 0x2000 : 0x000;
237 param.input = DMX_IN_FRONTEND;
238 param.output = DMX_OUT_TSDEMUX_TAP;
239 param.pes_type = DMX_PES_OTHER;
240 param.flags = DMX_IMMEDIATE_START;
241 if (ioctl (d->demux, DMX_SET_PES_FILTER, ¶m) < 0)
243 msg_Err (obj, "cannot setup TS demultiplexer: %s",
244 vlc_strerror_c(errno));
251 for (size_t i = 0; i < MAX_PIDS; i++)
252 d->pids[i].pid = d->pids[i].fd = -1;
253 d->demux = dvb_open_node (d, "dvr", O_RDONLY);
256 msg_Err (obj, "cannot access DVR: %s", vlc_strerror_c(errno));
265 int ca = dvb_open_node (d, "ca", O_RDWR);
268 d->cam = en50221_Init (obj, ca);
273 msg_Dbg (obj, "conditional access module not available: %s",
274 vlc_strerror_c(errno));
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)
304 static void dvb_frontend_status(vlc_object_t *obj, fe_status_t s)
306 msg_Dbg(obj, "frontend status:");
309 msg_Dbg(obj, "\t%s", #f);
322 * Reads TS data from the tuner.
323 * @return number of bytes read, 0 on EOF, -1 if no data (yet).
325 ssize_t dvb_read (dvb_device_t *d, void *buf, size_t len)
327 struct pollfd ufd[2];
332 en50221_Poll (d->cam);
335 ufd[0].fd = d->demux;
336 ufd[0].events = POLLIN;
337 if (d->frontend != -1)
339 ufd[1].fd = d->frontend;
340 ufd[1].events = POLLIN;
346 if (poll (ufd, n, 500 /* FIXME */) < 0)
349 if (d->frontend != -1 && ufd[1].revents)
351 struct dvb_frontend_event ev;
353 if (ioctl (d->frontend, FE_GET_EVENT, &ev) < 0)
355 if (errno == EOVERFLOW)
357 msg_Err (d->obj, "cannot dequeue events fast enough!");
360 msg_Err (d->obj, "cannot dequeue frontend event: %s",
361 vlc_strerror_c(errno));
365 dvb_frontend_status(d->obj, ev.status);
370 ssize_t val = read (d->demux, buf, len);
371 if (val == -1 && (errno != EAGAIN && errno != EINTR))
373 if (errno == EOVERFLOW)
375 msg_Err (d->obj, "cannot demux data fast enough!");
378 msg_Err (d->obj, "cannot demux: %s", vlc_strerror_c(errno));
387 int dvb_add_pid (dvb_device_t *d, uint16_t pid)
392 if (pid == 0 || ioctl (d->demux, DMX_ADD_PID, &pid) >= 0)
395 for (size_t i = 0; i < MAX_PIDS; i++)
397 if (d->pids[i].pid == pid)
399 if (d->pids[i].fd != -1)
402 int fd = dvb_open_node (d, "demux", O_RDONLY);
406 /* We need to filter at least one PID. The tap for TS demultiplexing
407 * cannot be configured otherwise. So add the PAT. */
408 struct dmx_pes_filter_params param;
411 param.input = DMX_IN_FRONTEND;
412 param.output = DMX_OUT_TS_TAP;
413 param.pes_type = DMX_PES_OTHER;
414 param.flags = DMX_IMMEDIATE_START;
415 if (ioctl (fd, DMX_SET_PES_FILTER, ¶m) < 0)
421 d->pids[i].pid = pid;
427 msg_Err (d->obj, "cannot add PID 0x%04"PRIu16": %s", pid,
428 vlc_strerror_c(errno));
432 void dvb_remove_pid (dvb_device_t *d, uint16_t pid)
438 ioctl (d->demux, DMX_REMOVE_PID, &pid);
440 for (size_t i = 0; i < MAX_PIDS; i++)
442 if (d->pids[i].pid == pid)
444 close (d->pids[i].fd);
445 d->pids[i].pid = d->pids[i].fd = -1;
452 /** Finds a frontend of the correct type */
453 static int dvb_open_frontend (dvb_device_t *d)
455 if (d->frontend != -1)
457 int fd = dvb_open_node (d, "frontend", O_RDWR);
460 msg_Err (d->obj, "cannot access frontend: %s", vlc_strerror_c(errno));
467 #define dvb_find_frontend(d, sys) (dvb_open_frontend(d))
470 * Detects supported delivery systems.
471 * @return a bit mask of supported systems (zero on failure)
473 unsigned dvb_enum_systems (dvb_device_t *d)
475 if (dvb_open_frontend (d))
478 struct dtv_property prop[2] = {
479 { .cmd = DTV_API_VERSION },
480 { .cmd = DTV_ENUM_DELSYS },
482 struct dtv_properties props = {
487 if (ioctl (d->frontend, FE_GET_PROPERTY, &props) < 0)
489 msg_Err (d->obj, "cannot enumerate frontend systems: %s",
490 vlc_strerror_c(errno));
494 static const unsigned systab[] = {
496 [SYS_DVBC_ANNEX_A] = DVB_C,
497 [SYS_DVBC_ANNEX_B] = CQAM,
501 [SYS_DVBS2] = DVB_S2,
503 [SYS_ISDBT] = ISDB_T,
504 [SYS_ISDBS] = ISDB_S,
505 [SYS_ISDBC] = ISDB_C, // no drivers exist (as of 3.3-rc6)
511 [SYS_DVBT2] = DVB_T2,
513 [SYS_DVBC_ANNEX_C] = ISDB_C, // another name for ISDB-C?
515 unsigned systems = 0;
517 msg_Dbg (d->obj, "probing frontend (kernel API v%u.%u, user API v%u.%u)",
518 prop[0].u.data >> 8, prop[0].u.data & 0xFF,
519 DVB_API_VERSION, DVB_API_VERSION_MINOR);
521 for (size_t i = 0; i < prop[1].u.buffer.len; i++)
523 unsigned sys = prop[1].u.buffer.data[i];
525 if (sys >= (sizeof (systab) / sizeof (systab[0])) || !systab[sys])
527 msg_Warn (d->obj, "unknown delivery system %u", sys);
530 msg_Dbg (d->obj, " system %u", sys);
531 systems |= systab[sys];
538 struct dtv_property prop[1] = {
539 { .cmd = DTV_API_VERSION },
541 struct dtv_properties props = {
545 unsigned systems = 0;
547 if (ioctl (d->frontend, FE_GET_PROPERTY, &props) < 0)
549 msg_Err (d->obj, "unsupported kernel DVB version 3 or older (%s)",
550 vlc_strerror_c(errno));
554 msg_Dbg (d->obj, "probing frontend (kernel API v%u.%u, user API v%u.%u)",
555 prop[0].u.data >> 8, prop[0].u.data & 0xFF,
556 DVB_API_VERSION, DVB_API_VERSION_MINOR);
558 /* Some delivery systems cannot be detected without the DVB API v5.5.
559 * To run correctly on recent kernels (Linux >= 3.3),
560 * VLC needs to be compiled with up-to-date kernel headers. */
561 if ((prop[0].u.data >> 8) > 5
562 || ((prop[0].u.data >> 8) == 5 && (prop[0].u.data & 0xFF) >= 5))
563 msg_Err (d->obj, "obsolete user API version running on a new kernel");
564 msg_Info (d->obj, "please recompile "PACKAGE_NAME" "PACKAGE_VERSION);
566 struct dvb_frontend_info info;
567 if (ioctl (d->frontend, FE_GET_INFO, &info) < 0)
569 msg_Err (d->obj, "cannot get frontend info: %s",
570 vlc_strerror_c(errno));
573 msg_Dbg (d->obj, " name %s", info.name);
574 msg_Dbg (d->obj, " type %u, capabilities 0x%08X", info.type, info.caps);
575 msg_Dbg (d->obj, " frequencies %10"PRIu32" to %10"PRIu32,
576 info.frequency_min, info.frequency_max);
577 msg_Dbg (d->obj, " (%"PRIu32" tolerance, %"PRIu32" per step)",
578 info.frequency_tolerance, info.frequency_stepsize);
579 msg_Dbg (d->obj, " bauds rates %10"PRIu32" to %10"PRIu32,
580 info.symbol_rate_min, info.symbol_rate_max);
581 msg_Dbg (d->obj, " (%"PRIu32" tolerance)", info.symbol_rate_tolerance);
583 /* DVB first generation and ATSC */
586 case FE_QPSK: systems = DVB_S; break;
587 case FE_QAM: systems = DVB_C; break;
588 case FE_OFDM: systems = DVB_T; break;
589 case FE_ATSC: systems = ATSC | CQAM; break;
591 msg_Err (d->obj, "unknown frontend type %u", info.type);
594 /* DVB 2nd generation */
600 if (info.caps & FE_CAN_2G_MODULATION)
601 systems |= systems << 1; /* DVB_foo -> DVB_foo|DVB_foo2 */
606 /* ISDB (only terrestrial before DVBv5.5) */
607 if (info.type == FE_OFDM)
613 float dvb_get_signal_strength (dvb_device_t *d)
617 if (d->frontend == -1
618 || ioctl (d->frontend, FE_READ_SIGNAL_STRENGTH, &strength) < 0)
620 return strength / 65535.;
623 float dvb_get_snr (dvb_device_t *d)
627 if (d->frontend == -1 || ioctl (d->frontend, FE_READ_SNR, &snr) < 0)
633 void dvb_set_ca_pmt (dvb_device_t *d, struct dvbpsi_pmt_s *pmt)
636 en50221_SetCAPMT (d->cam, pmt);
640 static int dvb_vset_props (dvb_device_t *d, size_t n, va_list ap)
642 assert (n <= DTV_IOCTL_MAX_MSGS);
644 struct dtv_property buf[n], *prop = buf;
645 struct dtv_properties props = { .num = n, .props = buf };
647 memset (buf, 0, sizeof (buf));
651 prop->cmd = va_arg (ap, uint32_t);
652 prop->u.data = va_arg (ap, uint32_t);
653 msg_Dbg (d->obj, "setting property %2"PRIu32" to %"PRIu32,
654 prop->cmd, prop->u.data);
659 if (ioctl (d->frontend, FE_SET_PROPERTY, &props) < 0)
661 msg_Err (d->obj, "cannot set frontend tuning parameters: %s",
662 vlc_strerror_c(errno));
668 static int dvb_set_props (dvb_device_t *d, size_t n, ...)
674 ret = dvb_vset_props (d, n, ap);
679 static int dvb_set_prop (dvb_device_t *d, uint32_t prop, uint32_t val)
681 return dvb_set_props (d, 1, prop, val);
684 int dvb_set_inversion (dvb_device_t *d, int v)
688 case 0: v = INVERSION_OFF; break;
689 case 1: v = INVERSION_ON; break;
690 default: v = INVERSION_AUTO; break;
692 return dvb_set_prop (d, DTV_INVERSION, v);
695 int dvb_tune (dvb_device_t *d)
697 return dvb_set_prop (d, DTV_TUNE, 0 /* dummy */);
702 int dvb_set_dvbc (dvb_device_t *d, uint32_t freq, const char *modstr,
703 uint32_t srate, uint32_t fec)
705 unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
706 fec = dvb_parse_fec (fec);
708 if (dvb_find_frontend (d, DVB_C))
710 return dvb_set_props (d, 6, DTV_CLEAR, 0,
712 DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_A,
714 DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_AC,
716 DTV_FREQUENCY, freq, DTV_MODULATION, mod,
717 DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec);
722 static unsigned dvb_parse_polarization (char pol)
724 static const dvb_int_map_t tab[5] = {
725 { 0, SEC_VOLTAGE_OFF },
726 { 'H', SEC_VOLTAGE_18 },
727 { 'L', SEC_VOLTAGE_18 },
728 { 'R', SEC_VOLTAGE_13 },
729 { 'V', SEC_VOLTAGE_13 },
731 return dvb_parse_int (pol, tab, 5, SEC_VOLTAGE_OFF);
734 int dvb_set_sec (dvb_device_t *d, uint64_t freq_Hz, char pol,
735 uint32_t lowf, uint32_t highf, uint32_t switchf)
737 uint32_t freq = freq_Hz / 1000;
739 /* Always try to configure high voltage, but only warn on enable failure */
740 int val = var_InheritBool (d->obj, "dvb-high-voltage");
741 if (ioctl (d->frontend, FE_ENABLE_HIGH_LNB_VOLTAGE, &val) < 0 && val)
742 msg_Err (d->obj, "cannot enable high LNB voltage: %s",
743 vlc_strerror_c(errno));
745 /* Windows BDA exposes a higher-level API covering LNB oscillators.
746 * So lets pretend this is platform-specific stuff and do it here. */
748 { /* Default oscillator frequencies */
751 uint16_t min, max, low, high;
753 { /* min max low high */
754 { 10700, 13250, 9750, 10600 }, /* Ku band */
755 { 4500, 4800, 5950, 0 }, /* C band (high) */
756 { 3400, 4200, 5150, 0 }, /* C band (low) */
757 { 2500, 2700, 3650, 0 }, /* S band */
758 { 950, 2150, 0, 0 }, /* adjusted IF (L band) */
760 uint_fast16_t mHz = freq / 1000;
762 for (size_t i = 0; i < sizeof (tab) / sizeof (tab[0]); i++)
763 if (mHz >= tab[i].min && mHz <= tab[i].max)
765 lowf = tab[i].low * 1000;
766 highf = tab[i].high * 1000;
770 msg_Err (d->obj, "no known band for frequency %u kHz", freq);
772 msg_Dbg (d->obj, "selected LNB low: %u kHz, LNB high: %u kHz",
776 /* Use high oscillator frequency? */
777 bool high = highf != 0 && freq > switchf;
779 freq -= high ? highf : lowf;
780 if ((int32_t)freq < 0)
782 assert (freq < 0x7fffffff);
785 switch (var_InheritInteger (d->obj, "dvb-tone"))
787 case 0: tone = SEC_TONE_OFF; break;
788 case 1: tone = SEC_TONE_ON; break;
789 default: tone = high ? SEC_TONE_ON : SEC_TONE_OFF;
792 /*** LNB selection / DiSEqC ***/
793 unsigned voltage = dvb_parse_polarization (pol);
794 if (dvb_set_props (d, 2, DTV_TONE, SEC_TONE_OFF, DTV_VOLTAGE, voltage))
797 unsigned satno = var_InheritInteger (d->obj, "dvb-satno");
800 #undef msleep /* we know what we are doing! */
802 /* DiSEqC Bus Specification:
803 http://www.eutelsat.com/satellites/pdf/Diseqc/Reference%20docs/bus_spec.pdf */
806 struct dvb_diseqc_master_cmd uncmd;
809 struct dvb_diseqc_master_cmd cmd;
811 satno = (satno - 1) & 3;
812 cmd.msg[0] = 0xE0; /* framing: master, no reply, 1st TX */
813 cmd.msg[1] = 0x10; /* address: all LNB/switch */
814 cmd.msg[2] = 0x38; /* command: Write Port Group 0 (committed) */
815 cmd.msg[3] = 0xF0 /* data[0]: clear all bits */
816 | (satno << 2) /* LNB (A, B, C or D) */
817 | ((voltage == SEC_VOLTAGE_18) << 1) /* polarization */
818 | (tone == SEC_TONE_ON); /* option */
819 cmd.msg[4] = cmd.msg[5] = 0; /* unused */
820 cmd.msg_len = 4; /* length */
822 msleep (15000); /* wait 15 ms before DiSEqC command */
823 unsigned uncommitted = var_InheritInteger (d->obj, "dvb-uncommitted");
826 uncommitted = (uncommitted - 1) & 3;
827 uncmd.msg[0] = 0xE0; /* framing: master, no reply, 1st TX */
828 uncmd.msg[1] = 0x10; /* address: all LNB/switch */
829 uncmd.msg[2] = 0x39; /* command: Write Port Group 1 (uncommitted) */
830 uncmd.msg[3] = 0xF0 /* data[0]: clear all bits */
831 | (uncommitted << 2) /* LNB (A, B, C or D) */
832 | ((voltage == SEC_VOLTAGE_18) << 1) /* polarization */
833 | (tone == SEC_TONE_ON); /* option */
834 uncmd.msg[4] = uncmd.msg[5] = 0; /* unused */
835 uncmd.msg_len = 4; /* length */
836 if (ioctl (d->frontend, FE_DISEQC_SEND_MASTER_CMD, &uncmd) < 0)
838 msg_Err (d->obj, "cannot send uncommitted DiSEqC command: %s",
839 vlc_strerror_c(errno));
842 /* Repeat uncommitted command */
843 uncmd.msg[0] = 0xE1; /* framing: master, no reply, repeated TX */
844 if (ioctl (d->frontend, FE_DISEQC_SEND_MASTER_CMD, &uncmd) < 0)
847 "cannot send repeated uncommitted DiSEqC command: %s",
848 vlc_strerror_c(errno));
851 msleep(125000); /* wait 125 ms before committed DiSEqC command */
853 if (ioctl (d->frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) < 0)
855 msg_Err (d->obj, "cannot send committed DiSEqC command: %s",
856 vlc_strerror_c(errno));
859 msleep (54000 + 15000);
863 if (ioctl (d->frontend, FE_DISEQC_SEND_BURST,
864 satno ? SEC_MINI_B : SEC_MINI_A) < 0)
866 msg_Err (d->obj, "cannot send Mini-DiSEqC tone burst: %s",
867 vlc_strerror_c(errno));
873 /* Continuous tone (to select high oscillator frequency) */
874 return dvb_set_props (d, 2, DTV_FREQUENCY, freq, DTV_TONE, tone);
877 int dvb_set_dvbs (dvb_device_t *d, uint64_t freq_Hz,
878 uint32_t srate, uint32_t fec)
880 uint32_t freq = freq_Hz / 1000;
881 fec = dvb_parse_fec (fec);
883 if (dvb_find_frontend (d, DVB_S))
885 return dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBS,
886 DTV_FREQUENCY, freq, DTV_SYMBOL_RATE, srate,
890 int dvb_set_dvbs2 (dvb_device_t *d, uint64_t freq_Hz, const char *modstr,
891 uint32_t srate, uint32_t fec, int pilot, int rolloff)
893 uint32_t freq = freq_Hz / 1000;
894 unsigned mod = dvb_parse_modulation (modstr, QPSK);
895 fec = dvb_parse_fec (fec);
899 case 0: pilot = PILOT_OFF; break;
900 case 1: pilot = PILOT_ON; break;
901 default: pilot = PILOT_AUTO; break;
906 case 20: rolloff = ROLLOFF_20; break;
907 case 25: rolloff = ROLLOFF_25; break;
908 case 35: rolloff = ROLLOFF_35; break;
909 default: rolloff = PILOT_AUTO; break;
912 if (dvb_find_frontend (d, DVB_S2))
914 return dvb_set_props (d, 8, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBS2,
915 DTV_FREQUENCY, freq, DTV_MODULATION, mod,
916 DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec,
917 DTV_PILOT, pilot, DTV_ROLLOFF, rolloff);
922 static uint32_t dvb_parse_bandwidth (uint32_t i)
927 case 2: return 1712000;
928 default: return i * 1000000;
932 static int dvb_parse_transmit_mode (int i)
934 static const dvb_int_map_t tab[] = {
935 { -1, TRANSMISSION_MODE_AUTO },
937 { 1, TRANSMISSION_MODE_1K },
939 { 2, TRANSMISSION_MODE_2K },
940 { 4, TRANSMISSION_MODE_4K },
941 { 8, TRANSMISSION_MODE_8K },
943 { 16, TRANSMISSION_MODE_16K },
944 { 32, TRANSMISSION_MODE_32K },
947 return dvb_parse_int (i, tab, sizeof (tab) / sizeof (*tab),
948 TRANSMISSION_MODE_AUTO);
951 static int dvb_parse_guard (uint32_t guard)
953 static const dvb_int_map_t tab[] = {
954 { VLC_GUARD(1,4), GUARD_INTERVAL_1_4 },
955 { VLC_GUARD(1,8), GUARD_INTERVAL_1_8 },
956 { VLC_GUARD(1,16), GUARD_INTERVAL_1_16 },
957 { VLC_GUARD(1,32), GUARD_INTERVAL_1_32 },
959 { VLC_GUARD(1,128), GUARD_INTERVAL_1_128 },
960 { VLC_GUARD(19,128), GUARD_INTERVAL_19_128 },
961 { VLC_GUARD(19,256), GUARD_INTERVAL_19_256 },
963 { VLC_GUARD_AUTO, GUARD_INTERVAL_AUTO },
965 return dvb_parse_int (guard, tab, sizeof (tab) / sizeof (*tab),
966 GUARD_INTERVAL_AUTO);
969 static int dvb_parse_hierarchy (int i)
971 static const dvb_int_map_t tab[] = {
972 { HIERARCHY_AUTO, -1 },
973 { HIERARCHY_NONE, 0 },
978 return dvb_parse_int (i, tab, sizeof (tab) / sizeof (*tab),
982 int dvb_set_dvbt (dvb_device_t *d, uint32_t freq, const char *modstr,
983 uint32_t fec_hp, uint32_t fec_lp, uint32_t bandwidth,
984 int transmit_mode, uint32_t guard, int hierarchy)
986 uint32_t mod = dvb_parse_modulation (modstr, QAM_AUTO);
987 fec_hp = dvb_parse_fec (fec_hp);
988 fec_lp = dvb_parse_fec (fec_lp);
989 bandwidth = dvb_parse_bandwidth (bandwidth);
990 transmit_mode = dvb_parse_transmit_mode (transmit_mode);
991 guard = dvb_parse_guard (guard);
992 hierarchy = dvb_parse_hierarchy (hierarchy);
994 if (dvb_find_frontend (d, DVB_T))
996 return dvb_set_props (d, 10, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBT,
997 DTV_FREQUENCY, freq, DTV_MODULATION, mod,
998 DTV_CODE_RATE_HP, fec_hp, DTV_CODE_RATE_LP, fec_lp,
999 DTV_BANDWIDTH_HZ, bandwidth,
1000 DTV_TRANSMISSION_MODE, transmit_mode,
1001 DTV_GUARD_INTERVAL, guard,
1002 DTV_HIERARCHY, hierarchy);
1005 int dvb_set_dvbt2 (dvb_device_t *d, uint32_t freq, const char *modstr,
1006 uint32_t fec, uint32_t bandwidth,
1007 int transmit_mode, uint32_t guard, uint32_t plp)
1010 uint32_t mod = dvb_parse_modulation (modstr, QAM_AUTO);
1011 fec = dvb_parse_fec (fec);
1012 bandwidth = dvb_parse_bandwidth (bandwidth);
1013 transmit_mode = dvb_parse_transmit_mode (transmit_mode);
1014 guard = dvb_parse_guard (guard);
1016 if (dvb_find_frontend (d, DVB_T2))
1018 return dvb_set_props (d, 9, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBT2,
1019 DTV_FREQUENCY, freq, DTV_MODULATION, mod,
1020 DTV_INNER_FEC, fec, DTV_BANDWIDTH_HZ, bandwidth,
1021 DTV_TRANSMISSION_MODE, transmit_mode,
1022 DTV_GUARD_INTERVAL, guard,
1030 # warning DVB-T2 needs Linux DVB version 5.3 or later.
1031 msg_Err (d->obj, "DVB-T2 support not compiled-in");
1032 (void) freq; (void) modstr; (void) fec; (void) bandwidth;
1033 (void) transmit_mode; (void) guard;
1040 int dvb_set_isdbc (dvb_device_t *d, uint32_t freq, const char *modstr,
1041 uint32_t srate, uint32_t fec)
1043 unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
1044 fec = dvb_parse_fec (fec);
1046 if (dvb_find_frontend (d, ISDB_C))
1048 return dvb_set_props (d, 6, DTV_CLEAR, 0,
1050 DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_C,
1052 # warning ISDB-C might need Linux DVB version 5.5 or later.
1053 DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_AC,
1055 DTV_FREQUENCY, freq, DTV_MODULATION, mod,
1056 DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec);
1061 int dvb_set_isdbs (dvb_device_t *d, uint64_t freq_Hz, uint16_t ts_id)
1063 uint32_t freq = freq_Hz / 1000;
1065 if (dvb_find_frontend (d, ISDB_S))
1067 return dvb_set_props (d, 4, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ISDBS,
1068 DTV_FREQUENCY, freq,
1079 static int dvb_set_isdbt_layer (dvb_device_t *d, unsigned num,
1080 const isdbt_layer_t *l)
1082 uint32_t mod = dvb_parse_modulation (l->modulation, QAM_AUTO);
1083 uint32_t fec = dvb_parse_fec (l->code_rate);
1084 uint32_t count = l->segment_count;
1085 uint32_t ti = l->time_interleaving;
1087 num *= DTV_ISDBT_LAYERB_FEC - DTV_ISDBT_LAYERA_FEC;
1089 return dvb_set_props (d, 5, DTV_DELIVERY_SYSTEM, SYS_ISDBT,
1090 DTV_ISDBT_LAYERA_FEC + num, fec,
1091 DTV_ISDBT_LAYERA_MODULATION + num, mod,
1092 DTV_ISDBT_LAYERA_SEGMENT_COUNT + num, count,
1093 DTV_ISDBT_LAYERA_TIME_INTERLEAVING + num, ti);
1096 int dvb_set_isdbt (dvb_device_t *d, uint32_t freq, uint32_t bandwidth,
1097 int transmit_mode, uint32_t guard,
1098 const isdbt_layer_t layers[3])
1100 bandwidth = dvb_parse_bandwidth (bandwidth);
1101 transmit_mode = dvb_parse_transmit_mode (transmit_mode);
1102 guard = dvb_parse_guard (guard);
1104 if (dvb_find_frontend (d, ISDB_T))
1106 if (dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ISDBT,
1107 DTV_FREQUENCY, freq, DTV_BANDWIDTH_HZ, bandwidth,
1108 DTV_GUARD_INTERVAL, guard))
1110 for (unsigned i = 0; i < 3; i++)
1111 if (dvb_set_isdbt_layer (d, i, layers + i))
1118 int dvb_set_atsc (dvb_device_t *d, uint32_t freq, const char *modstr)
1120 unsigned mod = dvb_parse_modulation (modstr, VSB_8);
1122 if (dvb_find_frontend (d, ATSC))
1124 return dvb_set_props (d, 4, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ATSC,
1125 DTV_FREQUENCY, freq, DTV_MODULATION, mod);
1128 int dvb_set_cqam (dvb_device_t *d, uint32_t freq, const char *modstr)
1130 unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
1132 if (dvb_find_frontend (d, CQAM))
1134 return dvb_set_props (d, 4, DTV_CLEAR, 0,
1135 DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_B,
1136 DTV_FREQUENCY, freq, DTV_MODULATION, mod);