Commit d9009201 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

V4L/DVB (6765): ivtv: convert to bus-based i2c API

Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 9d1a16a4
...@@ -40,6 +40,27 @@ ...@@ -40,6 +40,27 @@
#define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \ #define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \
MSP_DSP_IN_SCART, MSP_DSP_IN_SCART) MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
/* usual i2c tuner addresses to probe */
static struct ivtv_card_tuner_i2c ivtv_i2c_std = {
.radio = { I2C_CLIENT_END },
.demod = { 0x43, I2C_CLIENT_END },
.tv = { 0x61, 0x60, I2C_CLIENT_END },
};
/* as above, but with possible radio tuner */
static struct ivtv_card_tuner_i2c ivtv_i2c_radio = {
.radio = { 0x60, I2C_CLIENT_END },
.demod = { 0x43, I2C_CLIENT_END },
.tv = { 0x61, I2C_CLIENT_END },
};
/* using the tda8290+75a combo */
static struct ivtv_card_tuner_i2c ivtv_i2c_tda8290 = {
.radio = { I2C_CLIENT_END },
.demod = { I2C_CLIENT_END },
.tv = { 0x4b, I2C_CLIENT_END },
};
/********************** card configuration *******************************/ /********************** card configuration *******************************/
/* Please add new PCI IDs to: http://pci-ids.ucw.cz/iii /* Please add new PCI IDs to: http://pci-ids.ucw.cz/iii
...@@ -73,6 +94,7 @@ static const struct ivtv_card ivtv_card_pvr250 = { ...@@ -73,6 +94,7 @@ static const struct ivtv_card ivtv_card_pvr250 = {
{ IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 }, { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
}, },
.radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 }, .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -127,6 +149,7 @@ static const struct ivtv_card ivtv_card_pvr350 = { ...@@ -127,6 +149,7 @@ static const struct ivtv_card ivtv_card_pvr350 = {
{ IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 }, { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
}, },
.radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 }, .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
.i2c = &ivtv_i2c_std,
}; };
/* PVR-350 V1 boards have a different audio tuner input and use a /* PVR-350 V1 boards have a different audio tuner input and use a
...@@ -158,6 +181,7 @@ static const struct ivtv_card ivtv_card_pvr350_v1 = { ...@@ -158,6 +181,7 @@ static const struct ivtv_card ivtv_card_pvr350_v1 = {
{ IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 }, { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
}, },
.radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 }, .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -193,6 +217,7 @@ static const struct ivtv_card ivtv_card_pvr150 = { ...@@ -193,6 +217,7 @@ static const struct ivtv_card ivtv_card_pvr150 = {
CX25840_AUDIO_SERIAL, WM8775_AIN4 }, CX25840_AUDIO_SERIAL, WM8775_AIN4 },
/* apparently needed for the IR blaster */ /* apparently needed for the IR blaster */
.gpio_init = { .direction = 0x1f01, .initial_value = 0x26f3 }, .gpio_init = { .direction = 0x1f01, .initial_value = 0x26f3 },
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -235,6 +260,7 @@ static const struct ivtv_card ivtv_card_m179 = { ...@@ -235,6 +260,7 @@ static const struct ivtv_card ivtv_card_m179 = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_NTSC }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_NTSC },
}, },
.pci_list = ivtv_pci_m179, .pci_list = ivtv_pci_m179,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -276,6 +302,7 @@ static const struct ivtv_card ivtv_card_mpg600 = { ...@@ -276,6 +302,7 @@ static const struct ivtv_card ivtv_card_mpg600 = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
}, },
.pci_list = ivtv_pci_mpg600, .pci_list = ivtv_pci_mpg600,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -316,6 +343,7 @@ static const struct ivtv_card ivtv_card_mpg160 = { ...@@ -316,6 +343,7 @@ static const struct ivtv_card ivtv_card_mpg160 = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
}, },
.pci_list = ivtv_pci_mpg160, .pci_list = ivtv_pci_mpg160,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -351,6 +379,7 @@ static const struct ivtv_card ivtv_card_pg600 = { ...@@ -351,6 +379,7 @@ static const struct ivtv_card ivtv_card_pg600 = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
}, },
.pci_list = ivtv_pci_pg600, .pci_list = ivtv_pci_pg600,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -394,6 +423,7 @@ static const struct ivtv_card ivtv_card_avc2410 = { ...@@ -394,6 +423,7 @@ static const struct ivtv_card ivtv_card_avc2410 = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
}, },
.pci_list = ivtv_pci_avc2410, .pci_list = ivtv_pci_avc2410,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -464,6 +494,7 @@ static const struct ivtv_card ivtv_card_tg5000tv = { ...@@ -464,6 +494,7 @@ static const struct ivtv_card ivtv_card_tg5000tv = {
{ .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 }, { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 },
}, },
.pci_list = ivtv_pci_tg5000tv, .pci_list = ivtv_pci_tg5000tv,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -494,6 +525,7 @@ static const struct ivtv_card ivtv_card_va2000 = { ...@@ -494,6 +525,7 @@ static const struct ivtv_card ivtv_card_va2000 = {
{ .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 }, { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 },
}, },
.pci_list = ivtv_pci_va2000, .pci_list = ivtv_pci_va2000,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -538,6 +570,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc = { ...@@ -538,6 +570,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
}, },
.pci_list = ivtv_pci_cx23416gyc, .pci_list = ivtv_pci_cx23416gyc,
.i2c = &ivtv_i2c_std,
}; };
static const struct ivtv_card ivtv_card_cx23416gyc_nogr = { static const struct ivtv_card ivtv_card_cx23416gyc_nogr = {
...@@ -568,6 +601,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogr = { ...@@ -568,6 +601,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogr = {
{ .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
}, },
.i2c = &ivtv_i2c_std,
}; };
static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = { static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = {
...@@ -597,6 +631,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = { ...@@ -597,6 +631,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = {
{ .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
}, },
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -636,6 +671,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx = { ...@@ -636,6 +671,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx = {
{ .std = V4L2_STD_525_60, .tuner = TUNER_PANASONIC_VP27 }, { .std = V4L2_STD_525_60, .tuner = TUNER_PANASONIC_VP27 },
}, },
.pci_list = ivtv_pci_gv_mvprx, .pci_list = ivtv_pci_gv_mvprx,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -672,6 +708,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx2e = { ...@@ -672,6 +708,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx2e = {
{ .std = V4L2_STD_525_60, .tuner = TUNER_PANASONIC_VP27 }, { .std = V4L2_STD_525_60, .tuner = TUNER_PANASONIC_VP27 },
}, },
.pci_list = ivtv_pci_gv_mvprx2e, .pci_list = ivtv_pci_gv_mvprx2e,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -706,6 +743,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd = { ...@@ -706,6 +743,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd = {
{ .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
}, },
.pci_list = ivtv_pci_gotview_pci_dvd, .pci_list = ivtv_pci_gotview_pci_dvd,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -744,6 +782,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd2 = { ...@@ -744,6 +782,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd2 = {
{ .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
}, },
.pci_list = ivtv_pci_gotview_pci_dvd2, .pci_list = ivtv_pci_gotview_pci_dvd2,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -779,6 +818,7 @@ static const struct ivtv_card ivtv_card_yuan_mpc622 = { ...@@ -779,6 +818,7 @@ static const struct ivtv_card ivtv_card_yuan_mpc622 = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_TDA8290 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_TDA8290 },
}, },
.pci_list = ivtv_pci_yuan_mpc622, .pci_list = ivtv_pci_yuan_mpc622,
.i2c = &ivtv_i2c_tda8290,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -820,6 +860,7 @@ static const struct ivtv_card ivtv_card_dctmvtvp1 = { ...@@ -820,6 +860,7 @@ static const struct ivtv_card ivtv_card_dctmvtvp1 = {
{ .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 }, { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 },
}, },
.pci_list = ivtv_pci_dctmvtvp1, .pci_list = ivtv_pci_dctmvtvp1,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -852,6 +893,7 @@ static const struct ivtv_card ivtv_card_pg600v2 = { ...@@ -852,6 +893,7 @@ static const struct ivtv_card ivtv_card_pg600v2 = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
}, },
.pci_list = ivtv_pci_pg600v2, .pci_list = ivtv_pci_pg600v2,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -883,6 +925,7 @@ static const struct ivtv_card ivtv_card_club3d = { ...@@ -883,6 +925,7 @@ static const struct ivtv_card ivtv_card_club3d = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
}, },
.pci_list = ivtv_pci_club3d, .pci_list = ivtv_pci_club3d,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -914,6 +957,7 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = { ...@@ -914,6 +957,7 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
}, },
.pci_list = ivtv_pci_avertv_mce116, .pci_list = ivtv_pci_avertv_mce116,
.i2c = &ivtv_i2c_std,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -952,6 +996,7 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = { ...@@ -952,6 +996,7 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = {
{ .std = V4L2_STD_525_60, .tuner = TUNER_TCL_2002N }, { .std = V4L2_STD_525_60, .tuner = TUNER_TCL_2002N },
}, },
.pci_list = ivtv_pci_aver_pvr150, .pci_list = ivtv_pci_aver_pvr150,
.i2c = &ivtv_i2c_radio,
}; };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
...@@ -979,6 +1024,7 @@ static const struct ivtv_card ivtv_card_aver_ezmaker = { ...@@ -979,6 +1024,7 @@ static const struct ivtv_card ivtv_card_aver_ezmaker = {
{ IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 0 }, { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 0 },
}, },
.gpio_init = { .direction = 0x4000, .initial_value = 0x4000 }, .gpio_init = { .direction = 0x4000, .initial_value = 0x4000 },
/* Does not have a tuner */
.pci_list = ivtv_pci_aver_ezmaker, .pci_list = ivtv_pci_aver_ezmaker,
}; };
...@@ -1018,6 +1064,7 @@ static const struct ivtv_card ivtv_card_asus_falcon2 = { ...@@ -1018,6 +1064,7 @@ static const struct ivtv_card ivtv_card_asus_falcon2 = {
{ .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FM1236_MK3 }, { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FM1236_MK3 },
}, },
.pci_list = ivtv_pci_asus_falcon2, .pci_list = ivtv_pci_asus_falcon2,
.i2c = &ivtv_i2c_std,
}; };
static const struct ivtv_card *ivtv_card_list[] = { static const struct ivtv_card *ivtv_card_list[] = {
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
#define IVTV_PCI_ID_GOTVIEW1 0xffac #define IVTV_PCI_ID_GOTVIEW1 0xffac
#define IVTV_PCI_ID_GOTVIEW2 0xffad #define IVTV_PCI_ID_GOTVIEW2 0xffad
/* hardware flags */ /* hardware flags, no gaps allowed, IVTV_HW_GPIO must always be last */
#define IVTV_HW_CX25840 (1 << 0) #define IVTV_HW_CX25840 (1 << 0)
#define IVTV_HW_SAA7115 (1 << 1) #define IVTV_HW_SAA7115 (1 << 1)
#define IVTV_HW_SAA7127 (1 << 2) #define IVTV_HW_SAA7127 (1 << 2)
...@@ -94,14 +94,13 @@ ...@@ -94,14 +94,13 @@
#define IVTV_HW_CS53L32A (1 << 6) #define IVTV_HW_CS53L32A (1 << 6)
#define IVTV_HW_TVEEPROM (1 << 7) #define IVTV_HW_TVEEPROM (1 << 7)
#define IVTV_HW_SAA7114 (1 << 8) #define IVTV_HW_SAA7114 (1 << 8)
#define IVTV_HW_TVAUDIO (1 << 9) #define IVTV_HW_UPD64031A (1 << 9)
#define IVTV_HW_UPD64031A (1 << 10) #define IVTV_HW_UPD6408X (1 << 10)
#define IVTV_HW_UPD6408X (1 << 11) #define IVTV_HW_SAA717X (1 << 11)
#define IVTV_HW_SAA717X (1 << 12) #define IVTV_HW_WM8739 (1 << 12)
#define IVTV_HW_WM8739 (1 << 13) #define IVTV_HW_VP27SMPX (1 << 13)
#define IVTV_HW_VP27SMPX (1 << 14) #define IVTV_HW_M52790 (1 << 14)
#define IVTV_HW_M52790 (1 << 15) #define IVTV_HW_GPIO (1 << 15)
#define IVTV_HW_GPIO (1 << 16)
#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114) #define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
...@@ -235,6 +234,12 @@ struct ivtv_card_tuner { ...@@ -235,6 +234,12 @@ struct ivtv_card_tuner {
int tuner; /* tuner ID (from tuner.h) */ int tuner; /* tuner ID (from tuner.h) */
}; };
struct ivtv_card_tuner_i2c {
unsigned short radio[2];/* radio tuner i2c address to probe */
unsigned short demod[2];/* demodulator i2c address to probe */
unsigned short tv[4]; /* tv tuner i2c addresses to probe */
};
/* for card information/parameters */ /* for card information/parameters */
struct ivtv_card { struct ivtv_card {
int type; int type;
...@@ -262,6 +267,7 @@ struct ivtv_card { ...@@ -262,6 +267,7 @@ struct ivtv_card {
struct ivtv_gpio_audio_detect gpio_audio_detect; struct ivtv_gpio_audio_detect gpio_audio_detect;
struct ivtv_card_tuner tuners[IVTV_CARD_MAX_TUNERS]; struct ivtv_card_tuner tuners[IVTV_CARD_MAX_TUNERS];
struct ivtv_card_tuner_i2c *i2c;
/* list of device and subsystem vendor/devices that /* list of device and subsystem vendor/devices that
correspond to this card type. */ correspond to this card type. */
......
...@@ -400,6 +400,7 @@ static void ivtv_process_eeprom(struct ivtv *itv) ...@@ -400,6 +400,7 @@ static void ivtv_process_eeprom(struct ivtv *itv)
itv->v4l2_cap = itv->card->v4l2_capabilities; itv->v4l2_cap = itv->card->v4l2_capabilities;
itv->card_name = itv->card->name; itv->card_name = itv->card->name;
itv->card_i2c = itv->card->i2c;
/* If this is a PVR500 then it should be possible to detect whether it is the /* If this is a PVR500 then it should be possible to detect whether it is the
first or second unit by looking at the subsystem device ID: is bit 4 is first or second unit by looking at the subsystem device ID: is bit 4 is
...@@ -417,7 +418,14 @@ static void ivtv_process_eeprom(struct ivtv *itv) ...@@ -417,7 +418,14 @@ static void ivtv_process_eeprom(struct ivtv *itv)
This detection is needed since the eeprom reports incorrectly that a radio is This detection is needed since the eeprom reports incorrectly that a radio is
present on the second unit. */ present on the second unit. */
if (tv.model / 1000 == 23) { if (tv.model / 1000 == 23) {
static const struct ivtv_card_tuner_i2c ivtv_i2c_radio = {
.radio = { 0x60, I2C_CLIENT_END },
.demod = { 0x43, I2C_CLIENT_END },
.tv = { 0x61, I2C_CLIENT_END },
};
itv->card_name = "WinTV PVR 500"; itv->card_name = "WinTV PVR 500";
itv->card_i2c = &ivtv_i2c_radio;
if (pci_slot == 8 || pci_slot == 9) { if (pci_slot == 8 || pci_slot == 9) {
int is_first = (pci_slot & 1) == 0; int is_first = (pci_slot & 1) == 0;
...@@ -635,6 +643,7 @@ static void ivtv_process_options(struct ivtv *itv) ...@@ -635,6 +643,7 @@ static void ivtv_process_options(struct ivtv *itv)
} }
itv->v4l2_cap = itv->card->v4l2_capabilities; itv->v4l2_cap = itv->card->v4l2_capabilities;
itv->card_name = itv->card->name; itv->card_name = itv->card->name;
itv->card_i2c = itv->card->i2c;
} }
/* Precondition: the ivtv structure has been memset to 0. Only /* Precondition: the ivtv structure has been memset to 0. Only
...@@ -816,79 +825,66 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev, ...@@ -816,79 +825,66 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
return 0; return 0;
} }
static void ivtv_request_module(struct ivtv *itv, const char *name) static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
const char *name, u32 id)
{ {
if ((hw & id) == 0)
return hw;
if (request_module(name) != 0) { if (request_module(name) != 0) {
IVTV_ERR("Failed to load module %s\n", name); IVTV_ERR("Failed to load module %s\n", name);
} else { return hw & ~id;
IVTV_DEBUG_INFO("Loaded module %s\n", name);
} }
IVTV_DEBUG_INFO("Loaded module %s\n", name);
return hw;
} }
static void ivtv_load_and_init_modules(struct ivtv *itv) static void ivtv_load_and_init_modules(struct ivtv *itv)
{ {
u32 hw = itv->card->hw_all; u32 hw = itv->card->hw_all;
int i; unsigned i;
/* load modules */ /* load modules */
#ifndef CONFIG_VIDEO_TUNER if ((hw & IVTV_HW_TUNER) && itv->options.tuner == TUNER_XC2028) {
if (hw & IVTV_HW_TUNER) { IVTV_INFO("Xceive tuner not yet supported, only composite\n");
if (itv->options.tuner == TUNER_XC2028) { IVTV_INFO("and S-Video inputs will be available\n");
IVTV_INFO("Xceive tuner not yet supported, only composite and S-Video inputs will be available\n"); hw &= ~IVTV_HW_TUNER;
itv->tunerid = 1;
}
else {
ivtv_request_module(itv, "tuner");
}
} }
#ifndef CONFIG_VIDEO_TUNER
hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
#endif #endif
#ifndef CONFIG_VIDEO_CX25840 #ifndef CONFIG_VIDEO_CX25840
if (hw & IVTV_HW_CX25840) hw = ivtv_request_module(itv, hw, "cx25840", IVTV_HW_CX25840);
ivtv_request_module(itv, "cx25840");
#endif #endif
#ifndef CONFIG_VIDEO_SAA711X #ifndef CONFIG_VIDEO_SAA711X
if (hw & IVTV_HW_SAA711X) hw = ivtv_request_module(itv, hw, "saa7115", IVTV_HW_SAA711X);
ivtv_request_module(itv, "saa7115");
#endif #endif
#ifndef CONFIG_VIDEO_SAA7127 #ifndef CONFIG_VIDEO_SAA7127
if (hw & IVTV_HW_SAA7127) hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127);
ivtv_request_module(itv, "saa7127");
#endif #endif
if (hw & IVTV_HW_SAA717X) hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X);
ivtv_request_module(itv, "saa717x");
#ifndef CONFIG_VIDEO_UPD64031A #ifndef CONFIG_VIDEO_UPD64031A
if (hw & IVTV_HW_UPD64031A) hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A);
ivtv_request_module(itv, "upd64031a");
#endif #endif
#ifndef CONFIG_VIDEO_UPD64083 #ifndef CONFIG_VIDEO_UPD64083
if (hw & IVTV_HW_UPD6408X) hw = ivtv_request_module(itv, hw, "upd64083", IVTV_HW_UPD6408X);
ivtv_request_module(itv, "upd64083");
#endif #endif
#ifndef CONFIG_VIDEO_MSP3400 #ifndef CONFIG_VIDEO_MSP3400
if (hw & IVTV_HW_MSP34XX) hw = ivtv_request_module(itv, hw, "msp3400", IVTV_HW_MSP34XX);
ivtv_request_module(itv, "msp3400");
#endif #endif
#ifndef CONFIG_VIDEO_VP27SMPX #ifndef CONFIG_VIDEO_VP27SMPX
if (hw & IVTV_HW_VP27SMPX) hw = ivtv_request_module(itv, hw, "vp27smpx", IVTV_HW_VP27SMPX);
ivtv_request_module(itv, "vp27smpx");
#endif #endif
if (hw & IVTV_HW_TVAUDIO)
ivtv_request_module(itv, "tvaudio");
#ifndef CONFIG_VIDEO_WM8775 #ifndef CONFIG_VIDEO_WM8775
if (hw & IVTV_HW_WM8775) hw = ivtv_request_module(itv, hw, "wm8775", IVTV_HW_WM8775);
ivtv_request_module(itv, "wm8775");
#endif #endif
#ifndef CONFIG_VIDEO_WM8739 #ifndef CONFIG_VIDEO_WM8739
if (hw & IVTV_HW_WM8739) hw = ivtv_request_module(itv, hw, "wm8739", IVTV_HW_WM8739);
ivtv_request_module(itv, "wm8739");
#endif #endif
#ifndef CONFIG_VIDEO_CS53L32A #ifndef CONFIG_VIDEO_CS53L32A
if (hw & IVTV_HW_CS53L32A) hw = ivtv_request_module(itv, hw, "cs53l32a", IVTV_HW_CS53L32A);
ivtv_request_module(itv, "cs53l32a");
#endif #endif
#ifndef CONFIG_VIDEO_M52790 #ifndef CONFIG_VIDEO_M52790
if (hw & IVTV_HW_M52790) hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790);
ivtv_request_module(itv, "m52790");
#endif #endif
/* check which i2c devices are actually found */ /* check which i2c devices are actually found */
...@@ -897,11 +893,12 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) ...@@ -897,11 +893,12 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
if (!(device & hw)) if (!(device & hw))
continue; continue;
if (device == IVTV_HW_GPIO) { if (device == IVTV_HW_GPIO || device == IVTV_HW_TVEEPROM) {
/* GPIO is always available */ /* GPIO and TVEEPROM do not use i2c probing */
itv->hw_flags |= IVTV_HW_GPIO; itv->hw_flags |= device;
continue; continue;
} }
ivtv_i2c_register(itv, i);
if (ivtv_i2c_hw_addr(itv, device) > 0) if (ivtv_i2c_hw_addr(itv, device) > 0)
itv->hw_flags |= device; itv->hw_flags |= device;
} }
...@@ -1075,9 +1072,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev, ...@@ -1075,9 +1072,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active); IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active);
if (itv->card->hw_all & IVTV_HW_TVEEPROM) { if (itv->card->hw_all & IVTV_HW_TVEEPROM) {
#ifdef CONFIG_VIDEO_TVEEPROM_MODULE
ivtv_request_module(itv, "tveeprom");
#endif
/* Based on the model number the cardtype may be changed. /* Based on the model number the cardtype may be changed.
The PCI IDs are not always reliable. */ The PCI IDs are not always reliable. */
ivtv_process_eeprom(itv); ivtv_process_eeprom(itv);
...@@ -1150,7 +1144,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, ...@@ -1150,7 +1144,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
if (itv->options.radio > 0) if (itv->options.radio > 0)
itv->v4l2_cap |= V4L2_CAP_RADIO; itv->v4l2_cap |= V4L2_CAP_RADIO;
if (itv->options.tuner > -1 && itv->tunerid == 0) { if (itv->options.tuner > -1) {
struct tuner_setup setup; struct tuner_setup setup;
setup.addr = ADDR_UNSET; setup.addr = ADDR_UNSET;
......
...@@ -590,13 +590,13 @@ struct ivtv { ...@@ -590,13 +590,13 @@ struct ivtv {
struct pci_dev *dev; /* PCI device */ struct pci_dev *dev; /* PCI device */
const struct ivtv_card *card; /* card information */ const struct ivtv_card *card; /* card information */
const char *card_name; /* full name of the card */ const char *card_name; /* full name of the card */
const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
u8 has_cx23415; /* 1 if it is a cx23415 based card, 0 for cx23416 */ u8 has_cx23415; /* 1 if it is a cx23415 based card, 0 for cx23416 */
u8 pvr150_workaround; /* 1 if the cx25840 needs to workaround a PVR150 bug */ u8 pvr150_workaround; /* 1 if the cx25840 needs to workaround a PVR150 bug */
u8 nof_inputs; /* number of video inputs */ u8 nof_inputs; /* number of video inputs */
u8 nof_audio_inputs; /* number of audio inputs */ u8 nof_audio_inputs; /* number of audio inputs */
u32 v4l2_cap; /* V4L2 capabilities of card */ u32 v4l2_cap; /* V4L2 capabilities of card */
u32 hw_flags; /* hardware description of the board */ u32 hw_flags; /* hardware description of the board */
int tunerid; /* userspace tuner ID for experimental Xceive tuner support */
v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */ v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */
/* controlling video decoder function */ /* controlling video decoder function */
int (*video_dec_func)(struct ivtv *, unsigned int, void *); int (*video_dec_func)(struct ivtv *, unsigned int, void *);
......
...@@ -92,7 +92,8 @@ ...@@ -92,7 +92,8 @@
#define IVTV_TEA5767_I2C_ADDR 0x60 #define IVTV_TEA5767_I2C_ADDR 0x60
#define IVTV_UPD64031A_I2C_ADDR 0x12 #define IVTV_UPD64031A_I2C_ADDR 0x12
#define IVTV_UPD64083_I2C_ADDR 0x5c #define IVTV_UPD64083_I2C_ADDR 0x5c
#define IVTV_TDA985X_I2C_ADDR 0x5b #define IVTV_VP27SMPX_I2C_ADDR 0x5b
#define IVTV_M52790_I2C_ADDR 0x48
/* This array should match the IVTV_HW_ defines */ /* This array should match the IVTV_HW_ defines */
static const u8 hw_driverids[] = { static const u8 hw_driverids[] = {
...@@ -105,7 +106,6 @@ static const u8 hw_driverids[] = { ...@@ -105,7 +106,6 @@ static const u8 hw_driverids[] = {
I2C_DRIVERID_CS53L32A, I2C_DRIVERID_CS53L32A,
I2C_DRIVERID_TVEEPROM, I2C_DRIVERID_TVEEPROM,
I2C_DRIVERID_SAA711X, I2C_DRIVERID_SAA711X,
I2C_DRIVERID_TVAUDIO,
I2C_DRIVERID_UPD64031A, I2C_DRIVERID_UPD64031A,
I2C_DRIVERID_UPD64083, I2C_DRIVERID_UPD64083,
I2C_DRIVERID_SAA717X, I2C_DRIVERID_SAA717X,
...@@ -115,9 +115,29 @@ static const u8 hw_driverids[] = { ...@@ -115,9 +115,29 @@ static const u8 hw_driverids[] = {
0 /* IVTV_HW_GPIO dummy driver ID */ 0 /* IVTV_HW_GPIO dummy driver ID */
}; };
/* This array should match the IVTV_HW_ defines */
static const u8 hw_addrs[] = {
IVTV_CX25840_I2C_ADDR,
IVTV_SAA7115_I2C_ADDR,
IVTV_SAA7127_I2C_ADDR,
IVTV_MSP3400_I2C_ADDR,
0,
IVTV_WM8775_I2C_ADDR,
IVTV_CS53L32A_I2C_ADDR,
0,
IVTV_SAA7115_I2C_ADDR,
IVTV_UPD64031A_I2C_ADDR,
IVTV_UPD64083_I2C_ADDR,
IVTV_SAA717x_I2C_ADDR,
IVTV_WM8739_I2C_ADDR,
IVTV_VP27SMPX_I2C_ADDR,
IVTV_M52790_I2C_ADDR,
0 /* IVTV_HW_GPIO dummy driver ID */
};
/* This array should match the IVTV_HW_ defines */ /* This array should match the IVTV_HW_ defines */
static const char * const hw_drivernames[] = { static const char * const hw_drivernames[] = {
"cx2584x", "cx25840",
"saa7115", "saa7115",
"saa7127", "saa7127",
"msp3400", "msp3400",
...@@ -125,8 +145,7 @@ static const char * const hw_drivernames[] = { ...@@ -125,8 +145,7 @@ static const char * const hw_drivernames[] = {
"wm8775", "wm8775",
"cs53l32a", "cs53l32a",
"tveeprom", "tveeprom",
"saa7114", "saa7115",
"tvaudio",
"upd64031a", "upd64031a",
"upd64083", "upd64083",
"saa717x", "saa717x",
...@@ -136,21 +155,57 @@ static const char * const hw_drivernames[] = { ...@@ -136,21 +155,57 @@ static const char * const hw_drivernames[] = {
"gpio", "gpio",
}; };
static int attach_inform(struct i2c_client *client) int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
{ {
struct ivtv *itv = (struct ivtv *)i2c_get_adapdata(client->adapter); struct i2c_board_info info;
struct i2c_client *c;
u8 id;
int i; int i;
IVTV_DEBUG_I2C("i2c client attach\n"); IVTV_DEBUG_I2C("i2c client register\n");
for (i = 0; i < I2C_CLIENTS_MAX; i++) { if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
if (itv->i2c_clients[i] == NULL) { return -1;
itv->i2c_clients[i] = client; id = hw_driverids[idx];
break; memset(&info, 0, sizeof(info));
} strcpy(info.driver_name, hw_drivernames[idx]);
} info.addr = hw_addrs[idx];
for (i = 0; itv->i2c_clients[i] && i < I2C_CLIENTS_MAX; i++) {}
if (i == I2C_CLIENTS_MAX) { if (i == I2C_CLIENTS_MAX) {
IVTV_ERR("Insufficient room for new I2C client\n"); IVTV_ERR("insufficient room for new I2C client!\n");
return -ENOMEM;
} }
if (id != I2C_DRIVERID_TUNER) {
c = i2c_new_device(&itv->i2c_adap, &info);
if (c->driver == NULL)
i2c_unregister_device(c);
else
itv->i2c_clients[i] = c;
return itv->i2c_clients[i] ? 0 : -ENODEV;
}
/* special tuner handling */
c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->radio);
if (c && c->driver == NULL)
i2c_unregister_device(c);
else if (c)
itv->i2c_clients[i++] = c;
c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->demod);
if (c && c->driver == NULL)
i2c_unregister_device(c);
else if (c)
itv->i2c_clients[i++] = c;
c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->tv);
if (c && c->driver == NULL)
i2c_unregister_device(c);
else if (c)
itv->i2c_clients[i++] = c;
return 0;
}
static int attach_inform(struct i2c_client *client)
{
return 0; return 0;
} }
...@@ -478,9 +533,6 @@ static struct i2c_adapter ivtv_i2c_adap_hw_template = { ...@@ -478,9 +533,6 @@ static struct i2c_adapter ivtv_i2c_adap_hw_template = {
.client_register = attach_inform, .client_register = attach_inform,
.client_unregister = detach_inform, .client_unregister = detach_inform,
.owner = THIS_MODULE, .owner = THIS_MODULE,
#ifdef I2C_ADAP_CLASS_TV_ANALOG
.class = I2C_ADAP_CLASS_TV_ANALOG,
#endif
}; };
static void ivtv_setscl_old(void *data, int state) static void ivtv_setscl_old(void *data, int state)
...@@ -534,9 +586,6 @@ static struct i2c_adapter ivtv_i2c_adap_template = { ...@@ -534,9 +586,6 @@ static struct i2c_adapter ivtv_i2c_adap_template = {
.client_register = attach_inform, .client_register = attach_inform,
.client_unregister = detach_inform, .client_unregister = detach_inform,
.owner = THIS_MODULE, .owner = THIS_MODULE,
#ifdef I2C_ADAP_CLASS_TV_ANALOG
.class = I2C_ADAP_CLASS_TV_ANALOG,
#endif
}; };
static const struct i2c_algo_bit_data ivtv_i2c_algo_template = { static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
...@@ -561,12 +610,9 @@ int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg ...@@ -561,12 +610,9 @@ int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg
IVTV_DEBUG_I2C("call_i2c_client addr=%02x\n", addr); IVTV_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
for (i = 0; i < I2C_CLIENTS_MAX; i++) { for (i = 0; i < I2C_CLIENTS_MAX; i++) {
client = itv->i2c_clients[i]; client = itv->i2c_clients[i];
if (client == NULL) { if (client == NULL || client->driver == NULL ||
continue; client->driver->command == NULL)
}
if (client->driver->command == NULL) {
continue; continue;
}
if (addr == client->addr) { if (addr == client->addr) {
retval = client->driver->command(client, cmd, arg); retval = client->driver->command(client, cmd, arg);
return retval; return retval;
...@@ -587,7 +633,7 @@ static int ivtv_i2c_id_addr(struct ivtv *itv, u32 id) ...@@ -587,7 +633,7 @@ static int ivtv_i2c_id_addr(struct ivtv *itv, u32 id)
for (i = 0; i < I2C_CLIENTS_MAX; i++) { for (i = 0; i < I2C_CLIENTS_MAX; i++) {
client = itv->i2c_clients[i]; client = itv->i2c_clients[i];
if (client == NULL) if (client == NULL || client->driver == NULL)
continue; continue;
if (id == client->driver->id) { if (id == client->driver->id) {
retval = client->addr; retval = client->addr;
...@@ -713,6 +759,16 @@ int init_ivtv_i2c(struct ivtv *itv) ...@@ -713,6 +759,16 @@ int init_ivtv_i2c(struct ivtv *itv)
{ {
IVTV_DEBUG_I2C("i2c init\n"); IVTV_DEBUG_I2C("i2c init\n");
/* Sanity checks for the I2C hardware arrays. They must be the
* same size and GPIO must be the last entry.
*/
if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) ||
ARRAY_SIZE(hw_drivernames) != ARRAY_SIZE(hw_addrs) ||
IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1)) ||
hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
IVTV_ERR("Mismatched I2C hardware arrays\n");
return -ENODEV;
}
if (itv->options.newi2c > 0) { if (itv->options.newi2c > 0) {
memcpy(&itv->i2c_adap, &ivtv_i2c_adap_hw_template, memcpy(&itv->i2c_adap, &ivtv_i2c_adap_hw_template,
sizeof(struct i2c_adapter)); sizeof(struct i2c_adapter));
......
...@@ -33,6 +33,7 @@ int ivtv_i2c_hw(struct ivtv *itv, u32 hw, unsigned int cmd, void *arg); ...@@ -33,6 +33,7 @@ int ivtv_i2c_hw(struct ivtv *itv, u32 hw, unsigned int cmd, void *arg);
int ivtv_i2c_id(struct ivtv *itv, u32 id, unsigned int cmd, void *arg); int ivtv_i2c_id(struct ivtv *itv, u32 id, unsigned int cmd, void *arg);
int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg); int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg);
void ivtv_call_i2c_clients(struct ivtv *itv, unsigned int cmd, void *arg); void ivtv_call_i2c_clients(struct ivtv *itv, unsigned int cmd, void *arg);
int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
/* init + register i2c algo-bit adapter */ /* init + register i2c algo-bit adapter */
int init_ivtv_i2c(struct ivtv *itv); int init_ivtv_i2c(struct ivtv *itv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment