aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 32526f103b59..1a94c6bb601c 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -254,6 +254,26 @@ int avc_recv(struct firedtv *fdtv, void *data, size_t length)
254 return 0; 254 return 0;
255} 255}
256 256
257static int add_pid_filter(struct firedtv *fdtv, u8 *operand)
258{
259 int i, n, pos = 1;
260
261 for (i = 0, n = 0; i < 16; i++) {
262 if (test_bit(i, &fdtv->channel_active)) {
263 operand[pos++] = 0x13; /* flowfunction relay */
264 operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
265 operand[pos++] = (fdtv->channel_pid[i] >> 8) & 0x1f;
266 operand[pos++] = fdtv->channel_pid[i] & 0xff;
267 operand[pos++] = 0x00; /* tableID */
268 operand[pos++] = 0x00; /* filter_length */
269 n++;
270 }
271 }
272 operand[0] = n;
273
274 return pos;
275}
276
257/* 277/*
258 * tuning command for setting the relative LNB frequency 278 * tuning command for setting the relative LNB frequency
259 * (not supported by the AVC standard) 279 * (not supported by the AVC standard)
@@ -316,7 +336,8 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
316 } 336 }
317} 337}
318 338
319static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, 339static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
340 struct dvb_frontend_parameters *params,
320 struct avc_command_frame *c) 341 struct avc_command_frame *c)
321{ 342{
322 c->opcode = AVC_OPCODE_DSD; 343 c->opcode = AVC_OPCODE_DSD;
@@ -378,13 +399,13 @@ static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params,
378 399
379 c->operand[20] = 0x00; 400 c->operand[20] = 0x00;
380 c->operand[21] = 0x00; 401 c->operand[21] = 0x00;
381 /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
382 c->operand[22] = 0x00;
383 402
384 c->length = 28; 403 /* Add PIDs to filter */
404 c->length = ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4);
385} 405}
386 406
387static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, 407static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
408 struct dvb_frontend_parameters *params,
388 struct avc_command_frame *c) 409 struct avc_command_frame *c)
389{ 410{
390 struct dvb_ofdm_parameters *ofdm = &params->u.ofdm; 411 struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
@@ -481,10 +502,9 @@ static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params,
481 502
482 c->operand[15] = 0x00; /* network_ID[0] */ 503 c->operand[15] = 0x00; /* network_ID[0] */
483 c->operand[16] = 0x00; /* network_ID[1] */ 504 c->operand[16] = 0x00; /* network_ID[1] */
484 /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
485 c->operand[17] = 0x00;
486 505
487 c->length = 24; 506 /* Add PIDs to filter */
507 c->length = ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4);
488} 508}
489 509
490int avc_tuner_dsd(struct firedtv *fdtv, 510int avc_tuner_dsd(struct firedtv *fdtv,
@@ -502,8 +522,8 @@ int avc_tuner_dsd(struct firedtv *fdtv,
502 switch (fdtv->type) { 522 switch (fdtv->type) {
503 case FIREDTV_DVB_S: 523 case FIREDTV_DVB_S:
504 case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break; 524 case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break;
505 case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break; 525 case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params, c); break;
506 case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break; 526 case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params, c); break;
507 default: 527 default:
508 BUG(); 528 BUG();
509 } 529 }