Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] DVB: Query DVB frontend delivery capabilities

Currently, for any multi-standard frontend it is assumed that it just
has a single standard capability. This is fine in some cases, but
makes things hard when there are incompatible standards in conjuction.
Eg: DVB-S can be seen as a subset of DVB-S2, but the same doesn't hold
the same for DSS. This is not specific to any driver as it is, but a
generic issue. This was handled correctly in the multiproto tree,
while such functionality is missing from the v5 API update.

http://www.linuxtv.org/pipermail/vdr/2008-November/018417.html

Later on a FE_CAN_2G_MODULATION was added as a hack to workaround this
issue in the v5 API, but that hack is incapable of addressing the
issue, as it can be used to simply distinguish between DVB-S and
DVB-S2 alone, or another X vs X2 modulation. If there are more systems,
then you have a potential issue.

An application needs to query the device capabilities before requesting
any operation from the device.

Signed-off-by: Manu Abraham <abraham.manu@gmail.com>
Acked-by: Andreas Oberritter <obi@linuxtv.org>
Acked-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Manu Abraham and committed by
Mauro Carvalho Chehab
ba2780c7 e79c70e6

+40 -2
+36
drivers/media/dvb/dvb-core/dvb_frontend.c
··· 974 974 _DTV_CMD(DTV_GUARD_INTERVAL, 0, 0), 975 975 _DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0), 976 976 _DTV_CMD(DTV_HIERARCHY, 0, 0), 977 + 978 + _DTV_CMD(DTV_ENUM_DELSYS, 0, 0), 977 979 }; 978 980 979 981 static void dtv_property_dump(struct dtv_property *tvp) ··· 1211 1209 static int dvb_frontend_ioctl_properties(struct file *file, 1212 1210 unsigned int cmd, void *parg); 1213 1211 1212 + static void dtv_set_default_delivery_caps(const struct dvb_frontend *fe, struct dtv_property *p) 1213 + { 1214 + const struct dvb_frontend_info *info = &fe->ops.info; 1215 + u32 ncaps = 0; 1216 + 1217 + switch (info->type) { 1218 + case FE_QPSK: 1219 + p->u.buffer.data[ncaps++] = SYS_DVBS; 1220 + if (info->caps & FE_CAN_2G_MODULATION) 1221 + p->u.buffer.data[ncaps++] = SYS_DVBS2; 1222 + if (info->caps & FE_CAN_TURBO_FEC) 1223 + p->u.buffer.data[ncaps++] = SYS_TURBO; 1224 + break; 1225 + case FE_QAM: 1226 + p->u.buffer.data[ncaps++] = SYS_DVBC_ANNEX_AC; 1227 + break; 1228 + case FE_OFDM: 1229 + p->u.buffer.data[ncaps++] = SYS_DVBT; 1230 + if (info->caps & FE_CAN_2G_MODULATION) 1231 + p->u.buffer.data[ncaps++] = SYS_DVBT2; 1232 + break; 1233 + case FE_ATSC: 1234 + if (info->caps & (FE_CAN_8VSB | FE_CAN_16VSB)) 1235 + p->u.buffer.data[ncaps++] = SYS_ATSC; 1236 + if (info->caps & (FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256)) 1237 + p->u.buffer.data[ncaps++] = SYS_DVBC_ANNEX_B; 1238 + break; 1239 + } 1240 + p->u.buffer.len = ncaps; 1241 + } 1242 + 1214 1243 static int dtv_property_process_get(struct dvb_frontend *fe, 1215 1244 struct dtv_property *tvp, 1216 1245 struct file *file) ··· 1262 1229 } 1263 1230 1264 1231 switch(tvp->cmd) { 1232 + case DTV_ENUM_DELSYS: 1233 + dtv_set_default_delivery_caps(fe, tvp); 1234 + break; 1265 1235 case DTV_FREQUENCY: 1266 1236 tvp->u.data = c->frequency; 1267 1237 break;
+3 -1
include/linux/dvb/frontend.h
··· 316 316 317 317 #define DTV_DVBT2_PLP_ID 43 318 318 319 - #define DTV_MAX_COMMAND DTV_DVBT2_PLP_ID 319 + #define DTV_ENUM_DELSYS 44 320 + 321 + #define DTV_MAX_COMMAND DTV_ENUM_DELSYS 320 322 321 323 typedef enum fe_pilot { 322 324 PILOT_ON,
+1 -1
include/linux/dvb/version.h
··· 24 24 #define _DVBVERSION_H_ 25 25 26 26 #define DVB_API_VERSION 5 27 - #define DVB_API_VERSION_MINOR 4 27 + #define DVB_API_VERSION_MINOR 5 28 28 29 29 #endif /*_DVBVERSION_H_*/