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

[media] cx23885: add support for ViewCast 260e and 460e

Add support for these two new cards.

Based upon Devin's initial patch made for an older kernel which I
cleaned up and rebased. Thanks to Kernel Labs for that work.
Signed-off-by: default avatarDevin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent fc279cc2
...@@ -10,6 +10,7 @@ config VIDEO_CX23885 ...@@ -10,6 +10,7 @@ config VIDEO_CX23885
select VIDEOBUF2_DMA_SG select VIDEOBUF2_DMA_SG
select VIDEO_CX25840 select VIDEO_CX25840
select VIDEO_CX2341X select VIDEO_CX2341X
select VIDEO_CS3308
select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT
select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
......
...@@ -715,6 +715,56 @@ struct cx23885_board cx23885_boards[] = { ...@@ -715,6 +715,56 @@ struct cx23885_board cx23885_boards[] = {
.portb = CX23885_MPEG_DVB, .portb = CX23885_MPEG_DVB,
.portc = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB,
}, },
[CX23885_BOARD_VIEWCAST_260E] = {
.name = "ViewCast 260e",
.porta = CX23885_ANALOG_VIDEO,
.force_bff = 1,
.input = {{
.type = CX23885_VMUX_COMPOSITE1,
.vmux = CX25840_VIN6_CH1,
.amux = CX25840_AUDIO7,
}, {
.type = CX23885_VMUX_SVIDEO,
.vmux = CX25840_VIN7_CH3 |
CX25840_VIN5_CH1 |
CX25840_SVIDEO_ON,
.amux = CX25840_AUDIO7,
}, {
.type = CX23885_VMUX_COMPONENT,
.vmux = CX25840_VIN7_CH3 |
CX25840_VIN6_CH2 |
CX25840_VIN5_CH1 |
CX25840_COMPONENT_ON,
.amux = CX25840_AUDIO7,
} },
},
[CX23885_BOARD_VIEWCAST_460E] = {
.name = "ViewCast 460e",
.porta = CX23885_ANALOG_VIDEO,
.force_bff = 1,
.input = {{
.type = CX23885_VMUX_COMPOSITE1,
.vmux = CX25840_VIN4_CH1,
.amux = CX25840_AUDIO7,
}, {
.type = CX23885_VMUX_SVIDEO,
.vmux = CX25840_VIN7_CH3 |
CX25840_VIN6_CH1 |
CX25840_SVIDEO_ON,
.amux = CX25840_AUDIO7,
}, {
.type = CX23885_VMUX_COMPONENT,
.vmux = CX25840_VIN7_CH3 |
CX25840_VIN6_CH1 |
CX25840_VIN5_CH2 |
CX25840_COMPONENT_ON,
.amux = CX25840_AUDIO7,
}, {
.type = CX23885_VMUX_COMPOSITE2,
.vmux = CX25840_VIN6_CH1,
.amux = CX25840_AUDIO7,
} },
},
}; };
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
...@@ -1002,6 +1052,14 @@ struct cx23885_subid cx23885_subids[] = { ...@@ -1002,6 +1052,14 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x0070, .subvendor = 0x0070,
.subdevice = 0xf038, .subdevice = 0xf038,
.card = CX23885_BOARD_HAUPPAUGE_HVR5525, .card = CX23885_BOARD_HAUPPAUGE_HVR5525,
}, {
.subvendor = 0x1576,
.subdevice = 0x0260,
.card = CX23885_BOARD_VIEWCAST_260E,
}, {
.subvendor = 0x1576,
.subdevice = 0x0460,
.card = CX23885_BOARD_VIEWCAST_460E,
}, },
}; };
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
...@@ -1034,6 +1092,28 @@ void cx23885_card_list(struct cx23885_dev *dev) ...@@ -1034,6 +1092,28 @@ void cx23885_card_list(struct cx23885_dev *dev)
dev->name, i, cx23885_boards[i].name); dev->name, i, cx23885_boards[i].name);
} }
static void viewcast_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
{
u32 sn;
/* The serial number record begins with tag 0x59 */
if (*(eeprom_data + 0x00) != 0x59) {
pr_info("%s() eeprom records are undefined, no serial number\n",
__func__);
return;
}
sn = (*(eeprom_data + 0x06) << 24) |
(*(eeprom_data + 0x05) << 16) |
(*(eeprom_data + 0x04) << 8) |
(*(eeprom_data + 0x03));
pr_info("%s: card '%s' sn# MM%d\n",
dev->name,
cx23885_boards[dev->board].name,
sn);
}
static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
{ {
struct tveeprom tv; struct tveeprom tv;
...@@ -1671,6 +1751,12 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) ...@@ -1671,6 +1751,12 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
cx23885_gpio_set(dev, GPIO_8 | GPIO_9); cx23885_gpio_set(dev, GPIO_8 | GPIO_9);
msleep(100); msleep(100);
break; break;
case CX23885_BOARD_VIEWCAST_260E:
case CX23885_BOARD_VIEWCAST_460E:
/* For documentation purposes, it's worth noting that this
* card does not have any GPIO's connected to subcomponents.
*/
break;
} }
} }
...@@ -1917,6 +2003,14 @@ void cx23885_card_setup(struct cx23885_dev *dev) ...@@ -1917,6 +2003,14 @@ void cx23885_card_setup(struct cx23885_dev *dev)
if (dev->i2c_bus[0].i2c_rc == 0) if (dev->i2c_bus[0].i2c_rc == 0)
hauppauge_eeprom(dev, eeprom+0xc0); hauppauge_eeprom(dev, eeprom+0xc0);
break; break;
case CX23885_BOARD_VIEWCAST_260E:
case CX23885_BOARD_VIEWCAST_460E:
dev->i2c_bus[1].i2c_client.addr = 0xa0 >> 1;
tveeprom_read(&dev->i2c_bus[1].i2c_client,
eeprom, sizeof(eeprom));
if (dev->i2c_bus[0].i2c_rc == 0)
viewcast_eeprom(dev, eeprom);
break;
} }
switch (dev->board) { switch (dev->board) {
...@@ -2120,6 +2214,8 @@ void cx23885_card_setup(struct cx23885_dev *dev) ...@@ -2120,6 +2214,8 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_DVBSKY_S950: case CX23885_BOARD_DVBSKY_S950:
case CX23885_BOARD_DVBSKY_S952: case CX23885_BOARD_DVBSKY_S952:
case CX23885_BOARD_DVBSKY_T982: case CX23885_BOARD_DVBSKY_T982:
case CX23885_BOARD_VIEWCAST_260E:
case CX23885_BOARD_VIEWCAST_460E:
dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[2].i2c_adap, &dev->i2c_bus[2].i2c_adap,
"cx25840", 0x88 >> 1, NULL); "cx25840", 0x88 >> 1, NULL);
...@@ -2130,6 +2226,24 @@ void cx23885_card_setup(struct cx23885_dev *dev) ...@@ -2130,6 +2226,24 @@ void cx23885_card_setup(struct cx23885_dev *dev)
break; break;
} }
switch (dev->board) {
case CX23885_BOARD_VIEWCAST_260E:
v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[0].i2c_adap,
"cs3308", 0x82 >> 1, NULL);
break;
case CX23885_BOARD_VIEWCAST_460E:
/* This cs3308 controls the audio from the breakout cable */
v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[0].i2c_adap,
"cs3308", 0x80 >> 1, NULL);
/* This cs3308 controls the audio from the onboard header */
v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[0].i2c_adap,
"cs3308", 0x82 >> 1, NULL);
break;
}
/* AUX-PLL 27MHz CLK */ /* AUX-PLL 27MHz CLK */
switch (dev->board) { switch (dev->board) {
case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
......
...@@ -968,6 +968,16 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) ...@@ -968,6 +968,16 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
call_all(dev, core, s_power, 0); call_all(dev, core, s_power, 0);
cx23885_ir_init(dev); cx23885_ir_init(dev);
if (dev->board == CX23885_BOARD_VIEWCAST_460E) {
/*
* GPIOs 9/8 are input detection bits for the breakout video
* (gpio 8) and audio (gpio 9) cables. When they're attached,
* this gpios are pulled high. Make sure these GPIOs are marked
* as inputs.
*/
cx23885_gpio_enable(dev, 0x300, 0);
}
if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
if (cx23885_video_register(dev) < 0) { if (cx23885_video_register(dev) < 0) {
printk(KERN_ERR "%s() Failed to register analog " printk(KERN_ERR "%s() Failed to register analog "
......
...@@ -279,6 +279,8 @@ static char *i2c_devs[128] = { ...@@ -279,6 +279,8 @@ static char *i2c_devs[128] = {
[0x10 >> 1] = "tda10048", [0x10 >> 1] = "tda10048",
[0x12 >> 1] = "dib7000pc", [0x12 >> 1] = "dib7000pc",
[0x1c >> 1] = "lgdt3303", [0x1c >> 1] = "lgdt3303",
[0x80 >> 1] = "cs3308",
[0x82 >> 1] = "cs3308",
[0x86 >> 1] = "tda9887", [0x86 >> 1] = "tda9887",
[0x32 >> 1] = "cx24227", [0x32 >> 1] = "cx24227",
[0x88 >> 1] = "cx25837", [0x88 >> 1] = "cx25837",
......
...@@ -263,7 +263,9 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) ...@@ -263,7 +263,9 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) ||
(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) ||
(dev->board == CX23885_BOARD_MYGICA_X8507) || (dev->board == CX23885_BOARD_MYGICA_X8507) ||
(dev->board == CX23885_BOARD_AVERMEDIA_HC81R)) { (dev->board == CX23885_BOARD_AVERMEDIA_HC81R) ||
(dev->board == CX23885_BOARD_VIEWCAST_260E) ||
(dev->board == CX23885_BOARD_VIEWCAST_460E)) {
/* Configure audio routing */ /* Configure audio routing */
v4l2_subdev_call(dev->sd_cx25840, audio, s_routing, v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
INPUT(input)->amux, 0, 0); INPUT(input)->amux, 0, 0);
......
...@@ -101,6 +101,8 @@ ...@@ -101,6 +101,8 @@
#define CX23885_BOARD_DVBSKY_T982 51 #define CX23885_BOARD_DVBSKY_T982 51
#define CX23885_BOARD_HAUPPAUGE_HVR5525 52 #define CX23885_BOARD_HAUPPAUGE_HVR5525 52
#define CX23885_BOARD_HAUPPAUGE_STARBURST 53 #define CX23885_BOARD_HAUPPAUGE_STARBURST 53
#define CX23885_BOARD_VIEWCAST_260E 54
#define CX23885_BOARD_VIEWCAST_460E 55
#define GPIO_0 0x00000001 #define GPIO_0 0x00000001
#define GPIO_1 0x00000002 #define GPIO_1 0x00000002
......
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