V4L/DVB (8089): cx18: add support for Conexant Raptor PAL/SECAM card

Patch provided courtesy of Conexant http://www.conexant.com.

Signed-off-by: Srinivasa Deevi <srinivasa.deevi@conexant.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
Sri Deevi 2008-06-21 11:06:44 -03:00 committed by Mauro Carvalho Chehab
parent 464e9f3a0c
commit 03c2808503
7 changed files with 122 additions and 3 deletions

View File

@ -27,6 +27,8 @@
#include "cx18-i2c.h"
#include <media/cs5345.h>
#define V4L2_STD_NOT_MN (V4L2_STD_PAL|V4L2_STD_SECAM)
/********************** card configuration *******************************/
/* usual i2c tuner addresses to probe */
@ -232,11 +234,64 @@ static const struct cx18_card cx18_card_mpc718 = {
.i2c = &cx18_i2c_std,
};
/* ------------------------------------------------------------------------- */
/* Conexant Raptor PAL/SECAM: note that this card is analog only! */
static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
{ PCI_DEVICE_ID_CX23418, CX18_PCI_ID_CONEXANT, 0x0009 },
{ 0, 0, 0 }
};
static const struct cx18_card cx18_card_cnxt_raptor_pal = {
.type = CX18_CARD_CNXT_RAPTOR_PAL,
.name = "Conexant Raptor PAL/SECAM",
.comment = "VBI is not yet supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_muxer = CX18_HW_GPIO,
.hw_all = CX18_HW_TUNER | CX18_HW_GPIO,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
{ CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
{ CX18_CARD_INPUT_SVIDEO2, 2,
CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
{ CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
},
.audio_inputs = {
{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 1 },
{ CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 0 },
{ CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 },
},
.tuners = {
{ .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
},
.ddr = {
/* MT 46V16M16 memory */
.chip_config = 0x50306,
.refresh = 0x753,
.timing1 = 0x33220953,
.timing2 = 0x09,
.tune_lane = 0,
.initial_emrs = 0,
},
.gpio_init.initial_value = 0x02,
.gpio_init.direction = 0x02,
.gpio_audio_input = { .mask = 0x02, .tuner = 0x02, .linein = 0x00 },
.pci_list = cx18_pci_cnxt_raptor_pal,
.i2c = &cx18_i2c_std,
};
/* ------------------------------------------------------------------------- */
static const struct cx18_card *cx18_card_list[] = {
&cx18_card_hvr1600_esmt,
&cx18_card_hvr1600_samsung,
&cx18_card_h900,
&cx18_card_mpc718,
&cx18_card_cnxt_raptor_pal,
};
const struct cx18_card *cx18_get_card(u16 index)

View File

@ -85,6 +85,13 @@ struct cx18_gpio_i2c_slave_reset {
int msecs_recovery; /* time after deassert for chips to be ready */
};
struct ivtv_gpio_audio_input { /* select tuner/line in input */
u32 mask; /* leave to 0 if not supported */
u32 tuner;
u32 linein;
u32 radio;
};
struct cx18_card_tuner {
v4l2_std_id std; /* standard for which the tuner is suitable */
int tuner; /* tuner ID (from tuner.h) */
@ -123,6 +130,7 @@ struct cx18_card {
u8 xceive_pin; /* XCeive tuner GPIO reset pin */
struct cx18_gpio_init gpio_init;
struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
struct ivtv_gpio_audio_input gpio_audio_input;
struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
struct cx18_card_tuner_i2c *i2c;

View File

@ -120,6 +120,7 @@ MODULE_PARM_DESC(cardtype,
"\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n"
"\t\t\t 3 = Compro VideoMate H900\n"
"\t\t\t 4 = Yuan MPC718\n"
"\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
"\t\t\t 0 = Autodetect (default)\n"
"\t\t\t-1 = Ignore this card\n\t\t");
MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@ -435,7 +436,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
(cx->params.video_temporal_filter_mode << 1) |
(cx->params.video_median_filter_type << 2);
cx->params.port = CX2341X_PORT_MEMORY;
cx->params.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
cx->params.capabilities = 0;
init_waitqueue_head(&cx->cap_w);
init_waitqueue_head(&cx->mb_apu_waitq);
init_waitqueue_head(&cx->mb_cpu_waitq);

View File

@ -75,7 +75,8 @@
#define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */
#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
#define CX18_CARD_LAST 3
#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
#define CX18_CARD_LAST 4
#define CX18_ENC_STREAM_TYPE_MPG 0
#define CX18_ENC_STREAM_TYPE_TS 1
@ -94,6 +95,7 @@
#define CX18_PCI_ID_HAUPPAUGE 0x0070
#define CX18_PCI_ID_COMPRO 0x185b
#define CX18_PCI_ID_YUAN 0x12ab
#define CX18_PCI_ID_CONEXANT 0x14f1
/* ======================================================================== */
/* ========================== START USER SETTABLE DMA VARIABLES =========== */

View File

@ -122,3 +122,37 @@ int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
schedule_timeout_interruptible(msecs_to_jiffies(1));
return 0;
}
int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg)
{
struct v4l2_routing *route = arg;
u32 mask, data;
switch (command) {
case VIDIOC_INT_S_AUDIO_ROUTING:
if (route->input > 2)
return -EINVAL;
mask = cx->card->gpio_audio_input.mask;
switch (route->input) {
case 0:
data = cx->card->gpio_audio_input.tuner;
break;
case 1:
data = cx->card->gpio_audio_input.linein;
break;
case 2:
default:
data = cx->card->gpio_audio_input.radio;
break;
}
break;
default:
return -EINVAL;
}
if (mask) {
cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
gpio_write(cx);
}
return 0;
}

View File

@ -23,3 +23,4 @@
void cx18_gpio_init(struct cx18 *cx);
void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
int cx18_reset_tuner_gpio(void *dev, int cmd, int value);
int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg);

View File

@ -311,8 +311,12 @@ int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
{
int addr;
if (hw == CX18_HW_GPIO || hw == 0)
if (hw == 0)
return 0;
if (hw == CX18_HW_GPIO)
return cx18_gpio(cx, cmd, arg);
if (hw == CX18_HW_CX23418)
return cx18_av_cmd(cx, cmd, arg);
@ -350,6 +354,8 @@ void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg)
cx18_av_cmd(cx, cmd, arg);
i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
if (cx->hw_flags & CX18_HW_GPIO)
cx18_gpio(cx, cmd, arg);
}
/* init + register i2c algo-bit adapter */
@ -358,6 +364,18 @@ int init_cx18_i2c(struct cx18 *cx)
int i;
CX18_DEBUG_I2C("i2c init\n");
/* Sanity checks for the I2C hardware arrays. They must be the
* same size and GPIO/CX23418 must be the last entries.
*/
if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) ||
ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) ||
CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) ||
hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
CX18_ERR("Mismatched I2C hardware arrays\n");
return -ENODEV;
}
for (i = 0; i < 2; i++) {
memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
sizeof(struct i2c_adapter));