summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/drivers/media/common/tuners/mxl5007t.c435
-rw-r--r--linux/drivers/media/dvb/Kconfig4
-rw-r--r--linux/drivers/media/dvb/Makefile2
-rw-r--r--linux/drivers/media/dvb/firewire/Kconfig22
-rw-r--r--linux/drivers/media/dvb/firewire/Makefile8
-rw-r--r--linux/drivers/media/dvb/firewire/firedtv-1394.c285
-rw-r--r--linux/drivers/media/dvb/firewire/firedtv-avc.c1315
-rw-r--r--linux/drivers/media/dvb/firewire/firedtv-ci.c260
-rw-r--r--linux/drivers/media/dvb/firewire/firedtv-dvb.c364
-rw-r--r--linux/drivers/media/dvb/firewire/firedtv-fe.c247
-rw-r--r--linux/drivers/media/dvb/firewire/firedtv-rc.c190
-rw-r--r--linux/drivers/media/dvb/firewire/firedtv.h182
-rw-r--r--linux/drivers/media/dvb/siano/sms-cards.c4
-rw-r--r--linux/drivers/media/dvb/siano/smscoreapi.c2
-rw-r--r--linux/drivers/media/dvb/siano/smscoreapi.h2
-rw-r--r--linux/drivers/media/dvb/siano/smsdvb.c4
-rw-r--r--linux/drivers/media/dvb/siano/smsusb.c4
-rw-r--r--linux/drivers/media/video/Kconfig16
-rw-r--r--linux/drivers/media/video/pxa_camera.h95
-rw-r--r--linux/drivers/media/video/tvmixer.c345
-rw-r--r--linux/include/sound/tea575x-tuner.h22
-rw-r--r--linux/sound/i2c/other/tea575x-tuner.c322
-rw-r--r--linux/sound/oss/btaudio.c1156
-rw-r--r--v4l/Kconfig.sound26
-rw-r--r--v4l/Makefile5
-rw-r--r--v4l/Makefile.sound11
-rwxr-xr-xv4l/scripts/checkpatch.pl578
-rwxr-xr-xv4l/scripts/fix_kconfig.pl21
-rw-r--r--v4l/versions.txt2
-rw-r--r--v4l_experimental/firesat/Kconfig11
-rw-r--r--v4l_experimental/firesat/Makefile11
-rw-r--r--v4l_experimental/firesat/avc_api.c953
-rw-r--r--v4l_experimental/firesat/avc_api.h435
-rw-r--r--v4l_experimental/firesat/cmp.c176
-rw-r--r--v4l_experimental/firesat/cmp.h9
-rw-r--r--v4l_experimental/firesat/firesat-ci.c124
-rw-r--r--v4l_experimental/firesat/firesat-ci.h9
-rw-r--r--v4l_experimental/firesat/firesat-rc.c83
-rw-r--r--v4l_experimental/firesat/firesat-rc.h9
-rw-r--r--v4l_experimental/firesat/firesat.c917
-rw-r--r--v4l_experimental/firesat/firesat.h72
41 files changed, 3712 insertions, 5026 deletions
diff --git a/linux/drivers/media/common/tuners/mxl5007t.c b/linux/drivers/media/common/tuners/mxl5007t.c
index c7aa69df1..09d93144d 100644
--- a/linux/drivers/media/common/tuners/mxl5007t.c
+++ b/linux/drivers/media/common/tuners/mxl5007t.c
@@ -1,7 +1,7 @@
/*
* mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
*
- * Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -67,22 +67,17 @@ MODULE_PARM_DESC(debug, "set debug level");
#define MHz 1000000
enum mxl5007t_mode {
- MxL_MODE_OTA_DVBT_ATSC = 0,
- MxL_MODE_OTA_NTSC_PAL_GH = 1,
- MxL_MODE_OTA_PAL_IB = 2,
- MxL_MODE_OTA_PAL_D_SECAM_KL = 3,
- MxL_MODE_OTA_ISDBT = 4,
- MxL_MODE_CABLE_DIGITAL = 0x10,
- MxL_MODE_CABLE_NTSC_PAL_GH = 0x11,
- MxL_MODE_CABLE_PAL_IB = 0x12,
- MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13,
- MxL_MODE_CABLE_SCTE40 = 0x14,
+ MxL_MODE_ISDBT = 0,
+ MxL_MODE_DVBT = 1,
+ MxL_MODE_ATSC = 2,
+ MxL_MODE_CABLE = 0x10,
};
enum mxl5007t_chip_version {
MxL_UNKNOWN_ID = 0x00,
MxL_5007_V1_F1 = 0x11,
MxL_5007_V1_F2 = 0x12,
+ MxL_5007_V4 = 0x14,
MxL_5007_V2_100_F1 = 0x21,
MxL_5007_V2_100_F2 = 0x22,
MxL_5007_V2_200_F1 = 0x23,
@@ -97,67 +92,61 @@ struct reg_pair_t {
/* ------------------------------------------------------------------------- */
static struct reg_pair_t init_tab[] = {
- { 0x0b, 0x44 }, /* XTAL */
- { 0x0c, 0x60 }, /* IF */
- { 0x10, 0x00 }, /* MISC */
- { 0x12, 0xca }, /* IDAC */
- { 0x16, 0x90 }, /* MODE */
- { 0x32, 0x38 }, /* MODE Analog/Digital */
- { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
- { 0x2c, 0x34 }, /* OVERRIDE */
- { 0x4d, 0x40 }, /* OVERRIDE */
- { 0x7f, 0x02 }, /* OVERRIDE */
- { 0x9a, 0x52 }, /* OVERRIDE */
- { 0x48, 0x5a }, /* OVERRIDE */
- { 0x76, 0x1a }, /* OVERRIDE */
- { 0x6a, 0x48 }, /* OVERRIDE */
- { 0x64, 0x28 }, /* OVERRIDE */
- { 0x66, 0xe6 }, /* OVERRIDE */
- { 0x35, 0x0e }, /* OVERRIDE */
- { 0x7e, 0x01 }, /* OVERRIDE */
- { 0x83, 0x00 }, /* OVERRIDE */
- { 0x04, 0x0b }, /* OVERRIDE */
- { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+ { 0x02, 0x06 },
+ { 0x03, 0x48 },
+ { 0x05, 0x04 },
+ { 0x06, 0x10 },
+ { 0x2e, 0x15 }, /* OVERRIDE */
+ { 0x30, 0x10 }, /* OVERRIDE */
+ { 0x45, 0x58 }, /* OVERRIDE */
+ { 0x48, 0x19 }, /* OVERRIDE */
+ { 0x52, 0x03 }, /* OVERRIDE */
+ { 0x53, 0x44 }, /* OVERRIDE */
+ { 0x6a, 0x4b }, /* OVERRIDE */
+ { 0x76, 0x00 }, /* OVERRIDE */
+ { 0x78, 0x18 }, /* OVERRIDE */
+ { 0x7a, 0x17 }, /* OVERRIDE */
+ { 0x85, 0x06 }, /* OVERRIDE */
+ { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
{ 0, 0 }
};
static struct reg_pair_t init_tab_cable[] = {
- { 0x0b, 0x44 }, /* XTAL */
- { 0x0c, 0x60 }, /* IF */
- { 0x10, 0x00 }, /* MISC */
- { 0x12, 0xca }, /* IDAC */
- { 0x16, 0x90 }, /* MODE */
- { 0x32, 0x38 }, /* MODE A/D */
- { 0x71, 0x3f }, /* TOP1 */
- { 0x72, 0x3f }, /* TOP2 */
- { 0x74, 0x3f }, /* TOP3 */
- { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
- { 0x2c, 0x34 }, /* OVERRIDE */
- { 0x4d, 0x40 }, /* OVERRIDE */
- { 0x7f, 0x02 }, /* OVERRIDE */
- { 0x9a, 0x52 }, /* OVERRIDE */
- { 0x48, 0x5a }, /* OVERRIDE */
- { 0x76, 0x1a }, /* OVERRIDE */
- { 0x6a, 0x48 }, /* OVERRIDE */
- { 0x64, 0x28 }, /* OVERRIDE */
- { 0x66, 0xe6 }, /* OVERRIDE */
- { 0x35, 0x0e }, /* OVERRIDE */
- { 0x7e, 0x01 }, /* OVERRIDE */
- { 0x04, 0x0b }, /* OVERRIDE */
- { 0x68, 0xb4 }, /* OVERRIDE */
- { 0x36, 0x00 }, /* OVERRIDE */
- { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+ { 0x02, 0x06 },
+ { 0x03, 0x48 },
+ { 0x05, 0x04 },
+ { 0x06, 0x10 },
+ { 0x09, 0x3f },
+ { 0x0a, 0x3f },
+ { 0x0b, 0x3f },
+ { 0x2e, 0x15 }, /* OVERRIDE */
+ { 0x30, 0x10 }, /* OVERRIDE */
+ { 0x45, 0x58 }, /* OVERRIDE */
+ { 0x48, 0x19 }, /* OVERRIDE */
+ { 0x52, 0x03 }, /* OVERRIDE */
+ { 0x53, 0x44 }, /* OVERRIDE */
+ { 0x6a, 0x4b }, /* OVERRIDE */
+ { 0x76, 0x00 }, /* OVERRIDE */
+ { 0x78, 0x18 }, /* OVERRIDE */
+ { 0x7a, 0x17 }, /* OVERRIDE */
+ { 0x85, 0x06 }, /* OVERRIDE */
+ { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
{ 0, 0 }
};
/* ------------------------------------------------------------------------- */
static struct reg_pair_t reg_pair_rftune[] = {
- { 0x11, 0x00 }, /* abort tune */
- { 0x13, 0x15 },
- { 0x14, 0x40 },
- { 0x15, 0x0e },
- { 0x11, 0x02 }, /* start tune */
+ { 0x0f, 0x00 }, /* abort tune */
+ { 0x0c, 0x15 },
+ { 0x0d, 0x40 },
+ { 0x0e, 0x0e },
+ { 0x1f, 0x87 }, /* OVERRIDE */
+ { 0x20, 0x1f }, /* OVERRIDE */
+ { 0x21, 0x87 }, /* OVERRIDE */
+ { 0x22, 0x1f }, /* OVERRIDE */
+ { 0x80, 0x01 }, /* freq dependent */
+ { 0x0f, 0x01 }, /* start tune */
{ 0, 0 }
};
@@ -232,63 +221,20 @@ static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
s32 if_diff_out_level)
{
switch (mode) {
- case MxL_MODE_OTA_DVBT_ATSC:
- set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
- set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e);
+ case MxL_MODE_ATSC:
+ set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12);
break;
- case MxL_MODE_OTA_ISDBT:
- set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
- set_reg_bits(state->tab_init, 0x35, 0xff, 0x12);
+ case MxL_MODE_DVBT:
+ set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11);
break;
- case MxL_MODE_OTA_NTSC_PAL_GH:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+ case MxL_MODE_ISDBT:
+ set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10);
break;
- case MxL_MODE_OTA_PAL_IB:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- break;
- case MxL_MODE_OTA_PAL_D_SECAM_KL:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- break;
- case MxL_MODE_CABLE_DIGITAL:
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_NTSC_PAL_GH:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_PAL_IB:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+ case MxL_MODE_CABLE:
+ set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1);
+ set_reg_bits(state->tab_init_cable, 0x0a, 0xff,
8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_PAL_D_SECAM_KL:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_SCTE40:
- set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08);
- set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+ set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17);
break;
default:
mxl_fail(-EINVAL);
@@ -307,43 +253,43 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
val = 0x00;
break;
case MxL_IF_4_5_MHZ:
- val = 0x20;
+ val = 0x02;
break;
case MxL_IF_4_57_MHZ:
- val = 0x30;
+ val = 0x03;
break;
case MxL_IF_5_MHZ:
- val = 0x40;
+ val = 0x04;
break;
case MxL_IF_5_38_MHZ:
- val = 0x50;
+ val = 0x05;
break;
case MxL_IF_6_MHZ:
- val = 0x60;
+ val = 0x06;
break;
case MxL_IF_6_28_MHZ:
- val = 0x70;
+ val = 0x07;
break;
case MxL_IF_9_1915_MHZ:
- val = 0x80;
+ val = 0x08;
break;
case MxL_IF_35_25_MHZ:
- val = 0x90;
+ val = 0x09;
break;
case MxL_IF_36_15_MHZ:
- val = 0xa0;
+ val = 0x0a;
break;
case MxL_IF_44_MHZ:
- val = 0xb0;
+ val = 0x0b;
break;
default:
mxl_fail(-EINVAL);
return;
}
- set_reg_bits(state->tab_init, 0x0c, 0xf0, val);
+ set_reg_bits(state->tab_init, 0x02, 0x0f, val);
/* set inverted IF or normal IF */
- set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00);
+ set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
return;
}
@@ -351,56 +297,68 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
enum mxl5007t_xtal_freq xtal_freq)
{
- u8 val;
-
switch (xtal_freq) {
case MxL_XTAL_16_MHZ:
- val = 0x00; /* select xtal freq & Ref Freq */
+ /* select xtal freq & ref freq */
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00);
break;
case MxL_XTAL_20_MHZ:
- val = 0x11;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01);
break;
case MxL_XTAL_20_25_MHZ:
- val = 0x22;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02);
break;
case MxL_XTAL_20_48_MHZ:
- val = 0x33;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03);
break;
case MxL_XTAL_24_MHZ:
- val = 0x44;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04);
break;
case MxL_XTAL_25_MHZ:
- val = 0x55;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05);
break;
case MxL_XTAL_25_14_MHZ:
- val = 0x66;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06);
break;
case MxL_XTAL_27_MHZ:
- val = 0x77;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07);
break;
case MxL_XTAL_28_8_MHZ:
- val = 0x88;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08);
break;
case MxL_XTAL_32_MHZ:
- val = 0x99;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09);
break;
case MxL_XTAL_40_MHZ:
- val = 0xaa;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a);
break;
case MxL_XTAL_44_MHZ:
- val = 0xbb;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b);
break;
case MxL_XTAL_48_MHZ:
- val = 0xcc;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c);
break;
case MxL_XTAL_49_3811_MHZ:
- val = 0xdd;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d);
break;
default:
mxl_fail(-EINVAL);
return;
}
- set_reg_bits(state->tab_init, 0x0b, 0xff, val);
return;
}
@@ -417,16 +375,11 @@ static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
- set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6);
-
- set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3);
-
- set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp);
+ set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable);
+ set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3);
+ set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp);
- /* set IDAC to automatic mode control by AGC */
- set_reg_bits(state->tab_init, 0x12, 0x80, 0x00);
-
- if (mode >= MxL_MODE_CABLE_DIGITAL) {
+ if (mode >= MxL_MODE_CABLE) {
copy_reg_bits(state->tab_init, state->tab_init_cable);
return state->tab_init_cable;
} else
@@ -452,7 +405,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
* and DIG_MODEINDEX_CSF */
break;
case MxL_BW_7MHz:
- val = 0x21;
+ val = 0x2a;
break;
case MxL_BW_8MHz:
val = 0x3f;
@@ -461,7 +414,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
mxl_fail(-EINVAL);
return;
}
- set_reg_bits(state->tab_rftune, 0x13, 0x3f, val);
+ set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val);
return;
}
@@ -498,8 +451,11 @@ reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
if (temp > 7812)
dig_rf_freq++;
- set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq);
- set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8));
+ set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq);
+ set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8));
+
+ if (rf_freq >= 333000000)
+ set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40);
return state->tab_rftune;
}
@@ -556,9 +512,10 @@ static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
static int mxl5007t_soft_reset(struct mxl5007t_state *state)
{
u8 d = 0xff;
- struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
- .buf = &d, .len = 1 };
-
+ struct i2c_msg msg = {
+ .addr = state->i2c_props.addr, .flags = 0,
+ .buf = &d, .len = 1
+ };
int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
if (ret != 1) {
@@ -585,9 +542,6 @@ static int mxl5007t_tuner_init(struct mxl5007t_state *state,
if (mxl_fail(ret))
goto fail;
mdelay(1);
-
- ret = mxl5007t_write_reg(state, 0x2c, 0x35);
- mxl_fail(ret);
fail:
return ret;
}
@@ -620,7 +574,7 @@ static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
*rf_locked = 0;
*ref_locked = 0;
- ret = mxl5007t_read_reg(state, 0xcf, &d);
+ ret = mxl5007t_read_reg(state, 0xd8, &d);
if (mxl_fail(ret))
goto fail;
@@ -633,37 +587,14 @@ fail:
return ret;
}
-static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state,
- s32 *rf_input_level)
-{
- u8 d1, d2;
- int ret;
-
- ret = mxl5007t_read_reg(state, 0xb7, &d1);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_read_reg(state, 0xbf, &d2);
- if (mxl_fail(ret))
- goto fail;
-
- d2 = d2 >> 4;
- if (d2 > 7)
- d2 += 0xf0;
-
- *rf_input_level = (s32)(d1 + d2 - 113);
-fail:
- return ret;
-}
-
/* ------------------------------------------------------------------------- */
static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
{
struct mxl5007t_state *state = fe->tuner_priv;
- int rf_locked, ref_locked;
- s32 rf_input_level = 0;
- int ret;
+ int rf_locked, ref_locked, ret;
+
+ *status = 0;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -674,10 +605,8 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
mxl_debug("%s%s", rf_locked ? "rf locked " : "",
ref_locked ? "ref locked" : "");
- ret = mxl5007t_check_rf_input_power(state, &rf_input_level);
- if (mxl_fail(ret))
- goto fail;
- mxl_debug("rf input power: %d", rf_input_level);
+ if ((rf_locked) || (ref_locked))
+ *status |= TUNER_STATUS_LOCKED;
fail:
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -700,11 +629,11 @@ static int mxl5007t_set_params(struct dvb_frontend *fe,
switch (params->u.vsb.modulation) {
case VSB_8:
case VSB_16:
- mode = MxL_MODE_OTA_DVBT_ATSC;
+ mode = MxL_MODE_ATSC;
break;
case QAM_64:
case QAM_256:
- mode = MxL_MODE_CABLE_DIGITAL;
+ mode = MxL_MODE_CABLE;
break;
default:
mxl_err("modulation not set!");
@@ -726,7 +655,7 @@ static int mxl5007t_set_params(struct dvb_frontend *fe,
mxl_err("bandwidth not set!");
return -EINVAL;
}
- mode = MxL_MODE_OTA_DVBT_ATSC;
+ mode = MxL_MODE_DVBT;
} else {
mxl_err("modulation type not supported!");
return -EINVAL;
@@ -757,103 +686,20 @@ fail:
return ret;
}
-static int mxl5007t_set_analog_params(struct dvb_frontend *fe,
- struct analog_parameters *params)
-{
- struct mxl5007t_state *state = fe->tuner_priv;
- enum mxl5007t_bw_mhz bw = 0; /* FIXME */
- enum mxl5007t_mode cbl_mode;
- enum mxl5007t_mode ota_mode;
- char *mode_name;
- int ret;
- u32 freq = params->frequency * 62500;
-
-#if 0
- if (params->mode == V4L2_TUNER_RADIO) {
- freq = freq / 1000;
- mode_name = "fm";
- } else
-#else
-#define cable 1
-#endif
- if (params->std & V4L2_STD_MN) {
- cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
- ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
- mode_name = "MN";
- } else if (params->std & V4L2_STD_B) {
- cbl_mode = MxL_MODE_CABLE_PAL_IB;
- ota_mode = MxL_MODE_OTA_PAL_IB;
- mode_name = "B";
- } else if (params->std & V4L2_STD_GH) {
- cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
- ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
- mode_name = "GH";
- } else if (params->std & V4L2_STD_PAL_I) {
- cbl_mode = MxL_MODE_CABLE_PAL_IB;
- ota_mode = MxL_MODE_OTA_PAL_IB;
- mode_name = "I";
- } else if (params->std & V4L2_STD_DK) {
- cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
- ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
- mode_name = "DK";
- } else if (params->std & V4L2_STD_SECAM_L) {
- cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
- ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
- mode_name = "L";
- } else if (params->std & V4L2_STD_SECAM_LC) {
- cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
- ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
- mode_name = "L'";
- } else {
- mode_name = "xx";
- /* FIXME */
- cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
- ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
- }
- mxl_debug("setting mxl5007 to system %s", mode_name);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
-
- mutex_lock(&state->lock);
-
- ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_tuner_rf_tune(state, freq, bw);
- if (mxl_fail(ret))
- goto fail;
-
- state->frequency = freq;
- state->bandwidth = 0;
-fail:
- mutex_unlock(&state->lock);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0);
-
- return ret;
-}
-
/* ------------------------------------------------------------------------- */
static int mxl5007t_init(struct dvb_frontend *fe)
{
struct mxl5007t_state *state = fe->tuner_priv;
int ret;
- u8 d;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- ret = mxl5007t_read_reg(state, 0x05, &d);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_write_reg(state, 0x05, d | 0x01);
+ /* wake from standby */
+ ret = mxl5007t_write_reg(state, 0x01, 0x01);
mxl_fail(ret);
-fail:
+
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -864,18 +710,16 @@ static int mxl5007t_sleep(struct dvb_frontend *fe)
{
struct mxl5007t_state *state = fe->tuner_priv;
int ret;
- u8 d;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- ret = mxl5007t_read_reg(state, 0x05, &d);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_write_reg(state, 0x05, d & ~0x01);
+ /* enter standby mode */
+ ret = mxl5007t_write_reg(state, 0x01, 0x00);
mxl_fail(ret);
-fail:
+ ret = mxl5007t_write_reg(state, 0x0f, 0x00);
+ mxl_fail(ret);
+
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -928,7 +772,6 @@ static struct dvb_tuner_ops mxl5007t_tuner_ops = {
.init = mxl5007t_init,
.sleep = mxl5007t_sleep,
.set_params = mxl5007t_set_params,
- .set_analog_params = mxl5007t_set_analog_params,
.get_status = mxl5007t_get_status,
.get_frequency = mxl5007t_get_frequency,
.get_bandwidth = mxl5007t_get_bandwidth,
@@ -941,7 +784,7 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
int ret;
u8 id;
- ret = mxl5007t_read_reg(state, 0xd3, &id);
+ ret = mxl5007t_read_reg(state, 0xd9, &id);
if (mxl_fail(ret))
goto fail;
@@ -964,12 +807,16 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
case MxL_5007_V2_200_F2:
name = "MxL5007.v2.200.f2";
break;
+ case MxL_5007_V4:
+ name = "MxL5007T.v4";
+ break;
default:
#if 0
ret = -EINVAL;
goto fail;
#else
name = "MxL5007T";
+ printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id);
id = MxL_UNKNOWN_ID;
#endif
}
@@ -997,7 +844,7 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
mutex_lock(&mxl5007t_list_mutex);
instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
hybrid_tuner_instance_list,
- i2c, addr, "mxl5007");
+ i2c, addr, "mxl5007t");
switch (instance) {
case 0:
goto fail;
@@ -1040,7 +887,7 @@ EXPORT_SYMBOL_GPL(mxl5007t_attach);
MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1");
+MODULE_VERSION("0.2");
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/linux/drivers/media/dvb/Kconfig b/linux/drivers/media/dvb/Kconfig
index 40ebde53b..b01986918 100644
--- a/linux/drivers/media/dvb/Kconfig
+++ b/linux/drivers/media/dvb/Kconfig
@@ -51,6 +51,10 @@ comment "Supported SDMC DM1105 Adapters"
depends on DVB_CORE && PCI && I2C
source "drivers/media/dvb/dm1105/Kconfig"
+comment "Supported FireWire (IEEE 1394) Adapters"
+ depends on DVB_CORE && IEEE1394
+source "drivers/media/dvb/firewire/Kconfig"
+
comment "Supported DVB Frontends"
depends on DVB_CORE
source "drivers/media/dvb/frontends/Kconfig"
diff --git a/linux/drivers/media/dvb/Makefile b/linux/drivers/media/dvb/Makefile
index f91e9eb15..6092a5bb5 100644
--- a/linux/drivers/media/dvb/Makefile
+++ b/linux/drivers/media/dvb/Makefile
@@ -3,3 +3,5 @@
#
obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/
+
+obj-$(CONFIG_DVB_FIREDTV) += firewire/
diff --git a/linux/drivers/media/dvb/firewire/Kconfig b/linux/drivers/media/dvb/firewire/Kconfig
new file mode 100644
index 000000000..69028253e
--- /dev/null
+++ b/linux/drivers/media/dvb/firewire/Kconfig
@@ -0,0 +1,22 @@
+config DVB_FIREDTV
+ tristate "FireDTV and FloppyDTV"
+ depends on DVB_CORE && IEEE1394
+ help
+ Support for DVB receivers from Digital Everywhere
+ which are connected via IEEE 1394 (FireWire).
+
+ These devices don't have an MPEG decoder built in,
+ so you need an external software decoder to watch TV.
+
+ To compile this driver as a module, say M here:
+ the module will be called firedtv.
+
+if DVB_FIREDTV
+
+config DVB_FIREDTV_IEEE1394
+ def_bool IEEE1394
+
+config DVB_FIREDTV_INPUT
+ def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
+
+endif # DVB_FIREDTV
diff --git a/linux/drivers/media/dvb/firewire/Makefile b/linux/drivers/media/dvb/firewire/Makefile
new file mode 100644
index 000000000..2034695ba
--- /dev/null
+++ b/linux/drivers/media/dvb/firewire/Makefile
@@ -0,0 +1,8 @@
+obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
+
+firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o
+firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o
+firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o
+
+ccflags-y += -Idrivers/media/dvb/dvb-core
+ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394
diff --git a/linux/drivers/media/dvb/firewire/firedtv-1394.c b/linux/drivers/media/dvb/firewire/firedtv-1394.c
new file mode 100644
index 000000000..4e207658c
--- /dev/null
+++ b/linux/drivers/media/dvb/firewire/firedtv-1394.c
@@ -0,0 +1,285 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <dma.h>
+#include <csr1212.h>
+#include <highlevel.h>
+#include <hosts.h>
+#include <ieee1394.h>
+#include <iso.h>
+#include <nodemgr.h>
+
+#include "firedtv.h"
+
+static LIST_HEAD(node_list);
+static DEFINE_SPINLOCK(node_list_lock);
+
+#define FIREWIRE_HEADER_SIZE 4
+#define CIP_HEADER_SIZE 8
+
+static void rawiso_activity_cb(struct hpsb_iso *iso)
+{
+ struct firedtv *f, *fdtv = NULL;
+ unsigned int i, num, packet;
+ unsigned char *buf;
+ unsigned long flags;
+ int count;
+
+ spin_lock_irqsave(&node_list_lock, flags);
+ list_for_each_entry(f, &node_list, list)
+ if (f->backend_data == iso) {
+ fdtv = f;
+ break;
+ }
+ spin_unlock_irqrestore(&node_list_lock, flags);
+
+ packet = iso->first_packet;
+ num = hpsb_iso_n_ready(iso);
+
+ if (!fdtv) {
+ dev_err(fdtv->device, "received at unknown iso channel\n");
+ goto out;
+ }
+
+ for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) {
+ buf = dma_region_i(&iso->data_buf, unsigned char,
+ iso->infos[packet].offset + CIP_HEADER_SIZE);
+ count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
+ (188 + FIREWIRE_HEADER_SIZE);
+
+ /* ignore empty packet */
+ if (iso->infos[packet].len <= CIP_HEADER_SIZE)
+ continue;
+
+ while (count--) {
+ if (buf[FIREWIRE_HEADER_SIZE] == 0x47)
+ dvb_dmx_swfilter_packets(&fdtv->demux,
+ &buf[FIREWIRE_HEADER_SIZE], 1);
+ else
+ dev_err(fdtv->device,
+ "skipping invalid packet\n");
+ buf += 188 + FIREWIRE_HEADER_SIZE;
+ }
+ }
+out:
+ hpsb_iso_recv_release_packets(iso, num);
+}
+
+static inline struct node_entry *node_of(struct firedtv *fdtv)
+{
+ return container_of(fdtv->device, struct unit_directory, device)->ne;
+}
+
+static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg)
+{
+ return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data,
+ (__force quadlet_t)arg);
+}
+
+static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+{
+ return hpsb_node_read(node_of(fdtv), addr, data, len);
+}
+
+static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+{
+ return hpsb_node_write(node_of(fdtv), addr, data, len);
+}
+
+#define FDTV_ISO_BUFFER_PACKETS 256
+#define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200)
+
+static int start_iso(struct firedtv *fdtv)
+{
+ struct hpsb_iso *iso_handle;
+ int ret;
+
+ iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host,
+ FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS,
+ fdtv->isochannel, HPSB_ISO_DMA_DEFAULT,
+ -1, /* stat.config.irq_interval */
+ rawiso_activity_cb);
+ if (iso_handle == NULL) {
+ dev_err(fdtv->device, "cannot initialize iso receive\n");
+ return -ENOMEM;
+ }
+ fdtv->backend_data = iso_handle;
+
+ ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0);
+ if (ret != 0) {
+ dev_err(fdtv->device, "cannot start iso receive\n");
+ hpsb_iso_shutdown(iso_handle);
+ fdtv->backend_data = NULL;
+ }
+ return ret;
+}
+
+static void stop_iso(struct firedtv *fdtv)
+{
+ struct hpsb_iso *iso_handle = fdtv->backend_data;
+
+ if (iso_handle != NULL) {
+ hpsb_iso_stop(iso_handle);
+ hpsb_iso_shutdown(iso_handle);
+ }
+ fdtv->backend_data = NULL;
+}
+
+static const struct firedtv_backend fdtv_1394_backend = {
+ .lock = node_lock,
+ .read = node_read,
+ .write = node_write,
+ .start_iso = start_iso,
+ .stop_iso = stop_iso,
+};
+
+static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
+ int cts, u8 *data, size_t length)
+{
+ struct firedtv *f, *fdtv = NULL;
+ unsigned long flags;
+ int su;
+
+ if (length == 0 || (data[0] & 0xf0) != 0)
+ return;
+
+ su = data[1] & 0x7;
+
+ spin_lock_irqsave(&node_list_lock, flags);
+ list_for_each_entry(f, &node_list, list)
+ if (node_of(f)->host == host &&
+ node_of(f)->nodeid == nodeid &&
+ (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
+ fdtv = f;
+ break;
+ }
+ spin_unlock_irqrestore(&node_list_lock, flags);
+
+ if (fdtv)
+ avc_recv(fdtv, data, length);
+}
+
+static int node_probe(struct device *dev)
+{
+ struct unit_directory *ud =
+ container_of(dev, struct unit_directory, device);
+ struct firedtv *fdtv;
+ int kv_len, err;
+ void *kv_str;
+
+ kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t);
+ kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
+
+ fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len);
+ if (!fdtv)
+ return -ENOMEM;
+
+ /*
+ * Work around a bug in udev's path_id script: Use the fw-host's dev
+ * instead of the unit directory's dev as parent of the input device.
+ */
+ err = fdtv_register_rc(fdtv, dev->parent->parent);
+ if (err)
+ goto fail_free;
+
+ spin_lock_irq(&node_list_lock);
+ list_add_tail(&fdtv->list, &node_list);
+ spin_unlock_irq(&node_list_lock);
+
+ err = avc_identify_subunit(fdtv);
+ if (err)
+ goto fail;
+
+ err = fdtv_dvb_register(fdtv);
+ if (err)
+ goto fail;
+
+ avc_register_remote_control(fdtv);
+ return 0;
+fail:
+ spin_lock_irq(&node_list_lock);
+ list_del(&fdtv->list);
+ spin_unlock_irq(&node_list_lock);
+ fdtv_unregister_rc(fdtv);
+fail_free:
+ kfree(fdtv);
+ return err;
+}
+
+static int node_remove(struct device *dev)
+{
+ struct firedtv *fdtv = dev->driver_data;
+
+ fdtv_dvb_unregister(fdtv);
+
+ spin_lock_irq(&node_list_lock);
+ list_del(&fdtv->list);
+ spin_unlock_irq(&node_list_lock);
+
+ cancel_work_sync(&fdtv->remote_ctrl_work);
+ fdtv_unregister_rc(fdtv);
+
+ kfree(fdtv);
+ return 0;
+}
+
+static int node_update(struct unit_directory *ud)
+{
+ struct firedtv *fdtv = ud->device.driver_data;
+
+ if (fdtv->isochannel >= 0)
+ cmp_establish_pp_connection(fdtv, fdtv->subunit,
+ fdtv->isochannel);
+ return 0;
+}
+
+static struct hpsb_protocol_driver fdtv_driver = {
+ .name = "firedtv",
+ .update = node_update,
+ .driver = {
+ .probe = node_probe,
+ .remove = node_remove,
+ },
+};
+
+static struct hpsb_highlevel fdtv_highlevel = {
+ .name = "firedtv",
+ .fcp_request = fcp_request,
+};
+
+int __init fdtv_1394_init(struct ieee1394_device_id id_table[])
+{
+ int ret;
+
+ hpsb_register_highlevel(&fdtv_highlevel);
+ fdtv_driver.id_table = id_table;
+ ret = hpsb_register_protocol(&fdtv_driver);
+ if (ret) {
+ printk(KERN_ERR "firedtv: failed to register protocol\n");
+ hpsb_unregister_highlevel(&fdtv_highlevel);
+ }
+ return ret;
+}
+
+void __exit fdtv_1394_exit(void)
+{
+ hpsb_unregister_protocol(&fdtv_driver);
+ hpsb_unregister_highlevel(&fdtv_highlevel);
+}
diff --git a/linux/drivers/media/dvb/firewire/firedtv-avc.c b/linux/drivers/media/dvb/firewire/firedtv-avc.c
new file mode 100644
index 000000000..b55d9ccaf
--- /dev/null
+++ b/linux/drivers/media/dvb/firewire/firedtv-avc.c
@@ -0,0 +1,1315 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Ben Backx <ben@bbackx.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/bug.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/stringify.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include "firedtv.h"
+
+#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL
+
+#define AVC_CTYPE_CONTROL 0x0
+#define AVC_CTYPE_STATUS 0x1
+#define AVC_CTYPE_NOTIFY 0x3
+
+#define AVC_RESPONSE_ACCEPTED 0x9
+#define AVC_RESPONSE_STABLE 0xc
+#define AVC_RESPONSE_CHANGED 0xd
+#define AVC_RESPONSE_INTERIM 0xf
+
+#define AVC_SUBUNIT_TYPE_TUNER (0x05 << 3)
+#define AVC_SUBUNIT_TYPE_UNIT (0x1f << 3)
+
+#define AVC_OPCODE_VENDOR 0x00
+#define AVC_OPCODE_READ_DESCRIPTOR 0x09
+#define AVC_OPCODE_DSIT 0xc8
+#define AVC_OPCODE_DSD 0xcb
+
+#define DESCRIPTOR_TUNER_STATUS 0x80
+#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00
+
+#define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */
+#define SFE_VENDOR_DE_COMPANYID_1 0x12
+#define SFE_VENDOR_DE_COMPANYID_2 0x87
+
+#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a
+#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52
+#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 /* for DVB-S */
+
+#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00
+#define SFE_VENDOR_OPCODE_HOST2CA 0x56
+#define SFE_VENDOR_OPCODE_CA2HOST 0x57
+#define SFE_VENDOR_OPCODE_CISTATUS 0x59
+#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 /* for DVB-S2 */
+
+#define SFE_VENDOR_TAG_CA_RESET 0x00
+#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01
+#define SFE_VENDOR_TAG_CA_PMT 0x02
+#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04
+#define SFE_VENDOR_TAG_CA_MMI 0x05
+#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07
+
+#define EN50221_LIST_MANAGEMENT_ONLY 0x03
+#define EN50221_TAG_APP_INFO 0x9f8021
+#define EN50221_TAG_CA_INFO 0x9f8031
+
+struct avc_command_frame {
+ int length;
+ u8 ctype;
+ u8 subunit;
+ u8 opcode;
+ u8 operand[509];
+};
+
+struct avc_response_frame {
+ int length;
+ u8 response;
+ u8 subunit;
+ u8 opcode;
+ u8 operand[509];
+};
+
+#define AVC_DEBUG_FCP_SUBACTIONS 1
+#define AVC_DEBUG_FCP_PAYLOADS 2
+
+static int avc_debug;
+module_param_named(debug, avc_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Verbose logging (default = 0"
+ ", FCP subactions = " __stringify(AVC_DEBUG_FCP_SUBACTIONS)
+ ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS)
+ ", or all = -1)");
+
+static const char *debug_fcp_ctype(unsigned int ctype)
+{
+ static const char *ctypes[] = {
+ [0x0] = "CONTROL", [0x1] = "STATUS",
+ [0x2] = "SPECIFIC INQUIRY", [0x3] = "NOTIFY",
+ [0x4] = "GENERAL INQUIRY", [0x8] = "NOT IMPLEMENTED",
+ [0x9] = "ACCEPTED", [0xa] = "REJECTED",
+ [0xb] = "IN TRANSITION", [0xc] = "IMPLEMENTED/STABLE",
+ [0xd] = "CHANGED", [0xf] = "INTERIM",
+ };
+ const char *ret = ctype < ARRAY_SIZE(ctypes) ? ctypes[ctype] : NULL;
+
+ return ret ? ret : "?";
+}
+
+static const char *debug_fcp_opcode(unsigned int opcode,
+ const u8 *data, size_t length)
+{
+ switch (opcode) {
+ case AVC_OPCODE_VENDOR: break;
+ case AVC_OPCODE_READ_DESCRIPTOR: return "ReadDescriptor";
+ case AVC_OPCODE_DSIT: return "DirectSelectInfo.Type";
+ case AVC_OPCODE_DSD: return "DirectSelectData";
+ default: return "?";
+ }
+
+ if (length < 7 ||
+ data[3] != SFE_VENDOR_DE_COMPANYID_0 ||
+ data[4] != SFE_VENDOR_DE_COMPANYID_1 ||
+ data[5] != SFE_VENDOR_DE_COMPANYID_2)
+ return "Vendor";
+
+ switch (data[6]) {
+ case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC";
+ case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl";
+ case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK";
+ case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA";
+ case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host";
+ }
+ return "Vendor";
+}
+
+static void debug_fcp(const u8 *data, size_t length)
+{
+ unsigned int subunit_type, subunit_id, op;
+ const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
+
+ if (avc_debug & AVC_DEBUG_FCP_SUBACTIONS) {
+ subunit_type = data[1] >> 3;
+ subunit_id = data[1] & 7;
+ op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
+ printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
+ prefix, subunit_type, subunit_id, length,
+ debug_fcp_ctype(data[0]),
+ debug_fcp_opcode(op, data, length));
+ }
+
+ if (avc_debug & AVC_DEBUG_FCP_PAYLOADS)
+ print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1,
+ data, length, false);
+}
+
+static int __avc_write(struct firedtv *fdtv,
+ const struct avc_command_frame *c, struct avc_response_frame *r)
+{
+ int err, retry;
+
+ if (r)
+ fdtv->avc_reply_received = false;
+
+ for (retry = 0; retry < 6; retry++) {
+ if (unlikely(avc_debug))
+ debug_fcp(&c->ctype, c->length);
+
+ err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER,
+ (void *)&c->ctype, c->length);
+ if (err) {
+ fdtv->avc_reply_received = true;
+ dev_err(fdtv->device, "FCP command write failed\n");
+ return err;
+ }
+
+ if (!r)
+ return 0;
+
+ /*
+ * AV/C specs say that answers should be sent within 150 ms.
+ * Time out after 200 ms.
+ */
+ if (wait_event_timeout(fdtv->avc_wait,
+ fdtv->avc_reply_received,
+ msecs_to_jiffies(200)) != 0) {
+ r->length = fdtv->response_length;
+ memcpy(&r->response, fdtv->response, r->length);
+
+ return 0;
+ }
+ }
+ dev_err(fdtv->device, "FCP response timed out\n");
+ return -ETIMEDOUT;
+}
+
+static int avc_write(struct firedtv *fdtv,
+ const struct avc_command_frame *c, struct avc_response_frame *r)
+{
+ int ret;
+
+ if (mutex_lock_interruptible(&fdtv->avc_mutex))
+ return -EINTR;
+
+ ret = __avc_write(fdtv, c, r);
+
+ mutex_unlock(&fdtv->avc_mutex);
+ return ret;
+}
+
+int avc_recv(struct firedtv *fdtv, void *data, size_t length)
+{
+ struct avc_response_frame *r =
+ data - offsetof(struct avc_response_frame, response);
+
+ if (unlikely(avc_debug))
+ debug_fcp(data, length);
+
+ if (length >= 8 &&
+ r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
+ r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
+ r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 &&
+ r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
+ if (r->response == AVC_RESPONSE_CHANGED) {
+ fdtv_handle_rc(fdtv,
+ r->operand[4] << 8 | r->operand[5]);
+ schedule_work(&fdtv->remote_ctrl_work);
+ } else if (r->response != AVC_RESPONSE_INTERIM) {
+ dev_info(fdtv->device,
+ "remote control result = %d\n", r->response);
+ }
+ return 0;
+ }
+
+ if (fdtv->avc_reply_received) {
+ dev_err(fdtv->device, "out-of-order AVC response, ignored\n");
+ return -EIO;
+ }
+
+ memcpy(fdtv->response, data, length);
+ fdtv->response_length = length;
+
+ fdtv->avc_reply_received = true;
+ wake_up(&fdtv->avc_wait);
+
+ return 0;
+}
+
+/*
+ * tuning command for setting the relative LNB frequency
+ * (not supported by the AVC standard)
+ */
+static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
+ struct dvb_frontend_parameters *params,
+ struct avc_command_frame *c)
+{
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
+
+ c->operand[4] = (params->frequency >> 24) & 0xff;
+ c->operand[5] = (params->frequency >> 16) & 0xff;
+ c->operand[6] = (params->frequency >> 8) & 0xff;
+ c->operand[7] = params->frequency & 0xff;
+
+ c->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff;
+ c->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff;
+
+ switch (params->u.qpsk.fec_inner) {
+ case FEC_1_2: c->operand[10] = 0x1; break;
+ case FEC_2_3: c->operand[10] = 0x2; break;
+ case FEC_3_4: c->operand[10] = 0x3; break;
+ case FEC_5_6: c->operand[10] = 0x4; break;
+ case FEC_7_8: c->operand[10] = 0x5; break;
+ case FEC_4_5:
+ case FEC_8_9:
+ case FEC_AUTO:
+ default: c->operand[10] = 0x0;
+ }
+
+ if (fdtv->voltage == 0xff)
+ c->operand[11] = 0xff;
+ else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */
+ c->operand[11] = 0;
+ else
+ c->operand[11] = 1;
+
+ if (fdtv->tone == 0xff)
+ c->operand[12] = 0xff;
+ else if (fdtv->tone == SEC_TONE_ON) /* band */
+ c->operand[12] = 1;
+ else
+ c->operand[12] = 0;
+
+ if (fdtv->type == FIREDTV_DVB_S2) {
+ c->operand[13] = 0x1;
+ c->operand[14] = 0xff;
+ c->operand[15] = 0xff;
+ c->length = 20;
+ } else {
+ c->length = 16;
+ }
+}
+
+static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params,
+ struct avc_command_frame *c)
+{
+ c->opcode = AVC_OPCODE_DSD;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0x20; /* system id = DVB */
+ c->operand[3] = 0x00; /* antenna number */
+ c->operand[4] = 0x11; /* system_specific_multiplex selection_length */
+
+ /* multiplex_valid_flags, high byte */
+ c->operand[5] = 0 << 7 /* reserved */
+ | 0 << 6 /* Polarisation */
+ | 0 << 5 /* Orbital_Pos */
+ | 1 << 4 /* Frequency */
+ | 1 << 3 /* Symbol_Rate */
+ | 0 << 2 /* FEC_outer */
+ | (params->u.qam.fec_inner != FEC_AUTO ? 1 << 1 : 0)
+ | (params->u.qam.modulation != QAM_AUTO ? 1 << 0 : 0);
+
+ /* multiplex_valid_flags, low byte */
+ c->operand[6] = 0 << 7 /* NetworkID */
+ | 0 << 0 /* reserved */ ;
+
+ c->operand[7] = 0x00;
+ c->operand[8] = 0x00;
+ c->operand[9] = 0x00;
+ c->operand[10] = 0x00;
+
+ c->operand[11] = (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6);
+ c->operand[12] = ((params->frequency / 4000) >> 8) & 0xff;
+ c->operand[13] = (params->frequency / 4000) & 0xff;
+ c->operand[14] = ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff;
+ c->operand[15] = ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff;
+ c->operand[16] = ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0;
+ c->operand[17] = 0x00;
+
+ switch (params->u.qpsk.fec_inner) {
+ case FEC_1_2: c->operand[18] = 0x1; break;
+ case FEC_2_3: c->operand[18] = 0x2; break;
+ case FEC_3_4: c->operand[18] = 0x3; break;
+ case FEC_5_6: c->operand[18] = 0x4; break;
+ case FEC_7_8: c->operand[18] = 0x5; break;
+ case FEC_8_9: c->operand[18] = 0x6; break;
+ case FEC_4_5: c->operand[18] = 0x8; break;
+ case FEC_AUTO:
+ default: c->operand[18] = 0x0;
+ }
+
+ switch (params->u.qam.modulation) {
+ case QAM_16: c->operand[19] = 0x08; break;
+ case QAM_32: c->operand[19] = 0x10; break;
+ case QAM_64: c->operand[19] = 0x18; break;
+ case QAM_128: c->operand[19] = 0x20; break;
+ case QAM_256: c->operand[19] = 0x28; break;
+ case QAM_AUTO:
+ default: c->operand[19] = 0x00;
+ }
+
+ c->operand[20] = 0x00;
+ c->operand[21] = 0x00;
+ /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
+ c->operand[22] = 0x00;
+
+ c->length = 28;
+}
+
+static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params,
+ struct avc_command_frame *c)
+{
+ struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
+
+ c->opcode = AVC_OPCODE_DSD;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0x20; /* system id = DVB */
+ c->operand[3] = 0x00; /* antenna number */
+ c->operand[4] = 0x0c; /* system_specific_multiplex selection_length */
+
+ /* multiplex_valid_flags, high byte */
+ c->operand[5] =
+ 0 << 7 /* reserved */
+ | 1 << 6 /* CenterFrequency */
+ | (ofdm->bandwidth != BANDWIDTH_AUTO ? 1 << 5 : 0)
+ | (ofdm->constellation != QAM_AUTO ? 1 << 4 : 0)
+ | (ofdm->hierarchy_information != HIERARCHY_AUTO ? 1 << 3 : 0)
+ | (ofdm->code_rate_HP != FEC_AUTO ? 1 << 2 : 0)
+ | (ofdm->code_rate_LP != FEC_AUTO ? 1 << 1 : 0)
+ | (ofdm->guard_interval != GUARD_INTERVAL_AUTO ? 1 << 0 : 0);
+
+ /* multiplex_valid_flags, low byte */
+ c->operand[6] =
+ 0 << 7 /* NetworkID */
+ | (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0)
+ | 0 << 5 /* OtherFrequencyFlag */
+ | 0 << 0 /* reserved */ ;
+
+ c->operand[7] = 0x0;
+ c->operand[8] = (params->frequency / 10) >> 24;
+ c->operand[9] = ((params->frequency / 10) >> 16) & 0xff;
+ c->operand[10] = ((params->frequency / 10) >> 8) & 0xff;
+ c->operand[11] = (params->frequency / 10) & 0xff;
+
+ switch (ofdm->bandwidth) {
+ case BANDWIDTH_7_MHZ: c->operand[12] = 0x20; break;
+ case BANDWIDTH_8_MHZ:
+ case BANDWIDTH_6_MHZ: /* not defined by AVC spec */
+ case BANDWIDTH_AUTO:
+ default: c->operand[12] = 0x00;
+ }
+
+ switch (ofdm->constellation) {
+ case QAM_16: c->operand[13] = 1 << 6; break;
+ case QAM_64: c->operand[13] = 2 << 6; break;
+ case QPSK:
+ default: c->operand[13] = 0x00;
+ }
+
+ switch (ofdm->hierarchy_information) {
+ case HIERARCHY_1: c->operand[13] |= 1 << 3; break;
+ case HIERARCHY_2: c->operand[13] |= 2 << 3; break;
+ case HIERARCHY_4: c->operand[13] |= 3 << 3; break;
+ case HIERARCHY_AUTO:
+ case HIERARCHY_NONE:
+ default: break;
+ }
+
+ switch (ofdm->code_rate_HP) {
+ case FEC_2_3: c->operand[13] |= 1; break;
+ case FEC_3_4: c->operand[13] |= 2; break;
+ case FEC_5_6: c->operand[13] |= 3; break;
+ case FEC_7_8: c->operand[13] |= 4; break;
+ case FEC_1_2:
+ default: break;
+ }
+
+ switch (ofdm->code_rate_LP) {
+ case FEC_2_3: c->operand[14] = 1 << 5; break;
+ case FEC_3_4: c->operand[14] = 2 << 5; break;
+ case FEC_5_6: c->operand[14] = 3 << 5; break;
+ case FEC_7_8: c->operand[14] = 4 << 5; break;
+ case FEC_1_2:
+ default: c->operand[14] = 0x00; break;
+ }
+
+ switch (ofdm->guard_interval) {
+ case GUARD_INTERVAL_1_16: c->operand[14] |= 1 << 3; break;
+ case GUARD_INTERVAL_1_8: c->operand[14] |= 2 << 3; break;
+ case GUARD_INTERVAL_1_4: c->operand[14] |= 3 << 3; break;
+ case GUARD_INTERVAL_1_32:
+ case GUARD_INTERVAL_AUTO:
+ default: break;
+ }
+
+ switch (ofdm->transmission_mode) {
+ case TRANSMISSION_MODE_8K: c->operand[14] |= 1 << 1; break;
+ case TRANSMISSION_MODE_2K:
+ case TRANSMISSION_MODE_AUTO:
+ default: break;
+ }
+
+ c->operand[15] = 0x00; /* network_ID[0] */
+ c->operand[16] = 0x00; /* network_ID[1] */
+ /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
+ c->operand[17] = 0x00;
+
+ c->length = 24;
+}
+
+int avc_tuner_dsd(struct firedtv *fdtv,
+ struct dvb_frontend_parameters *params)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+
+ switch (fdtv->type) {
+ case FIREDTV_DVB_S:
+ case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break;
+ case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break;
+ case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break;
+ default:
+ BUG();
+ }
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ msleep(500);
+#if 0
+ /* FIXME: */
+ /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */
+ if (status)
+ *status = r->operand[2];
+#endif
+ return 0;
+}
+
+int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[])
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+ int pos, k;
+
+ if (pidc > 16 && pidc != 0xff)
+ return -EINVAL;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_DSD;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0x20; /* system id = DVB */
+ c->operand[3] = 0x00; /* antenna number */
+ c->operand[4] = 0x00; /* system_specific_multiplex selection_length */
+ c->operand[5] = pidc; /* Nr_of_dsd_sel_specs */
+
+ pos = 6;
+ if (pidc != 0xff)
+ for (k = 0; k < pidc; k++) {
+ c->operand[pos++] = 0x13; /* flowfunction relay */
+ c->operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
+ c->operand[pos++] = (pid[k] >> 8) & 0x1f;
+ c->operand[pos++] = pid[k] & 0xff;
+ c->operand[pos++] = 0x00; /* tableID */
+ c->operand[pos++] = 0x00; /* filter_length */
+ }
+
+ c->length = ALIGN(3 + pos, 4);
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ msleep(50);
+ return 0;
+}
+
+int avc_tuner_get_ts(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+ int sl;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_DSIT;
+
+ sl = fdtv->type == FIREDTV_DVB_T ? 0x0c : 0x11;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0xff; /* status */
+ c->operand[3] = 0x20; /* system id = DVB */
+ c->operand[4] = 0x00; /* antenna number */
+ c->operand[5] = 0x0; /* system_specific_search_flags */
+ c->operand[6] = sl; /* system_specific_multiplex selection_length */
+ c->operand[7] = 0x00; /* valid_flags [0] */
+ c->operand[8] = 0x00; /* valid_flags [1] */
+ c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */
+
+ c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ msleep(250);
+ return 0;
+}
+
+int avc_identify_subunit(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_READ_DESCRIPTOR;
+
+ c->operand[0] = DESCRIPTOR_SUBUNIT_IDENTIFIER;
+ c->operand[1] = 0xff;
+ c->operand[2] = 0x00;
+ c->operand[3] = 0x00; /* length highbyte */
+ c->operand[4] = 0x08; /* length lowbyte */
+ c->operand[5] = 0x00; /* offset highbyte */
+ c->operand[6] = 0x0d; /* offset lowbyte */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if ((r->response != AVC_RESPONSE_STABLE &&
+ r->response != AVC_RESPONSE_ACCEPTED) ||
+ (r->operand[3] << 8) + r->operand[4] != 8) {
+ dev_err(fdtv->device, "cannot read subunit identifier\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+#define SIZEOF_ANTENNA_INPUT_INFO 22
+
+int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int length;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_READ_DESCRIPTOR;
+
+ c->operand[0] = DESCRIPTOR_TUNER_STATUS;
+ c->operand[1] = 0xff; /* read_result_status */
+ c->operand[2] = 0x00; /* reserved */
+ c->operand[3] = 0; /* SIZEOF_ANTENNA_INPUT_INFO >> 8; */
+ c->operand[4] = 0; /* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */
+ c->operand[5] = 0x00;
+ c->operand[6] = 0x00;
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if (r->response != AVC_RESPONSE_STABLE &&
+ r->response != AVC_RESPONSE_ACCEPTED) {
+ dev_err(fdtv->device, "cannot read tuner status\n");
+ return -EINVAL;
+ }
+
+ length = r->operand[9];
+ if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) {
+ dev_err(fdtv->device, "got invalid tuner status\n");
+ return -EINVAL;
+ }
+
+ stat->active_system = r->operand[10];
+ stat->searching = r->operand[11] >> 7 & 1;
+ stat->moving = r->operand[11] >> 6 & 1;
+ stat->no_rf = r->operand[11] >> 5 & 1;
+ stat->input = r->operand[12] >> 7 & 1;
+ stat->selected_antenna = r->operand[12] & 0x7f;
+ stat->ber = r->operand[13] << 24 |
+ r->operand[14] << 16 |
+ r->operand[15] << 8 |
+ r->operand[16];
+ stat->signal_strength = r->operand[17];
+ stat->raster_frequency = r->operand[18] >> 6 & 2;
+ stat->rf_frequency = (r->operand[18] & 0x3f) << 16 |
+ r->operand[19] << 8 |
+ r->operand[20];
+ stat->man_dep_info_length = r->operand[21];
+ stat->front_end_error = r->operand[22] >> 4 & 1;
+ stat->antenna_error = r->operand[22] >> 3 & 1;
+ stat->front_end_power_status = r->operand[22] >> 1 & 1;
+ stat->power_supply = r->operand[22] & 1;
+ stat->carrier_noise_ratio = r->operand[23] << 8 |
+ r->operand[24];
+ stat->power_supply_voltage = r->operand[27];
+ stat->antenna_voltage = r->operand[28];
+ stat->firewire_bus_voltage = r->operand[29];
+ stat->ca_mmi = r->operand[30] & 1;
+ stat->ca_pmt_reply = r->operand[31] >> 7 & 1;
+ stat->ca_date_time_request = r->operand[31] >> 6 & 1;
+ stat->ca_application_info = r->operand[31] >> 5 & 1;
+ stat->ca_module_present_status = r->operand[31] >> 4 & 1;
+ stat->ca_dvb_flag = r->operand[31] >> 3 & 1;
+ stat->ca_error_flag = r->operand[31] >> 2 & 1;
+ stat->ca_initialization_status = r->operand[31] >> 1 & 1;
+
+ return 0;
+}
+
+int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
+ char conttone, char nrdiseq,
+ struct dvb_diseqc_master_cmd *diseqcmd)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int i, j, k;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL;
+
+ c->operand[4] = voltage;
+ c->operand[5] = nrdiseq;
+
+ i = 6;
+
+ for (j = 0; j < nrdiseq; j++) {
+ c->operand[i++] = diseqcmd[j].msg_len;
+
+ for (k = 0; k < diseqcmd[j].msg_len; k++)
+ c->operand[i++] = diseqcmd[j].msg[k];
+ }
+
+ c->operand[i++] = burst;
+ c->operand[i++] = conttone;
+
+ c->length = ALIGN(3 + i, 4);
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if (r->response != AVC_RESPONSE_ACCEPTED) {
+ dev_err(fdtv->device, "LNB control failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int avc_register_remote_control(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_NOTIFY;
+ c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
+
+ c->length = 8;
+
+ return avc_write(fdtv, c, NULL);
+}
+
+void avc_remote_ctrl_work(struct work_struct *work)
+{
+ struct firedtv *fdtv =
+ container_of(work, struct firedtv, remote_ctrl_work);
+
+ /* Should it be rescheduled in failure cases? */
+ avc_register_remote_control(fdtv);
+}
+
+#if 0 /* FIXME: unused */
+int avc_tuner_host2ca(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ return 0;
+}
+#endif
+
+static int get_ca_object_pos(struct avc_response_frame *r)
+{
+ int length = 1;
+
+ /* Check length of length field */
+ if (r->operand[7] & 0x80)
+ length = (r->operand[7] & 0x7f) + 1;
+ return length + 7;
+}
+
+static int get_ca_object_length(struct avc_response_frame *r)
+{
+#if 0 /* FIXME: unused */
+ int size = 0;
+ int i;
+
+ if (r->operand[7] & 0x80)
+ for (i = 0; i < (r->operand[7] & 0x7f); i++) {
+ size <<= 8;
+ size += r->operand[8 + i];
+ }
+#endif
+ return r->operand[7];
+}
+
+int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int pos;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ /* FIXME: check response code and validate response data */
+
+ pos = get_ca_object_pos(r);
+ app_info[0] = (EN50221_TAG_APP_INFO >> 16) & 0xff;
+ app_info[1] = (EN50221_TAG_APP_INFO >> 8) & 0xff;
+ app_info[2] = (EN50221_TAG_APP_INFO >> 0) & 0xff;
+ app_info[3] = 6 + r->operand[pos + 4];
+ app_info[4] = 0x01;
+ memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]);
+ *len = app_info[3] + 4;
+
+ return 0;
+}
+
+int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int pos;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ pos = get_ca_object_pos(r);
+ app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff;
+ app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff;
+ app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff;
+ app_info[3] = 2;
+ app_info[4] = r->operand[pos + 0];
+ app_info[5] = r->operand[pos + 1];
+ *len = app_info[3] + 4;
+
+ return 0;
+}
+
+int avc_ca_reset(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_RESET; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 1; /* length */
+ c->operand[8] = 0; /* force hardware reset */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ return 0;
+}
+
+int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int list_management;
+ int program_info_length;
+ int pmt_cmd_id;
+ int read_pos;
+ int write_pos;
+ int es_info_length;
+ int crc32_csum;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ if (msg[0] != EN50221_LIST_MANAGEMENT_ONLY) {
+ dev_info(fdtv->device, "forcing list_management to ONLY\n");
+ msg[0] = EN50221_LIST_MANAGEMENT_ONLY;
+ }
+ /* We take the cmd_id from the programme level only! */
+ list_management = msg[0];
+ program_info_length = ((msg[4] & 0x0f) << 8) + msg[5];
+ if (program_info_length > 0)
+ program_info_length--; /* Remove pmt_cmd_id */
+ pmt_cmd_id = msg[6];
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ /* c->operand[7] = XXXprogram_info_length + 17; */ /* length */
+ c->operand[8] = list_management;
+ c->operand[9] = 0x01; /* pmt_cmd=OK_descramble */
+
+ /* TS program map table */
+
+ c->operand[10] = 0x02; /* Table id=2 */
+ c->operand[11] = 0x80; /* Section syntax + length */
+ /* c->operand[12] = XXXprogram_info_length + 12; */
+ c->operand[13] = msg[1]; /* Program number */
+ c->operand[14] = msg[2];
+ c->operand[15] = 0x01; /* Version number=0 + current/next=1 */
+ c->operand[16] = 0x00; /* Section number=0 */
+ c->operand[17] = 0x00; /* Last section number=0 */
+ c->operand[18] = 0x1f; /* PCR_PID=1FFF */
+ c->operand[19] = 0xff;
+ c->operand[20] = (program_info_length >> 8); /* Program info length */
+ c->operand[21] = (program_info_length & 0xff);
+
+ /* CA descriptors at programme level */
+ read_pos = 6;
+ write_pos = 22;
+ if (program_info_length > 0) {
+ pmt_cmd_id = msg[read_pos++];
+ if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
+ dev_err(fdtv->device,
+ "invalid pmt_cmd_id %d\n", pmt_cmd_id);
+
+ memcpy(&c->operand[write_pos], &msg[read_pos],
+ program_info_length);
+ read_pos += program_info_length;
+ write_pos += program_info_length;
+ }
+ while (read_pos < length) {
+ c->operand[write_pos++] = msg[read_pos++];
+ c->operand[write_pos++] = msg[read_pos++];
+ c->operand[write_pos++] = msg[read_pos++];
+ es_info_length =
+ ((msg[read_pos] & 0x0f) << 8) + msg[read_pos + 1];
+ read_pos += 2;
+ if (es_info_length > 0)
+ es_info_length--; /* Remove pmt_cmd_id */
+ c->operand[write_pos++] = es_info_length >> 8;
+ c->operand[write_pos++] = es_info_length & 0xff;
+ if (es_info_length > 0) {
+ pmt_cmd_id = msg[read_pos++];
+ if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
+ dev_err(fdtv->device, "invalid pmt_cmd_id %d "
+ "at stream level\n", pmt_cmd_id);
+
+ memcpy(&c->operand[write_pos], &msg[read_pos],
+ es_info_length);
+ read_pos += es_info_length;
+ write_pos += es_info_length;
+ }
+ }
+
+ /* CRC */
+ c->operand[write_pos++] = 0x00;
+ c->operand[write_pos++] = 0x00;
+ c->operand[write_pos++] = 0x00;
+ c->operand[write_pos++] = 0x00;
+
+ c->operand[7] = write_pos - 8;
+ c->operand[12] = write_pos - 13;
+
+ crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1);
+ c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff;
+ c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff;
+ c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff;
+ c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff;
+
+ c->length = ALIGN(3 + write_pos, 4);
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if (r->response != AVC_RESPONSE_ACCEPTED) {
+ dev_err(fdtv->device,
+ "CA PMT failed with response 0x%x\n", r->response);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int avc_ca_get_time_date(struct firedtv *fdtv, int *interval)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ /* FIXME: check response code and validate response data */
+
+ *interval = r->operand[get_ca_object_pos(r)];
+
+ return 0;
+}
+
+int avc_ca_enter_menu(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU;
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ return 0;
+}
+
+int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_MMI;
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ /* FIXME: check response code and validate response data */
+
+ *len = get_ca_object_length(r);
+ memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len);
+
+ return 0;
+}
+
+#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
+
+static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len)
+{
+ int ret;
+
+ if (mutex_lock_interruptible(&fdtv->avc_mutex))
+ return -EINTR;
+
+ ret = fdtv->backend->read(fdtv, addr, buf, len);
+ if (ret < 0)
+ dev_err(fdtv->device, "CMP: read I/O error\n");
+
+ mutex_unlock(&fdtv->avc_mutex);
+ return ret;
+}
+
+static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg)
+{
+ int ret;
+
+ if (mutex_lock_interruptible(&fdtv->avc_mutex))
+ return -EINTR;
+
+ ret = fdtv->backend->lock(fdtv, addr, data, arg);
+ if (ret < 0)
+ dev_err(fdtv->device, "CMP: lock I/O error\n");
+
+ mutex_unlock(&fdtv->avc_mutex);
+ return ret;
+}
+
+static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift)
+{
+ return (be32_to_cpu(opcr) >> shift) & mask;
+}
+
+static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
+{
+ *opcr &= ~cpu_to_be32(mask << shift);
+ *opcr |= cpu_to_be32((value & mask) << shift);
+}
+
+#define get_opcr_online(v) get_opcr((v), 0x1, 31)
+#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24)
+#define get_opcr_channel(v) get_opcr((v), 0x3f, 16)
+
+#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24)
+#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16)
+#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14)
+#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10)
+
+int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
+{
+ __be32 old_opcr, opcr;
+ u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
+ int attempts = 0;
+ int ret;
+
+ ret = cmp_read(fdtv, &opcr, opcr_address, 4);
+ if (ret < 0)
+ return ret;
+
+repeat:
+ if (!get_opcr_online(opcr)) {
+ dev_err(fdtv->device, "CMP: output offline\n");
+ return -EBUSY;
+ }
+
+ old_opcr = opcr;
+
+ if (get_opcr_p2p_connections(opcr)) {
+ if (get_opcr_channel(opcr) != channel) {
+ dev_err(fdtv->device, "CMP: cannot change channel\n");
+ return -EBUSY;
+ }
+ dev_info(fdtv->device, "CMP: overlaying connection\n");
+
+ /* We don't allocate isochronous resources. */
+ } else {
+ set_opcr_channel(&opcr, channel);
+ set_opcr_data_rate(&opcr, 2); /* S400 */
+
+ /* FIXME: this is for the worst case - optimize */
+ set_opcr_overhead_id(&opcr, 0);
+
+ /*
+ * FIXME: allocate isochronous channel and bandwidth at IRM
+ * fdtv->backend->alloc_resources(fdtv, channels_mask, bw);
+ */
+ }
+
+ set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1);
+
+ ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr);
+ if (ret < 0)
+ return ret;
+
+ if (old_opcr != opcr) {
+ /*
+ * FIXME: if old_opcr.P2P_Connections > 0,
+ * deallocate isochronous channel and bandwidth at IRM
+ * if (...)
+ * fdtv->backend->dealloc_resources(fdtv, channel, bw);
+ */
+
+ if (++attempts < 6) /* arbitrary limit */
+ goto repeat;
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
+{
+ __be32 old_opcr, opcr;
+ u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
+ int attempts = 0;
+
+ if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0)
+ return;
+
+repeat:
+ if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) ||
+ get_opcr_channel(opcr) != channel) {
+ dev_err(fdtv->device, "CMP: no connection to break\n");
+ return;
+ }
+
+ old_opcr = opcr;
+ set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1);
+
+ if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0)
+ return;
+
+ if (old_opcr != opcr) {
+ /*
+ * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
+ * owner, deallocate isochronous channel and bandwidth at IRM
+ * if (...)
+ * fdtv->backend->dealloc_resources(fdtv, channel, bw);
+ */
+
+ if (++attempts < 6) /* arbitrary limit */
+ goto repeat;
+ }
+}
diff --git a/linux/drivers/media/dvb/firewire/firedtv-ci.c b/linux/drivers/media/dvb/firewire/firedtv-ci.c
new file mode 100644
index 000000000..eeb80d0ea
--- /dev/null
+++ b/linux/drivers/media/dvb/firewire/firedtv-ci.c
@@ -0,0 +1,260 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/dvb/ca.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+
+#include <dvbdev.h>
+
+#include "firedtv.h"
+
+#define EN50221_TAG_APP_INFO_ENQUIRY 0x9f8020
+#define EN50221_TAG_CA_INFO_ENQUIRY 0x9f8030
+#define EN50221_TAG_CA_PMT 0x9f8032
+#define EN50221_TAG_ENTER_MENU 0x9f8022
+
+static int fdtv_ca_ready(struct firedtv_tuner_status *stat)
+{
+ return stat->ca_initialization_status == 1 &&
+ stat->ca_error_flag == 0 &&
+ stat->ca_dvb_flag == 1 &&
+ stat->ca_module_present_status == 1;
+}
+
+static int fdtv_get_ca_flags(struct firedtv_tuner_status *stat)
+{
+ int flags = 0;
+
+ if (stat->ca_module_present_status == 1)
+ flags |= CA_CI_MODULE_PRESENT;
+ if (stat->ca_initialization_status == 1 &&
+ stat->ca_error_flag == 0 &&
+ stat->ca_dvb_flag == 1)
+ flags |= CA_CI_MODULE_READY;
+ return flags;
+}
+
+static int fdtv_ca_reset(struct firedtv *fdtv)
+{
+ return avc_ca_reset(fdtv) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_get_caps(void *arg)
+{
+ struct ca_caps *cap = arg;
+
+ cap->slot_num = 1;
+ cap->slot_type = CA_CI;
+ cap->descr_num = 1;
+ cap->descr_type = CA_ECD;
+ return 0;
+}
+
+static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg)
+{
+ struct firedtv_tuner_status stat;
+ struct ca_slot_info *slot = arg;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EFAULT;
+
+ if (slot->num != 0)
+ return -EFAULT;
+
+ slot->type = CA_CI;
+ slot->flags = fdtv_get_ca_flags(&stat);
+ return 0;
+}
+
+static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *reply = arg;
+
+ return avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_info(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *reply = arg;
+
+ return avc_ca_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *reply = arg;
+
+ return avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg)
+{
+ struct firedtv_tuner_status stat;
+ int err;
+
+ switch (fdtv->ca_last_command) {
+ case EN50221_TAG_APP_INFO_ENQUIRY:
+ err = fdtv_ca_app_info(fdtv, arg);
+ break;
+ case EN50221_TAG_CA_INFO_ENQUIRY:
+ err = fdtv_ca_info(fdtv, arg);
+ break;
+ default:
+ if (avc_tuner_status(fdtv, &stat))
+ err = -EFAULT;
+ else if (stat.ca_mmi == 1)
+ err = fdtv_ca_get_mmi(fdtv, arg);
+ else {
+ dev_info(fdtv->device, "unhandled CA message 0x%08x\n",
+ fdtv->ca_last_command);
+ err = -EFAULT;
+ }
+ }
+ fdtv->ca_last_command = 0;
+ return err;
+}
+
+static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *msg = arg;
+ int data_pos;
+ int data_length;
+ int i;
+
+ data_pos = 4;
+ if (msg->msg[3] & 0x80) {
+ data_length = 0;
+ for (i = 0; i < (msg->msg[3] & 0x7f); i++)
+ data_length = (data_length << 8) + msg->msg[data_pos++];
+ } else {
+ data_length = msg->msg[3];
+ }
+
+ return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *msg = arg;
+ int err;
+
+ /* Do we need a semaphore for this? */
+ fdtv->ca_last_command =
+ (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2];
+ switch (fdtv->ca_last_command) {
+ case EN50221_TAG_CA_PMT:
+ err = fdtv_ca_pmt(fdtv, arg);
+ break;
+ case EN50221_TAG_APP_INFO_ENQUIRY:
+ /* handled in ca_get_msg */
+ err = 0;
+ break;
+ case EN50221_TAG_CA_INFO_ENQUIRY:
+ /* handled in ca_get_msg */
+ err = 0;
+ break;
+ case EN50221_TAG_ENTER_MENU:
+ err = avc_ca_enter_menu(fdtv);
+ break;
+ default:
+ dev_err(fdtv->device, "unhandled CA message 0x%08x\n",
+ fdtv->ca_last_command);
+ err = -EFAULT;
+ }
+ return err;
+}
+
+static int fdtv_ca_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ struct firedtv *fdtv = dvbdev->priv;
+ struct firedtv_tuner_status stat;
+ int err;
+
+ switch (cmd) {
+ case CA_RESET:
+ err = fdtv_ca_reset(fdtv);
+ break;
+ case CA_GET_CAP:
+ err = fdtv_ca_get_caps(arg);
+ break;
+ case CA_GET_SLOT_INFO:
+ err = fdtv_ca_get_slot_info(fdtv, arg);
+ break;
+ case CA_GET_MSG:
+ err = fdtv_ca_get_msg(fdtv, arg);
+ break;
+ case CA_SEND_MSG:
+ err = fdtv_ca_send_msg(fdtv, arg);
+ break;
+ default:
+ dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd);
+ err = -EOPNOTSUPP;
+ }
+
+ /* FIXME Is this necessary? */
+ avc_tuner_status(fdtv, &stat);
+
+ return err;
+}
+
+static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait)
+{
+ return POLLIN;
+}
+
+static struct file_operations fdtv_ca_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = dvb_generic_ioctl,
+ .open = dvb_generic_open,
+ .release = dvb_generic_release,
+ .poll = fdtv_ca_io_poll,
+};
+
+static struct dvb_device fdtv_ca = {
+ .users = 1,
+ .readers = 1,
+ .writers = 1,
+ .fops = &fdtv_ca_fops,
+ .kernel_ioctl = fdtv_ca_ioctl,
+};
+
+int fdtv_ca_register(struct firedtv *fdtv)
+{
+ struct firedtv_tuner_status stat;
+ int err;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ if (!fdtv_ca_ready(&stat))
+ return -EFAULT;
+
+ err = dvb_register_device(&fdtv->adapter, &fdtv->cadev,
+ &fdtv_ca, fdtv, DVB_DEVICE_CA);
+
+ if (stat.ca_application_info == 0)
+ dev_err(fdtv->device, "CaApplicationInfo is not set\n");
+ if (stat.ca_date_time_request == 1)
+ avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval);
+
+ return err;
+}
+
+void fdtv_ca_release(struct firedtv *fdtv)
+{
+ if (fdtv->cadev)
+ dvb_unregister_device(fdtv->cadev);
+}
diff --git a/linux/drivers/media/dvb/firewire/firedtv-dvb.c b/linux/drivers/media/dvb/firewire/firedtv-dvb.c
new file mode 100644
index 000000000..9d308dd32
--- /dev/null
+++ b/linux/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -0,0 +1,364 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <dmxdev.h>
+#include <dvb_demux.h>
+#include <dvbdev.h>
+#include <dvb_frontend.h>
+
+#include "firedtv.h"
+
+static int alloc_channel(struct firedtv *fdtv)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ if (!__test_and_set_bit(i, &fdtv->channel_active))
+ break;
+ return i;
+}
+
+static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[])
+{
+ int i, n;
+
+ for (i = 0, n = 0; i < 16; i++)
+ if (test_bit(i, &fdtv->channel_active))
+ pid[n++] = fdtv->channel_pid[i];
+ *pidc = n;
+}
+
+static inline void dealloc_channel(struct firedtv *fdtv, int i)
+{
+ __clear_bit(i, &fdtv->channel_active);
+}
+
+int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ struct firedtv *fdtv = dvbdmxfeed->demux->priv;
+ int pidc, c, ret;
+ u16 pids[16];
+
+ switch (dvbdmxfeed->type) {
+ case DMX_TYPE_TS:
+ case DMX_TYPE_SEC:
+ break;
+ default:
+ dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n",
+ dvbdmxfeed->type);
+ return -EINVAL;
+ }
+
+ if (mutex_lock_interruptible(&fdtv->demux_mutex))
+ return -EINTR;
+
+ if (dvbdmxfeed->type == DMX_TYPE_TS) {
+ switch (dvbdmxfeed->pes_type) {
+ case DMX_TS_PES_VIDEO:
+ case DMX_TS_PES_AUDIO:
+ case DMX_TS_PES_TELETEXT:
+ case DMX_TS_PES_PCR:
+ case DMX_TS_PES_OTHER:
+ c = alloc_channel(fdtv);
+ break;
+ default:
+ dev_err(fdtv->device,
+ "can't start dmx feed: invalid pes type %u\n",
+ dvbdmxfeed->pes_type);
+ ret = -EINVAL;
+ goto out;
+ }
+ } else {
+ c = alloc_channel(fdtv);
+ }
+
+ if (c > 15) {
+ dev_err(fdtv->device, "can't start dmx feed: busy\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c;
+ fdtv->channel_pid[c] = dvbdmxfeed->pid;
+ collect_channels(fdtv, &pidc, pids);
+
+ if (dvbdmxfeed->pid == 8192) {
+ ret = avc_tuner_get_ts(fdtv);
+ if (ret) {
+ dealloc_channel(fdtv, c);
+ dev_err(fdtv->device, "can't get TS\n");
+ goto out;
+ }
+ } else {
+ ret = avc_tuner_set_pids(fdtv, pidc, pids);
+ if (ret) {
+ dealloc_channel(fdtv, c);
+ dev_err(fdtv->device, "can't set PIDs\n");
+ goto out;
+ }
+ }
+out:
+ mutex_unlock(&fdtv->demux_mutex);
+
+ return ret;
+}
+
+int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ struct dvb_demux *demux = dvbdmxfeed->demux;
+ struct firedtv *fdtv = demux->priv;
+ int pidc, c, ret;
+ u16 pids[16];
+
+ if (dvbdmxfeed->type == DMX_TYPE_TS &&
+ !((dvbdmxfeed->ts_type & TS_PACKET) &&
+ (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
+
+ if (dvbdmxfeed->ts_type & TS_DECODER) {
+ if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER ||
+ !demux->pesfilter[dvbdmxfeed->pes_type])
+ return -EINVAL;
+
+ demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
+ demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
+ }
+
+ if (!(dvbdmxfeed->ts_type & TS_DECODER &&
+ dvbdmxfeed->pes_type < DMX_TS_PES_OTHER))
+ return 0;
+ }
+
+ if (mutex_lock_interruptible(&fdtv->demux_mutex))
+ return -EINTR;
+
+ c = (unsigned long)dvbdmxfeed->priv;
+ dealloc_channel(fdtv, c);
+ collect_channels(fdtv, &pidc, pids);
+
+ ret = avc_tuner_set_pids(fdtv, pidc, pids);
+
+ mutex_unlock(&fdtv->demux_mutex);
+
+ return ret;
+}
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+int fdtv_dvb_register(struct firedtv *fdtv)
+{
+ int err;
+
+ err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type],
+ THIS_MODULE, fdtv->device, adapter_nr);
+ if (err < 0)
+ goto fail_log;
+
+ /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
+ fdtv->demux.dmx.capabilities = 0;
+
+ fdtv->demux.priv = fdtv;
+ fdtv->demux.filternum = 16;
+ fdtv->demux.feednum = 16;
+ fdtv->demux.start_feed = fdtv_start_feed;
+ fdtv->demux.stop_feed = fdtv_stop_feed;
+ fdtv->demux.write_to_decoder = NULL;
+
+ err = dvb_dmx_init(&fdtv->demux);
+ if (err)
+ goto fail_unreg_adapter;
+
+ fdtv->dmxdev.filternum = 16;
+ fdtv->dmxdev.demux = &fdtv->demux.dmx;
+ fdtv->dmxdev.capabilities = 0;
+
+ err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter);
+ if (err)
+ goto fail_dmx_release;
+
+ fdtv->frontend.source = DMX_FRONTEND_0;
+
+ err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend);
+ if (err)
+ goto fail_dmxdev_release;
+
+ err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx,
+ &fdtv->frontend);
+ if (err)
+ goto fail_rem_frontend;
+
+ dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
+
+ fdtv_frontend_init(fdtv);
+ err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
+ if (err)
+ goto fail_net_release;
+
+ err = fdtv_ca_register(fdtv);
+ if (err)
+ dev_info(fdtv->device,
+ "Conditional Access Module not enabled\n");
+ return 0;
+
+fail_net_release:
+ dvb_net_release(&fdtv->dvbnet);
+ fdtv->demux.dmx.close(&fdtv->demux.dmx);
+fail_rem_frontend:
+ fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
+fail_dmxdev_release:
+ dvb_dmxdev_release(&fdtv->dmxdev);
+fail_dmx_release:
+ dvb_dmx_release(&fdtv->demux);
+fail_unreg_adapter:
+ dvb_unregister_adapter(&fdtv->adapter);
+fail_log:
+ dev_err(fdtv->device, "DVB initialization failed\n");
+ return err;
+}
+
+void fdtv_dvb_unregister(struct firedtv *fdtv)
+{
+ fdtv_ca_release(fdtv);
+ dvb_unregister_frontend(&fdtv->fe);
+ dvb_net_release(&fdtv->dvbnet);
+ fdtv->demux.dmx.close(&fdtv->demux.dmx);
+ fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
+ dvb_dmxdev_release(&fdtv->dmxdev);
+ dvb_dmx_release(&fdtv->demux);
+ dvb_unregister_adapter(&fdtv->adapter);
+}
+
+const char *fdtv_model_names[] = {
+ [FIREDTV_UNKNOWN] = "unknown type",
+ [FIREDTV_DVB_S] = "FireDTV S/CI",
+ [FIREDTV_DVB_C] = "FireDTV C/CI",
+ [FIREDTV_DVB_T] = "FireDTV T/CI",
+ [FIREDTV_DVB_S2] = "FireDTV S2 ",
+};
+
+struct firedtv *fdtv_alloc(struct device *dev,
+ const struct firedtv_backend *backend,
+ const char *name, size_t name_len)
+{
+ struct firedtv *fdtv;
+ int i;
+
+ fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
+ if (!fdtv)
+ return NULL;
+
+ dev->driver_data = fdtv;
+ fdtv->device = dev;
+ fdtv->isochannel = -1;
+ fdtv->voltage = 0xff;
+ fdtv->tone = 0xff;
+ fdtv->backend = backend;
+
+ mutex_init(&fdtv->avc_mutex);
+ init_waitqueue_head(&fdtv->avc_wait);
+ fdtv->avc_reply_received = true;
+ mutex_init(&fdtv->demux_mutex);
+ INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
+
+ for (i = ARRAY_SIZE(fdtv_model_names); --i; )
+ if (strlen(fdtv_model_names[i]) <= name_len &&
+ strncmp(name, fdtv_model_names[i], name_len) == 0)
+ break;
+ fdtv->type = i;
+
+ return fdtv;
+}
+
+#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
+ IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
+
+#define DIGITAL_EVERYWHERE_OUI 0x001287
+#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
+#define AVC_SW_VERSION_ENTRY 0x010001
+
+static struct ieee1394_device_id fdtv_id_table[] = {
+ {
+ /* FloppyDTV S/CI and FloppyDTV S2 */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000024,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FloppyDTV T/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000025,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FloppyDTV C/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000026,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FireDTV S/CI and FloppyDTV S2 */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000034,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FireDTV T/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000035,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FireDTV C/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000036,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {}
+};
+MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
+
+static int __init fdtv_init(void)
+{
+ return fdtv_1394_init(fdtv_id_table);
+}
+
+static void __exit fdtv_exit(void)
+{
+ fdtv_1394_exit();
+}
+
+module_init(fdtv_init);
+module_exit(fdtv_exit);
+
+MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
+MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
+MODULE_DESCRIPTION("FireDTV DVB Driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("FireDTV DVB");
diff --git a/linux/drivers/media/dvb/firewire/firedtv-fe.c b/linux/drivers/media/dvb/firewire/firedtv-fe.c
new file mode 100644
index 000000000..7ba43630a
--- /dev/null
+++ b/linux/drivers/media/dvb/firewire/firedtv-fe.c
@@ -0,0 +1,247 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <dvb_frontend.h>
+
+#include "firedtv.h"
+
+static int fdtv_dvb_init(struct dvb_frontend *fe)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ int err;
+
+ /* FIXME - allocate free channel at IRM */
+ fdtv->isochannel = fdtv->adapter.num;
+
+ err = cmp_establish_pp_connection(fdtv, fdtv->subunit,
+ fdtv->isochannel);
+ if (err) {
+ dev_err(fdtv->device,
+ "could not establish point to point connection\n");
+ return err;
+ }
+
+ return fdtv->backend->start_iso(fdtv);
+}
+
+static int fdtv_sleep(struct dvb_frontend *fe)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ fdtv->backend->stop_iso(fdtv);
+ cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel);
+ fdtv->isochannel = -1;
+ return 0;
+}
+
+#define LNBCONTROL_DONTCARE 0xff
+
+static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe,
+ struct dvb_diseqc_master_cmd *cmd)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE,
+ LNBCONTROL_DONTCARE, 1, cmd);
+}
+
+static int fdtv_diseqc_send_burst(struct dvb_frontend *fe,
+ fe_sec_mini_cmd_t minicmd)
+{
+ return 0;
+}
+
+static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ fdtv->tone = tone;
+ return 0;
+}
+
+static int fdtv_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ fdtv->voltage = voltage;
+ return 0;
+}
+
+static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ if (stat.no_rf)
+ *status = 0;
+ else
+ *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC |
+ FE_HAS_CARRIER | FE_HAS_LOCK;
+ return 0;
+}
+
+static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ *ber = stat.ber;
+ return 0;
+}
+
+static int fdtv_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ *strength = stat.signal_strength << 8;
+ return 0;
+}
+
+static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ /* C/N[dB] = -10 * log10(snr / 65535) */
+ *snr = stat.carrier_noise_ratio * 257;
+ return 0;
+}
+
+static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ return -EOPNOTSUPP;
+}
+
+#define ACCEPTED 0x9
+
+static int fdtv_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */
+ if (avc_tuner_dsd(fdtv, params) != ACCEPTED)
+ return -EINVAL;
+ else
+ return 0; /* not sure of this... */
+}
+
+static int fdtv_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ return -EOPNOTSUPP;
+}
+
+void fdtv_frontend_init(struct firedtv *fdtv)
+{
+ struct dvb_frontend_ops *ops = &fdtv->fe.ops;
+ struct dvb_frontend_info *fi = &ops->info;
+
+ ops->init = fdtv_dvb_init;
+ ops->sleep = fdtv_sleep;
+
+ ops->set_frontend = fdtv_set_frontend;
+ ops->get_frontend = fdtv_get_frontend;
+
+ ops->read_status = fdtv_read_status;
+ ops->read_ber = fdtv_read_ber;
+ ops->read_signal_strength = fdtv_read_signal_strength;
+ ops->read_snr = fdtv_read_snr;
+ ops->read_ucblocks = fdtv_read_uncorrected_blocks;
+
+ ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd;
+ ops->diseqc_send_burst = fdtv_diseqc_send_burst;
+ ops->set_tone = fdtv_set_tone;
+ ops->set_voltage = fdtv_set_voltage;
+
+ switch (fdtv->type) {
+ case FIREDTV_DVB_S:
+ case FIREDTV_DVB_S2:
+ fi->type = FE_QPSK;
+
+ fi->frequency_min = 950000;
+ fi->frequency_max = 2150000;
+ fi->frequency_stepsize = 125;
+ fi->symbol_rate_min = 1000000;
+ fi->symbol_rate_max = 40000000;
+
+ fi->caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 |
+ FE_CAN_FEC_2_3 |
+ FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 |
+ FE_CAN_FEC_7_8 |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK;
+ break;
+
+ case FIREDTV_DVB_C:
+ fi->type = FE_QAM;
+
+ fi->frequency_min = 47000000;
+ fi->frequency_max = 866000000;
+ fi->frequency_stepsize = 62500;
+ fi->symbol_rate_min = 870000;
+ fi->symbol_rate_max = 6900000;
+
+ fi->caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_QAM_16 |
+ FE_CAN_QAM_32 |
+ FE_CAN_QAM_64 |
+ FE_CAN_QAM_128 |
+ FE_CAN_QAM_256 |
+ FE_CAN_QAM_AUTO;
+ break;
+
+ case FIREDTV_DVB_T:
+ fi->type = FE_OFDM;
+
+ fi->frequency_min = 49000000;
+ fi->frequency_max = 861000000;
+ fi->frequency_stepsize = 62500;
+
+ fi->caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_2_3 |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_HIERARCHY_AUTO;
+ break;
+
+ default:
+ dev_err(fdtv->device, "no frontend for model type %d\n",
+ fdtv->type);
+ }
+ strcpy(fi->name, fdtv_model_names[fdtv->type]);
+
+ fdtv->fe.dvb = &fdtv->adapter;
+ fdtv->fe.sec_priv = fdtv;
+}
diff --git a/linux/drivers/media/dvb/firewire/firedtv-rc.c b/linux/drivers/media/dvb/firewire/firedtv-rc.c
new file mode 100644
index 000000000..46a6324d7
--- /dev/null
+++ b/linux/drivers/media/dvb/firewire/firedtv-rc.c
@@ -0,0 +1,190 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/bitops.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "firedtv.h"
+
+/* fixed table with older keycodes, geared towards MythTV */
+const static u16 oldtable[] = {
+
+ /* code from device: 0x4501...0x451f */
+
+ KEY_ESC,
+ KEY_F9,
+ KEY_1,
+ KEY_2,
+ KEY_3,
+ KEY_4,
+ KEY_5,
+ KEY_6,
+ KEY_7,
+ KEY_8,
+ KEY_9,
+ KEY_I,
+ KEY_0,
+ KEY_ENTER,
+ KEY_RED,
+ KEY_UP,
+ KEY_GREEN,
+ KEY_F10,
+ KEY_SPACE,
+ KEY_F11,
+ KEY_YELLOW,
+ KEY_DOWN,
+ KEY_BLUE,
+ KEY_Z,
+ KEY_P,
+ KEY_PAGEDOWN,
+ KEY_LEFT,
+ KEY_W,
+ KEY_RIGHT,
+ KEY_P,
+ KEY_M,
+
+ /* code from device: 0x4540...0x4542 */
+
+ KEY_R,
+ KEY_V,
+ KEY_C,
+};
+
+/* user-modifiable table for a remote as sold in 2008 */
+const static u16 keytable[] = {
+
+ /* code from device: 0x0300...0x031f */
+
+ [0x00] = KEY_POWER,
+ [0x01] = KEY_SLEEP,
+ [0x02] = KEY_STOP,
+ [0x03] = KEY_OK,
+ [0x04] = KEY_RIGHT,
+ [0x05] = KEY_1,
+ [0x06] = KEY_2,
+ [0x07] = KEY_3,
+ [0x08] = KEY_LEFT,
+ [0x09] = KEY_4,
+ [0x0a] = KEY_5,
+ [0x0b] = KEY_6,
+ [0x0c] = KEY_UP,
+ [0x0d] = KEY_7,
+ [0x0e] = KEY_8,
+ [0x0f] = KEY_9,
+ [0x10] = KEY_DOWN,
+ [0x11] = KEY_TITLE, /* "OSD" - fixme */
+ [0x12] = KEY_0,
+ [0x13] = KEY_F20, /* "16:9" - fixme */
+ [0x14] = KEY_SCREEN, /* "FULL" - fixme */
+ [0x15] = KEY_MUTE,
+ [0x16] = KEY_SUBTITLE,
+ [0x17] = KEY_RECORD,
+ [0x18] = KEY_TEXT,
+ [0x19] = KEY_AUDIO,
+ [0x1a] = KEY_RED,
+ [0x1b] = KEY_PREVIOUS,
+ [0x1c] = KEY_REWIND,
+ [0x1d] = KEY_PLAYPAUSE,
+ [0x1e] = KEY_NEXT,
+ [0x1f] = KEY_VOLUMEUP,
+
+ /* code from device: 0x0340...0x0354 */
+
+ [0x20] = KEY_CHANNELUP,
+ [0x21] = KEY_F21, /* "4:3" - fixme */
+ [0x22] = KEY_TV,
+ [0x23] = KEY_DVD,
+ [0x24] = KEY_VCR,
+ [0x25] = KEY_AUX,
+ [0x26] = KEY_GREEN,
+ [0x27] = KEY_YELLOW,
+ [0x28] = KEY_BLUE,
+ [0x29] = KEY_CHANNEL, /* "CH.LIST" */
+ [0x2a] = KEY_VENDOR, /* "CI" - fixme */
+ [0x2b] = KEY_VOLUMEDOWN,
+ [0x2c] = KEY_CHANNELDOWN,
+ [0x2d] = KEY_LAST,
+ [0x2e] = KEY_INFO,
+ [0x2f] = KEY_FORWARD,
+ [0x30] = KEY_LIST,
+ [0x31] = KEY_FAVORITES,
+ [0x32] = KEY_MENU,
+ [0x33] = KEY_EPG,
+ [0x34] = KEY_EXIT,
+};
+
+int fdtv_register_rc(struct firedtv *fdtv, struct device *dev)
+{
+ struct input_dev *idev;
+ int i, err;
+
+ idev = input_allocate_device();
+ if (!idev)
+ return -ENOMEM;
+
+ fdtv->remote_ctrl_dev = idev;
+ idev->name = "FireDTV remote control";
+ idev->dev.parent = dev;
+ idev->evbit[0] = BIT_MASK(EV_KEY);
+ idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL);
+ if (!idev->keycode) {
+ err = -ENOMEM;
+ goto fail;
+ }
+ idev->keycodesize = sizeof(keytable[0]);
+ idev->keycodemax = ARRAY_SIZE(keytable);
+
+ for (i = 0; i < ARRAY_SIZE(keytable); i++)
+ set_bit(keytable[i], idev->keybit);
+
+ err = input_register_device(idev);
+ if (err)
+ goto fail_free_keymap;
+
+ return 0;
+
+fail_free_keymap:
+ kfree(idev->keycode);
+fail:
+ input_free_device(idev);
+ return err;
+}
+
+void fdtv_unregister_rc(struct firedtv *fdtv)
+{
+ kfree(fdtv->remote_ctrl_dev->keycode);
+ input_unregister_device(fdtv->remote_ctrl_dev);
+}
+
+void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
+{
+ u16 *keycode = fdtv->remote_ctrl_dev->keycode;
+
+ if (code >= 0x0300 && code <= 0x031f)
+ code = keycode[code - 0x0300];
+ else if (code >= 0x0340 && code <= 0x0354)
+ code = keycode[code - 0x0320];
+ else if (code >= 0x4501 && code <= 0x451f)
+ code = oldtable[code - 0x4501];
+ else if (code >= 0x4540 && code <= 0x4542)
+ code = oldtable[code - 0x4521];
+ else {
+ printk(KERN_DEBUG "firedtv: invalid key code 0x%04x "
+ "from remote control\n", code);
+ return;
+ }
+
+ input_report_key(fdtv->remote_ctrl_dev, code, 1);
+ input_report_key(fdtv->remote_ctrl_dev, code, 0);
+}
diff --git a/linux/drivers/media/dvb/firewire/firedtv.h b/linux/drivers/media/dvb/firewire/firedtv.h
new file mode 100644
index 000000000..d48530b81
--- /dev/null
+++ b/linux/drivers/media/dvb/firewire/firedtv.h
@@ -0,0 +1,182 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef _FIREDTV_H
+#define _FIREDTV_H
+
+#include <linux/dvb/dmx.h>
+#include <linux/dvb/frontend.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock_types.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <demux.h>
+#include <dmxdev.h>
+#include <dvb_demux.h>
+#include <dvb_frontend.h>
+#include <dvb_net.h>
+#include <dvbdev.h>
+
+struct firedtv_tuner_status {
+ unsigned active_system:8;
+ unsigned searching:1;
+ unsigned moving:1;
+ unsigned no_rf:1;
+ unsigned input:1;
+ unsigned selected_antenna:7;
+ unsigned ber:32;
+ unsigned signal_strength:8;
+ unsigned raster_frequency:2;
+ unsigned rf_frequency:22;
+ unsigned man_dep_info_length:8;
+ unsigned front_end_error:1;
+ unsigned antenna_error:1;
+ unsigned front_end_power_status:1;
+ unsigned power_supply:1;
+ unsigned carrier_noise_ratio:16;
+ unsigned power_supply_voltage:8;
+ unsigned antenna_voltage:8;
+ unsigned firewire_bus_voltage:8;
+ unsigned ca_mmi:1;
+ unsigned ca_pmt_reply:1;
+ unsigned ca_date_time_request:1;
+ unsigned ca_application_info:1;
+ unsigned ca_module_present_status:1;
+ unsigned ca_dvb_flag:1;
+ unsigned ca_error_flag:1;
+ unsigned ca_initialization_status:1;
+};
+
+enum model_type {
+ FIREDTV_UNKNOWN = 0,
+ FIREDTV_DVB_S = 1,
+ FIREDTV_DVB_C = 2,
+ FIREDTV_DVB_T = 3,
+ FIREDTV_DVB_S2 = 4,
+};
+
+struct device;
+struct input_dev;
+struct firedtv;
+
+struct firedtv_backend {
+ int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg);
+ int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
+ int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
+ int (*start_iso)(struct firedtv *fdtv);
+ void (*stop_iso)(struct firedtv *fdtv);
+};
+
+struct firedtv {
+ struct device *device;
+ struct list_head list;
+
+ struct dvb_adapter adapter;
+ struct dmxdev dmxdev;
+ struct dvb_demux demux;
+ struct dmx_frontend frontend;
+ struct dvb_net dvbnet;
+ struct dvb_frontend fe;
+
+ struct dvb_device *cadev;
+ int ca_last_command;
+ int ca_time_interval;
+
+ struct mutex avc_mutex;
+ wait_queue_head_t avc_wait;
+ bool avc_reply_received;
+ struct work_struct remote_ctrl_work;
+ struct input_dev *remote_ctrl_dev;
+
+ enum model_type type;
+ char subunit;
+ char isochannel;
+ fe_sec_voltage_t voltage;
+ fe_sec_tone_mode_t tone;
+
+ const struct firedtv_backend *backend;
+ void *backend_data;
+
+ struct mutex demux_mutex;
+ unsigned long channel_active;
+ u16 channel_pid[16];
+
+ size_t response_length;
+ u8 response[512];
+};
+
+/* firedtv-1394.c */
+#ifdef CONFIG_DVB_FIREDTV_IEEE1394
+int fdtv_1394_init(struct ieee1394_device_id id_table[]);
+void fdtv_1394_exit(void);
+#else
+static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; }
+static inline void fdtv_1394_exit(void) {}
+#endif
+
+/* firedtv-avc.c */
+int avc_recv(struct firedtv *fdtv, void *data, size_t length);
+int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat);
+struct dvb_frontend_parameters;
+int avc_tuner_dsd(struct firedtv *fdtv, struct dvb_frontend_parameters *params);
+int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]);
+int avc_tuner_get_ts(struct firedtv *fdtv);
+int avc_identify_subunit(struct firedtv *fdtv);
+struct dvb_diseqc_master_cmd;
+int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
+ char conttone, char nrdiseq,
+ struct dvb_diseqc_master_cmd *diseqcmd);
+void avc_remote_ctrl_work(struct work_struct *work);
+int avc_register_remote_control(struct firedtv *fdtv);
+int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len);
+int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len);
+int avc_ca_reset(struct firedtv *fdtv);
+int avc_ca_pmt(struct firedtv *fdtv, char *app_info, int length);
+int avc_ca_get_time_date(struct firedtv *fdtv, int *interval);
+int avc_ca_enter_menu(struct firedtv *fdtv);
+int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len);
+int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel);
+void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel);
+
+/* firedtv-ci.c */
+int fdtv_ca_register(struct firedtv *fdtv);
+void fdtv_ca_release(struct firedtv *fdtv);
+
+/* firedtv-dvb.c */
+int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed);
+int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
+int fdtv_dvb_register(struct firedtv *fdtv);
+void fdtv_dvb_unregister(struct firedtv *fdtv);
+struct firedtv *fdtv_alloc(struct device *dev,
+ const struct firedtv_backend *backend,
+ const char *name, size_t name_len);
+extern const char *fdtv_model_names[];
+
+/* firedtv-fe.c */
+void fdtv_frontend_init(struct firedtv *fdtv);
+
+/* firedtv-rc.c */
+#ifdef CONFIG_DVB_FIREDTV_INPUT
+int fdtv_register_rc(struct firedtv *fdtv, struct device *dev);
+void fdtv_unregister_rc(struct firedtv *fdtv);
+void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code);
+#else
+static inline int fdtv_register_rc(struct firedtv *fdtv,
+ struct device *dev) { return 0; }
+static inline void fdtv_unregister_rc(struct firedtv *fdtv) {}
+static inline void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) {}
+#endif
+
+#endif /* _FIREDTV_H */
diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c
index 66f591937..63e4d0ec6 100644
--- a/linux/drivers/media/dvb/siano/sms-cards.c
+++ b/linux/drivers/media/dvb/siano/sms-cards.c
@@ -19,6 +19,10 @@
#include "sms-cards.h"
+static int sms_dbg;
+module_param_named(cards_dbg, sms_dbg, int, 0644);
+MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
+
static struct sms_board sms_boards[] = {
[SMS_BOARD_UNKNOWN] = {
.name = "Unknown board",
diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c
index 812b57ab7..8c37a060b 100644
--- a/linux/drivers/media/dvb/siano/smscoreapi.c
+++ b/linux/drivers/media/dvb/siano/smscoreapi.c
@@ -34,7 +34,7 @@
#include "smscoreapi.h"
#include "sms-cards.h"
-int sms_dbg;
+static int sms_dbg;
module_param_named(debug, sms_dbg, int, 0644);
MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h
index 14dcbdd80..85da09f86 100644
--- a/linux/drivers/media/dvb/siano/smscoreapi.h
+++ b/linux/drivers/media/dvb/siano/smscoreapi.h
@@ -578,8 +578,6 @@ int smscore_led_state(struct smscore_device_t *core, int led);
/* ------------------------------------------------------------------------ */
-extern int sms_dbg;
-
#define DBG_INFO 1
#define DBG_ADV 2
diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c
index c91f6f242..035bd52c9 100644
--- a/linux/drivers/media/dvb/siano/smsdvb.c
+++ b/linux/drivers/media/dvb/siano/smsdvb.c
@@ -50,6 +50,10 @@ struct smsdvb_client_t {
static struct list_head g_smsdvb_clients;
static struct mutex g_smsdvb_clientslock;
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
{
struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c
index b25ab60a4..67be79549 100644
--- a/linux/drivers/media/dvb/siano/smsusb.c
+++ b/linux/drivers/media/dvb/siano/smsusb.c
@@ -27,6 +27,10 @@
#include "smscoreapi.h"
#include "sms-cards.h"
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
#define USB1_BUFFER_SIZE 0x1000
#define USB2_BUFFER_SIZE 0x4000
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index bb7df8c18..6c26618b8 100644
--- a/linux/drivers/media/video/Kconfig
+++ b/linux/drivers/media/video/Kconfig
@@ -253,7 +253,7 @@ comment "Video decoders"
config VIDEO_BT819
tristate "BT819A VideoStream decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for BT819A video decoder.
@@ -262,7 +262,7 @@ config VIDEO_BT819
config VIDEO_BT856
tristate "BT856 VideoStream decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for BT856 video decoder.
@@ -271,7 +271,7 @@ config VIDEO_BT856
config VIDEO_BT866
tristate "BT866 VideoStream decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for BT866 video decoder.
@@ -280,7 +280,7 @@ config VIDEO_BT866
config VIDEO_KS0127
tristate "KS0127 video decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for KS0127 video decoder.
@@ -363,7 +363,7 @@ config VIDEO_TVP5150
config VIDEO_VPX3220
tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for VPX322x video decoders.
@@ -401,7 +401,7 @@ config VIDEO_SAA7127
config VIDEO_SAA7185
tristate "Philips SAA7185 video encoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Philips SAA7185 video encoder.
@@ -410,7 +410,7 @@ config VIDEO_SAA7185
config VIDEO_ADV7170
tristate "Analog Devices ADV7170 video encoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Analog Devices ADV7170 video encoder driver
@@ -419,7 +419,7 @@ config VIDEO_ADV7170
config VIDEO_ADV7175
tristate "Analog Devices ADV7175 video encoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Analog Devices ADV7175 video encoder driver
diff --git a/linux/drivers/media/video/pxa_camera.h b/linux/drivers/media/video/pxa_camera.h
deleted file mode 100644
index 89cbfc9a3..000000000
--- a/linux/drivers/media/video/pxa_camera.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Camera Interface */
-#define CICR0 __REG(0x50000000)
-#define CICR1 __REG(0x50000004)
-#define CICR2 __REG(0x50000008)
-#define CICR3 __REG(0x5000000C)
-#define CICR4 __REG(0x50000010)
-#define CISR __REG(0x50000014)
-#define CIFR __REG(0x50000018)
-#define CITOR __REG(0x5000001C)
-#define CIBR0 __REG(0x50000028)
-#define CIBR1 __REG(0x50000030)
-#define CIBR2 __REG(0x50000038)
-
-#define CICR0_DMAEN (1 << 31) /* DMA request enable */
-#define CICR0_PAR_EN (1 << 30) /* Parity enable */
-#define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */
-#define CICR0_ENB (1 << 28) /* Camera interface enable */
-#define CICR0_DIS (1 << 27) /* Camera interface disable */
-#define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */
-#define CICR0_TOM (1 << 9) /* Time-out mask */
-#define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */
-#define CICR0_FEM (1 << 7) /* FIFO-empty mask */
-#define CICR0_EOLM (1 << 6) /* End-of-line mask */
-#define CICR0_PERRM (1 << 5) /* Parity-error mask */
-#define CICR0_QDM (1 << 4) /* Quick-disable mask */
-#define CICR0_CDM (1 << 3) /* Disable-done mask */
-#define CICR0_SOFM (1 << 2) /* Start-of-frame mask */
-#define CICR0_EOFM (1 << 1) /* End-of-frame mask */
-#define CICR0_FOM (1 << 0) /* FIFO-overrun mask */
-
-#define CICR1_TBIT (1 << 31) /* Transparency bit */
-#define CICR1_RGBT_CONV (0x3 << 29) /* RGBT conversion mask */
-#define CICR1_PPL (0x7ff << 15) /* Pixels per line mask */
-#define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */
-#define CICR1_RGB_F (1 << 11) /* RGB format */
-#define CICR1_YCBCR_F (1 << 10) /* YCbCr format */
-#define CICR1_RGB_BPP (0x7 << 7) /* RGB bis per pixel mask */
-#define CICR1_RAW_BPP (0x3 << 5) /* Raw bis per pixel mask */
-#define CICR1_COLOR_SP (0x3 << 3) /* Color space mask */
-#define CICR1_DW (0x7 << 0) /* Data width mask */
-
-#define CICR2_BLW (0xff << 24) /* Beginning-of-line pixel clock
- wait count mask */
-#define CICR2_ELW (0xff << 16) /* End-of-line pixel clock
- wait count mask */
-#define CICR2_HSW (0x3f << 10) /* Horizontal sync pulse width mask */
-#define CICR2_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock
- wait count mask */
-#define CICR2_FSW (0x7 << 0) /* Frame stabilization
- wait count mask */
-
-#define CICR3_BFW (0xff << 24) /* Beginning-of-frame line clock
- wait count mask */
-#define CICR3_EFW (0xff << 16) /* End-of-frame line clock
- wait count mask */
-#define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */
-#define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock
- wait count mask */
-#define CICR3_LPF (0x7ff << 0) /* Lines per frame mask */
-
-#define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */
-#define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */
-#define CICR4_PCP (1 << 22) /* Pixel clock polarity */
-#define CICR4_HSP (1 << 21) /* Horizontal sync polarity */
-#define CICR4_VSP (1 << 20) /* Vertical sync polarity */
-#define CICR4_MCLK_EN (1 << 19) /* MCLK enable */
-#define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */
-#define CICR4_DIV (0xff << 0) /* Clock divisor mask */
-
-#define CISR_FTO (1 << 15) /* FIFO time-out */
-#define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */
-#define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */
-#define CISR_RDAV_0 (1 << 12) /* Channel 0 receive data available */
-#define CISR_FEMPTY_2 (1 << 11) /* Channel 2 FIFO empty */
-#define CISR_FEMPTY_1 (1 << 10) /* Channel 1 FIFO empty */
-#define CISR_FEMPTY_0 (1 << 9) /* Channel 0 FIFO empty */
-#define CISR_EOL (1 << 8) /* End of line */
-#define CISR_PAR_ERR (1 << 7) /* Parity error */
-#define CISR_CQD (1 << 6) /* Camera interface quick disable */
-#define CISR_CDD (1 << 5) /* Camera interface disable done */
-#define CISR_SOF (1 << 4) /* Start of frame */
-#define CISR_EOF (1 << 3) /* End of frame */
-#define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */
-#define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */
-#define CISR_IFO_0 (1 << 0) /* FIFO overrun for Channel 0 */
-
-#define CIFR_FLVL2 (0x7f << 23) /* FIFO 2 level mask */
-#define CIFR_FLVL1 (0x7f << 16) /* FIFO 1 level mask */
-#define CIFR_FLVL0 (0xff << 8) /* FIFO 0 level mask */
-#define CIFR_THL_0 (0x3 << 4) /* Threshold Level for Channel 0 FIFO */
-#define CIFR_RESET_F (1 << 3) /* Reset input FIFOs */
-#define CIFR_FEN2 (1 << 2) /* FIFO enable for channel 2 */
-#define CIFR_FEN1 (1 << 1) /* FIFO enable for channel 1 */
-#define CIFR_FEN0 (1 << 0) /* FIFO enable for channel 0 */
-
diff --git a/linux/drivers/media/video/tvmixer.c b/linux/drivers/media/video/tvmixer.c
deleted file mode 100644
index bc6702a0a..000000000
--- a/linux/drivers/media/video/tvmixer.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/smp_lock.h>
-#include "compat.h"
-#include <linux/videodev2.h>
-#include <linux/init.h>
-#include <linux/kdev_t.h>
-#include <linux/sound.h>
-#include <linux/soundcard.h>
-
-#include <asm/uaccess.h>
-
-#define DEV_MAX 4
-
-static int devnr = -1;
-module_param(devnr, int, 0644);
-
-MODULE_AUTHOR("Gerd Knorr");
-MODULE_LICENSE("GPL");
-
-/* ----------------------------------------------------------------------- */
-
-struct TVMIXER {
- struct i2c_client *dev;
- int minor;
- int count;
-};
-
-static struct TVMIXER devices[DEV_MAX];
-
-static int tvmixer_adapters(struct i2c_adapter *adap);
-static int tvmixer_clients(struct i2c_client *client);
-
-/* ----------------------------------------------------------------------- */
-
-static int mix_to_v4l(int i)
-{
- int r;
-
- r = ((i & 0xff) * 65536 + 50) / 100;
- if (r > 65535) r = 65535;
- if (r < 0) r = 0;
- return r;
-}
-
-static int v4l_to_mix(int i)
-{
- int r;
-
- r = (i * 100 + 32768) / 65536;
- if (r > 100) r = 100;
- if (r < 0) r = 0;
- return r | (r << 8);
-}
-
-static int v4l_to_mix2(int l, int r)
-{
- r = (r * 100 + 32768) / 65536;
- if (r > 100) r = 100;
- if (r < 0) r = 0;
- l = (l * 100 + 32768) / 65536;
- if (l > 100) l = 100;
- if (l < 0) l = 0;
- return (r << 8) | l;
-}
-
-static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct video_audio va;
- int left,right,ret,val = 0;
- struct TVMIXER *mix = file->private_data;
- struct i2c_client *client = mix->dev;
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
-
- if (NULL == client)
- return -ENODEV;
-
- if (cmd == SOUND_MIXER_INFO) {
- mixer_info info;
- strlcpy(info.id, "tv card", sizeof(info.id));
- strlcpy(info.name, client->name, sizeof(info.name));
- info.modify_counter = 42 /* FIXME */;
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (cmd == SOUND_OLD_MIXER_INFO) {
- _old_mixer_info info;
- strlcpy(info.id, "tv card", sizeof(info.id));
- strlcpy(info.name, client->name, sizeof(info.name));
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, p);
-
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- if (get_user(val, p))
- return -EFAULT;
-
- /* read state */
- memset(&va,0,sizeof(va));
- client->driver->command(client,VIDIOCGAUDIO,&va);
-
- switch (cmd) {
- case MIXER_READ(SOUND_MIXER_RECMASK):
- case MIXER_READ(SOUND_MIXER_CAPS):
- case MIXER_READ(SOUND_MIXER_RECSRC):
- case MIXER_WRITE(SOUND_MIXER_RECSRC):
- ret = 0;
- break;
-
- case MIXER_READ(SOUND_MIXER_STEREODEVS):
- ret = SOUND_MASK_VOLUME;
- break;
- case MIXER_READ(SOUND_MIXER_DEVMASK):
- ret = SOUND_MASK_VOLUME;
- if (va.flags & VIDEO_AUDIO_BASS)
- ret |= SOUND_MASK_BASS;
- if (va.flags & VIDEO_AUDIO_TREBLE)
- ret |= SOUND_MASK_TREBLE;
- break;
-
- case MIXER_WRITE(SOUND_MIXER_VOLUME):
- left = mix_to_v4l(val);
- right = mix_to_v4l(val >> 8);
- va.volume = max(left,right);
- va.balance = (32768*min(left,right)) / (va.volume ? va.volume : 1);
- va.balance = (left<right) ? (65535-va.balance) : va.balance;
- if (va.volume)
- va.flags &= ~VIDEO_AUDIO_MUTE;
- client->driver->command(client,VIDIOCSAUDIO,&va);
- client->driver->command(client,VIDIOCGAUDIO,&va);
- /* fall throuth */
- case MIXER_READ(SOUND_MIXER_VOLUME):
- left = (min(65536 - va.balance,32768) *
- va.volume) / 32768;
- right = (min(va.balance,(u16)32768) *
- va.volume) / 32768;
- ret = v4l_to_mix2(left,right);
- break;
-
- case MIXER_WRITE(SOUND_MIXER_BASS):
- va.bass = mix_to_v4l(val);
- client->driver->command(client,VIDIOCSAUDIO,&va);
- client->driver->command(client,VIDIOCGAUDIO,&va);
- /* fall throuth */
- case MIXER_READ(SOUND_MIXER_BASS):
- ret = v4l_to_mix(va.bass);
- break;
-
- case MIXER_WRITE(SOUND_MIXER_TREBLE):
- va.treble = mix_to_v4l(val);
- client->driver->command(client,VIDIOCSAUDIO,&va);
- client->driver->command(client,VIDIOCGAUDIO,&va);
- /* fall throuth */
- case MIXER_READ(SOUND_MIXER_TREBLE):
- ret = v4l_to_mix(va.treble);
- break;
-
- default:
- return -EINVAL;
- }
- if (put_user(ret, p))
- return -EFAULT;
- return 0;
-}
-
-static int tvmixer_open(struct inode *inode, struct file *file)
-{
- int i, minor = iminor(inode);
- struct TVMIXER *mix = NULL;
- struct i2c_client *client = NULL;
-
- lock_kernel();
- for (i = 0; i < DEV_MAX; i++) {
- if (devices[i].minor == minor) {
- mix = devices+i;
- client = mix->dev;
- break;
- }
- }
-
- if (NULL == client) {
- unlock_kernel();
- return -ENODEV;
- }
-
- /* lock bttv in memory while the mixer is in use */
- file->private_data = mix;
- if (client->adapter->owner)
- try_module_get(client->adapter->owner);
- unlock_kernel();
- return 0;
-}
-
-static int tvmixer_release(struct inode *inode, struct file *file)
-{
- struct TVMIXER *mix = file->private_data;
- struct i2c_client *client;
-
- client = mix->dev;
- if (NULL == client) {
- return -ENODEV;
- }
-
- module_put(client->adapter->owner);
- return 0;
-}
-
-static struct i2c_driver driver = {
- .driver = {
- .name = "tvmixer",
- },
-#ifndef I2C_DF_DUMMY
- .detach_adapter = tvmixer_adapters,
-#endif
- .attach_adapter = tvmixer_adapters,
- .detach_client = tvmixer_clients,
-};
-
-static const struct file_operations tvmixer_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .ioctl = tvmixer_ioctl,
- .open = tvmixer_open,
- .release = tvmixer_release,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int tvmixer_adapters(struct i2c_adapter *adap)
-{
- struct i2c_client *client;
-
- list_for_each_entry(client, &adap->clients, list)
- tvmixer_clients(client);
- return 0;
-}
-
-static int tvmixer_clients(struct i2c_client *client)
-{
- struct video_audio va;
- int i,minor;
-
- if (!(client->adapter->class & I2C_CLASS_TV_ANALOG))
- return -1;
-
- /* unregister ?? */
- for (i = 0; i < DEV_MAX; i++) {
- if (devices[i].dev == client) {
- /* unregister */
- unregister_sound_mixer(devices[i].minor);
- devices[i].dev = NULL;
- devices[i].minor = -1;
- printk("tvmixer: %s unregistered (#1)\n",
- client->name);
- return 0;
- }
- }
-
- /* look for a free slot */
- for (i = 0; i < DEV_MAX; i++)
- if (NULL == devices[i].dev)
- break;
- if (i == DEV_MAX) {
- printk(KERN_WARNING "tvmixer: DEV_MAX too small\n");
- return -1;
- }
-
- /* audio chip with mixer ??? */
- if (NULL == client->driver->command)
- return -1;
- memset(&va,0,sizeof(va));
- if (0 != client->driver->command(client,VIDIOCGAUDIO,&va))
- return -1;
- if (0 == (va.flags & VIDEO_AUDIO_VOLUME))
- return -1;
-
- /* everything is fine, register */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
- if ((minor = register_sound_mixer(&tvmixer_fops, devnr)) < 0) {
-#else
- if ((minor = register_sound_mixer((struct file_operations *)&tvmixer_fops, devnr)) < 0) {
-#endif
- printk(KERN_ERR "tvmixer: cannot allocate mixer device\n");
- return -1;
- }
-
- devices[i].minor = minor;
- devices[i].count = 0;
- devices[i].dev = client;
- printk("tvmixer: %s (%s) registered with minor %d\n",
- client->name,client->adapter->name,minor);
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int __init tvmixer_init_module(void)
-{
- int i;
-
- for (i = 0; i < DEV_MAX; i++)
- devices[i].minor = -1;
-
- return i2c_add_driver(&driver);
-}
-
-static void __exit tvmixer_cleanup_module(void)
-{
- int i;
-
- i2c_del_driver(&driver);
- for (i = 0; i < DEV_MAX; i++) {
- if (devices[i].minor != -1) {
- unregister_sound_mixer(devices[i].minor);
- printk("tvmixer: %s unregistered (#2)\n",
- devices[i].dev->name);
- }
- }
-}
-
-module_init(tvmixer_init_module);
-module_exit(tvmixer_cleanup_module);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/linux/include/sound/tea575x-tuner.h b/linux/include/sound/tea575x-tuner.h
index b09cf5882..4c6443a7a 100644
--- a/linux/include/sound/tea575x-tuner.h
+++ b/linux/include/sound/tea575x-tuner.h
@@ -23,24 +23,16 @@
*/
#include "compat.h"
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
-typedef struct snd_tea575x tea575x_t;
-#else
struct snd_tea575x;
-#endif
struct snd_tea575x_ops {
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
- void (*write)(tea575x_t *tea, unsigned int val);
- unsigned int (*read)(tea575x_t *tea);
-#else
void (*write)(struct snd_tea575x *tea, unsigned int val);
unsigned int (*read)(struct snd_tea575x *tea);
void (*mute)(struct snd_tea575x *tea, unsigned int mute);
-#endif
};
struct snd_tea575x {
@@ -49,11 +41,10 @@ struct snd_tea575x {
#else
struct snd_card *card;
#endif
- struct video_device vd; /* video device */
- struct v4l2_file_operations fops;
+ struct video_device *vd; /* video device */
int dev_nr; /* requested device number + 1 */
- int vd_registered; /* video device is registered */
int tea5759; /* 5759 chip is present */
+ int mute; /* Device is muted? */
unsigned int freq_fixup; /* crystal onboard */
unsigned int val; /* hw value */
unsigned long freq; /* frequency */
@@ -62,12 +53,7 @@ struct snd_tea575x {
void *private_data;
};
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
-void snd_tea575x_init(tea575x_t *tea);
-void snd_tea575x_exit(tea575x_t *tea);
-#else
void snd_tea575x_init(struct snd_tea575x *tea);
void snd_tea575x_exit(struct snd_tea575x *tea);
-#endif
#endif /* __SOUND_TEA575X_TUNER_H */
diff --git a/linux/sound/i2c/other/tea575x-tuner.c b/linux/sound/i2c/other/tea575x-tuner.c
index db47945e9..8937198db 100644
--- a/linux/sound/i2c/other/tea575x-tuner.c
+++ b/linux/sound/i2c/other/tea575x-tuner.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
+#include <linux/version.h>
#include "compat.h"
#include <sound/core.h>
#include <sound/tea575x-tuner.h>
@@ -32,6 +33,13 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
MODULE_LICENSE("GPL");
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+#define FREQ_LO (87 * 16000)
+#define FREQ_HI (108 * 16000)
+
/*
* definitions
*/
@@ -54,6 +62,17 @@ MODULE_LICENSE("GPL");
#define TEA575X_BIT_DUMMY (1<<15) /* buffer */
#define TEA575X_BIT_FREQ_MASK 0x7fff
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ }
+};
+
/*
* lowlevel part
*/
@@ -89,125 +108,196 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea)
* Linux Video interface
*/
-static long snd_tea575x_ioctl(struct file *file,
- unsigned int cmd, unsigned long data)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
{
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
- tea575x_t *tea = video_drvdata(file);
-#else
struct snd_tea575x *tea = video_drvdata(file);
-#endif
- void __user *arg = (void __user *)data;
-
- switch(cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type = VID_TYPE_TUNER;
- v.channels = 1;
- v.audios = 1;
- /* No we don't do pictures */
- v.maxwidth = 0;
- v.maxheight = 0;
- v.minwidth = 0;
- v.minheight = 0;
- strcpy(v.name, tea->tea5759 ? "TEA5759" : "TEA5757");
- if (copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if (copy_from_user(&v, arg,sizeof(v))!=0)
- return -EFAULT;
- if (v.tuner) /* Only 1 tuner */
- return -EINVAL;
- v.rangelow = (87*16000);
- v.rangehigh = (108*16000);
- v.flags = VIDEO_TUNER_LOW;
- v.mode = VIDEO_MODE_AUTO;
- strcpy(v.name, "FM");
- v.signal = 0xFFFF;
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner!=0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
+
+ strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757");
+ strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver));
+ strlcpy(v->card, "Maestro Radio", sizeof(v->card));
+ sprintf(v->bus_info, "PCI");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = FREQ_LO;
+ v->rangehigh = FREQ_HI;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xffff;
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = tea->freq;
+ return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+
+ if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
+ return -EINVAL;
+
+ tea->freq = f->frequency;
+
+ snd_tea575x_set_freq(tea);
+
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOCGFREQ:
- if(copy_to_user(arg, &tea->freq, sizeof(tea->freq)))
- return -EFAULT;
- return 0;
- case VIDIOCSFREQ:
- if(copy_from_user(&tea->freq, arg, sizeof(tea->freq)))
- return -EFAULT;
- snd_tea575x_set_freq(tea);
- return 0;
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- memset(&v, 0, sizeof(v));
- strcpy(v.name, "Radio");
- if(copy_to_user(arg,&v, sizeof(v)))
- return -EFAULT;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (tea->ops->mute) {
+ ctrl->value = tea->mute;
return 0;
}
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)
- if (tea->ops->mute)
- tea->ops->mute(tea,
- (v.flags &
- VIDEO_AUDIO_MUTE) ? 1 : 0);
+ }
#endif
- if(v.audio)
- return -EINVAL;
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (tea->ops->mute) {
+ tea->ops->mute(tea, ctrl->value);
+ tea->mute = 1;
return 0;
}
- default:
- return -ENOIOCTLCMD;
}
+#endif
+ return -EINVAL;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
}
-static void snd_tea575x_release(struct video_device *vfd)
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
}
static int snd_tea575x_exclusive_open(struct file *file)
{
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
- tea575x_t *tea = video_drvdata(file);
-#else
struct snd_tea575x *tea = video_drvdata(file);
-#endif
return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0;
}
static int snd_tea575x_exclusive_release(struct file *file)
{
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
- tea575x_t *tea = video_drvdata(file);
-#else
struct snd_tea575x *tea = video_drvdata(file);
-#endif
clear_bit(0, &tea->in_use);
return 0;
}
+static const struct v4l2_file_operations tea575x_fops = {
+ .owner = THIS_MODULE,
+ .open = snd_tea575x_exclusive_open,
+ .release = snd_tea575x_exclusive_release,
+ .ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+};
+
+static struct video_device tea575x_radio = {
+ .name = "tea575x-tuner",
+ .fops = &tea575x_fops,
+ .ioctl_ops = &tea575x_ioctl_ops,
+ .release = video_device_release,
+};
+
/*
* initialize all the tea575x chips
*/
@@ -217,51 +307,59 @@ void snd_tea575x_init(tea575x_t *tea)
void snd_tea575x_init(struct snd_tea575x *tea)
#endif
{
+ int retval;
unsigned int val;
+ struct video_device *tea575x_radio_inst;
val = tea->ops->read(tea);
if (val == 0x1ffffff || val == 0) {
- snd_printk(KERN_ERR "Cannot find TEA575x chip\n");
+ snd_printk(KERN_ERR
+ "tea575x-tuner: Cannot find TEA575x chip\n");
return;
}
- memset(&tea->vd, 0, sizeof(tea->vd));
- strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio");
- tea->vd.release = snd_tea575x_release;
- video_set_drvdata(&tea->vd, tea);
- tea->vd.fops = &tea->fops;
tea->in_use = 0;
- tea->fops.owner = tea->card->module;
- tea->fops.open = snd_tea575x_exclusive_open;
- tea->fops.release = snd_tea575x_exclusive_release;
- tea->fops.ioctl = snd_tea575x_ioctl;
- if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) {
- snd_printk(KERN_ERR "unable to register tea575x tuner\n");
+ tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40;
+ tea->freq = 90500 * 16; /* 90.5Mhz default */
+
+ tea575x_radio_inst = video_device_alloc();
+ if (tea575x_radio_inst == NULL) {
+ printk(KERN_ERR "tea575x-tuner: not enough memory\n");
return;
}
- tea->vd_registered = 1;
- tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40;
- tea->freq = 90500 * 16; /* 90.5Mhz default */
+ memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio));
+
+ strcpy(tea575x_radio.name, tea->tea5759 ?
+ "TEA5759 radio" : "TEA5757 radio");
+
+ video_set_drvdata(tea575x_radio_inst, tea);
+
+ retval = video_register_device(tea575x_radio_inst,
+ VFL_TYPE_RADIO, radio_nr);
+ if (retval) {
+ printk(KERN_ERR "tea575x-tuner: can't register video device!\n");
+ kfree(tea575x_radio_inst);
+ return;
+ }
snd_tea575x_set_freq(tea);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)
/* mute on init */
- if (tea->ops->mute)
+ if (tea->ops->mute) {
tea->ops->mute(tea, 1);
+ tea->mute = 1;
+ }
#endif
+ tea->vd = tea575x_radio_inst;
}
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
-void snd_tea575x_exit(tea575x_t *tea)
-#else
void snd_tea575x_exit(struct snd_tea575x *tea)
-#endif
{
- if (tea->vd_registered) {
- video_unregister_device(&tea->vd);
- tea->vd_registered = 0;
+ if (tea->vd) {
+ video_unregister_device(tea->vd);
+ tea->vd = NULL;
}
}
diff --git a/linux/sound/oss/btaudio.c b/linux/sound/oss/btaudio.c
deleted file mode 100644
index cf10bf82a..000000000
--- a/linux/sound/oss/btaudio.c
+++ /dev/null
@@ -1,1156 +0,0 @@
-/*
- btaudio - bt878 audio dma driver for linux 2.4.x
-
- (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/sound.h>
-#include <linux/soundcard.h>
-#include <linux/slab.h>
-#include <linux/kdev_t.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include "compat.h"
-
-
-/* mmio access */
-#define btwrite(dat,adr) writel((dat), (bta->mmio+(adr)))
-#define btread(adr) readl(bta->mmio+(adr))
-
-#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
-#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
-#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
-
-/* registers (shifted because bta->mmio is long) */
-#define REG_INT_STAT (0x100 >> 2)
-#define REG_INT_MASK (0x104 >> 2)
-#define REG_GPIO_DMA_CTL (0x10c >> 2)
-#define REG_PACKET_LEN (0x110 >> 2)
-#define REG_RISC_STRT_ADD (0x114 >> 2)
-#define REG_RISC_COUNT (0x120 >> 2)
-
-/* IRQ bits - REG_INT_(STAT|MASK) */
-#define IRQ_SCERR (1 << 19)
-#define IRQ_OCERR (1 << 18)
-#define IRQ_PABORT (1 << 17)
-#define IRQ_RIPERR (1 << 16)
-#define IRQ_PPERR (1 << 15)
-#define IRQ_FDSR (1 << 14)
-#define IRQ_FTRGT (1 << 13)
-#define IRQ_FBUS (1 << 12)
-#define IRQ_RISCI (1 << 11)
-#define IRQ_OFLOW (1 << 3)
-
-#define IRQ_BTAUDIO (IRQ_SCERR | IRQ_OCERR | IRQ_PABORT | IRQ_RIPERR |\
- IRQ_PPERR | IRQ_FDSR | IRQ_FTRGT | IRQ_FBUS |\
- IRQ_RISCI)
-
-/* REG_GPIO_DMA_CTL bits */
-#define DMA_CTL_A_PWRDN (1 << 26)
-#define DMA_CTL_DA_SBR (1 << 14)
-#define DMA_CTL_DA_ES2 (1 << 13)
-#define DMA_CTL_ACAP_EN (1 << 4)
-#define DMA_CTL_RISC_EN (1 << 1)
-#define DMA_CTL_FIFO_EN (1 << 0)
-
-/* RISC instructions */
-#define RISC_WRITE (0x01 << 28)
-#define RISC_JUMP (0x07 << 28)
-#define RISC_SYNC (0x08 << 28)
-
-/* RISC bits */
-#define RISC_WR_SOL (1 << 27)
-#define RISC_WR_EOL (1 << 26)
-#define RISC_IRQ (1 << 24)
-#define RISC_SYNC_RESYNC (1 << 15)
-#define RISC_SYNC_FM1 0x06
-#define RISC_SYNC_VRO 0x0c
-
-#define HWBASE_AD (448000)
-
-/* -------------------------------------------------------------- */
-
-struct btaudio {
- /* linked list */
- struct btaudio *next;
-
- /* device info */
- int dsp_digital;
- int dsp_analog;
- int mixer_dev;
- struct pci_dev *pci;
- unsigned int irq;
- unsigned long mem;
- unsigned long __iomem *mmio;
-
- /* locking */
- int users;
- struct mutex lock;
-
- /* risc instructions */
- unsigned int risc_size;
- unsigned long *risc_cpu;
- dma_addr_t risc_dma;
-
- /* audio data */
- unsigned int buf_size;
- unsigned char *buf_cpu;
- dma_addr_t buf_dma;
-
- /* buffer setup */
- int line_bytes;
- int line_count;
- int block_bytes;
- int block_count;
-
- /* read fifo management */
- int recording;
- int dma_block;
- int read_offset;
- int read_count;
- wait_queue_head_t readq;
-
- /* settings */
- int gain[3];
- int source;
- int bits;
- int decimation;
- int mixcount;
- int sampleshift;
- int channels;
- int analog;
- int rate;
-};
-
-struct cardinfo {
- char *name;
- int rate;
-};
-
-static struct btaudio *btaudios;
-static unsigned int debug;
-static unsigned int irq_debug;
-
-/* -------------------------------------------------------------- */
-
-#define BUF_DEFAULT 128*1024
-#define BUF_MIN 8192
-
-static int alloc_buffer(struct btaudio *bta)
-{
- if (NULL == bta->buf_cpu) {
- for (bta->buf_size = BUF_DEFAULT; bta->buf_size >= BUF_MIN;
- bta->buf_size = bta->buf_size >> 1) {
- bta->buf_cpu = pci_alloc_consistent
- (bta->pci, bta->buf_size, &bta->buf_dma);
- if (NULL != bta->buf_cpu)
- break;
- }
- if (NULL == bta->buf_cpu)
- return -ENOMEM;
- memset(bta->buf_cpu,0,bta->buf_size);
- }
- if (NULL == bta->risc_cpu) {
- bta->risc_size = PAGE_SIZE;
- bta->risc_cpu = pci_alloc_consistent
- (bta->pci, bta->risc_size, &bta->risc_dma);
- if (NULL == bta->risc_cpu) {
- pci_free_consistent(bta->pci, bta->buf_size, bta->buf_cpu, bta->buf_dma);
- bta->buf_cpu = NULL;
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-static void free_buffer(struct btaudio *bta)
-{
- if (NULL != bta->buf_cpu) {
- pci_free_consistent(bta->pci, bta->buf_size,
- bta->buf_cpu, bta->buf_dma);
- bta->buf_cpu = NULL;
- }
- if (NULL != bta->risc_cpu) {
- pci_free_consistent(bta->pci, bta->risc_size,
- bta->risc_cpu, bta->risc_dma);
- bta->risc_cpu = NULL;
- }
-}
-
-static int make_risc(struct btaudio *bta)
-{
- int rp, bp, line, block;
- unsigned long risc;
-
- bta->block_bytes = bta->buf_size >> 4;
- bta->block_count = 1 << 4;
- bta->line_bytes = bta->block_bytes;
- bta->line_count = bta->block_count;
- while (bta->line_bytes > 4095) {
- bta->line_bytes >>= 1;
- bta->line_count <<= 1;
- }
- if (bta->line_count > 255)
- return -EINVAL;
- if (debug)
- printk(KERN_DEBUG
- "btaudio: bufsize=%d - bs=%d bc=%d - ls=%d, lc=%d\n",
- bta->buf_size,bta->block_bytes,bta->block_count,
- bta->line_bytes,bta->line_count);
- rp = 0; bp = 0;
- block = 0;
- bta->risc_cpu[rp++] = cpu_to_le32(RISC_SYNC|RISC_SYNC_FM1);
- bta->risc_cpu[rp++] = cpu_to_le32(0);
- for (line = 0; line < bta->line_count; line++) {
- risc = RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL;
- risc |= bta->line_bytes;
- if (0 == (bp & (bta->block_bytes-1))) {
- risc |= RISC_IRQ;
- risc |= (block & 0x0f) << 16;
- risc |= (~block & 0x0f) << 20;
- block++;
- }
- bta->risc_cpu[rp++] = cpu_to_le32(risc);
- bta->risc_cpu[rp++] = cpu_to_le32(bta->buf_dma + bp);
- bp += bta->line_bytes;
- }
- bta->risc_cpu[rp++] = cpu_to_le32(RISC_SYNC|RISC_SYNC_VRO);
- bta->risc_cpu[rp++] = cpu_to_le32(0);
- bta->risc_cpu[rp++] = cpu_to_le32(RISC_JUMP);
- bta->risc_cpu[rp++] = cpu_to_le32(bta->risc_dma);
- return 0;
-}
-
-static int start_recording(struct btaudio *bta)
-{
- int ret;
-
- if (0 != (ret = alloc_buffer(bta)))
- return ret;
- if (0 != (ret = make_risc(bta)))
- return ret;
-
- btwrite(bta->risc_dma, REG_RISC_STRT_ADD);
- btwrite((bta->line_count << 16) | bta->line_bytes,
- REG_PACKET_LEN);
- btwrite(IRQ_BTAUDIO, REG_INT_MASK);
- if (bta->analog) {
- btwrite(DMA_CTL_ACAP_EN |
- DMA_CTL_RISC_EN |
- DMA_CTL_FIFO_EN |
- DMA_CTL_DA_ES2 |
- ((bta->bits == 8) ? DMA_CTL_DA_SBR : 0) |
- (bta->gain[bta->source] << 28) |
- (bta->source << 24) |
- (bta->decimation << 8),
- REG_GPIO_DMA_CTL);
- } else {
- btwrite(DMA_CTL_ACAP_EN |
- DMA_CTL_RISC_EN |
- DMA_CTL_FIFO_EN |
- DMA_CTL_DA_ES2 |
- DMA_CTL_A_PWRDN |
- (1 << 6) |
- ((bta->bits == 8) ? DMA_CTL_DA_SBR : 0) |
- (bta->gain[bta->source] << 28) |
- (bta->source << 24) |
- (bta->decimation << 8),
- REG_GPIO_DMA_CTL);
- }
- bta->dma_block = 0;
- bta->read_offset = 0;
- bta->read_count = 0;
- bta->recording = 1;
- if (debug)
- printk(KERN_DEBUG "btaudio: recording started\n");
- return 0;
-}
-
-static void stop_recording(struct btaudio *bta)
-{
- btand(~15, REG_GPIO_DMA_CTL);
- bta->recording = 0;
- if (debug)
- printk(KERN_DEBUG "btaudio: recording stopped\n");
-}
-
-
-/* -------------------------------------------------------------- */
-
-static int btaudio_mixer_open(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- struct btaudio *bta;
-
- for (bta = btaudios; bta != NULL; bta = bta->next)
- if (bta->mixer_dev == minor)
- break;
- if (NULL == bta)
- return -ENODEV;
-
- if (debug)
- printk("btaudio: open mixer [%d]\n",minor);
- file->private_data = bta;
- return 0;
-}
-
-static int btaudio_mixer_release(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct btaudio *bta = file->private_data;
- int ret,val=0,i=0;
- void __user *argp = (void __user *)arg;
-
- if (cmd == SOUND_MIXER_INFO) {
- mixer_info info;
- memset(&info,0,sizeof(info));
- strlcpy(info.id,"bt878",sizeof(info.id));
- strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
- info.modify_counter = bta->mixcount;
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (cmd == SOUND_OLD_MIXER_INFO) {
- _old_mixer_info info;
- memset(&info,0,sizeof(info));
- strlcpy(info.id, "bt878", sizeof(info.id));
- strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int __user *)argp);
-
- /* read */
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- if (get_user(val, (int __user *)argp))
- return -EFAULT;
-
- switch (cmd) {
- case MIXER_READ(SOUND_MIXER_CAPS):
- ret = SOUND_CAP_EXCL_INPUT;
- break;
- case MIXER_READ(SOUND_MIXER_STEREODEVS):
- ret = 0;
- break;
- case MIXER_READ(SOUND_MIXER_RECMASK):
- case MIXER_READ(SOUND_MIXER_DEVMASK):
- ret = SOUND_MASK_LINE1|SOUND_MASK_LINE2|SOUND_MASK_LINE3;
- break;
-
- case MIXER_WRITE(SOUND_MIXER_RECSRC):
- if (val & SOUND_MASK_LINE1 && bta->source != 0)
- bta->source = 0;
- else if (val & SOUND_MASK_LINE2 && bta->source != 1)
- bta->source = 1;
- else if (val & SOUND_MASK_LINE3 && bta->source != 2)
- bta->source = 2;
- btaor((bta->gain[bta->source] << 28) |
- (bta->source << 24),
- 0x0cffffff, REG_GPIO_DMA_CTL);
- case MIXER_READ(SOUND_MIXER_RECSRC):
- switch (bta->source) {
- case 0: ret = SOUND_MASK_LINE1; break;
- case 1: ret = SOUND_MASK_LINE2; break;
- case 2: ret = SOUND_MASK_LINE3; break;
- default: ret = 0;
- }
- break;
-
- case MIXER_WRITE(SOUND_MIXER_LINE1):
- case MIXER_WRITE(SOUND_MIXER_LINE2):
- case MIXER_WRITE(SOUND_MIXER_LINE3):
- if (MIXER_WRITE(SOUND_MIXER_LINE1) == cmd)
- i = 0;
- if (MIXER_WRITE(SOUND_MIXER_LINE2) == cmd)
- i = 1;
- if (MIXER_WRITE(SOUND_MIXER_LINE3) == cmd)
- i = 2;
- bta->gain[i] = (val & 0xff) * 15 / 100;
- if (bta->gain[i] > 15) bta->gain[i] = 15;
- if (bta->gain[i] < 0) bta->gain[i] = 0;
- if (i == bta->source)
- btaor((bta->gain[bta->source]<<28),
- 0x0fffffff, REG_GPIO_DMA_CTL);
- ret = bta->gain[i] * 100 / 15;
- ret |= ret << 8;
- break;
-
- case MIXER_READ(SOUND_MIXER_LINE1):
- case MIXER_READ(SOUND_MIXER_LINE2):
- case MIXER_READ(SOUND_MIXER_LINE3):
- if (MIXER_READ(SOUND_MIXER_LINE1) == cmd)
- i = 0;
- if (MIXER_READ(SOUND_MIXER_LINE2) == cmd)
- i = 1;
- if (MIXER_READ(SOUND_MIXER_LINE3) == cmd)
- i = 2;
- ret = bta->gain[i] * 100 / 15;
- ret |= ret << 8;
- break;
-
- default:
- return -EINVAL;
- }
- if (put_user(ret, (int __user *)argp))
- return -EFAULT;
- return 0;
-}
-
-static const struct file_operations btaudio_mixer_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .open = btaudio_mixer_open,
- .release = btaudio_mixer_release,
- .ioctl = btaudio_mixer_ioctl,
-};
-
-/* -------------------------------------------------------------- */
-
-static int btaudio_dsp_open(struct inode *inode, struct file *file,
- struct btaudio *bta, int analog)
-{
- mutex_lock(&bta->lock);
- if (bta->users)
- goto busy;
- bta->users++;
- file->private_data = bta;
-
- bta->analog = analog;
- bta->dma_block = 0;
- bta->read_offset = 0;
- bta->read_count = 0;
- bta->sampleshift = 0;
-
- mutex_unlock(&bta->lock);
- return 0;
-
- busy:
- mutex_unlock(&bta->lock);
- return -EBUSY;
-}
-
-static int btaudio_dsp_open_digital(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- struct btaudio *bta;
-
- for (bta = btaudios; bta != NULL; bta = bta->next)
- if (bta->dsp_digital == minor)
- break;
- if (NULL == bta)
- return -ENODEV;
-
- if (debug)
- printk("btaudio: open digital dsp [%d]\n",minor);
- return btaudio_dsp_open(inode,file,bta,0);
-}
-
-static int btaudio_dsp_open_analog(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- struct btaudio *bta;
-
- for (bta = btaudios; bta != NULL; bta = bta->next)
- if (bta->dsp_analog == minor)
- break;
- if (NULL == bta)
- return -ENODEV;
-
- if (debug)
- printk("btaudio: open analog dsp [%d]\n",minor);
- return btaudio_dsp_open(inode,file,bta,1);
-}
-
-static int btaudio_dsp_release(struct inode *inode, struct file *file)
-{
- struct btaudio *bta = file->private_data;
-
- mutex_lock(&bta->lock);
- if (bta->recording)
- stop_recording(bta);
- bta->users--;
- mutex_unlock(&bta->lock);
- return 0;
-}
-
-static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer,
- size_t swcount, loff_t *ppos)
-{
- struct btaudio *bta = file->private_data;
- int hwcount = swcount << bta->sampleshift;
- int nsrc, ndst, err, ret = 0;
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(&bta->readq, &wait);
- mutex_lock(&bta->lock);
- while (swcount > 0) {
- if (0 == bta->read_count) {
- if (!bta->recording) {
- if (0 != (err = start_recording(bta))) {
- if (0 == ret)
- ret = err;
- break;
- }
- }
- if (file->f_flags & O_NONBLOCK) {
- if (0 == ret)
- ret = -EAGAIN;
- break;
- }
- mutex_unlock(&bta->lock);
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- mutex_lock(&bta->lock);
- if(signal_pending(current)) {
- if (0 == ret)
- ret = -EINTR;
- break;
- }
- }
- nsrc = (bta->read_count < hwcount) ? bta->read_count : hwcount;
- if (nsrc > bta->buf_size - bta->read_offset)
- nsrc = bta->buf_size - bta->read_offset;
- ndst = nsrc >> bta->sampleshift;
-
- if ((bta->analog && 0 == bta->sampleshift) ||
- (!bta->analog && 2 == bta->channels)) {
- /* just copy */
- if (copy_to_user(buffer + ret, bta->buf_cpu + bta->read_offset, nsrc)) {
- if (0 == ret)
- ret = -EFAULT;
- break;
- }
-
- } else if (!bta->analog) {
- /* stereo => mono (digital audio) */
- __s16 *src = (__s16*)(bta->buf_cpu + bta->read_offset);
- __s16 __user *dst = (__s16 __user *)(buffer + ret);
- __s16 avg;
- int n = ndst>>1;
- if (!access_ok(VERIFY_WRITE, dst, ndst)) {
- if (0 == ret)
- ret = -EFAULT;
- break;
- }
- for (; n; n--, dst++) {
- avg = (__s16)le16_to_cpu(*src) / 2; src++;
- avg += (__s16)le16_to_cpu(*src) / 2; src++;
- __put_user(cpu_to_le16(avg),dst);
- }
-
- } else if (8 == bta->bits) {
- /* copy + byte downsampling (audio A/D) */
- __u8 *src = bta->buf_cpu + bta->read_offset;
- __u8 __user *dst = buffer + ret;
- int n = ndst;
- if (!access_ok(VERIFY_WRITE, dst, ndst)) {
- if (0 == ret)
- ret = -EFAULT;
- break;
- }
- for (; n; n--, src += (1 << bta->sampleshift), dst++)
- __put_user(*src, dst);
-
- } else {
- /* copy + word downsampling (audio A/D) */
- __u16 *src = (__u16*)(bta->buf_cpu + bta->read_offset);
- __u16 __user *dst = (__u16 __user *)(buffer + ret);
- int n = ndst>>1;
- if (!access_ok(VERIFY_WRITE,dst,ndst)) {
- if (0 == ret)
- ret = -EFAULT;
- break;
- }
- for (; n; n--, src += (1 << bta->sampleshift), dst++)
- __put_user(*src, dst);
- }
-
- ret += ndst;
- swcount -= ndst;
- hwcount -= nsrc;
- bta->read_count -= nsrc;
- bta->read_offset += nsrc;
- if (bta->read_offset == bta->buf_size)
- bta->read_offset = 0;
- }
- mutex_unlock(&bta->lock);
- remove_wait_queue(&bta->readq, &wait);
- current->state = TASK_RUNNING;
- return ret;
-}
-
-static ssize_t btaudio_dsp_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- return -EINVAL;
-}
-
-static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct btaudio *bta = file->private_data;
- int s, i, ret, val = 0;
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
-
- switch (cmd) {
- case OSS_GETVERSION:
- return put_user(SOUND_VERSION, p);
- case SNDCTL_DSP_GETCAPS:
- return 0;
-
- case SNDCTL_DSP_SPEED:
- if (get_user(val, p))
- return -EFAULT;
- if (bta->analog) {
- for (s = 0; s < 16; s++)
- if (val << s >= HWBASE_AD*4/15)
- break;
- for (i = 15; i >= 5; i--)
- if (val << s <= HWBASE_AD*4/i)
- break;
- bta->sampleshift = s;
- bta->decimation = i;
- if (debug)
- printk(KERN_DEBUG "btaudio: rate: req=%d "
- "dec=%d shift=%d hwrate=%d swrate=%d\n",
- val,i,s,(HWBASE_AD*4/i),(HWBASE_AD*4/i)>>s);
- } else {
- bta->sampleshift = (bta->channels == 2) ? 0 : 1;
- bta->decimation = 0;
- }
- if (bta->recording) {
- mutex_lock(&bta->lock);
- stop_recording(bta);
- start_recording(bta);
- mutex_unlock(&bta->lock);
- }
- /* fall through */
- case SOUND_PCM_READ_RATE:
- if (bta->analog) {
- return put_user(HWBASE_AD*4/bta->decimation>>bta->sampleshift, p);
- } else {
- return put_user(bta->rate, p);
- }
-
- case SNDCTL_DSP_STEREO:
- if (!bta->analog) {
- if (get_user(val, p))
- return -EFAULT;
- bta->channels = (val > 0) ? 2 : 1;
- bta->sampleshift = (bta->channels == 2) ? 0 : 1;
- if (debug)
- printk(KERN_INFO
- "btaudio: stereo=%d channels=%d\n",
- val,bta->channels);
- } else {
- if (val == 1)
- return -EFAULT;
- else {
- bta->channels = 1;
- if (debug)
- printk(KERN_INFO
- "btaudio: stereo=0 channels=1\n");
- }
- }
- return put_user((bta->channels)-1, p);
-
- case SNDCTL_DSP_CHANNELS:
- if (!bta->analog) {
- if (get_user(val, p))
- return -EFAULT;
- bta->channels = (val > 1) ? 2 : 1;
- bta->sampleshift = (bta->channels == 2) ? 0 : 1;
- if (debug)
- printk(KERN_DEBUG
- "btaudio: val=%d channels=%d\n",
- val,bta->channels);
- }
- /* fall through */
- case SOUND_PCM_READ_CHANNELS:
- return put_user(bta->channels, p);
-
- case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- if (bta->analog)
- return put_user(AFMT_S16_LE|AFMT_S8, p);
- else
- return put_user(AFMT_S16_LE, p);
-
- case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, p))
- return -EFAULT;
- if (val != AFMT_QUERY) {
- if (bta->analog)
- bta->bits = (val == AFMT_S8) ? 8 : 16;
- else
- bta->bits = 16;
- if (bta->recording) {
- mutex_lock(&bta->lock);
- stop_recording(bta);
- start_recording(bta);
- mutex_unlock(&bta->lock);
- }
- }
- if (debug)
- printk(KERN_DEBUG "btaudio: fmt: bits=%d\n",bta->bits);
- return put_user((bta->bits==16) ? AFMT_S16_LE : AFMT_S8,
- p);
- break;
- case SOUND_PCM_READ_BITS:
- return put_user(bta->bits, p);
-
- case SNDCTL_DSP_NONBLOCK:
- file->f_flags |= O_NONBLOCK;
- return 0;
-
- case SNDCTL_DSP_RESET:
- if (bta->recording) {
- mutex_lock(&bta->lock);
- stop_recording(bta);
- mutex_unlock(&bta->lock);
- }
- return 0;
- case SNDCTL_DSP_GETBLKSIZE:
- if (!bta->recording) {
- if (0 != (ret = alloc_buffer(bta)))
- return ret;
- if (0 != (ret = make_risc(bta)))
- return ret;
- }
- return put_user(bta->block_bytes>>bta->sampleshift,p);
-
- case SNDCTL_DSP_SYNC:
- /* NOP */
- return 0;
- case SNDCTL_DSP_GETISPACE:
- {
- audio_buf_info info;
- if (!bta->recording)
- return -EINVAL;
- info.fragsize = bta->block_bytes>>bta->sampleshift;
- info.fragstotal = bta->block_count;
- info.bytes = bta->read_count;
- info.fragments = info.bytes / info.fragsize;
- if (debug)
- printk(KERN_DEBUG "btaudio: SNDCTL_DSP_GETISPACE "
- "returns %d/%d/%d/%d\n",
- info.fragsize, info.fragstotal,
- info.bytes, info.fragments);
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
-#if 0 /* TODO */
- case SNDCTL_DSP_GETTRIGGER:
- case SNDCTL_DSP_SETTRIGGER:
- case SNDCTL_DSP_SETFRAGMENT:
-#endif
- default:
- return -EINVAL;
- }
-}
-
-static unsigned int btaudio_dsp_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct btaudio *bta = file->private_data;
- unsigned int mask = 0;
-
- poll_wait(file, &bta->readq, wait);
-
- if (0 != bta->read_count)
- mask |= (POLLIN | POLLRDNORM);
-
- return mask;
-}
-
-static const struct file_operations btaudio_digital_dsp_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .open = btaudio_dsp_open_digital,
- .release = btaudio_dsp_release,
- .read = btaudio_dsp_read,
- .write = btaudio_dsp_write,
- .ioctl = btaudio_dsp_ioctl,
- .poll = btaudio_dsp_poll,
-};
-
-static const struct file_operations btaudio_analog_dsp_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .open = btaudio_dsp_open_analog,
- .release = btaudio_dsp_release,
- .read = btaudio_dsp_read,
- .write = btaudio_dsp_write,
- .ioctl = btaudio_dsp_ioctl,
- .poll = btaudio_dsp_poll,
-};
-
-/* -------------------------------------------------------------- */
-
-static char *irq_name[] = { "", "", "", "OFLOW", "", "", "", "", "", "", "",
- "RISCI", "FBUS", "FTRGT", "FDSR", "PPERR",
- "RIPERR", "PABORT", "OCERR", "SCERR" };
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-static irqreturn_t btaudio_irq(int irq, void *dev_id, struct pt_regs * regs)
-#else
-static irqreturn_t btaudio_irq(int irq, void *dev_id)
-#endif
-{
- int count = 0;
- u32 stat,astat;
- struct btaudio *bta = dev_id;
- int handled = 0;
-
- for (;;) {
- count++;
- stat = btread(REG_INT_STAT);
- astat = stat & btread(REG_INT_MASK);
- if (!astat)
- return IRQ_RETVAL(handled);
- handled = 1;
- btwrite(astat,REG_INT_STAT);
-
- if (irq_debug) {
- int i;
- printk(KERN_DEBUG "btaudio: irq loop=%d risc=%x, bits:",
- count, stat>>28);
- for (i = 0; i < (sizeof(irq_name)/sizeof(char*)); i++) {
- if (stat & (1 << i))
- printk(" %s",irq_name[i]);
- if (astat & (1 << i))
- printk("*");
- }
- printk("\n");
- }
- if (stat & IRQ_RISCI) {
- int blocks;
- blocks = (stat >> 28) - bta->dma_block;
- if (blocks < 0)
- blocks += bta->block_count;
- bta->dma_block = stat >> 28;
- if (bta->read_count + 2*bta->block_bytes > bta->buf_size) {
- stop_recording(bta);
- printk(KERN_INFO "btaudio: buffer overrun\n");
- }
- if (blocks > 0) {
- bta->read_count += blocks * bta->block_bytes;
- wake_up_interruptible(&bta->readq);
- }
- }
- if (count > 10) {
- printk(KERN_WARNING
- "btaudio: Oops - irq mask cleared\n");
- btwrite(0, REG_INT_MASK);
- }
- }
- return IRQ_NONE;
-}
-
-/* -------------------------------------------------------------- */
-
-static unsigned int dsp1 = -1;
-static unsigned int dsp2 = -1;
-static unsigned int mixer = -1;
-static int latency = -1;
-static int digital = 1;
-static int analog = 1;
-static int rate;
-
-#define BTA_OSPREY200 1
-
-static struct cardinfo cards[] = {
- [0] = {
- .name = "default",
- .rate = 32000,
- },
- [BTA_OSPREY200] = {
- .name = "Osprey 200",
- .rate = 44100,
- },
-};
-
-static int __devinit btaudio_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- struct btaudio *bta;
- struct cardinfo *card = &cards[pci_id->driver_data];
- unsigned char revision,lat;
- int rc = -EBUSY;
-
- if (pci_enable_device(pci_dev))
- return -EIO;
- if (!request_mem_region(pci_resource_start(pci_dev,0),
- pci_resource_len(pci_dev,0),
- "btaudio")) {
- return -EBUSY;
- }
-
- bta = kzalloc(sizeof(*bta),GFP_ATOMIC);
- if (!bta) {
- rc = -ENOMEM;
- goto fail0;
- }
-
- bta->pci = pci_dev;
- bta->irq = pci_dev->irq;
- bta->mem = pci_resource_start(pci_dev,0);
- bta->mmio = ioremap(pci_resource_start(pci_dev,0),
- pci_resource_len(pci_dev,0));
-
- bta->source = 1;
- bta->bits = 8;
- bta->channels = 1;
- if (bta->analog) {
- bta->decimation = 15;
- } else {
- bta->decimation = 0;
- bta->sampleshift = 1;
- }
-
- /* sample rate */
- bta->rate = card->rate;
- if (rate)
- bta->rate = rate;
-
- mutex_init(&bta->lock);
- init_waitqueue_head(&bta->readq);
-
- if (-1 != latency) {
- printk(KERN_INFO "btaudio: setting pci latency timer to %d\n",
- latency);
- pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
- }
- pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
- pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &lat);
- printk(KERN_INFO "btaudio: Bt%x (rev %d) at %02x:%02x.%x, ",
- pci_dev->device,revision,pci_dev->bus->number,
- PCI_SLOT(pci_dev->devfn),PCI_FUNC(pci_dev->devfn));
- printk("irq: %d, latency: %d, mmio: 0x%lx\n",
- bta->irq, lat, bta->mem);
- printk("btaudio: using card config \"%s\"\n", card->name);
-
- /* init hw */
- btwrite(0, REG_GPIO_DMA_CTL);
- btwrite(0, REG_INT_MASK);
- btwrite(~0U, REG_INT_STAT);
- pci_set_master(pci_dev);
-
- if ((rc = request_irq(bta->irq, btaudio_irq, IRQF_SHARED|IRQF_DISABLED,
- "btaudio",(void *)bta)) < 0) {
- printk(KERN_WARNING
- "btaudio: can't request irq (rc=%d)\n",rc);
- goto fail1;
- }
-
- /* register devices */
- if (digital) {
- rc = bta->dsp_digital =
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
- register_sound_dsp(&btaudio_digital_dsp_fops, dsp1);
-#else
- register_sound_dsp((struct file_operations *)&btaudio_digital_dsp_fops, dsp1);
-#endif
- if (rc < 0) {
- printk(KERN_WARNING
- "btaudio: can't register digital dsp (rc=%d)\n",rc);
- goto fail2;
- }
- printk(KERN_INFO "btaudio: registered device dsp%d [digital]\n",
- bta->dsp_digital >> 4);
- }
- if (analog) {
- rc = bta->dsp_analog =
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
- register_sound_dsp(&btaudio_analog_dsp_fops, dsp2);
-#else
- register_sound_dsp((struct file_operations *)&btaudio_analog_dsp_fops, dsp2);
-#endif
- if (rc < 0) {
- printk(KERN_WARNING
- "btaudio: can't register analog dsp (rc=%d)\n",rc);
- goto fail3;
- }
- printk(KERN_INFO "btaudio: registered device dsp%d [analog]\n",
- bta->dsp_analog >> 4);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
- rc = bta->mixer_dev = register_sound_mixer(&btaudio_mixer_fops, mixer);
-#else
- rc = bta->mixer_dev = register_sound_mixer((struct file_operations *)&btaudio_mixer_fops, mixer);
-#endif
- if (rc < 0) {
- printk(KERN_WARNING
- "btaudio: can't register mixer (rc=%d)\n",rc);
- goto fail4;
- }
- printk(KERN_INFO "btaudio: registered device mixer%d\n",
- bta->mixer_dev >> 4);
- }
-
- /* hook into linked list */
- bta->next = btaudios;
- btaudios = bta;
-
- pci_set_drvdata(pci_dev,bta);
- return 0;
-
- fail4:
- unregister_sound_dsp(bta->dsp_analog);
- fail3:
- if (digital)
- unregister_sound_dsp(bta->dsp_digital);
- fail2:
- free_irq(bta->irq,bta);
- fail1:
- iounmap(bta->mmio);
- kfree(bta);
- fail0:
- release_mem_region(pci_resource_start(pci_dev,0),
- pci_resource_len(pci_dev,0));
- return rc;
-}
-
-static void __devexit btaudio_remove(struct pci_dev *pci_dev)
-{
- struct btaudio *bta = pci_get_drvdata(pci_dev);
- struct btaudio *walk;
-
- /* turn off all DMA / IRQs */
- btand(~15, REG_GPIO_DMA_CTL);
- btwrite(0, REG_INT_MASK);
- btwrite(~0U, REG_INT_STAT);
-
- /* unregister devices */
- if (digital) {
- unregister_sound_dsp(bta->dsp_digital);
- }
- if (analog) {
- unregister_sound_dsp(bta->dsp_analog);
- unregister_sound_mixer(bta->mixer_dev);
- }
-
- /* free resources */
- free_buffer(bta);
- free_irq(bta->irq,bta);
- release_mem_region(pci_resource_start(pci_dev,0),
- pci_resource_len(pci_dev,0));
- iounmap(bta->mmio);
-
- /* remove from linked list */
- if (bta == btaudios) {
- btaudios = NULL;
- } else {
- for (walk = btaudios; walk->next != bta; walk = walk->next)
- ; /* if (NULL == walk->next) BUG(); */
- walk->next = bta->next;
- }
-
- pci_set_drvdata(pci_dev, NULL);
- kfree(bta);
- return;
-}
-
-/* -------------------------------------------------------------- */
-
-static struct pci_device_id btaudio_pci_tbl[] = {
- {
- .vendor = PCI_VENDOR_ID_BROOKTREE,
- .device = 0x0878,
- .subvendor = 0x0070,
- .subdevice = 0xff01,
- .driver_data = BTA_OSPREY200,
- },{
- .vendor = PCI_VENDOR_ID_BROOKTREE,
- .device = 0x0878,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },{
- .vendor = PCI_VENDOR_ID_BROOKTREE,
- .device = 0x0878,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },{
- /* --- end of list --- */
- }
-};
-
-static struct pci_driver btaudio_pci_driver = {
- .name = "btaudio",
- .id_table = btaudio_pci_tbl,
- .probe = btaudio_probe,
- .remove = __devexit_p(btaudio_remove),
-};
-
-static int btaudio_init_module(void)
-{
- printk(KERN_INFO "btaudio: driver version 0.7 loaded [%s%s%s]\n",
- digital ? "digital" : "",
- analog && digital ? "+" : "",
- analog ? "analog" : "");
- return pci_register_driver(&btaudio_pci_driver);
-}
-
-static void btaudio_cleanup_module(void)
-{
- pci_unregister_driver(&btaudio_pci_driver);
- return;
-}
-
-module_init(btaudio_init_module);
-module_exit(btaudio_cleanup_module);
-
-module_param(dsp1, int, S_IRUGO);
-module_param(dsp2, int, S_IRUGO);
-module_param(mixer, int, S_IRUGO);
-module_param(debug, int, S_IRUGO | S_IWUSR);
-module_param(irq_debug, int, S_IRUGO | S_IWUSR);
-module_param(digital, int, S_IRUGO);
-module_param(analog, int, S_IRUGO);
-module_param(rate, int, S_IRUGO);
-module_param(latency, int, S_IRUGO);
-MODULE_PARM_DESC(latency,"pci latency timer");
-
-MODULE_DEVICE_TABLE(pci, btaudio_pci_tbl);
-MODULE_DESCRIPTION("bt878 audio dma driver");
-MODULE_AUTHOR("Gerd Knorr");
-MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/v4l/Kconfig.sound b/v4l/Kconfig.sound
index 597c9c72b..55be75cce 100644
--- a/v4l/Kconfig.sound
+++ b/v4l/Kconfig.sound
@@ -45,30 +45,4 @@ config SND_FM801_TEA575X
This will enable support for the old V4L1 API.
-# This is part of sound/oss/Kconfig
-comment "OSS sound"
-
-config SOUND_BT878
- tristate "BT878 audio dma"
- depends on SOUND_PRIME && PCI
- ---help---
- Audio DMA support for bt878 based grabber boards. As you might have
- already noticed, bt878 is listed with two functions in /proc/pci.
- Function 0 does the video stuff (bt848 compatible), function 1 does
- the same for audio data. This is a driver for the audio part of
- the chip. If you say 'Y' here you get a oss-compatible dsp device
- where you can record from. If you want just watch TV you probably
- don't need this driver as most TV cards handle sound with a short
- cable from the TV card to your sound card's line-in.
-
- To compile this driver as a module, choose M here: the module will
- be called btaudio.
-
-config SOUND_TVMIXER
- tristate "TV card (bt848) mixer support"
- depends on SOUND_PRIME && I2C && VIDEO_V4L1
- help
- Support for audio mixer facilities on the BT848 TV frame-grabber
- card.
-
endmenu
diff --git a/v4l/Makefile b/v4l/Makefile
index 512b355f4..9d194178f 100644
--- a/v4l/Makefile
+++ b/v4l/Makefile
@@ -361,18 +361,23 @@ $(obj)/Kconfig: $(obj)/.version
xconfig:: $(QCONF) $(obj)/Kconfig
$(QCONF) $(obj)/Kconfig
+ ./scripts/fix_kconfig.pl
gconfig:: $(GCONF) $(obj)/Kconfig
$(GCONF) $(obj)/Kconfig
+ ./scripts/fix_kconfig.pl
config:: $(CONF) $(obj)/Kconfig
$(CONF) $(obj)/Kconfig
+ ./scripts/fix_kconfig.pl
menuconfig:: $(MCONF) lxdialog $(obj)/Kconfig
$(MCONF) $(obj)/Kconfig
+ ./scripts/fix_kconfig.pl
allyesconfig allmodconfig:: $(obj)/.version
./scripts/make_kconfig.pl $(OUTDIR) $(SRCDIR) 1
+ ./scripts/fix_kconfig.pl
# rule to build kernel conf programs
KMAKEVARS := config-targets=1 mixed-targets=0 dot-config=0 SRCDIR=$(SRCDIR)
diff --git a/v4l/Makefile.sound b/v4l/Makefile.sound
index 941dbc65c..38e868629 100644
--- a/v4l/Makefile.sound
+++ b/v4l/Makefile.sound
@@ -3,10 +3,6 @@
snd-bt87x-objs := bt87x.o
obj-$(CONFIG_SND_BT87X) += snd-bt87x.o
-# From sound/oss/Makefile
-
-obj-$(CONFIG_SOUND_BT878) += btaudio.o
-
# From sound/i2c/other/Makefile
snd-tea575x-tuner-objs := tea575x-tuner.o
obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o
@@ -22,13 +18,6 @@ sound-install install-sound::
for i in $$files;do if [ -e $$i ]; then echo -n "$$i "; \
install -m 644 -c $$i $(KDIRA)/$$dir; fi; done; echo;
- @dir="sound/oss"; \
- files='btaudio.ko'; \
- echo -e "\nInstalling $(KDIRA)/$$dir files:"; \
- install -d $(KDIRA)/$$dir; \
- for i in $$files;do if [ -e $$i ]; then echo -n "$$i "; \
- install -m 644 -c $$i $(KDIRA)/$$dir; fi; done; echo;
-
@dir="sound/i2c/other"; \
files='snd-tea575x-tuner.ko'; \
echo -e "\nInstalling $(KDIRA)/$$dir files:"; \
diff --git a/v4l/scripts/checkpatch.pl b/v4l/scripts/checkpatch.pl
index a4f512753..2d5ece798 100755
--- a/v4l/scripts/checkpatch.pl
+++ b/v4l/scripts/checkpatch.pl
@@ -1,7 +1,8 @@
#!/usr/bin/perl -w
-# (c) 2001, Dave Jones. <davej@codemonkey.org.uk> (the file handling bit)
+# (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit)
# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
-# (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc)
+# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
+# (c) 2008, Andy Whitcroft <apw@canonical.com>
# Licensed under the terms of the GNU GPL License version 2
use strict;
@@ -9,7 +10,7 @@ use strict;
my $P = $0;
$P =~ s@.*/@@g;
-my $V = '0.21';
+my $V = '0.28';
use Getopt::Long qw(:config no_auto_abbrev);
@@ -66,8 +67,11 @@ if ($#ARGV < 0) {
my $dbg_values = 0;
my $dbg_possible = 0;
my $dbg_type = 0;
+my $dbg_attr = 0;
for my $key (keys %debug) {
- eval "\${dbg_$key} = '$debug{$key}';"
+ ## no critic
+ eval "\${dbg_$key} = '$debug{$key}';";
+ die "$@" if ($@);
}
if ($terse) {
@@ -106,13 +110,18 @@ our $Sparse = qr{
__iomem|
__must_check|
__init_refok|
- __kprobes
+ __kprobes|
+ __ref
}x;
our $Attribute = qr{
const|
__read_mostly|
__kprobes|
- __(?:mem|cpu|dev|)(?:initdata|init)
+ __(?:mem|cpu|dev|)(?:initdata|init)|
+ ____cacheline_aligned|
+ ____cacheline_aligned_in_smp|
+ ____cacheline_internodealigned_in_smp|
+ __weak
}x;
our $Modifier;
our $Inline = qr{inline|__always_inline|noinline};
@@ -121,6 +130,7 @@ our $Lval = qr{$Ident(?:$Member)*};
our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
+our $Compare = qr{<=|>=|==|!=|<|>};
our $Operators = qr{
<=|>=|==|!=|
=>|->|<<|>>|<|>|!|~|
@@ -142,6 +152,11 @@ our $UTF8 = qr {
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
}x;
+our $typeTypedefs = qr{(?x:
+ (?:__)?(?:u|s|be|le)(?:\d|\d\d)|
+ atomic_t
+)};
+
our @typeList = (
qr{void},
qr{(?:unsigned\s+)?char},
@@ -155,7 +170,6 @@ our @typeList = (
qr{float},
qr{double},
qr{bool},
- qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)},
qr{struct\s+$Ident},
qr{union\s+$Ident},
qr{enum\s+$Ident},
@@ -175,13 +189,14 @@ sub build_types {
(?:$Modifier\s+|const\s+)*
(?:
(?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)|
+ (?:$typeTypedefs\b)|
(?:${all}\b)
)
(?:\s+$Modifier|\s+const)*
}x;
$Type = qr{
$NonptrType
- (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
+ (?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)?
(?:\s+$Inline|\s+$Modifier)*
}x;
$Declare = qr{(?:$Storage\s+)?$Type};
@@ -194,9 +209,9 @@ my @dep_includes = ();
my @dep_functions = ();
my $removal = "Documentation/feature-removal-schedule.txt";
if ($tree && -f "$root/$removal") {
- open(REMOVE, "<$root/$removal") ||
+ open(my $REMOVE, '<', "$root/$removal") ||
die "$P: $removal: open failed - $!\n";
- while (<REMOVE>) {
+ while (<$REMOVE>) {
if (/^Check:\s+(.*\S)/) {
for my $entry (split(/[, ]+/, $1)) {
if ($entry =~ m@include/(.*)@) {
@@ -208,17 +223,21 @@ if ($tree && -f "$root/$removal") {
}
}
}
+ close($REMOVE);
}
my @rawlines = ();
my @lines = ();
my $vname;
for my $filename (@ARGV) {
+ my $FILE;
if ($file) {
- open(FILE, "diff -u /dev/null $filename|") ||
+ open($FILE, '-|', "diff -u /dev/null $filename") ||
die "$P: $filename: diff failed - $!\n";
+ } elsif ($filename eq '-') {
+ open($FILE, '<&STDIN');
} else {
- open(FILE, "<$filename") ||
+ open($FILE, '<', "$filename") ||
die "$P: $filename: open failed - $!\n";
}
if ($filename eq '-') {
@@ -226,11 +245,11 @@ for my $filename (@ARGV) {
} else {
$vname = $filename;
}
- while (<FILE>) {
+ while (<$FILE>) {
chomp;
push(@rawlines, $_);
}
- close(FILE);
+ close($FILE);
if (!process($filename)) {
$exit = 1;
}
@@ -331,7 +350,7 @@ sub sanitise_line {
$off++;
next;
}
- if (substr($line, $off, 2) eq '*/') {
+ if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
$sanitise_quote = '';
substr($res, $off, 2, "$;$;");
$off++;
@@ -357,7 +376,7 @@ sub sanitise_line {
}
}
- #print "SQ:$sanitise_quote\n";
+ #print "c<$c> SQ<$sanitise_quote>\n";
if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
substr($res, $off, 1, $;);
} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
@@ -393,17 +412,21 @@ sub ctx_statement_block {
my $type = '';
my $level = 0;
+ my @stack = ();
my $p;
my $c;
my $len = 0;
my $remainder;
while (1) {
+ @stack = (['', 0]) if ($#stack == -1);
+
#warn "CSB: blk<$blk> remain<$remain>\n";
# If we are about to drop off the end, pull in more
# context.
if ($off >= $len) {
for (; $remain > 0; $line++) {
+ last if (!defined $lines[$line]);
next if ($lines[$line] =~ /^-/);
$remain--;
$loff = $len;
@@ -423,6 +446,16 @@ sub ctx_statement_block {
$remainder = substr($blk, $off);
#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
+
+ # Handle nested #if/#else.
+ if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
+ push(@stack, [ $type, $level ]);
+ } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
+ ($type, $level) = @{$stack[$#stack - 1]};
+ } elsif ($remainder =~ /^#\s*endif\b/) {
+ ($type, $level) = @{pop(@stack)};
+ }
+
# Statement ends at the ';' or a close '}' at the
# outermost level.
if ($level == 0 && $c eq ';') {
@@ -569,11 +602,22 @@ sub ctx_block_get {
my @res = ();
my $level = 0;
+ my @stack = ($level);
for ($line = $start; $remain > 0; $line++) {
next if ($rawlines[$line] =~ /^-/);
$remain--;
$blk .= $rawlines[$line];
+
+ # Handle nested #if/#else.
+ if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
+ push(@stack, $level);
+ } elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
+ $level = $stack[$#stack - 1];
+ } elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) {
+ $level = pop(@stack);
+ }
+
foreach my $c (split(//, $rawlines[$line])) {
##print "C<$c>L<$level><$open$close>O<$off>\n";
if ($off > 0) {
@@ -669,6 +713,22 @@ sub ctx_has_comment {
return ($cmt ne '');
}
+sub raw_line {
+ my ($linenr, $cnt) = @_;
+
+ my $offset = $linenr - 1;
+ $cnt++;
+
+ my $line;
+ while ($cnt) {
+ $line = $rawlines[$offset++];
+ next if (defined($line) && $line =~ /^-/);
+ $cnt--;
+ }
+
+ return $line;
+}
+
sub cat_vet {
my ($vet) = @_;
my ($res, $coded);
@@ -782,9 +842,9 @@ sub annotate_values {
}
$type = 'N';
- } elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) {
+ } elsif ($cur =~ /^(if|while|for)\b/o) {
print "COND($1)\n" if ($dbg_values > 1);
- $av_pending = 'N';
+ $av_pending = 'E';
$type = 'N';
} elsif ($cur =~/^(case)/o) {
@@ -792,7 +852,7 @@ sub annotate_values {
$av_pend_colon = 'C';
$type = 'N';
- } elsif ($cur =~/^(return|else|goto)/o) {
+ } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
print "KEYWORD($1)\n" if ($dbg_values > 1);
$type = 'N';
@@ -817,11 +877,11 @@ sub annotate_values {
$type = 'V';
$av_pending = 'V';
- } elsif ($cur =~ /^($Ident\s*):/) {
- if ($type eq 'E') {
- $av_pend_colon = 'L';
- } elsif ($type eq 'T') {
+ } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
+ if (defined $2 && $type eq 'C' || $type eq 'T') {
$av_pend_colon = 'B';
+ } elsif ($type eq 'E') {
+ $av_pend_colon = 'L';
}
print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
$type = 'V';
@@ -839,6 +899,10 @@ sub annotate_values {
$type = 'E';
$av_pend_colon = 'O';
+ } elsif ($cur =~/^(,)/) {
+ print "COMMA($1)\n" if ($dbg_values > 1);
+ $type = 'C';
+
} elsif ($cur =~ /^(\?)/o) {
print "QUESTION($1)\n" if ($dbg_values > 1);
$type = 'N';
@@ -854,11 +918,11 @@ sub annotate_values {
}
$av_pend_colon = 'O';
- } elsif ($cur =~ /^(;|\[)/o) {
+ } elsif ($cur =~ /^(\[)/o) {
print "CLOSE($1)\n" if ($dbg_values > 1);
$type = 'N';
- } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&(?!\&))/o) {
+ } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
my $variant;
print "OPV($1)\n" if ($dbg_values > 1);
@@ -892,12 +956,22 @@ sub annotate_values {
sub possible {
my ($possible, $line) = @_;
- print "CHECK<$possible> ($line)\n" if ($dbg_possible > 1);
- if ($possible !~ /^(?:$Modifier|$Storage|$Type|DEFINE_\S+)$/ &&
- $possible ne 'goto' && $possible ne 'return' &&
- $possible ne 'case' && $possible ne 'else' &&
- $possible ne 'asm' && $possible ne '__asm__' &&
- $possible !~ /^(typedef|struct|enum)\b/) {
+ print "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
+ if ($possible !~ /(?:
+ ^(?:
+ $Modifier|
+ $Storage|
+ $Type|
+ DEFINE_\S+|
+ goto|
+ return|
+ case|
+ else|
+ asm|__asm__|
+ do
+ )$|
+ ^(?:typedef|struct|enum)\b
+ )/x) {
# Check for modifiers.
$possible =~ s/\s*$Storage\s*//g;
$possible =~ s/\s*$Sparse\s*//g;
@@ -915,6 +989,8 @@ sub possible {
push(@typeList, $possible);
}
build_types();
+ } else {
+ warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
}
}
@@ -954,6 +1030,33 @@ sub CHK {
}
}
+sub check_absolute_file {
+ my ($absolute, $herecurr) = @_;
+ my $file = $absolute;
+
+ ##print "absolute<$absolute>\n";
+
+ # See if any suffix of this path is a path within the tree.
+ while ($file =~ s@^[^/]*/@@) {
+ if (-f "$root/$file") {
+ ##print "file<$file>\n";
+ last;
+ }
+ }
+ if (! -f _) {
+ return 0;
+ }
+
+ # It is, so see if the prefix is acceptable.
+ my $prefix = $absolute;
+ substr($prefix, -length($file)) = '';
+
+ ##print "prefix<$prefix>\n";
+ if ($prefix ne ".../") {
+ WARN("use relative pathname instead of absolute in changelog text\n" . $herecurr);
+ }
+}
+
sub process {
my $filename = shift;
@@ -986,11 +1089,13 @@ sub process {
my $in_comment = 0;
my $comment_edge = 0;
my $first_line = 0;
+ my $p1_prefix = '';
my $prev_values = 'E';
# suppression flags
my %suppress_ifbraces;
+ my %suppress_whiletrailers;
# Pre-scan the patch sanitizing the lines.
# Pre-scan the patch looking for any __setup documentation.
@@ -1025,10 +1130,18 @@ sub process {
# edge is a close comment then we must be in a comment
# at context start.
my $edge;
- for (my $ln = $linenr + 1; $ln < ($linenr + $realcnt); $ln++) {
- next if ($line =~ /^-/);
- ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@);
- last if (defined $edge);
+ my $cnt = $realcnt;
+ for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
+ next if (defined $rawlines[$ln - 1] &&
+ $rawlines[$ln - 1] =~ /^-/);
+ $cnt--;
+ #print "RAW<$rawlines[$ln - 1]>\n";
+ last if (!defined $rawlines[$ln - 1]);
+ if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
+ $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
+ ($edge) = $1;
+ last;
+ }
}
if (defined $edge && $edge eq '*/') {
$in_comment = 1;
@@ -1038,7 +1151,7 @@ sub process {
# is the start of a diff block and this line starts
# ' *' then it is very likely a comment.
if (!defined $edge &&
- $rawlines[$linenr] =~ m@^.\s* \*(?:\s|$)@)
+ $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
{
$in_comment = 1;
}
@@ -1075,6 +1188,7 @@ sub process {
$linenr++;
my $rawline = $rawlines[$linenr - 1];
+ my $hunk_line = ($realcnt != 0);
#extract the line range in the file after the patch is applied
if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
@@ -1090,6 +1204,7 @@ sub process {
$prev_values = 'E';
%suppress_ifbraces = ();
+ %suppress_whiletrailers = ();
next;
# track the line number as we move through the hunk, note that
@@ -1123,9 +1238,15 @@ sub process {
# extract the filename as it passes
if ($line=~/^\+\+\+\s+(\S+)/) {
$realfile = $1;
- $realfile =~ s@^[^/]*/@@;
+ $realfile =~ s@^([^/]*)/@@;
- if ($realfile =~ m@include/asm/@) {
+ $p1_prefix = $1;
+ if (!$file && $tree && $p1_prefix ne '' &&
+ -e "$root/$p1_prefix") {
+ WARN("patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
+ }
+
+ if ($realfile =~ m@^include/asm/@) {
ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
}
next;
@@ -1159,6 +1280,20 @@ sub process {
$herecurr) if (!$emitted_corrupt++);
}
+# Check for absolute kernel paths.
+ if ($tree) {
+ while ($line =~ m{(?:^|\s)(/\S*)}g) {
+ my $file = $1;
+
+ if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
+ check_absolute_file($1, $herecurr)) {
+ #
+ } else {
+ check_absolute_file($file, $herecurr);
+ }
+ }
+ }
+
# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
if (($realfile =~ /^$/ || $line =~ /^\+/) &&
$rawline !~ m/^$UTF8*$/) {
@@ -1171,11 +1306,8 @@ sub process {
ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
}
-#ignore lines being removed
- if ($line=~/^-/) {next;}
-
-# check we are in a valid source file if not then ignore this hunk
- next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
+# ignore non-hunk lines and lines being removed
+ next if (!$hunk_line || $line =~ /^-/);
#trailing whitespace
if ($line =~ /^\+.*\015/) {
@@ -1186,6 +1318,10 @@ sub process {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
ERROR("trailing whitespace\n" . $herevet);
}
+
+# check we are in a valid source file if not then ignore this hunk
+ next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
+
#80 column limit
if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
$rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
@@ -1200,8 +1336,8 @@ sub process {
WARN("adding a line without newline at end of file\n" . $herecurr);
}
-# check we are in a valid source file *.[hc] if not then ignore this hunk
- next if ($realfile !~ /\.[hc]$/);
+# check we are in a valid source file C or perl if not then ignore this hunk
+ next if ($realfile !~ /\.(h|c|pl)$/);
# at the beginning of a line any tabs must come first and anything
# more than 8 must use tabs.
@@ -1211,15 +1347,18 @@ sub process {
ERROR("code indent should use tabs where possible\n" . $herevet);
}
+# check we are in a valid C source file if not then ignore this hunk
+ next if ($realfile !~ /\.(h|c)$/);
+
# check for RCS/CVS revision markers
if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
}
# Check for potential 'bare' types
- my ($stat, $cond, $line_nr_next, $remain_next);
+ my ($stat, $cond, $line_nr_next, $remain_next, $off_next);
if ($realcnt && $line =~ /.\s*\S/) {
- ($stat, $cond, $line_nr_next, $remain_next) =
+ ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
ctx_statement_block($linenr, $realcnt, 0);
$stat =~ s/\n./\n /g;
$cond =~ s/\n./\n /g;
@@ -1240,12 +1379,12 @@ sub process {
possible($type, "A:" . $s);
# definitions in global scope can only start with types
- } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/s) {
+ } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
possible($1, "B:" . $s);
}
# any (foo ... *) is a pointer cast, and foo is a type
- while ($s =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/sg) {
+ while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
possible($1, "C:" . $s);
}
@@ -1294,10 +1433,6 @@ sub process {
ERROR("switch and case should be at the same indent\n$hereline$err");
}
}
- if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
- $line !~ /\G(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$/g) {
- ERROR("trailing statements should be on next line\n" . $herecurr);
- }
# if/while/etc brace do not go on next line, unless defining a do while loop,
# or if that brace on the next line is for something else
@@ -1338,6 +1473,91 @@ sub process {
}
}
+# Check relative indent for conditionals and blocks.
+ if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
+ my ($s, $c) = ($stat, $cond);
+
+ substr($s, 0, length($c), '');
+
+ # Make sure we remove the line prefixes as we have
+ # none on the first line, and are going to readd them
+ # where necessary.
+ $s =~ s/\n./\n/gs;
+
+ # Find out how long the conditional actually is.
+ my @newlines = ($c =~ /\n/gs);
+ my $cond_lines = 1 + $#newlines;
+
+ # We want to check the first line inside the block
+ # starting at the end of the conditional, so remove:
+ # 1) any blank line termination
+ # 2) any opening brace { on end of the line
+ # 3) any do (...) {
+ my $continuation = 0;
+ my $check = 0;
+ $s =~ s/^.*\bdo\b//;
+ $s =~ s/^\s*{//;
+ if ($s =~ s/^\s*\\//) {
+ $continuation = 1;
+ }
+ if ($s =~ s/^\s*?\n//) {
+ $check = 1;
+ $cond_lines++;
+ }
+
+ # Also ignore a loop construct at the end of a
+ # preprocessor statement.
+ if (($prevline =~ /^.\s*#\s*define\s/ ||
+ $prevline =~ /\\\s*$/) && $continuation == 0) {
+ $check = 0;
+ }
+
+ my $cond_ptr = -1;
+ $continuation = 0;
+ while ($cond_ptr != $cond_lines) {
+ $cond_ptr = $cond_lines;
+
+ # If we see an #else/#elif then the code
+ # is not linear.
+ if ($s =~ /^\s*\#\s*(?:else|elif)/) {
+ $check = 0;
+ }
+
+ # Ignore:
+ # 1) blank lines, they should be at 0,
+ # 2) preprocessor lines, and
+ # 3) labels.
+ if ($continuation ||
+ $s =~ /^\s*?\n/ ||
+ $s =~ /^\s*#\s*?/ ||
+ $s =~ /^\s*$Ident\s*:/) {
+ $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
+ $s =~ s/^.*?\n//;
+ $cond_lines++;
+ }
+ }
+
+ my (undef, $sindent) = line_stats("+" . $s);
+ my $stat_real = raw_line($linenr, $cond_lines);
+
+ # Check if either of these lines are modified, else
+ # this is not this patch's fault.
+ if (!defined($stat_real) ||
+ $stat !~ /^\+/ && $stat_real !~ /^\+/) {
+ $check = 0;
+ }
+ if (defined($stat_real) && $cond_lines > 1) {
+ $stat_real = "[...]\n$stat_real";
+ }
+
+ #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
+
+ if ($check && (($sindent % 8) != 0 ||
+ ($sindent <= $indent && $s ne ''))) {
+ WARN("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
+ }
+ }
+
# Track the 'values' across context and added lines.
my $opline = $line; $opline =~ s/^./ /;
my ($curr_values, $curr_vars) =
@@ -1363,6 +1583,15 @@ sub process {
}
next;
}
+# TEST: allow direct testing of the attribute matcher.
+ if ($dbg_attr) {
+ if ($line =~ /^.\s*$Modifier\s*$/) {
+ ERROR("TEST: is attr\n" . $herecurr);
+ } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
+ ERROR("TEST: is not attr ($1 is)\n". $herecurr);
+ }
+ next;
+ }
# check for initialisation to aggregates open brace on the next line
if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ &&
@@ -1395,13 +1624,14 @@ sub process {
if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) ||
($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
my $name = $1;
- if (($prevline !~ /^}/) &&
- ($prevline !~ /^\+}/) &&
- ($prevline !~ /^ }/) &&
- ($prevline !~ /^.DECLARE_$Ident\(\Q$name\E\)/) &&
- ($prevline !~ /^.LIST_HEAD\(\Q$name\E\)/) &&
- ($prevline !~ /^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(/) &&
- ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)/)) {
+ if ($prevline !~ /(?:
+ ^.}|
+ ^.DEFINE_$Ident\(\Q$name\E\)|
+ ^.DECLARE_$Ident\(\Q$name\E\)|
+ ^.LIST_HEAD\(\Q$name\E\)|
+ ^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
+ \b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)
+ )/x) {
WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
}
}
@@ -1412,7 +1642,7 @@ sub process {
$herecurr);
}
# check for static initialisers.
- if ($line =~ /\s*static\s.*=\s*(0|NULL|false)\s*;/) {
+ if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
ERROR("do not initialise statics to 0 or NULL\n" .
$herecurr);
}
@@ -1420,28 +1650,47 @@ sub process {
# check for new typedefs, only function parameters and sparse annotations
# make sense.
if ($line =~ /\btypedef\s/ &&
- $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ &&
+ $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
$line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
+ $line !~ /\b$typeTypedefs\b/ &&
$line !~ /\b__bitwise(?:__|)\b/) {
WARN("do not add new typedefs\n" . $herecurr);
}
# * goes on variable not on type
- if ($line =~ m{\($NonptrType(\*+)(?:\s+const)?\)}) {
- ERROR("\"(foo$1)\" should be \"(foo $1)\"\n" .
- $herecurr);
+ # (char*[ const])
+ if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) {
+ my ($from, $to) = ($1, $1);
- } elsif ($line =~ m{\($NonptrType\s+(\*+)(?!\s+const)\s+\)}) {
- ERROR("\"(foo $1 )\" should be \"(foo $1)\"\n" .
- $herecurr);
+ # Should start with a space.
+ $to =~ s/^(\S)/ $1/;
+ # Should not end with a space.
+ $to =~ s/\s+$//;
+ # '*'s should not have spaces between.
+ while ($to =~ s/\*\s+\*/\*\*/) {
+ }
- } elsif ($line =~ m{\b$NonptrType(\*+)(?:\s+(?:$Attribute|$Sparse))?\s+[A-Za-z\d_]+}) {
- ERROR("\"foo$1 bar\" should be \"foo $1bar\"\n" .
- $herecurr);
+ #print "from<$from> to<$to>\n";
+ if ($from ne $to) {
+ ERROR("\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr);
+ }
+ } elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) {
+ my ($from, $to, $ident) = ($1, $1, $2);
- } elsif ($line =~ m{\b$NonptrType\s+(\*+)(?!\s+(?:$Attribute|$Sparse))\s+[A-Za-z\d_]+}) {
- ERROR("\"foo $1 bar\" should be \"foo $1bar\"\n" .
- $herecurr);
+ # Should start with a space.
+ $to =~ s/^(\S)/ $1/;
+ # Should not end with a space.
+ $to =~ s/\s+$//;
+ # '*'s should not have spaces between.
+ while ($to =~ s/\*\s+\*/\*\*/) {
+ }
+ # Modifiers should have spaces.
+ $to =~ s/(\b$Modifier$)/$1 /;
+
+ #print "from<$from> to<$to> ident<$ident>\n";
+ if ($from ne $to && $ident !~ /^$Modifier$/) {
+ ERROR("\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr);
+ }
}
# # no BUG() or BUG_ON()
@@ -1493,11 +1742,13 @@ sub process {
# check for spacing round square brackets; allowed:
# 1. with a type on the left -- int [] a;
-# 2. at the beginning of a line for slice initialisers -- [0..10] = 5,
+# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
+# 3. inside a curly brace -- = { [0...10] = 5 }
while ($line =~ /(.*?\s)\[/g) {
my ($where, $prefix) = ($-[1], $1);
if ($prefix !~ /$Type\s+$/ &&
- ($where != 0 || $prefix !~ /^.\s+$/)) {
+ ($where != 0 || $prefix !~ /^.\s+$/) &&
+ $prefix !~ /{\s+$/) {
ERROR("space prohibited before open square bracket '['\n" . $herecurr);
}
}
@@ -1574,7 +1825,7 @@ sub process {
$c = 'C' if ($elements[$n + 2] =~ /^$;/);
$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
$c = 'O' if ($elements[$n + 2] eq '');
- $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/);
+ $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
} else {
$c = 'E';
}
@@ -1632,15 +1883,15 @@ sub process {
# unary operator, or a cast
} elsif ($op eq '!' || $op eq '~' ||
$opv eq '*U' || $opv eq '-U' ||
- $opv eq '&U') {
+ $opv eq '&U' || $opv eq '&&U') {
if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
ERROR("space required before that '$op' $at\n" . $hereptr);
}
- if ($op eq '*' && $cc =~/\s*const\b/) {
+ if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
# A unary '*' may be const
} elsif ($ctx =~ /.xW/) {
- ERROR("space prohibited after that '$op' $at\n" . $hereptr);
+ ERROR("Aspace prohibited after that '$op' $at\n" . $hereptr);
}
# unary ++ and unary -- are allowed no space on one side.
@@ -1686,13 +1937,13 @@ sub process {
($op eq '>' &&
$ca =~ /<\S+\@\S+$/))
{
- $ok = 1;
+ $ok = 1;
}
# Ignore ?:
if (($opv eq ':O' && $ca =~ /\?$/) ||
($op eq '?' && $cc =~ /^:/)) {
- $ok = 1;
+ $ok = 1;
}
if ($ok == 0) {
@@ -1765,9 +2016,13 @@ sub process {
my $spacing = $1;
my $value = $2;
- # Flatten any parentheses and braces
+ # Flatten any parentheses
$value =~ s/\)\(/\) \(/g;
- while ($value =~ s/\([^\(\)]*\)/1/) {
+ while ($value =~ s/\[[^\{\}]*\]/1/ ||
+ $value !~ /(?:$Ident|-?$Constant)\s*
+ $Compare\s*
+ (?:$Ident|-?$Constant)/x &&
+ $value =~ s/\([^\(\)]*\)/1/) {
}
if ($value =~ /^(?:$Ident|-?$Constant)$/) {
@@ -1785,10 +2040,29 @@ sub process {
# Check for illegal assignment in if conditional -- and check for trailing
# statements after the conditional.
- if ($line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
+ if ($line =~ /do\s*(?!{)/) {
+ my ($stat_next) = ctx_statement_block($line_nr_next,
+ $remain_next, $off_next);
+ $stat_next =~ s/\n./\n /g;
+ ##print "stat<$stat> stat_next<$stat_next>\n";
+
+ if ($stat_next =~ /^\s*while\b/) {
+ # If the statement carries leading newlines,
+ # then count those as offsets.
+ my ($whitespace) =
+ ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
+ my $offset =
+ statement_rawlines($whitespace) - 1;
+
+ $suppress_whiletrailers{$line_nr_next +
+ $offset} = 1;
+ }
+ }
+ if (!defined $suppress_whiletrailers{$linenr} &&
+ $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
my ($s, $c) = ($stat, $cond);
- if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) {
+ if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
ERROR("do not use assignment in if condition\n" . $herecurr);
}
@@ -1800,57 +2074,16 @@ sub process {
if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
$c !~ /}\s*while\s*/)
{
- ERROR("trailing statements should be on next line\n" . $herecurr);
- }
- }
-
-# Check relative indent for conditionals and blocks.
- if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
- my ($s, $c) = ($stat, $cond);
-
- substr($s, 0, length($c), '');
-
- # Make sure we remove the line prefixes as we have
- # none on the first line, and are going to readd them
- # where necessary.
- $s =~ s/\n./\n/gs;
-
- # We want to check the first line inside the block
- # starting at the end of the conditional, so remove:
- # 1) any blank line termination
- # 2) any opening brace { on end of the line
- # 3) any do (...) {
- my $continuation = 0;
- my $check = 0;
- $s =~ s/^.*\bdo\b//;
- $s =~ s/^\s*{//;
- if ($s =~ s/^\s*\\//) {
- $continuation = 1;
- }
- if ($s =~ s/^\s*\n//) {
- $check = 1;
- }
-
- # Also ignore a loop construct at the end of a
- # preprocessor statement.
- if (($prevline =~ /^.\s*#\s*define\s/ ||
- $prevline =~ /\\\s*$/) && $continuation == 0) {
- $check = 0;
- }
-
- # Ignore the current line if its is a preprocessor
- # line.
- if ($s =~ /^\s*#\s*/) {
- $check = 0;
- }
+ # Find out how long the conditional actually is.
+ my @newlines = ($c =~ /\n/gs);
+ my $cond_lines = 1 + $#newlines;
- my (undef, $sindent) = line_stats("+" . $s);
-
- ##print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s>\n";
+ my $stat_real = raw_line($linenr, $cond_lines);
+ if (defined($stat_real) && $cond_lines > 1) {
+ $stat_real = "[...]\n$stat_real";
+ }
- if ($check && (($sindent % 8) != 0 ||
- ($sindent <= $indent && $s ne ''))) {
- WARN("suspect code indent for conditional statements\n" . $herecurr);
+ ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real);
}
}
@@ -1877,6 +2110,20 @@ sub process {
ERROR("trailing statements should be on next line\n" . $herecurr);
}
}
+# if should not continue a brace
+ if ($line =~ /}\s*if\b/) {
+ ERROR("trailing statements should be on next line\n" .
+ $herecurr);
+ }
+# case and default should not have general statements after them
+ if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
+ $line !~ /\G(?:
+ (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
+ \s*return\s+
+ )/xg)
+ {
+ ERROR("trailing statements should be on next line\n" . $herecurr);
+ }
# Check for }<nl>else {, these must be at the same
# indent level to be relevant to each other.
@@ -1913,12 +2160,17 @@ sub process {
#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
- my $checkfile = "include/linux/$1.h";
- if (-f "$root/$checkfile" && $realfile ne $checkfile &&
+ my $file = "$1.h";
+ my $checkfile = "include/linux/$file";
+ if (-f "$root/$checkfile" &&
+ $realfile ne $checkfile &&
$1 ne 'irq')
{
- WARN("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
- $herecurr);
+ if ($realfile =~ m{^arch/}) {
+ CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
+ } else {
+ WARN("Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
+ }
}
}
@@ -1953,8 +2205,8 @@ sub process {
# Extract the remainder of the define (if any) and
# rip off surrounding spaces, and trailing \'s.
$rest = '';
- while ($off != 0 || ($cnt > 0 && $rest =~ /(?:^|\\)\s*$/)) {
- #print "ADDING $off <" . substr($lines[$ln - 1], $off) . ">\n";
+ while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) {
+ #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n";
if ($off != 0 || $lines[$ln - 1] !~ /^-/) {
$rest .= substr($lines[$ln - 1], $off) . "\n";
$cnt--;
@@ -1978,9 +2230,10 @@ sub process {
$dstat =~ s/\s*$//s;
# Flatten any parentheses and braces
- while ($dstat =~ s/\([^\(\)]*\)/1/) {
- }
- while ($dstat =~ s/\{[^\{\}]*\}/1/) {
+ while ($dstat =~ s/\([^\(\)]*\)/1/ ||
+ $dstat =~ s/\{[^\{\}]*\}/1/ ||
+ $dstat =~ s/\[[^\{\}]*\]/1/)
+ {
}
my $exceptions = qr{
@@ -1989,9 +2242,10 @@ sub process {
MODULE_PARAM_DESC|
DECLARE_PER_CPU|
DEFINE_PER_CPU|
- __typeof__\(
+ __typeof__\(|
+ \.$Ident\s*=\s*
}x;
- #print "REST<$rest>\n";
+ #print "REST<$rest> dstat<$dstat>\n";
if ($rest ne '') {
if ($rest !~ /while\s*\(/ &&
$dstat !~ /$exceptions/)
@@ -2003,6 +2257,7 @@ sub process {
if ($dstat ne '' &&
$dstat !~ /^(?:$Ident|-?$Constant)$/ &&
$dstat !~ /$exceptions/ &&
+ $dstat !~ /^\.$Ident\s*=/ &&
$dstat =~ /$Operators/)
{
ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n");
@@ -2010,6 +2265,15 @@ sub process {
}
}
+# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
+# all assignments may have only one of the following with an assignment:
+# .
+# ALIGN(...)
+# VMLINUX_SYMBOL(...)
+ if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
+ WARN("vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
+ }
+
# check for redundant bracing round if etc
if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
my ($level, $endln, @chunks) =
@@ -2103,10 +2367,10 @@ sub process {
}
if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
my $herectx = $here . "\n";;
- my $end = $linenr + statement_rawlines($block) - 1;
+ my $cnt = statement_rawlines($block);
- for (my $ln = $linenr - 1; $ln < $end; $ln++) {
- $herectx .= $rawlines[$ln] . "\n";;
+ for (my $n = 0; $n < $cnt; $n++) {
+ $herectx .= raw_line($linenr, $n) . "\n";;
}
WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
@@ -2264,6 +2528,12 @@ sub process {
if ($line =~ /^.\s*__initcall\s*\(/) {
WARN("please use device_initcall() instead of __initcall()\n" . $herecurr);
}
+# check for struct file_operations, ensure they are const.
+ if ($line !~ /\bconst\b/ &&
+ $line =~ /\bstruct\s+(file_operations|seq_operations)\b/) {
+ WARN("struct $1 should normally be const\n" .
+ $herecurr);
+ }
# use of NR_CPUS is usually wrong
# ignore definitions of NR_CPUS and usage to define arrays as likely right
@@ -2281,11 +2551,21 @@ sub process {
my $string;
while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
$string = substr($rawline, $-[1], $+[1] - $-[1]);
+ $string =~ s/%%/__/g;
if ($string =~ /(?<!%)%L[udi]/) {
WARN("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
last;
}
}
+
+# whine mightly about in_atomic
+ if ($line =~ /\bin_atomic\s*\(/) {
+ if ($realfile =~ m@^drivers/@) {
+ ERROR("do not use in_atomic in drivers\n" . $herecurr);
+ } elsif ($realfile !~ m@^kernel/@) {
+ WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
+ }
+ }
}
# If we have no input at all, then there is nothing to report on
diff --git a/v4l/scripts/fix_kconfig.pl b/v4l/scripts/fix_kconfig.pl
new file mode 100755
index 000000000..9a448cbc6
--- /dev/null
+++ b/v4l/scripts/fix_kconfig.pl
@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+use strict;
+
+my $need_changes = 0;
+my $out;
+
+open IN,".config";
+while (<IN>) {
+ if (s/CONFIG_VIDEO_CX88_MPEG=y/CONFIG_VIDEO_CX88_MPEG=m/) {
+ $need_changes=1;
+ $out .= $_;
+ }
+}
+close IN;
+
+if ($need_changes) {
+ printf("There's a known bug with the building system with this kernel. Working around.\n");
+ open OUT, ">.config";
+ print OUT $out;
+ close OUT;
+}
diff --git a/v4l/versions.txt b/v4l/versions.txt
index 8435046c5..369cbb15d 100644
--- a/v4l/versions.txt
+++ b/v4l/versions.txt
@@ -29,6 +29,8 @@ USB_STKWEBCAM
DVB_DRX397XD
# Assumes struct input_dev has a dev field
DVB_DM1105
+# This driver needs print_hex_dump
+DVB_FIREDTV
[2.6.20]
#This driver requires HID_REQ_GET_REPORT
diff --git a/v4l_experimental/firesat/Kconfig b/v4l_experimental/firesat/Kconfig
deleted file mode 100644
index fe8c82b32..000000000
--- a/v4l_experimental/firesat/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-config DVB_FIRESAT
- tristate "FireSAT devices"
- depends on DVB_CORE && ieee1394
- help
- Support for external IEEE1394 adapters designed by Digital Everywhere and
- produced by El Gato, shipped under the brand name 'EyeTV 300/400'.
-
- These devices don't have a MPEG decoder built in, so you need
- an external software decoder to watch TV.
-
- Say Y if you own such a device and want to use it.
diff --git a/v4l_experimental/firesat/Makefile b/v4l_experimental/firesat/Makefile
deleted file mode 100644
index 54e93b366..000000000
--- a/v4l_experimental/firesat/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-obj-$(CONFIG_DVB_FIRESAT) := dvb-firesat.o
-
-dvb-firesat-objs := firesat.o avc_api.o cmp.o firesat-rc.o
-
-EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
-
-firesat.c: firesat.h avc_api.h cmp.h firesat-rc.h firesat-ci.h
-avc_api.c: avc_api.h firesat.h
-cmp.c: cmp.h avc_api.h
-firesat-rc.c: firesat-rc.h
-firesat-ci.c: firesat-ci.h
diff --git a/v4l_experimental/firesat/avc_api.c b/v4l_experimental/firesat/avc_api.c
deleted file mode 100644
index eb597eaa4..000000000
--- a/v4l_experimental/firesat/avc_api.c
+++ /dev/null
@@ -1,953 +0,0 @@
-/*
- * FireSAT AVC driver
- *
- * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-#include <ieee1394_transactions.h>
-#include <nodemgr.h>
-#include <asm/byteorder.h>
-#include <linux/delay.h>
-#include "firesat.h"
-#include "avc_api.h"
-#include "firesat-rc.h"
-
-#define RESPONSE_REGISTER 0xFFFFF0000D00ULL
-#define COMMAND_REGISTER 0xFFFFF0000B00ULL
-#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
-
-static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal);
-
-/* Frees an allocated packet */
-static void avc_free_packet(struct hpsb_packet *packet)
-{
- hpsb_free_tlabel(packet);
- hpsb_free_packet(packet);
-}
-
-/*
- * Goofy routine that basically does a down_timeout function.
- * Stolen from sbp2.c
- */
-static int avc_down_timeout(atomic_t *done, int timeout)
-{
- int i;
-
- for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (schedule_timeout(HZ/10)) /* 100ms */
- return(1);
- }
- return ((i > 0) ? 0:1);
-}
-
-static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) {
- struct hpsb_packet *packet;
- struct node_entry *ne;
-
- ne = firesat->nodeentry;
- if(!ne) {
- printk("%s: lost node!\n",__FUNCTION__);
- return -EIO;
- }
-
- /* need all input data */
- if(!firesat || !ne || !CmdFrm)
- return -EINVAL;
-
-// printk(KERN_INFO "AVCWrite command %x\n",CmdFrm->opcode);
-
-// for(k=0;k<CmdFrm->length;k++)
-// printk(KERN_INFO "CmdFrm[%d] = %08x\n", k, ((quadlet_t*)CmdFrm)[k]);
-
- packet=hpsb_make_writepacket(ne->host, ne->nodeid, COMMAND_REGISTER,
- (quadlet_t*)CmdFrm, CmdFrm->length);
-
- hpsb_set_packet_complete_task(packet, (void (*)(void*))avc_free_packet,
- packet);
-
- hpsb_node_fill_packet(ne, packet);
-
- if(RspFrm)
- atomic_set(&firesat->avc_reply_received, 0);
-
- if (hpsb_send_packet(packet) < 0) {
- avc_free_packet(packet);
- atomic_set(&firesat->avc_reply_received, 1);
- return -EIO;
- }
-
- if(RspFrm) {
- if(avc_down_timeout(&firesat->avc_reply_received,HZ/2)) {
- printk("%s: timeout waiting for avc response\n",__FUNCTION__);
- atomic_set(&firesat->avc_reply_received, 1);
- return -ETIMEDOUT;
- }
-
- memcpy(RspFrm,firesat->respfrm,firesat->resp_length);
- }
-
- return 0;
-}
-
-int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) {
- int ret;
- if(down_interruptible(&firesat->avc_sem))
- return -EINTR;
-
- ret = __AVCWrite(firesat, CmdFrm, RspFrm);
-
- up(&firesat->avc_sem);
- return ret;
-}
-
-static void do_schedule_remotecontrol(unsigned long ignored);
-DECLARE_TASKLET(schedule_remotecontrol, do_schedule_remotecontrol, 0);
-
-static void do_schedule_remotecontrol(unsigned long ignored) {
- struct firesat *firesat;
- unsigned long flags;
-
- spin_lock_irqsave(&firesat_list_lock, flags);
- list_for_each_entry(firesat,&firesat_list,list) {
- if(atomic_read(&firesat->reschedule_remotecontrol) == 1) {
- if(down_trylock(&firesat->avc_sem))
- tasklet_schedule(&schedule_remotecontrol);
- else {
- if(__AVCRegisterRemoteControl(firesat, 1) == 0)
- atomic_set(&firesat->reschedule_remotecontrol, 0);
- else
- tasklet_schedule(&schedule_remotecontrol);
-
- up(&firesat->avc_sem);
- }
- }
- }
- spin_unlock_irqrestore(&firesat_list_lock, flags);
-}
-
-int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
-// printk(KERN_INFO "%s\n",__FUNCTION__);
-
- // remote control handling
-
- AVCRspFrm *RspFrm = (AVCRspFrm*)data;
-
- if(/*RspFrm->length >= 8 && ###*/
- ((RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
- RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
- RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2) ||
- (RspFrm->operand[0] == SFE_VENDOR_EL_COMPANYID_0 &&
- RspFrm->operand[1] == SFE_VENDOR_EL_COMPANYID_1 &&
- RspFrm->operand[2] == SFE_VENDOR_EL_COMPANYID_2)) &&
- RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
- if(RspFrm->resp == CHANGED) {
-// printk(KERN_INFO "%s: code = %02x %02x\n",__FUNCTION__,RspFrm->operand[4],RspFrm->operand[5]);
- firesat_got_remotecontrolcode((((u16)RspFrm->operand[4]) << 8) | ((u16)RspFrm->operand[5]));
-
- // schedule
- atomic_set(&firesat->reschedule_remotecontrol, 1);
- tasklet_schedule(&schedule_remotecontrol);
- } else if(RspFrm->resp != INTERIM)
- printk(KERN_INFO "%s: remote control result = %d\n",__FUNCTION__, RspFrm->resp);
- return 0;
- }
-
- if(atomic_read(&firesat->avc_reply_received) == 1) {
- printk("%s: received out-of-order AVC response, ignored\n",__FUNCTION__);
- return -EINVAL;
- }
-// AVCRspFrm *resp=(AVCRspFrm *)data;
-// int k;
-/*
- printk(KERN_INFO "resp=0x%x\n",resp->resp);
- printk(KERN_INFO "cts=0x%x\n",resp->cts);
- printk(KERN_INFO "suid=0x%x\n",resp->suid);
- printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp);
- printk(KERN_INFO "opcode=0x%x\n",resp->opcode);
- printk(KERN_INFO "length=%d\n",resp->length);
-*/
-// for(k=0;k<2;k++)
-// printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]);
-
- memcpy(firesat->respfrm,data,length);
- firesat->resp_length=length;
-
- atomic_set(&firesat->avc_reply_received, 1);
-
- return 0;
-}
-
-// tuning command for setting the relative LNB frequency (not supported by the AVC standard)
-static void AVCTuner_DSD_directcmd(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) {
- memset(CmdFrm, 0, sizeof(AVCCmdFrm));
-
- CmdFrm->cts = AVC;
- CmdFrm->ctype = CONTROL;
- CmdFrm->sutyp = 0x5;
- CmdFrm->suid = firesat->subunit;
- CmdFrm->opcode = VENDOR;
-
- /* ### should check for elgato and use SFE_VENDOR_EL_COMPANYID_0 in this case */
- CmdFrm->operand[0]=SFE_VENDOR_DE_COMPANYID_0;
- CmdFrm->operand[1]=SFE_VENDOR_DE_COMPANYID_1;
- CmdFrm->operand[2]=SFE_VENDOR_DE_COMPANYID_2;
- CmdFrm->operand[3]=0x58;
-
- printk(KERN_INFO "%s: tuning to frequency %u\n",__FUNCTION__,params->frequency);
-
- CmdFrm->operand[4] = (params->frequency >> 24) & 0xFF;
- CmdFrm->operand[5] = (params->frequency >> 16) & 0xFF;
- CmdFrm->operand[6] = (params->frequency >> 8) & 0xFF;
- CmdFrm->operand[7] = params->frequency & 0xFF;
-
- printk(KERN_INFO "%s: symbol rate = %uBd\n",__FUNCTION__,params->u.qpsk.symbol_rate);
-
- CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate/1000) >> 8) & 0xFF;
- CmdFrm->operand[9] = (params->u.qpsk.symbol_rate/1000) & 0xFF;
-
- switch(params->u.qpsk.fec_inner) {
- case FEC_1_2:
- CmdFrm->operand[10] = 0x1;
- break;
- case FEC_2_3:
- CmdFrm->operand[10] = 0x2;
- break;
- case FEC_3_4:
- CmdFrm->operand[10] = 0x3;
- break;
- case FEC_5_6:
- CmdFrm->operand[10] = 0x4;
- break;
- case FEC_7_8:
- CmdFrm->operand[10] = 0x5;
- break;
- case FEC_4_5:
- case FEC_8_9:
- case FEC_AUTO:
- default:
- CmdFrm->operand[10] = 0x0;
- }
-
- if(firesat->voltage == 0xff)
- CmdFrm->operand[11] = 0xff;
- else
- CmdFrm->operand[11] = (firesat->voltage==SEC_VOLTAGE_18)?0:1; // polarisation
- if(firesat->tone == 0xff)
- CmdFrm->operand[12] = 0xff;
- else
- CmdFrm->operand[12] = (firesat->tone==SEC_TONE_ON)?1:0; // band
-
- CmdFrm->length = 16;
-}
-
-int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status) {
- AVCCmdFrm CmdFrm;
- AVCRspFrm RspFrm;
- M_VALID_FLAGS flags;
- int k;
-
-// printk(KERN_INFO "%s\n", __FUNCTION__);
-
- if(firesat->type == FireSAT_DVB_S)
- AVCTuner_DSD_directcmd(firesat, params, &CmdFrm);
- else {
- if(firesat->type == FireSAT_DVB_T) {
- flags.Bits_T.GuardInterval = (params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO);
- flags.Bits_T.CodeRateLPStream = (params->u.ofdm.code_rate_LP != FEC_AUTO);
- flags.Bits_T.CodeRateHPStream = (params->u.ofdm.code_rate_HP != FEC_AUTO);
- flags.Bits_T.HierarchyInfo = (params->u.ofdm.hierarchy_information != HIERARCHY_AUTO);
- flags.Bits_T.Constellation = (params->u.ofdm.constellation != QAM_AUTO);
- flags.Bits_T.Bandwidth = (params->u.ofdm.bandwidth != BANDWIDTH_AUTO);
- flags.Bits_T.CenterFrequency = 1;
- flags.Bits_T.reserved1 = 0;
- flags.Bits_T.reserved2 = 0;
- flags.Bits_T.OtherFrequencyFlag = 0;
- flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO);
- flags.Bits_T.NetworkId = 0;
- } else {
- flags.Bits.Modulation = 0;
- if(firesat->type == FireSAT_DVB_S) {
- flags.Bits.FEC_inner = 1;
- } else if(firesat->type == FireSAT_DVB_C) {
- flags.Bits.FEC_inner = 0;
- }
- flags.Bits.FEC_outer = 0;
- flags.Bits.Symbol_Rate = 1;
- flags.Bits.Frequency = 1;
- flags.Bits.Orbital_Pos = 0;
- if(firesat->type == FireSAT_DVB_S) {
- flags.Bits.Polarisation = 1;
- } else if(firesat->type == FireSAT_DVB_C) {
- flags.Bits.Polarisation = 0;
- }
- flags.Bits.reserved_fields = 0;
- flags.Bits.reserved1 = 0;
- flags.Bits.Network_ID = 0;
- }
-
- memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
-
- CmdFrm.cts = AVC;
- CmdFrm.ctype = CONTROL;
- CmdFrm.sutyp = 0x5;
- CmdFrm.suid = firesat->subunit;
- CmdFrm.opcode = DSD;
-
- CmdFrm.operand[0] = 0; // source plug
- CmdFrm.operand[1] = 0xD2; // subfunction replace
- CmdFrm.operand[2] = 0x20; // system id = DVB
- CmdFrm.operand[3] = 0x00; // antenna number
- CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length
- CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0]
- CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1]
-
- if(firesat->type == FireSAT_DVB_T) {
- CmdFrm.operand[7] = 0x0;
- CmdFrm.operand[8] = (params->frequency/10) >> 24;
- CmdFrm.operand[9] = ((params->frequency/10) >> 16) & 0xFF;
- CmdFrm.operand[10] = ((params->frequency/10) >> 8) & 0xFF;
- CmdFrm.operand[11] = (params->frequency/10) & 0xFF;
- switch(params->u.ofdm.bandwidth) {
- case BANDWIDTH_7_MHZ:
- CmdFrm.operand[12] = 0x20;
- break;
- case BANDWIDTH_8_MHZ:
- case BANDWIDTH_6_MHZ: // not defined by AVC spec
- case BANDWIDTH_AUTO:
- default:
- CmdFrm.operand[12] = 0x00;
- }
- switch(params->u.ofdm.constellation) {
- case QAM_16:
- CmdFrm.operand[13] = 1 << 6;
- break;
- case QAM_64:
- CmdFrm.operand[13] = 2 << 6;
- break;
- case QPSK:
- default:
- CmdFrm.operand[13] = 0x00;
- }
- switch(params->u.ofdm.hierarchy_information) {
- case HIERARCHY_1:
- CmdFrm.operand[13] |= 1 << 3;
- break;
- case HIERARCHY_2:
- CmdFrm.operand[13] |= 2 << 3;
- break;
- case HIERARCHY_4:
- CmdFrm.operand[13] |= 3 << 3;
- break;
- case HIERARCHY_AUTO:
- case HIERARCHY_NONE:
- default:
- break;
- }
- switch(params->u.ofdm.code_rate_HP) {
- case FEC_2_3:
- CmdFrm.operand[13] |= 1;
- break;
- case FEC_3_4:
- CmdFrm.operand[13] |= 2;
- break;
- case FEC_5_6:
- CmdFrm.operand[13] |= 3;
- break;
- case FEC_7_8:
- CmdFrm.operand[13] |= 4;
- break;
- case FEC_1_2:
- default:
- break;
- }
- switch(params->u.ofdm.code_rate_LP) {
- case FEC_2_3:
- CmdFrm.operand[14] = 1 << 5;
- break;
- case FEC_3_4:
- CmdFrm.operand[14] = 2 << 5;
- break;
- case FEC_5_6:
- CmdFrm.operand[14] = 3 << 5;
- break;
- case FEC_7_8:
- CmdFrm.operand[14] = 4 << 5;
- break;
- case FEC_1_2:
- default:
- CmdFrm.operand[14] = 0x00;
- break;
- }
- switch(params->u.ofdm.guard_interval) {
- case GUARD_INTERVAL_1_16:
- CmdFrm.operand[14] |= 1 << 3;
- break;
- case GUARD_INTERVAL_1_8:
- CmdFrm.operand[14] |= 2 << 3;
- break;
- case GUARD_INTERVAL_1_4:
- CmdFrm.operand[14] |= 3 << 3;
- break;
- case GUARD_INTERVAL_1_32:
- case GUARD_INTERVAL_AUTO:
- default:
- break;
- }
- switch(params->u.ofdm.transmission_mode) {
- case TRANSMISSION_MODE_8K:
- CmdFrm.operand[14] |= 1 << 1;
- break;
- case TRANSMISSION_MODE_2K:
- case TRANSMISSION_MODE_AUTO:
- default:
- break;
- }
-
- CmdFrm.operand[15] = 0x00; // network_ID[0]
- CmdFrm.operand[16] = 0x00; // network_ID[1]
- CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
-
- CmdFrm.length = 20;
- } else {
- CmdFrm.operand[7] = 0x00;
- CmdFrm.operand[8] = (((firesat->voltage==SEC_VOLTAGE_18)?0:1)<<6); /* 0 = H, 1 = V */
- CmdFrm.operand[9] = 0x00;
- CmdFrm.operand[10] = 0x00;
-
- if(firesat->type == FireSAT_DVB_S) {
- /* ### relative frequency -> absolute frequency */
- CmdFrm.operand[11] = (((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
- CmdFrm.operand[12] = ((params->frequency/4) >> 8) & 0xFF;
- CmdFrm.operand[13] = (params->frequency/4) & 0xFF;
- } else if(firesat->type == FireSAT_DVB_C) {
- CmdFrm.operand[11] = (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6);
- CmdFrm.operand[12] = ((params->frequency/4000) >> 8) & 0xFF;
- CmdFrm.operand[13] = (params->frequency/4000) & 0xFF;
- }
-
- CmdFrm.operand[14] = ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
- CmdFrm.operand[15] = ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
- CmdFrm.operand[16] = ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
-
- CmdFrm.operand[17] = 0x00;
- switch(params->u.qpsk.fec_inner) {
- case FEC_1_2:
- CmdFrm.operand[18] = 0x1;
- break;
- case FEC_2_3:
- CmdFrm.operand[18] = 0x2;
- break;
- case FEC_3_4:
- CmdFrm.operand[18] = 0x3;
- break;
- case FEC_5_6:
- CmdFrm.operand[18] = 0x4;
- break;
- case FEC_7_8:
- CmdFrm.operand[18] = 0x5;
- break;
- case FEC_4_5:
- case FEC_8_9:
- case FEC_AUTO:
- default:
- CmdFrm.operand[18] = 0x0;
- }
- if(firesat->type == FireSAT_DVB_S) {
- CmdFrm.operand[19] = 0x08; // modulation
- } else if(firesat->type == FireSAT_DVB_C) {
- switch(params->u.qam.modulation) {
- case QAM_16:
- CmdFrm.operand[19] = 0x08; // modulation
- break;
- case QAM_32:
- CmdFrm.operand[19] = 0x10; // modulation
- break;
- case QAM_64:
- CmdFrm.operand[19] = 0x18; // modulation
- break;
- case QAM_128:
- CmdFrm.operand[19] = 0x20; // modulation
- break;
- case QAM_256:
- CmdFrm.operand[19] = 0x28; // modulation
- break;
- case QAM_AUTO:
- default:
- CmdFrm.operand[19] = 0x00; // modulation
- }
- }
- CmdFrm.operand[20] = 0x00;
- CmdFrm.operand[21] = 0x00;
- CmdFrm.operand[22] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
-
- CmdFrm.length=28;
- }
- } // AVCTuner_DSD_direct
-
- if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
- return k;
-
-// msleep(250);
- mdelay(500);
-
- if(status)
- *status=RspFrm.operand[2];
- return 0;
-}
-
-int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) {
- AVCCmdFrm CmdFrm;
- AVCRspFrm RspFrm;
- int pos,k;
-
- printk(KERN_INFO "%s\n", __FUNCTION__);
-
- if(pidc > 16 && pidc != 0xFF)
- return -EINVAL;
-
- memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
-
- CmdFrm.cts = AVC;
- CmdFrm.ctype = CONTROL;
- CmdFrm.sutyp = 0x5;
- CmdFrm.suid = firesat->subunit;
- CmdFrm.opcode = DSD;
-
- CmdFrm.operand[0] = 0; // source plug
- CmdFrm.operand[1] = 0xD2; // subfunction replace
- CmdFrm.operand[2] = 0x20; // system id = DVB
- CmdFrm.operand[3] = 0x00; // antenna number
- CmdFrm.operand[4] = 0x11; // system_specific_multiplex selection_length
- CmdFrm.operand[5] = 0x00; // valid_flags [0]
- CmdFrm.operand[6] = 0x00; // valid_flags [1]
-
- if(firesat->type == FireSAT_DVB_T) {
-/* CmdFrm.operand[7] = 0x00;
- CmdFrm.operand[8] = 0x00;//(params->frequency/10) >> 24;
- CmdFrm.operand[9] = 0x00;//((params->frequency/10) >> 16) & 0xFF;
- CmdFrm.operand[10] = 0x00;//((params->frequency/10) >> 8) & 0xFF;
- CmdFrm.operand[11] = 0x00;//(params->frequency/10) & 0xFF;
- CmdFrm.operand[12] = 0x00;
- CmdFrm.operand[13] = 0x00;
- CmdFrm.operand[14] = 0x00;
-
- CmdFrm.operand[15] = 0x00; // network_ID[0]
- CmdFrm.operand[16] = 0x00; // network_ID[1]
-*/ CmdFrm.operand[17] = pidc; // Nr_of_dsd_sel_specs
-
- pos=18;
- } else {
-/* CmdFrm.operand[7] = 0x00;
- CmdFrm.operand[8] = 0x00;
- CmdFrm.operand[9] = 0x00;
- CmdFrm.operand[10] = 0x00;
-
- CmdFrm.operand[11] = 0x00;//(((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
- CmdFrm.operand[12] = 0x00;//((params->frequency/4) >> 8) & 0xFF;
- CmdFrm.operand[13] = 0x00;//(params->frequency/4) & 0xFF;
-
- CmdFrm.operand[14] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
- CmdFrm.operand[15] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
- CmdFrm.operand[16] = 0x00;//((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
-
- CmdFrm.operand[17] = 0x00;
- CmdFrm.operand[18] = 0x00;
- CmdFrm.operand[19] = 0x00; // modulation
- CmdFrm.operand[20] = 0x00;
- CmdFrm.operand[21] = 0x00;*/
- CmdFrm.operand[22] = pidc; // Nr_of_dsd_sel_specs
-
- pos=23;
- }
- if(pidc != 0xFF)
- for(k=0;k<pidc;k++) {
- CmdFrm.operand[pos++] = 0x13; // flowfunction relay
- CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID
- CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F;
- CmdFrm.operand[pos++] = pid[k] & 0xFF;
- CmdFrm.operand[pos++] = 0x00; // tableID
- CmdFrm.operand[pos++] = 0x00; // filter_length
- }
-
- CmdFrm.length = pos+3;
-
- if((pos+3)%4)
- CmdFrm.length += 4 - ((pos+3)%4);
-
- if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
- return k;
-
- mdelay(250);
-
- return 0;
-}
-
-int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci) {
- AVCCmdFrm CmdFrm;
- AVCRspFrm RspFrm;
-
- memset(&CmdFrm,0,sizeof(AVCCmdFrm));
-
- CmdFrm.cts = AVC;
- CmdFrm.ctype = CONTROL;
- CmdFrm.sutyp = 0x5; // tuner
- CmdFrm.suid = firesat->subunit;
- CmdFrm.opcode = READ_DESCRIPTOR;
-
- CmdFrm.operand[0]=DESCRIPTOR_SUBUNIT_IDENTIFIER;
- CmdFrm.operand[1]=0xff;
- CmdFrm.operand[2]=0x00;
- CmdFrm.operand[3]=0x00; // length highbyte
- CmdFrm.operand[4]=0x08; // length lowbyte
- CmdFrm.operand[5]=0x00; // offset highbyte
- CmdFrm.operand[6]=0x0d; // offset lowbyte
-
- CmdFrm.length=12;
-
- if(AVCWrite(firesat,&CmdFrm,&RspFrm)<0)
- return -EIO;
-
- if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) {
- printk("%s: AVCWrite returned error code %d\n",__FUNCTION__,RspFrm.resp);
- return -EINVAL;
- }
- if(((RspFrm.operand[3] << 8) + RspFrm.operand[4]) != 8) {
- printk("%s: Invalid response length\n",__FUNCTION__);
- return -EINVAL;
- }
- if(systemId)
- *systemId = RspFrm.operand[7];
- if(transport)
- *transport = RspFrm.operand[14] & 0x7;
- switch(RspFrm.operand[14] & 0x7) {
- case 1:
- printk(KERN_INFO "%s: found DVB/S\n",__FUNCTION__);
- break;
- case 2:
- printk(KERN_INFO "%s: found DVB/C\n",__FUNCTION__);
- break;
- case 3:
- printk(KERN_INFO "%s: found DVB/T\n",__FUNCTION__);
- break;
- default:
- printk(KERN_INFO "%s: found unknown tuner id %u\n",__FUNCTION__,RspFrm.operand[14] & 0x7);
- }
- if(has_ci)
- *has_ci = (RspFrm.operand[14] >> 4) & 0x1;
- return 0;
-}
-
-int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info) {
- AVCCmdFrm CmdFrm;
- AVCRspFrm RspFrm;
- int length;
-
- printk(KERN_INFO "%s\n", __FUNCTION__);
-
- memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
-
- CmdFrm.cts=AVC;
- CmdFrm.ctype=CONTROL;
- CmdFrm.sutyp=0x05; // tuner
- CmdFrm.suid=firesat->subunit;
- CmdFrm.opcode=READ_DESCRIPTOR;
-
- CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS;
- CmdFrm.operand[1]=0xff;
- CmdFrm.operand[2]=0x00;
- CmdFrm.operand[3]=sizeof(ANTENNA_INPUT_INFO) >> 8;
- CmdFrm.operand[4]=sizeof(ANTENNA_INPUT_INFO) & 0xFF;
- CmdFrm.operand[5]=0x00;
- CmdFrm.operand[6]=0x03;
- CmdFrm.length=12;
- //Absenden des AVC request und warten auf response
- if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
- return -EIO;
-
- if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) {
- printk("%s: AVCWrite returned code %d\n",__FUNCTION__,RspFrm.resp);
- return -EINVAL;
- }
-
- length = (RspFrm.operand[3] << 8) + RspFrm.operand[4];
- if(length == sizeof(ANTENNA_INPUT_INFO))
- {
- memcpy(antenna_input_info,&RspFrm.operand[7],length);
- return 0;
- }
- printk("%s: invalid info returned from AVC\n",__FUNCTION__);
- return -EINVAL;
-}
-
-int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd) {
- AVCCmdFrm CmdFrm;
- AVCRspFrm RspFrm;
- int i,j;
-
- printk(KERN_INFO "%s: voltage = %x, burst = %x, conttone = %x\n",__FUNCTION__,voltage,burst,conttone);
-
- memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
-
- CmdFrm.cts=AVC;
- CmdFrm.ctype=CONTROL;
- CmdFrm.sutyp=0x05;
- CmdFrm.suid=firesat->subunit;
- CmdFrm.opcode=VENDOR;
-
- /* ### should check for elgato and use SFE_VENDOR_EL_COMPANYID_0 in this case */
- CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
- CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
- CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
- CmdFrm.operand[3]=SFE_VENDOR_OPCODE_LNB_CONTROL;
-
- CmdFrm.operand[4]=voltage;
- CmdFrm.operand[5]=nrdiseq;
-
- i=6;
-
- for(j=0;j<nrdiseq;j++) {
- int k;
- printk(KERN_INFO "%s: diseq %d len %x\n",__FUNCTION__,j,diseqcmd[j].msg_len);
- CmdFrm.operand[i++]=diseqcmd[j].msg_len;
-
- for(k=0;k<diseqcmd[j].msg_len;k++) {
- printk(KERN_INFO "%s: diseq %d msg[%d] = %x\n",__FUNCTION__,j,k,diseqcmd[j].msg[k]);
- CmdFrm.operand[i++]=diseqcmd[j].msg[k];
- }
- }
-
- CmdFrm.operand[i++]=burst;
- CmdFrm.operand[i++]=conttone;
-
- CmdFrm.length=i+3;
- if((i+3)%4)
- CmdFrm.length += 4 - ((i+3)%4);
-
-/* for(j=0;j<CmdFrm.length;j++)
- printk(KERN_INFO "%s: CmdFrm.operand[%d]=0x%x\n",__FUNCTION__,j,CmdFrm.operand[j]);
-
- printk(KERN_INFO "%s: cmdfrm.length = %u\n",__FUNCTION__,CmdFrm.length);
- */
- if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
- return -EIO;
-
- if(RspFrm.resp != ACCEPTED) {
- printk("%s: AVCWrite returned code %d\n",__FUNCTION__,RspFrm.resp);
- return -EINVAL;
- }
-
- return 0;
-}
-
-int AVCSubUnitInfo(struct firesat*firesat, char *subunitcount) {
- AVCCmdFrm CmdFrm;
- AVCRspFrm RspFrm;
-
- memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
-
- CmdFrm.cts = AVC;
- CmdFrm.ctype = STATUS;
- CmdFrm.sutyp = 0x1f;
- CmdFrm.suid = 0x7;
- CmdFrm.opcode = SUBUNIT_Info;
-
- CmdFrm.operand[0] = 0x07;
- CmdFrm.operand[1] = 0xff;
- CmdFrm.operand[2] = 0xff;
- CmdFrm.operand[3] = 0xff;
- CmdFrm.operand[4] = 0xff;
-
- CmdFrm.length = 8;
-
- if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
- return -EIO;
-
- if(RspFrm.resp != STABLE) {
- printk("%s: AVCWrite returned code %d\n",__FUNCTION__,RspFrm.resp);
- return -EINVAL;
- }
-
- if(subunitcount)
- *subunitcount = (RspFrm.operand[1] & 0x7) + 1;
-
- return 0;
-}
-
-static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal) {
- AVCCmdFrm CmdFrm;
-
-// printk(KERN_INFO "%s\n",__FUNCTION__);
-
- memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
-
- CmdFrm.cts = AVC;
- CmdFrm.ctype = NOTIFY;
- CmdFrm.sutyp = 0x1f;
- CmdFrm.suid = 0x7;
- CmdFrm.opcode = VENDOR;
-
- CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0;
- CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1;
- CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2;
-// CmdFrm.operand[0] = SFE_VENDOR_EL_COMPANYID_0;
-// CmdFrm.operand[1] = SFE_VENDOR_EL_COMPANYID_1;
-// CmdFrm.operand[2] = SFE_VENDOR_EL_COMPANYID_2;
- CmdFrm.operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
-
- CmdFrm.length = 8;
-
- if(internal) {
- if(__AVCWrite(firesat,&CmdFrm,NULL) < 0)
- return -EIO;
- } else
- if(AVCWrite(firesat,&CmdFrm,NULL) < 0)
- return -EIO;
-
- return 0;
-}
-
-int AVCRegisterRemoteControl(struct firesat*firesat) {
- return __AVCRegisterRemoteControl(firesat, 0);
-}
-
-int AVCResetTPDU(struct firesat*firesat) {
- AVCCmdFrm CmdFrm;
- AVCRspFrm RspFrm;
-
- memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
-
- CmdFrm.cts = AVC;
- CmdFrm.ctype = CONTROL;
- CmdFrm.sutyp = 0x05;
- CmdFrm.suid = firesat->subunit;
- CmdFrm.opcode = VENDOR;
-
- CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0;
- CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1;
- CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2;
-// CmdFrm.operand[0] = SFE_VENDOR_EL_COMPANYID_0;
-// CmdFrm.operand[1] = SFE_VENDOR_EL_COMPANYID_1;
-// CmdFrm.operand[2] = SFE_VENDOR_EL_COMPANYID_2;
- CmdFrm.operand[3] = SFE_VENDOR_OPCODE_CI_RESET;
-
- CmdFrm.operand[4] = 0x00; // 0x00 = hard, 0x01 = soft
-
- CmdFrm.length = 8;
- if(AVCWrite(firesat, &CmdFrm, &RspFrm) < 0)
- return -EIO;
-
- if(RspFrm.resp != STABLE) {
- printk("%s: AVCWrite returned error %d\n", __FUNCTION__, RspFrm.resp);
- return RspFrm.resp;
- }
-
- return 0;
-}
-
-int AVCWriteTPDU(struct firesat*firesat, const char *tpdupacket, int length) {
- AVCCmdFrm CmdFrm;
- AVCRspFrm RspFrm;
-
- if(length < 0 || length > 505 || tpdupacket == NULL)
- return -EINVAL;
-
- memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
-
- CmdFrm.cts = AVC;
- CmdFrm.ctype = CONTROL;
- CmdFrm.sutyp = 0x05;
- CmdFrm.suid = firesat->subunit;
- CmdFrm.opcode = VENDOR;
-
- CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0;
- CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1;
- CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2;
-// CmdFrm.operand[0] = SFE_VENDOR_EL_COMPANYID_0;
-// CmdFrm.operand[1] = SFE_VENDOR_EL_COMPANYID_1;
-// CmdFrm.operand[2] = SFE_VENDOR_EL_COMPANYID_2;
- CmdFrm.operand[3] = SFE_VENDOR_OPCODE_CI_WRITE_TPDU;
-
- memcpy(&CmdFrm.operand[6], tpdupacket, length);
-
- CmdFrm.length = length + 9;
- CmdFrm.operand[4] = (CmdFrm.length >> 8) & 0xFF;
- CmdFrm.operand[5] = CmdFrm.length & 0xFF;
-
- if(CmdFrm.length % 4)
- CmdFrm.length += 4 - (CmdFrm.length % 4);
-
- if(AVCWrite(firesat, &CmdFrm, &RspFrm) < 0)
- return -EIO;
-
- if(RspFrm.resp != STABLE) {
- printk("%s: AVCWrite returned error %d\n",__FUNCTION__,RspFrm.resp);
- return RspFrm.resp;
- }
- return 0;
-}
-
-int AVCReadTPDU(struct firesat*firesat, char *tpdupacket, int *length) {
- AVCCmdFrm CmdFrm;
- AVCRspFrm RspFrm;
-
- if(!length || !tpdupacket)
- return -EINVAL;
-
- memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
-
- CmdFrm.cts = AVC;
- CmdFrm.ctype = STATUS;
- CmdFrm.sutyp = 0x05;
- CmdFrm.suid = firesat->subunit;
- CmdFrm.opcode = VENDOR;
-
-// CmdFrm.operand[0] = SFE_VENDOR_EL_COMPANYID_0;
- CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0;
-// CmdFrm.operand[1] = SFE_VENDOR_EL_COMPANYID_1;
- CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1;
-// CmdFrm.operand[2] = SFE_VENDOR_EL_COMPANYID_2;
- CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2;
-// CmdFrm.operand[3] = SFE_VENDOR_OPCODE_CI_READ_TPDU;
-
- CmdFrm.length = 8;
-
- if(AVCWrite(firesat, &CmdFrm, &RspFrm) < 0)
- return -EIO;
-
- if(RspFrm.resp != STABLE) {
- printk("%s: AVCWrite returned error %d\n",__FUNCTION__,RspFrm.resp);
- return RspFrm.resp;
- }
-
- switch(RspFrm.operand[4]) {
- case 0x00: {
- int len = (RspFrm.operand[5] << 8) + RspFrm.operand[6];
- if(len < *length)
- *length = len;
- if(*length > 0)
- memcpy(tpdupacket, &RspFrm.operand[7], *length);
- break;
- }
- case 0xFF:
- printk("%s: No CI module present\n",__FUNCTION__);
- return -EINVAL;
- case 0xFE:
- printk("%s: No CI data\n",__FUNCTION__);
- *length = 0;
- break;
- case 0xFD:
- printk("%s: CI error\n",__FUNCTION__);
- return -EIO;
- default:
- printk("%s: unknown CI error\n",__FUNCTION__);
- return -EINVAL;
- }
- return 0;
-}
-
diff --git a/v4l_experimental/firesat/avc_api.h b/v4l_experimental/firesat/avc_api.h
deleted file mode 100644
index 7948a8f9d..000000000
--- a/v4l_experimental/firesat/avc_api.h
+++ /dev/null
@@ -1,435 +0,0 @@
-/***************************************************************************
- avc_api.h - description
- -------------------
- begin : Wed May 1 2000
- copyright : (C) 2000 by Manfred Weihs
- copyright : (C) 2003 by Philipp Gutgsell
- email : 0014guph@edu.fh-kaernten.ac.at
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-/*
- This is based on code written by Peter Halwachs, Thomas Groiss and Andreas Monitzer.
-*/
-
-
-#ifndef __AVC_API_H__
-#define __AVC_API_H__
-
-#include <linux/dvb/frontend.h>
-
-#define BYTE unsigned char
-#define WORD unsigned short
-#define DWORD unsigned long
-#define ULONG unsigned long
-#define LONG long
-
-
-/*************************************************************
-
- FCP Address range
-
-**************************************************************/
-
-#define RESPONSE_REGISTER 0xFFFFF0000D00ULL
-#define COMMAND_REGISTER 0xFFFFF0000B00ULL
-#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
-
-
-/********************** ********************* ***************
-
- definition of structures
-
-*************************************************************/
-
-typedef struct
-{
- int Nr_SourcePlugs;
- int Nr_DestinationPlugs;
-} TunerInfo;
-
-
-/***********************************************
-
- supported cts
-
-************************************************/
-
-#define AVC 0x0
-
-// FCP command frame with ctype = 0x0 is AVC command frame
-
-#ifdef __LITTLE_ENDIAN
-
-// Definition FCP Command Frame
-typedef struct _AVCCmdFrm
-{
- // AV/C command frame
- BYTE ctype : 4 ; // command type
- BYTE cts : 4 ; // always 0x0 for AVC
- BYTE suid : 3 ; // subunit ID
- BYTE sutyp : 5 ; // subunit_typ
- BYTE opcode : 8 ; // opcode
- BYTE operand[509] ; // array of operands [1-507]
- int length; //length of the command frame
-} AVCCmdFrm ;
-
-// Definition FCP Response Frame
-typedef struct _AVCRspFrm
-{
- // AV/C response frame
- BYTE resp : 4 ; // response type
- BYTE cts : 4 ; // always 0x0 for AVC
- BYTE suid : 3 ; // subunit ID
- BYTE sutyp : 5 ; // subunit_typ
- BYTE opcode : 8 ; // opcode
- BYTE operand[509] ; // array of operands [1-507]
- int length; //length of the response frame
-} AVCRspFrm ;
-
-#else
-
-typedef struct _AVCCmdFrm
-{
- BYTE cts:4;
- BYTE ctype:4;
- BYTE sutyp:5;
- BYTE suid:3;
- BYTE opcode;
- BYTE operand[509];
- int length;
-} AVCCmdFrm;
-
-typedef struct _AVCRspFrm
-{
- BYTE cts:4;
- BYTE resp:4;
- BYTE sutyp:5;
- BYTE suid:3;
- BYTE opcode;
- BYTE operand[509];
- int length;
-} AVCRspFrm;
-
-#endif
-
-/*************************************************************
-
-
- AVC command types (ctype)
-
-**************************************************************///
-
-
-#define CONTROL 0x00
-#define STATUS 0x01
-#define INQUIRY 0x02
-#define NOTIFY 0x03
-
-/*************************************************************
-
- AVC respond types
-
-**************************************************************///
-
-#define NOT_IMPLEMENTED 0x8
-#define ACCEPTED 0x9
-#define REJECTED 0xA
-#define STABLE 0xC
-#define CHANGED 0xD
-#define INTERIM 0xF
-
-/*************************************************************
-
- AVC FW UPDATE Responses
-
-**************************************************************///
-
-#define FW_INVALID_COUNT 0x4
-#define FW_INVALID_CRC 0x5
-#define FW_SUCCESS 0x6
-#define FW_ERROR 0x7
-#define FW_START_BURNING 0x8
-#define FW_INVALID_HW_VERSION 0x9
-
-/*************************************************************
-
- AVC opcodes
-
-**************************************************************///
-#define CONNECT 0x24
-#define DISCONNECT 0x25
-#define UNIT_INFO 0x30
-#define SUBUNIT_Info 0x31
-#define VENDOR 0x00
-
-#define PLUG_INFO 0x02
-#define OPEN_DESCRIPTOR 0x08
-#define READ_DESCRIPTOR 0x09
-#define OBJECT_NUMBER_SELECT 0x0D
-
-/*************************************************************
-
- AVCTuner opcodes
-
-**************************************************************/
-
-#define DSIT 0xC8
-#define DSD 0xCB
-#define DESCRIPTOR_TUNER_STATUS 0x80
-#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00
-
-/*************************************************************
-
- AVCTuner list types
-
-**************************************************************/
-
-#define Multiplex_List 0x80
-#define Service_List 0x82
-
-/*************************************************************
-
- AVCTuner object entries
-
-**************************************************************/
-
-#define Multiplex 0x80
-#define Service 0x82
-#define Service_with_specified_components 0x83
-#define Preferred_components 0x90
-#define Component 0x84
-
-/*************************************************************
-
- Vendor-specific commands
-
-**************************************************************/
-
-#define SFE_VENDOR_EL_COMPANYID_0 0x00
-#define SFE_VENDOR_EL_COMPANYID_1 0x0C
-#define SFE_VENDOR_EL_COMPANYID_2 0x6C
-#define SFE_VENDOR_DE_COMPANYID_0 0x00
-#define SFE_VENDOR_DE_COMPANYID_1 0x12
-#define SFE_VENDOR_DE_COMPANYID_2 0x87
-
-#define SFE_VENDOR_OPCODE_SET_LNB_PARAMS 0x50
-#define SFE_VENDOR_OPCODE_GET_LNB_PARAMS 0x51
-#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52
-
-#define SFE_VENDOR_OPCODE_CI_READ_TPDU 0x54
-#define SFE_VENDOR_OPCODE_CI_WRITE_TPDU 0x53
-#define SFE_VENDOR_OPCODE_CI_RESET 0x55
-
-#define SFE_VENDOR_MAX_NR_COMPONENTS 0x4
-#define SFE_VENDOR_MAX_NR_SERVICES 0x3
-#define SFE_VENDOR_MAX_NR_DSD_ELEMENTS 0x10
-
-#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0A
-
-
-//AVCTuner DVB identifier service_ID
-
-#define DVB 0x20
-
-/*************************************************************
-
- AVC descriptor types
-
-**************************************************************/
-
-#define Subunit_Identifier_Descriptor 0x00
-#define Tuner_Status_Descriptor 0x80
-
-typedef struct
-{
- BYTE Subunit_Type;
- BYTE Max_Subunit_ID;
-} SUBUNIT_INFO;
-
-/*************************************************************
-
- AVCTuner DVB object IDs are 6 byte long
-
-**************************************************************/
-
-typedef struct
-{
- BYTE Byte0;
- BYTE Byte1;
- BYTE Byte2;
- BYTE Byte3;
- BYTE Byte4;
- BYTE Byte5;
-
-}OBJECT_ID;
-
-/*************************************************************
-
- MULIPLEX Structs
-
-**************************************************************/
-typedef struct
-{
-#ifdef __LITTLE_ENDIAN
- BYTE RF_frequency_hByte:6;
- BYTE raster_Frequency:2;//Bit7,6 raster frequency
-#else
- BYTE raster_Frequency:2;
- BYTE RF_frequency_hByte:6;
-#endif
- BYTE RF_frequency_mByte;
- BYTE RF_frequency_lByte;
-
-}FREQUENCY;
-
-#ifdef __LITTLE_ENDIAN
-
-typedef struct
-{
- BYTE Modulation :1;
- BYTE FEC_inner :1;
- BYTE FEC_outer :1;
- BYTE Symbol_Rate :1;
- BYTE Frequency :1;
- BYTE Orbital_Pos :1;
- BYTE Polarisation :1;
- BYTE reserved_fields :1;
- BYTE reserved1 :7;
- BYTE Network_ID :1;
-
-}MULTIPLEX_VALID_FLAGS;
-
-typedef struct
-{
- BYTE GuardInterval:1;
- BYTE CodeRateLPStream:1;
- BYTE CodeRateHPStream:1;
- BYTE HierarchyInfo:1;
- BYTE Constellation:1;
- BYTE Bandwidth:1;
- BYTE CenterFrequency:1;
- BYTE reserved1:1;
- BYTE reserved2:5;
- BYTE OtherFrequencyFlag:1;
- BYTE TransmissionMode:1;
- BYTE NetworkId:1;
-}MULTIPLEX_VALID_FLAGS_DVBT;
-
-#else
-
-typedef struct
-{
- BYTE reserved_fields:1;
- BYTE Polarisation:1;
- BYTE Orbital_Pos:1;
- BYTE Frequency:1;
- BYTE Symbol_Rate:1;
- BYTE FEC_outer:1;
- BYTE FEC_inner:1;
- BYTE Modulation:1;
- BYTE Network_ID:1;
- BYTE reserved1:7;
-}MULTIPLEX_VALID_FLAGS;
-
-typedef struct
-{
- BYTE reserved1:1;
- BYTE CenterFrequency:1;
- BYTE Bandwidth:1;
- BYTE Constellation:1;
- BYTE HierarchyInfo:1;
- BYTE CodeRateHPStream:1;
- BYTE CodeRateLPStream:1;
- BYTE GuardInterval:1;
- BYTE NetworkId:1;
- BYTE TransmissionMode:1;
- BYTE OtherFrequencyFlag:1;
- BYTE reserved2:5;
-}MULTIPLEX_VALID_FLAGS_DVBT;
-
-#endif
-
-typedef union
-{
-
- MULTIPLEX_VALID_FLAGS Bits;
- MULTIPLEX_VALID_FLAGS_DVBT Bits_T;
- struct
- {
- BYTE ByteHi;
- BYTE ByteLo;
- } Valid_Word;
-
-} M_VALID_FLAGS;
-
-typedef struct
-{
-#ifdef __LITTLE_ENDIAN
- BYTE ActiveSystem;
- BYTE reserved:5;
- BYTE NoRF:1;
- BYTE Moving:1;
- BYTE Searching:1;
-
- BYTE SelectedAntenna:7;
- BYTE Input:1;
-
- BYTE BER[4];
-
- BYTE SignalStrength;
- FREQUENCY Frequency;
-
- BYTE ManDepInfoLength;
-#else
- BYTE ActiveSystem;
- BYTE Searching:1;
- BYTE Moving:1;
- BYTE NoRF:1;
- BYTE reserved:5;
-
- BYTE Input:1;
- BYTE SelectedAntenna:7;
-
- BYTE BER[4];
-
- BYTE SignalStrength;
- FREQUENCY Frequency;
-
- BYTE ManDepInfoLength;
-#endif
-} ANTENNA_INPUT_INFO; // 11 Byte
-
-#define LNBCONTROL_DONTCARE 0xff
-
-extern int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm);
-extern int AVCRecv(struct firesat *firesat, u8 *data, size_t length);
-
-extern int AVCTuner_DSIT(struct firesat *firesat,
- int Source_Plug,
- struct dvb_frontend_parameters *params,
- BYTE *status);
-
-extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info);
-extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status);
-extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]);
-
-extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci);
-extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd);
-extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount);
-extern int AVCRegisterRemoteControl(struct firesat *firesat);
-
-extern int AVCResetTPDU(struct firesat *firesat);
-extern int AVCWriteTPDU(struct firesat *firesat, const char *tpdupacket, int length);
-extern int AVCReadTPDU(struct firesat *firesat, char *tpdupacket, int *length);
-
-#endif
-
diff --git a/v4l_experimental/firesat/cmp.c b/v4l_experimental/firesat/cmp.c
deleted file mode 100644
index 29f8a7d3c..000000000
--- a/v4l_experimental/firesat/cmp.c
+++ /dev/null
@@ -1,176 +0,0 @@
-#include "cmp.h"
-#include <ieee1394.h>
-#include <nodemgr.h>
-#include <highlevel.h>
-#include <ohci1394.h>
-#include <hosts.h>
-#include <ieee1394_transactions.h>
-#include "avc_api.h"
-
-typedef struct _OPCR
-{
- BYTE PTPConnCount : 6 ; // Point to point connect. counter
- BYTE BrConnCount : 1 ; // Broadcast connection counter
- BYTE OnLine : 1 ; // On Line
-
- BYTE ChNr : 6 ; // Channel number
- BYTE Res : 2 ; // Reserved
-
- BYTE PayloadHi : 2 ; // Payoad high bits
- BYTE OvhdID : 4 ; // Overhead ID
- BYTE DataRate : 2 ; // Data Rate
-
- BYTE PayloadLo ; // Payoad low byte
-} OPCR ;
-
-#define FIRESAT_SPEED IEEE1394_SPEED_400
-
-static int cmp_read(struct firesat *firesat, void *buffer, u64 addr, size_t length) {
- int ret;
- if(down_interruptible(&firesat->avc_sem))
- return -EINTR;
-
- ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation,
- addr, buffer, length);
-
- up(&firesat->avc_sem);
- return ret;
-}
-
-static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, quadlet_t arg, int ext_tcode) {
- int ret;
- if(down_interruptible(&firesat->avc_sem))
- return -EINTR;
-
- ret = hpsb_lock(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation,
- addr, ext_tcode, data, arg);
-
- up(&firesat->avc_sem);
- return ret;
-}
-
-//try establishing a point-to-point connection (may be interrupted by a busreset
-int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel) {
- unsigned int BWU; //bandwidth to allocate
-
- quadlet_t old_oPCR,test_oPCR = 0x0;
- u64 oPCR_address=0xfffff0000904ull+(output_plug << 2);
- int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4);
-
- printk(KERN_INFO "%s: nodeid = %d\n",__FUNCTION__,firesat->nodeentry->nodeid);
-
- if (result < 0) {
- printk("%s: cannot read oPCR\n", __FUNCTION__);
- return result;
- } else {
- printk(KERN_INFO "%s: oPCR = %08x\n",__FUNCTION__,test_oPCR);
- do {
- OPCR *hilf= (OPCR*) &test_oPCR;
-
- if (!hilf->OnLine) {
- printk("%s: Output offline; oPCR: %08x\n", __FUNCTION__, test_oPCR);
- return -EBUSY;
- } else {
- quadlet_t new_oPCR;
-
- old_oPCR=test_oPCR;
- if (hilf->PTPConnCount) {
- if (hilf->ChNr != iso_channel) {
- printk("%s: Output plug has already connection on channel %u; cannot change it to channel %u\n",__FUNCTION__,hilf->ChNr,iso_channel);
- return -EBUSY;
- } else
- printk(KERN_INFO "%s: Overlaying existing connection; connection counter was: %u\n",__FUNCTION__, hilf->PTPConnCount);
- BWU=0; //we allocate no bandwidth (is this necessary?)
- } else {
- hilf->ChNr=iso_channel;
- hilf->DataRate=FIRESAT_SPEED;
-
- hilf->OvhdID=0; //FIXME: that is for worst case -> optimize
- BWU=hilf->OvhdID?hilf->OvhdID*32:512;
- BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate));
-/* if (allocate_1394_resources(iso_channel,BWU))
- {
- cout << "Allocation of resources failed\n";
- return -2;
- }*/
- }
-
- hilf->PTPConnCount++;
- new_oPCR=test_oPCR;
- printk(KERN_INFO "%s: trying compare_swap...\n",__FUNCTION__);
- printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__FUNCTION__, old_oPCR, new_oPCR);
- result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
-
- if (result < 0) {
- printk("%s: cannot compare_swap oPCR\n",__FUNCTION__);
- return result;
- }
- if ((old_oPCR != test_oPCR) && (!((OPCR*) &old_oPCR)->PTPConnCount))
- {
- printk("%s: change of oPCR failed -> freeing resources\n",__FUNCTION__);
-// hilf= (OPCR*) &new_oPCR;
-// unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512;
-// BWU += (hilf->Payload+3) * (2 << (3-hilf->DataRate));
-/* if (deallocate_1394_resources(iso_channel,BWU))
- {
-
- cout << "Deallocation of resources failed\n";
- return -3;
- }*/
- }
- }
- }
- while (old_oPCR != test_oPCR);
- }
- return 0;
-}
-
-//try breaking a point-to-point connection (may be interrupted by a busreset
-int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel) {
- quadlet_t old_oPCR,test_oPCR;
-
- u64 oPCR_address=0xfffff0000904ull+(output_plug << 2);
- int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4);
-
- printk(KERN_INFO "%s\n",__FUNCTION__);
-
- if (result < 0) {
- printk("%s: cannot read oPCR\n", __FUNCTION__);
- return result;
- } else {
- do {
- OPCR *hilf= (OPCR*) &test_oPCR;
-
- if (!hilf->OnLine || !hilf->PTPConnCount || hilf->ChNr != iso_channel) {
- printk("%s: Output plug does not have PtP-connection on that channel; oPCR: %08x\n", __FUNCTION__, test_oPCR);
- return -EINVAL;
- } else {
- quadlet_t new_oPCR;
- old_oPCR=test_oPCR;
- hilf->PTPConnCount--;
- new_oPCR=test_oPCR;
-
-// printk(KERN_INFO "%s: trying compare_swap...\n", __FUNCTION__);
- result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
- if (result < 0) {
- printk("%s: cannot compare_swap oPCR\n",__FUNCTION__);
- return result;
- }
- }
-
- } while (old_oPCR != test_oPCR);
-
-/* hilf = (OPCR*) &old_oPCR;
- if (hilf->PTPConnCount == 1) { // if we were the last owner of this connection
- cout << "deallocating 1394 resources\n";
- unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512;
- BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate));
- if (deallocate_1394_resources(iso_channel,BWU))
- {
- cout << "Deallocation of resources failed\n";
- return -3;
- }
- }*/
- }
- return 0;
-}
diff --git a/v4l_experimental/firesat/cmp.h b/v4l_experimental/firesat/cmp.h
deleted file mode 100644
index d43fbc29f..000000000
--- a/v4l_experimental/firesat/cmp.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __FIRESAT__CMP_H_
-#define __FIRESAT__CMP_H_
-
-#include "firesat.h"
-
-extern int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel);
-extern int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel);
-
-#endif
diff --git a/v4l_experimental/firesat/firesat-ci.c b/v4l_experimental/firesat/firesat-ci.c
deleted file mode 100644
index 3d005cb56..000000000
--- a/v4l_experimental/firesat/firesat-ci.c
+++ /dev/null
@@ -1,124 +0,0 @@
-#include "firesat-ci.h"
-#include "firesat.h"
-#include "avc_api.h"
-
-#include <linux/dvb/ca.h>
-
-#include "dvbdev.h"
-
-static int firesat_ca_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) {
- struct firesat *firesat = (struct firesat*)((struct dvb_device*)file->private_data)->priv;
- int err;
-
-// printk(KERN_INFO "%s: ioctl %d\n",__FUNCTION__,cmd);
-
- switch(cmd) {
- case CA_RESET:
- err = AVCResetTPDU(firesat);
-// if(err==0)
- mdelay(3000);
- break;
- case CA_GET_CAP: {
- ca_caps_t *cap=(ca_caps_t*)parg;
- cap->slot_num = 1;
- cap->slot_type = CA_CI_LINK;
- cap->descr_num = 1;
- cap->descr_type = CA_DSS; // ### peter fragen!
-
- err = 0;
- break;
- }
- case CA_GET_SLOT_INFO: {
- ca_slot_info_t *slot=(ca_slot_info_t*)parg;
- if(slot->num == 0) {
- slot->type = CA_CI | CA_CI_LINK | CA_DESCR;
- slot->flags = CA_CI_MODULE_PRESENT | CA_CI_MODULE_READY;
- } else {
- slot->type = 0;
- slot->flags = 0;
- }
- err = 0;
- break;
- }
- default:
- err=-EINVAL;
- }
- return err;
-}
-
-static int firesat_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) {
- return dvb_usercopy(inode, file, cmd, arg, firesat_ca_do_ioctl);
-}
-
-static ssize_t firesat_ca_io_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
- struct firesat *firesat = (struct firesat*)((struct dvb_device*)file->private_data)->priv;
- char *data=kmalloc(count,GFP_KERNEL);
-// printk(KERN_INFO "%s: count = %d\n",__FUNCTION__, count);
- copy_from_user(data,buf,count);
- int r=AVCWriteTPDU(firesat, data, count);
- kfree(data);
- if(!r)
- return count;
- printk("%s: failed writing data\n",__FUNCTION__);
- return 0;
-}
-
-static ssize_t firesat_ca_io_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) {
- struct firesat *firesat = (struct firesat*)((struct dvb_device*)file->private_data)->priv;
- char *data=kmalloc(count,GFP_KERNEL);
-// printk(KERN_INFO "%s: count = %d\n",__FUNCTION__,count);
- int r=AVCReadTPDU(firesat, data, &count);
- if(!r) {
- copy_to_user(buf,data,count);
- kfree(data);
- return count;
- }
- kfree(data);
- return 0;
-}
-
-static int firesat_ca_io_open(struct inode *inode, struct file *file) {
- printk(KERN_INFO "%s!\n",__FUNCTION__);
- return dvb_generic_open(inode, file);
-}
-
-static int firesat_ca_io_release(struct inode *inode, struct file *file) {
- printk(KERN_INFO "%s!\n",__FUNCTION__);
- return dvb_generic_release(inode, file);
-}
-
-static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) {
-// printk(KERN_INFO "%s!\n",__FUNCTION__);
- return POLLIN;
-}
-
-static struct file_operations firesat_ca_fops = {
- .owner = THIS_MODULE,
- .read = firesat_ca_io_read,
- .write = firesat_ca_io_write,
- .ioctl = firesat_ca_ioctl,
- .open = firesat_ca_io_open,
- .release = firesat_ca_io_release,
- .poll = firesat_ca_io_poll,
-};
-
-static struct dvb_device firesat_ca = {
- .priv = NULL,
- .users = 1,
- .readers = 1,
- .writers = 1,
- .fops = &firesat_ca_fops,
-};
-
-int firesat_ca_init(struct firesat *firesat) {
- int ret = dvb_register_device(firesat->adapter, &firesat->cadev, &firesat_ca, firesat, DVB_DEVICE_CA);
- if(ret) return ret;
- AVCResetTPDU(firesat);
- // avoid unnecessary delays, we're not talking to the CI yet anyways
- return 0;
-}
-
-void firesat_ca_release(struct firesat *firesat) {
- dvb_unregister_device(firesat->cadev);
-}
-
diff --git a/v4l_experimental/firesat/firesat-ci.h b/v4l_experimental/firesat/firesat-ci.h
deleted file mode 100644
index dafe3f0f0..000000000
--- a/v4l_experimental/firesat/firesat-ci.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __FIRESAT_CA_H
-#define __FIRESAT_CA_H
-
-#include "firesat.h"
-
-int firesat_ca_init(struct firesat *firesat);
-void firesat_ca_release(struct firesat *firesat);
-
-#endif
diff --git a/v4l_experimental/firesat/firesat-rc.c b/v4l_experimental/firesat/firesat-rc.c
deleted file mode 100644
index 702f90f6c..000000000
--- a/v4l_experimental/firesat/firesat-rc.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "firesat.h"
-#include "firesat-rc.h"
-
-#include <linux/input.h>
-
-static u16 firesat_irtable[] = {
- KEY_ESC,
- KEY_F9,
- KEY_1,
- KEY_2,
- KEY_3,
- KEY_4,
- KEY_5,
- KEY_6,
- KEY_7,
- KEY_8,
- KEY_9,
- KEY_I,
- KEY_0,
- KEY_ENTER,
- KEY_RED,
- KEY_UP,
- KEY_GREEN,
- KEY_F10,
- KEY_SPACE,
- KEY_F11,
- KEY_YELLOW,
- KEY_DOWN,
- KEY_BLUE,
- KEY_Z,
- KEY_P,
- KEY_PAGEDOWN,
- KEY_LEFT,
- KEY_W,
- KEY_RIGHT,
- KEY_P,
- KEY_M,
- KEY_R,
- KEY_V,
- KEY_C,
- 0
-};
-
-static struct input_dev firesat_idev;
-
-int firesat_register_rc(void) {
- int index;
-
- memset(&firesat_idev, 0, sizeof(firesat_idev));
-
- firesat_idev.evbit[0] = BIT(EV_KEY);
-
- for(index=0;firesat_irtable[index] != 0; index++)
- set_bit(firesat_irtable[index], firesat_idev.keybit);
-
- input_register_device(&firesat_idev);
-
- return 0;
-}
-
-int firesat_unregister_rc(void) {
- input_unregister_device(&firesat_idev);
- return 0;
-}
-
-int firesat_got_remotecontrolcode(u16 code) {
- u16 keycode;
-
- if(code > 0x4500 && code < 0x4520)
- keycode = firesat_irtable[code - 0x4501];
- else if(code > 0x453f && code < 0x4543)
- keycode = firesat_irtable[code - 0x4521];
- else {
- printk("%s: invalid key code 0x%04x\n",__FUNCTION__,code);
- return -EINVAL;
- }
-
- input_report_key(&firesat_idev, keycode, 1);
- input_report_key(&firesat_idev, keycode, 0);
-
- return 0;
-}
-
diff --git a/v4l_experimental/firesat/firesat-rc.h b/v4l_experimental/firesat/firesat-rc.h
deleted file mode 100644
index e89a8069b..000000000
--- a/v4l_experimental/firesat/firesat-rc.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __FIRESAT_LIRC_H
-#define __FIRESAT_LIRC_H
-
-extern int firesat_register_rc(void);
-extern int firesat_unregister_rc(void);
-extern int firesat_got_remotecontrolcode(u16 code);
-
-#endif
-
diff --git a/v4l_experimental/firesat/firesat.c b/v4l_experimental/firesat/firesat.c
deleted file mode 100644
index dcf268702..000000000
--- a/v4l_experimental/firesat/firesat.c
+++ /dev/null
@@ -1,917 +0,0 @@
-/*
- * FireSAT DVB driver
- *
- * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <linux/errno.h>
-#include <asm/semaphore.h>
-#include <ieee1394_hotplug.h>
-#include <nodemgr.h>
-#include <highlevel.h>
-#include <ohci1394.h>
-#include <hosts.h>
-
-/*#include "dvb_frontend.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-
-#include <linux/dvb/frontend.h>
-#include <linux/dvb/dmx.h>*/
-#include "firesat.h"
-#include "avc_api.h"
-#include "cmp.h"
-#include "firesat-rc.h"
-#include "firesat-ci.h"
-
-#define FIRESAT_Vendor_ID 0x001287
-
-/*** HOTPLUG STUFF **********************************************************/
-/*
- * Export information about protocols/devices supported by this driver.
- */
-static struct ieee1394_device_id firesat_id_table[] = {
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
- .model_id = 0x11,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
- .model_id = 0x12,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x13,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x14,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x21,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x22,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x23,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x24,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x25,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x26,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x27,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x34,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x35,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- {
- .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
-// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
-// .vendor_id = 0x000000,
- .model_id = 0x36,
- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = AVC_SW_VERSION_ENTRY & 0xffffff
- },
- { }
-};
-
-MODULE_DEVICE_TABLE(ieee1394, firesat_id_table);
-
-/* list of all firesat devices */
-LIST_HEAD(firesat_list);
-spinlock_t firesat_list_lock = SPIN_LOCK_UNLOCKED;
-
-static void firesat_add_host (struct hpsb_host *host);
-static void firesat_remove_host (struct hpsb_host *host);
-static void firesat_host_reset(struct hpsb_host *host);
-static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
- size_t length);
-static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
- int cts, u8 *data, size_t length);
-
-static struct hpsb_highlevel firesat_highlevel = {
- .name = "FireSAT",
- .add_host = firesat_add_host,
- .remove_host = firesat_remove_host,
- .host_reset = firesat_host_reset,
- .iso_receive = iso_receive,
- .fcp_request = fcp_request,
-};
-
-
-static struct dvb_frontend_info firesat_S_frontend_info = {
- .name = "FireSAT DVB-S Frontend",
- .type = FE_QPSK,
- .frequency_min = 950000,
- .frequency_max = 2150000,
- .frequency_stepsize = 125,
- .symbol_rate_min = 1000000,
- .symbol_rate_max = 40000000,
- .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
- FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
- FE_CAN_FEC_AUTO | FE_CAN_QPSK,
-};
-
-static struct dvb_frontend_info firesat_C_frontend_info = {
- .name = "FireSAT DVB-C Frontend",
- .type = FE_QAM,
- .frequency_min = 47000000,
- .frequency_max = 866000000,
- .frequency_stepsize = 62500,
- .symbol_rate_min = 870000,
- .symbol_rate_max = 6900000,
- .caps = FE_CAN_INVERSION_AUTO | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
- FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 |
- FE_CAN_QAM_AUTO,
-};
-
-static struct dvb_frontend_info firesat_T_frontend_info = {
- .name = "FireSAT DVB-T Frontend",
- .type = FE_OFDM,
- .frequency_min = 49000000,
- .frequency_max = 861000000,
- .frequency_stepsize = 62500,
- .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_2_3 |
- FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
- FE_CAN_HIERARCHY_AUTO,
-};
-
-static void firesat_add_host (struct hpsb_host *host) {
- struct ti_ohci *ohci;
-// printk(KERN_INFO "FireSAT add_host (nodeid = 0x%x)\n",host->node_id);
-
- /* We only work with the OHCI-1394 driver */
- if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
- return;
-
- ohci = (struct ti_ohci *)host->hostdata;
-
- if (!hpsb_create_hostinfo(&firesat_highlevel, host, 0)) {
- printk(KERN_ERR "Cannot allocate hostinfo\n");
- return;
- }
-
- hpsb_set_hostinfo(&firesat_highlevel, host, ohci);
- hpsb_set_hostinfo_key(&firesat_highlevel, host, ohci->host->id);
-}
-
-static void firesat_remove_host (struct hpsb_host *host) {
-// printk(KERN_INFO "FireSAT remove_host (nodeid = 0x%x)\n",host->node_id);
-}
-
-static void firesat_host_reset(struct hpsb_host *host) {
- printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active);
-}
-
-struct firewireheader {
- union {
- struct {
- unsigned char tcode:4;
- unsigned char sy:4;
- unsigned char tag:2;
- unsigned char channel:6;
-
- unsigned char length_l;
- unsigned char length_h;
- } hdr;
- unsigned long val;
- };
-};
-
-struct CIPHeader {
- union {
- struct {
- unsigned char syncbits:2;
- unsigned char sid:6;
- unsigned char dbs;
- unsigned char fn:2;
- unsigned char qpc:3;
- unsigned char sph:1;
- unsigned char rsv:2;
- unsigned char dbc;
- unsigned char syncbits2:2;
- unsigned char fmt:6;
- unsigned long fdf:24;
- } cip;
- unsigned long long val;
- };
-};
-
-struct MPEG2Header {
- union {
- struct {
- unsigned char sync; // must be 0x47
- unsigned char transport_error_indicator:1;
- unsigned char payload_unit_start_indicator:1;
- unsigned char transport_priority:1;
- unsigned short pid:13;
- unsigned char transport_scrambling_control:2;
- unsigned char adaption_field_control:2;
- unsigned char continuity_counter:4;
- } hdr;
- unsigned long val;
- };
-};
-
-static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
- size_t length) {
-// printk(KERN_INFO "FireSAT iso_receive: channel %d, length = %d\n", channel, length);
-
- if(length <= 12)
- return; // ignore empty packets
- else {
- struct firesat *firesat=NULL;
- struct firesat *firesat_entry;
- unsigned long flags;
-
- spin_lock_irqsave(&firesat_list_lock, flags);
- list_for_each_entry(firesat_entry,&firesat_list,list) {
- if(firesat_entry->host == host && firesat_entry->isochannel == channel) {
- firesat=firesat_entry;
- break;
- }
- }
- spin_unlock_irqrestore(&firesat_list_lock, flags);
-
- if(firesat) {
- char *buf=((char*)data) + sizeof(struct firewireheader)+sizeof(struct CIPHeader);
- int count = (length-sizeof(struct CIPHeader)) / 192;
-
-// printk(KERN_INFO "%s: length = %u\n data[0] = %08x\n data[1] = %08x\n data[2] = %08x\n data[3] = %08x\n data[4] = %08x\n",__FUNCTION__, length, data[0],data[1],data[2],data[3],data[4]);
-
- while (count--) {
-
- if(buf[sizeof(quadlet_t) /*timestamp*/] == 0x47)
- dvb_dmx_swfilter_packet(&firesat->demux, &buf[sizeof(quadlet_t)]);
- else
- printk("%s: invalid packet, skipping\n", __FUNCTION__);
- buf += 188 + sizeof(quadlet_t) /* timestamp */;
- }
- }
- }
-}
-
-static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
- int cts, u8 *data, size_t length) {
-// printk(KERN_INFO "FireSAT fcp_request length=%d\n",length);
- if(length>0 && ((data[0] & 0xF0) >> 4) == 0) {
- struct firesat *firesat=NULL;
- struct firesat *firesat_entry;
- unsigned long flags;
-
- spin_lock_irqsave(&firesat_list_lock, flags);
- list_for_each_entry(firesat_entry,&firesat_list,list) {
- if(firesat_entry->host == host && firesat_entry->nodeentry->nodeid == nodeid && (firesat_entry->subunit == (data[1]&0x7) || (firesat_entry->subunit == 0 && (data[1]&0x7) == 0x7))) {
- firesat=firesat_entry;
- break;
- }
- }
- spin_unlock_irqrestore(&firesat_list_lock, flags);
-
- if(firesat)
- AVCRecv(firesat,data,length);
- else
- printk("%s: received fcp request from unknown source, ignored\n",__FUNCTION__);
- } // else ignore
-}
-
-static int firesat_frontend_ioctl(struct dvb_frontend *frontend,
- unsigned int cmd, void *arg) {
- struct firesat *firesat=frontend->data;
-
- switch(cmd) {
- case FE_INIT:
- firesat->isochannel = firesat->adapter->num << 1 | (firesat->subunit & 0x1); // ### ask IRM
- try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel);
- hpsb_listen_channel(&firesat_highlevel, firesat->host, firesat->isochannel);
- break;
- case FE_SLEEP:
- hpsb_unlisten_channel(&firesat_highlevel, firesat->host, firesat->isochannel);
- try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel);
- firesat->isochannel = -1;
- break;
- case FE_GET_INFO:
-// printk(KERN_INFO "FE_GET_INFO\n");
- memcpy(arg, firesat->frontend_info,
- sizeof (struct dvb_frontend_info));
- break;
- case FE_DISEQC_RESET_OVERLOAD:
- case FE_DISEQC_RECV_SLAVE_REPLY:
- return -EOPNOTSUPP;
- case FE_DISEQC_SEND_MASTER_CMD:
- return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 1, (struct dvb_diseqc_master_cmd *)arg);
- return 0;
- case FE_DISEQC_SEND_BURST:
- return 0;
-// return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, (((fe_sec_mini_cmd_t)arg)==SEC_MINI_A)?0:1, LNBCONTROL_DONTCARE, 0, NULL);
- case FE_SET_TONE:
-// return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, (((fe_sec_tone_mode_t) arg)==SEC_TONE_ON)?1:0, 0, NULL);
- firesat->tone = (fe_sec_tone_mode_t)arg;
- return 0;
- case FE_SET_VOLTAGE:
-// printk(KERN_INFO "FE_SET_VOLTAGE\n");
- firesat->voltage=(fe_sec_voltage_t) arg;
- return 0;
-// return AVCLNBControl(firesat, ((fe_sec_voltage_t) arg, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 0, NULL);
- case FE_ENABLE_HIGH_LNB_VOLTAGE:
- return -EOPNOTSUPP;
- case FE_READ_STATUS: {
- ANTENNA_INPUT_INFO info;
- fe_status_t *status = (fe_status_t *)arg;
-// printk(KERN_INFO "%s: FE_READ_STATUS\n", __FUNCTION__);
-
- if(AVCTunerStatus(firesat,&info)) {
- return -EINVAL;
- }
-// printk(KERN_INFO "%s: NoRF=%c\n",__FUNCTION__,info.NoRF?'y':'n');
- if(info.NoRF)
- *status = 0;
- else
- *status = *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
- FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
-
- break;
- }
- case FE_READ_BER: {
- ANTENNA_INPUT_INFO info;
- u32 *ber = (u32 *)arg;
-// printk(KERN_INFO "%s: FE_READ_BER\n", __FUNCTION__);
-
- if(AVCTunerStatus(firesat,&info)) {
- return -EINVAL;
- }
-
-// *ber = *(u32*)info.BER; /* might need some byte ordering correction */
- *ber = ((info.BER[0] << 24) & 0xFF) | ((info.BER[1] << 16) & 0xFF) | ((info.BER[2] << 8) & 0xFF) | (info.BER[3] & 0xFF);
-
- break;
- }
- case FE_READ_SIGNAL_STRENGTH: {
- ANTENNA_INPUT_INFO info;
- u16 *signal = (u16 *)arg;
-// printk(KERN_INFO "%s: FE_READ_SIGNAL_STRENGTH\n", __FUNCTION__);
-
- if(AVCTunerStatus(firesat,&info)) {
- return -EINVAL;
- }
-
- *signal = info.SignalStrength;
-
- break;
- }
- case FE_READ_SNR:
- case FE_READ_UNCORRECTED_BLOCKS:
- return -EOPNOTSUPP;
- case FE_SET_FRONTEND: {
- struct dvb_frontend_parameters *p =
- (struct dvb_frontend_parameters *)arg;
-// printk(KERN_INFO "FE_GET_INFO\n");
-
-// printk(KERN_INFO "%s: FE_SET_FRONTEND\n", __FUNCTION__);
-
-// printk(KERN_INFO " frequency->%d\n", p->frequency);
-// printk(KERN_INFO " symbol_rate->%d\n",p->u.qam.symbol_rate);
-// printk(KERN_INFO " inversion->%d\n", p->inversion);
-
-// if(AVCTuner_DSIT(firesat, 0/*###*/, p, NULL))
-// return -EINVAL;
- if(AVCTuner_DSD(firesat, p, NULL) != ACCEPTED)
- return -EINVAL;
-
- break;
- }
- case FE_GET_FRONTEND:
- case FE_GET_EVENT:
- return -EOPNOTSUPP;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat) {
- int k;
-
- printk(KERN_INFO "%s\n",__FUNCTION__);
-
- if(down_interruptible(&firesat->demux_sem))
- return NULL;
-
- for(k=0;k<16;k++) {
- printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__FUNCTION__,k,firesat->channel[k].active,firesat->channel[k].pid);
- if(firesat->channel[k].active == 0) {
- firesat->channel[k].active = 1;
- up(&firesat->demux_sem);
- return &firesat->channel[k];
- }
- }
-
- up(&firesat->demux_sem);
- return NULL; // no more channels available
-}
-
-static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[]) {
- int k, l=0;
-
- if(down_interruptible(&firesat->demux_sem))
- return -EINTR;
-
- for(k=0;k<16;k++)
- if(firesat->channel[k].active == 1)
- pid[l++] = firesat->channel[k].pid;
-
- up(&firesat->demux_sem);
-
- *pidc = l;
-
- return 0;
-}
-
-static int firesat_channel_release(struct firesat *firesat, struct firesat_channel *channel) {
- if(down_interruptible(&firesat->demux_sem))
- return -EINTR;
-
- channel->active = 0;
-
- up(&firesat->demux_sem);
- return 0;
-}
-
-static int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) {
- struct firesat *firesat=(struct firesat*)dvbdmxfeed->demux->priv;
- struct firesat_channel *channel;
- int pidc,k;
- u16 pids[16];
-
- printk(KERN_INFO "%s (pid %u)\n",__FUNCTION__,dvbdmxfeed->pid);
-
- switch (dvbdmxfeed->type) {
- case DMX_TYPE_TS:
- case DMX_TYPE_SEC:
- break;
- default:
- printk("%s: invalid type %u\n",__FUNCTION__,dvbdmxfeed->type);
- return -EINVAL;
- }
-
- if (dvbdmxfeed->type == DMX_TYPE_TS) {
- switch (dvbdmxfeed->pes_type) {
- case DMX_TS_PES_VIDEO:
- case DMX_TS_PES_AUDIO:
- case DMX_TS_PES_TELETEXT:
- case DMX_TS_PES_PCR:
- case DMX_TS_PES_OTHER:
- channel = firesat_channel_allocate(firesat);
- break;
- default:
- printk("%s: invalid pes type %u\n",__FUNCTION__,dvbdmxfeed->pes_type);
- return -EINVAL;
- }
- } else {
- channel = firesat_channel_allocate(firesat);
- }
-
- if(!channel) {
- printk("%s: busy!\n",__FUNCTION__);
- return -EBUSY;
- }
-
- dvbdmxfeed->priv = channel;
-
- channel->dvbdmxfeed = dvbdmxfeed;
- channel->pid = dvbdmxfeed->pid;
- channel->type = dvbdmxfeed->type;
- channel->firesat = firesat;
-
- if(firesat_channel_collect(firesat, &pidc, pids)) {
- firesat_channel_release(firesat, channel);
- return -EINTR;
- }
-
- if((k=AVCTuner_SetPIDs(firesat, pidc, pids))) {
- firesat_channel_release(firesat, channel);
- printk("%s: AVCTuner failed with error %d\n",__FUNCTION__,k);
- return k;
- }
-
- return 0;
-}
-
-static int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) {
- struct dvb_demux *demux = dvbdmxfeed->demux;
- struct firesat *firesat=(struct firesat*)demux->priv;
- int k, l=0;
- u16 pids[16];
-
- printk(KERN_INFO "%s (pid %u)\n",__FUNCTION__,dvbdmxfeed->pid);
-
- if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) &&
- (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
- if (dvbdmxfeed->ts_type & TS_DECODER) {
- if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER ||
- !demux->pesfilter[dvbdmxfeed->pes_type])
- return -EINVAL;
- demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
- demux->pesfilter[dvbdmxfeed->pes_type] = 0;
- }
- if (!(dvbdmxfeed->ts_type & TS_DECODER &&
- dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) {
- return 0;
- }
- }
-
- if(down_interruptible(&firesat->demux_sem))
- return -EINTR;
-
- // list except channel to be removed
- for(k=0;k<16;k++)
- if(firesat->channel[k].active == 1 && &firesat->channel[k] != (struct firesat_channel*)dvbdmxfeed->priv)
- pids[l++] = firesat->channel[k].pid;
-
- if((k=AVCTuner_SetPIDs(firesat, l, pids))) {
- up(&firesat->demux_sem);
- return k;
- }
-
- ((struct firesat_channel*)dvbdmxfeed->priv)->active = 0;
-
- up(&firesat->demux_sem);
-
- return 0;
-}
-
-static int firesat_probe(struct device *dev) {
- struct unit_directory *ud=container_of(dev, struct unit_directory, device);
- struct firesat *firesat;
- unsigned long flags;
- int result;
- unsigned char subunitcount=0xff,subunit;
- struct firesat **firesats=kmalloc(sizeof(void*)*2,GFP_KERNEL);
-
- if(!firesats) {
- printk("%s: couldn't allocate memory.\n", __FUNCTION__);
- return -ENOMEM;
- }
-
-// printk(KERN_INFO "FireSAT: Detected device with GUID %08lx%04lx%04lx\n",(unsigned long)((ud->ne->guid)>>32),(unsigned long)(ud->ne->guid & 0xFFFF),(unsigned long)ud->ne->guid_vendor_id);
- printk(KERN_INFO "%s: loading device\n", __FUNCTION__);
-
- firesats[0]=NULL;
- firesats[1]=NULL;
-
- ud->device.driver_data = firesats;
-
- for(subunit=0;subunit<subunitcount;subunit++) {
- if (!(firesat = kmalloc(sizeof(struct firesat), GFP_KERNEL))) {
- printk("%s: couldn't allocate memory.\n", __FUNCTION__);
- kfree(firesats);
- return -ENOMEM;
- }
-
- memset(firesat, 0, sizeof(struct firesat));
- firesat->host=ud->ne->host;
- firesat->guid=ud->ne->guid;
- firesat->guid_vendor_id=ud->ne->guid_vendor_id;
- firesat->nodeentry=ud->ne;
- firesat->isochannel=-1;
- firesat->tone = 0xff;
- firesat->voltage = 0xff;
- if(!(firesat->respfrm = kmalloc(sizeof(AVCRspFrm), GFP_KERNEL))) {
- printk("%s: couldn't allocate memory.\n", __FUNCTION__);
- kfree(firesat);
- return -ENOMEM;
- }
-
- sema_init(&firesat->avc_sem, 1);
- atomic_set(&firesat->avc_reply_received, 1);
- sema_init(&firesat->demux_sem, 1);
- atomic_set(&firesat->reschedule_remotecontrol, 0);
-
- spin_lock_irqsave(&firesat_list_lock, flags);
- INIT_LIST_HEAD(&firesat->list);
- list_add_tail(&firesat->list, &firesat_list);
- spin_unlock_irqrestore(&firesat_list_lock, flags);
-
- if(subunit == 0) {
- firesat->subunit = 0x7; // 0x7 = don't care
- if(AVCSubUnitInfo(firesat, &subunitcount)) {
- printk("%s: AVC subunit info command failed.\n",__FUNCTION__);
- spin_lock_irqsave(&firesat_list_lock, flags);
- list_del(&firesat->list);
- spin_unlock_irqrestore(&firesat_list_lock, flags);
- kfree(firesat);
- return -EIO;
- }
- }
-
- printk(KERN_INFO "%s: subunit count = %d\n",__FUNCTION__,subunitcount);
-
- firesat->subunit=subunit;
-
- if(AVCIdentifySubunit(firesat,NULL,(int*)&firesat->type,&firesat->has_ci)) {
- printk("%s: cannot identify subunit %d\n",__FUNCTION__,subunit);
- spin_lock_irqsave(&firesat_list_lock, flags);
- list_del(&firesat->list);
- spin_unlock_irqrestore(&firesat_list_lock, flags);
- kfree(firesat);
- continue;
- }
- firesat->has_ci=1; // TEMP workaround
-
- switch(firesat->type) {
- case FireSAT_DVB_S:
- firesat->model_name="FireSAT DVB-S";
- firesat->frontend_info=&firesat_S_frontend_info;
- break;
- case FireSAT_DVB_C:
- firesat->model_name="FireSAT DVB-C";
- firesat->frontend_info=&firesat_C_frontend_info;
- break;
- case FireSAT_DVB_T:
- firesat->model_name="FireSAT DVB-T";
- firesat->frontend_info=&firesat_T_frontend_info;
- break;
- default:
- printk("%s: unknown model type 0x%x on subunit %d!\n",__FUNCTION__,firesat->type,subunit);
- firesat->model_name="Unknown";
- firesat->frontend_info=NULL;
- }
- if(!firesat->frontend_info) {
- spin_lock_irqsave(&firesat_list_lock, flags);
- list_del(&firesat->list);
- spin_unlock_irqrestore(&firesat_list_lock, flags);
- kfree(firesat);
- continue;
- }
-
- if ((result = dvb_register_adapter(&firesat->adapter,
- firesat->model_name, THIS_MODULE)) < 0) {
- printk("%s: dvb_register_adapter failed: error %d\n",
- __FUNCTION__, result);
-
- /* ### cleanup */
- spin_lock_irqsave(&firesat_list_lock, flags);
- list_del(&firesat->list);
- spin_unlock_irqrestore(&firesat_list_lock, flags);
- kfree(firesat);
-
- return result;
- }
-
- firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/;
-
- firesat->demux.priv = (void *)firesat;
- firesat->demux.filternum = 16;
- firesat->demux.feednum = 16;
- firesat->demux.start_feed = firesat_start_feed;
- firesat->demux.stop_feed = firesat_stop_feed;
-
- firesat->demux.write_to_decoder = NULL;
-
- if ((result = dvb_dmx_init(&firesat->demux)) < 0) {
- printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
- result);
-
- dvb_unregister_adapter(firesat->adapter);
-
- return result;
- }
-
- firesat->dmxdev.filternum = 16;
- firesat->dmxdev.demux = &firesat->demux.dmx;
- firesat->dmxdev.capabilities = 0;
-
- if ((result = dvb_dmxdev_init(&firesat->dmxdev, firesat->adapter)) < 0) {
- printk("%s: dvb_dmxdev_init failed: error %d\n",
- __FUNCTION__, result);
-
- dvb_dmx_release(&firesat->demux);
- dvb_unregister_adapter(firesat->adapter);
-
- return result;
- }
-
- firesat->frontend.source = DMX_FRONTEND_0;
-
- if ((result = firesat->demux.dmx.add_frontend(&firesat->demux.dmx,
- &firesat->frontend)) < 0) {
- printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
- result);
-
- dvb_dmxdev_release(&firesat->dmxdev);
- dvb_dmx_release(&firesat->demux);
- dvb_unregister_adapter(firesat->adapter);
-
- return result;
- }
-
- if ((result = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx,
- &firesat->frontend)) < 0) {
- printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
- result);
-
- firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, &firesat->frontend);
- dvb_dmxdev_release(&firesat->dmxdev);
- dvb_dmx_release(&firesat->demux);
- dvb_unregister_adapter(firesat->adapter);
-
- return result;
- }
-
- dvb_net_init(firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx);
-
- if((result= dvb_register_frontend(firesat_frontend_ioctl,firesat->adapter,firesat,firesat->frontend_info,THIS_MODULE)) < 0) {
- printk("%s: dvb_register_frontend_new failed: error %d\n", __FUNCTION__, result);
- /* ### cleanup */
-
- return result;
- }
-
- if(firesat->has_ci)
- firesat_ca_init(firesat);
-
- firesats[subunit] = firesat;
- } // loop fuer alle tuner am board
-
- if(firesats[0])
- AVCRegisterRemoteControl(firesats[0]);
-
- return 0;
-}
-
-static int firesat_remove(struct device *dev) {
- struct unit_directory *ud=container_of(dev, struct unit_directory, device);
- struct firesat **firesats=ud->device.driver_data;
-
- if(firesats) {
- int k;
- for(k=0;k<2;k++)
- if(firesats[k]) {
- unsigned long flags;
- if(firesats[k]->has_ci)
- firesat_ca_release(firesats[k]);
- dvb_unregister_frontend(firesat_frontend_ioctl,firesats[k]->adapter);
-
- dvb_net_release(&firesats[k]->dvbnet);
- firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx);
- firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend);
- dvb_dmxdev_release(&firesats[k]->dmxdev);
- dvb_dmx_release(&firesats[k]->demux);
- dvb_unregister_adapter(firesats[k]->adapter);
-
- spin_lock_irqsave(&firesat_list_lock, flags);
- list_del(&firesats[k]->list);
- spin_unlock_irqrestore(&firesat_list_lock, flags);
-
- kfree(firesats[k]->respfrm);
- kfree(firesats[k]);
- }
- kfree(firesats);
- } else
- printk("%s: can't get firesat handle\n",__FUNCTION__);
-
- printk(KERN_INFO "FireSAT: Removing device with vendor id 0x%x, model id 0x%x.\n",ud->vendor_id,ud->model_id);
- return 0;
-}
-
-static int firesat_update(struct unit_directory *ud) {
-// printk(KERN_INFO "FireSAT: Found device with vendor id 0x%x, model id 0x%x\n", ud->vendor_id,ud->model_id);
- struct firesat **firesats=ud->device.driver_data;
- int k;
- // loop over subunits
-
- for(k=0;k<2;k++)
- if(firesats[k]) {
- firesats[k]->nodeentry=ud->ne;
-
- if(firesats[k]->isochannel >= 0)
- try_CMPEstablishPPconnection(firesats[k], firesats[k]->subunit, firesats[k]->isochannel);
- }
-
- return 0;
-}
-
-static struct hpsb_protocol_driver firesat_driver = {
- .name = "FireSAT DVB",
- .id_table = firesat_id_table,
- .update = firesat_update,
- .driver = {
- .name = "firesat",
- .bus = &ieee1394_bus_type,
- .probe = firesat_probe,
- .remove = firesat_remove,
- },
-};
-
-static int __init firesat_init(void)
-{
- int ret;
- printk("FireSAT loaded\n");
- hpsb_register_highlevel(&firesat_highlevel);
- ret = hpsb_register_protocol(&firesat_driver);
- if(ret) {
- printk(KERN_ERR "FireSAT: failed to register protocol\n");
- hpsb_unregister_highlevel(&firesat_highlevel);
- return ret;
- }
-
- if((ret=firesat_register_rc()))
- printk("%s: firesat_register_rc return error code %d (ignored)\n",__FUNCTION__,ret);
-
- return 0;
-}
-
-static void __exit firesat_exit(void){
- firesat_unregister_rc();
-
- hpsb_unregister_protocol(&firesat_driver);
- hpsb_unregister_highlevel(&firesat_highlevel);
- printk("FireSAT quit\n");
-}
-
-module_init(firesat_init);
-module_exit(firesat_exit);
-
-MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
-MODULE_DESCRIPTION("FireSAT DVB Driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("FireSAT DVB");
diff --git a/v4l_experimental/firesat/firesat.h b/v4l_experimental/firesat/firesat.h
deleted file mode 100644
index c3a614b2a..000000000
--- a/v4l_experimental/firesat/firesat.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef __FIRESAT_H
-#define __FIRESAT_H
-
-#include "dvb_frontend.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-
-#include <linux/dvb/frontend.h>
-#include <linux/dvb/dmx.h>
-
-enum model_type {
- FireSAT_DVB_S = 1,
- FireSAT_DVB_C = 2,
- FireSAT_DVB_T = 3
-};
-
-struct firesat {
- struct dvb_demux dvb_demux;
- char *model_name;
-
- /* DVB bits */
- struct dvb_adapter *adapter;
- struct dmxdev dmxdev;
- struct dvb_demux demux;
- struct dmx_frontend frontend;
- struct dvb_net dvbnet;
- struct dvb_frontend_info *frontend_info;
-
- struct dvb_device *cadev;
- int has_ci;
-
- struct semaphore avc_sem;
- atomic_t avc_reply_received;
-
- atomic_t reschedule_remotecontrol;
-
- struct firesat_channel {
- struct firesat *firesat;
- struct dvb_demux_feed *dvbdmxfeed;
-
- int active;
- int id;
- int pid;
- int type; /* 1 - TS, 2 - Filter */
- } channel[16];
- struct semaphore demux_sem;
-
- /* needed by avc_api */
- void *respfrm;
- int resp_length;
-
-// nodeid_t nodeid;
- struct hpsb_host *host;
- u64 guid; /* GUID of this node */
- u32 guid_vendor_id; /* Top 24bits of guid */
- struct node_entry *nodeentry;
-
- enum model_type type;
- char subunit;
- fe_sec_voltage_t voltage;
- fe_sec_tone_mode_t tone;
-
- int isochannel;
-
- struct list_head list;
-};
-
-extern struct list_head firesat_list;
-extern spinlock_t firesat_list_lock;
-
-#endif