aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx23885
diff options
context:
space:
mode:
authorSteven Toth <stoth@kernellabs.com>2012-01-04 19:08:35 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-01-05 03:52:02 -0500
commit350451375d6d8e9b124eacad67e221a0fdff0ac9 (patch)
tree321a0535ef3f78804be28aa3b07e183014dd0c12 /drivers/media/video/cx23885
parentadddf86b4cf545b82e422a9897a377d7e55b50ee (diff)
[media] cx23885: Hauppauge HVR1850 Analog driver support
First in a series of patches that adds support to the cx23885 driver for CX23888 analog video handling. Raw and MPEG video support is being added for the HVR1850 driver in the patch, and the following series of patches. Some basic cx23885 driver cleanup. Partly to add HVR1850 support and partly to allow -417.c V4L2 calls to be routed through thr driver core and handled in a single place. Make a number of core driver functions available to the -417.c driver to streamline the driver. Add the analog tuner ops definition so we can reach/tune the hardware when we need to. Added the tff field so 888 based cards (which have a weird field ordering issue) can be accomodated and worked around in the driver. Signed-off-by: Steven Toth <stoth@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx23885')
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c28
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c24
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c14
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c153
-rw-r--r--drivers/media/video/cx23885/cx23885.h12
5 files changed, 197 insertions, 34 deletions
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index ac03c26d7a63..dc7864eb6b37 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -335,8 +335,33 @@ struct cx23885_board cx23885_boards[] = {
335 }, 335 },
336 [CX23885_BOARD_HAUPPAUGE_HVR1850] = { 336 [CX23885_BOARD_HAUPPAUGE_HVR1850] = {
337 .name = "Hauppauge WinTV-HVR1850", 337 .name = "Hauppauge WinTV-HVR1850",
338 .porta = CX23885_ANALOG_VIDEO,
338 .portb = CX23885_MPEG_ENCODER, 339 .portb = CX23885_MPEG_ENCODER,
339 .portc = CX23885_MPEG_DVB, 340 .portc = CX23885_MPEG_DVB,
341 .tuner_type = TUNER_ABSENT,
342 .tuner_addr = 0x42, /* 0x84 >> 1 */
343 .force_bff = 1,
344 .input = {{
345 .type = CX23885_VMUX_TELEVISION,
346 .vmux = CX25840_VIN7_CH3 |
347 CX25840_VIN5_CH2 |
348 CX25840_VIN2_CH1 |
349 CX25840_DIF_ON,
350 .amux = CX25840_AUDIO8,
351 }, {
352 .type = CX23885_VMUX_COMPOSITE1,
353 .vmux = CX25840_VIN7_CH3 |
354 CX25840_VIN4_CH2 |
355 CX25840_VIN6_CH1,
356 .amux = CX25840_AUDIO7,
357 }, {
358 .type = CX23885_VMUX_SVIDEO,
359 .vmux = CX25840_VIN7_CH3 |
360 CX25840_VIN4_CH2 |
361 CX25840_VIN8_CH1 |
362 CX25840_SVIDEO_ON,
363 .amux = CX25840_AUDIO7,
364 } },
340 }, 365 },
341 [CX23885_BOARD_COMPRO_VIDEOMATE_E800] = { 366 [CX23885_BOARD_COMPRO_VIDEOMATE_E800] = {
342 .name = "Compro VideoMate E800", 367 .name = "Compro VideoMate E800",
@@ -1402,6 +1427,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1402 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1427 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1403 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1428 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1404 break; 1429 break;
1430 case CX23885_BOARD_HAUPPAUGE_HVR1850:
1405 case CX23885_BOARD_HAUPPAUGE_HVR1800: 1431 case CX23885_BOARD_HAUPPAUGE_HVR1800:
1406 /* Defaults for VID B - Analog encoder */ 1432 /* Defaults for VID B - Analog encoder */
1407 /* DREQ_POL, SMODE, PUNC_CLK, MCLK_POL Serial bus + punc clk */ 1433 /* DREQ_POL, SMODE, PUNC_CLK, MCLK_POL Serial bus + punc clk */
@@ -1412,6 +1438,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1412 /* APB_TSVALERR_POL (active low)*/ 1438 /* APB_TSVALERR_POL (active low)*/
1413 ts1->vld_misc_val = 0x2000; 1439 ts1->vld_misc_val = 0x2000;
1414 ts1->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4 | 0xc); 1440 ts1->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4 | 0xc);
1441 cx_write(0x130184, 0xc);
1415 1442
1416 /* Defaults for VID C */ 1443 /* Defaults for VID C */
1417 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 1444 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
@@ -1466,7 +1493,6 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1466 case CX23885_BOARD_HAUPPAUGE_HVR1275: 1493 case CX23885_BOARD_HAUPPAUGE_HVR1275:
1467 case CX23885_BOARD_HAUPPAUGE_HVR1255: 1494 case CX23885_BOARD_HAUPPAUGE_HVR1255:
1468 case CX23885_BOARD_HAUPPAUGE_HVR1210: 1495 case CX23885_BOARD_HAUPPAUGE_HVR1210:
1469 case CX23885_BOARD_HAUPPAUGE_HVR1850:
1470 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 1496 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
1471 case CX23885_BOARD_HAUPPAUGE_HVR1290: 1497 case CX23885_BOARD_HAUPPAUGE_HVR1290:
1472 case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: 1498 case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 40e68b22015e..6ad227029a0f 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -206,12 +206,12 @@ static struct sram_channel cx23887_sram_channels[] = {
206 .cnt2_reg = DMA1_CNT2, 206 .cnt2_reg = DMA1_CNT2,
207 }, 207 },
208 [SRAM_CH02] = { 208 [SRAM_CH02] = {
209 .name = "ch2", 209 .name = "VID A (VBI)",
210 .cmds_start = 0x0, 210 .cmds_start = 0x10050,
211 .ctrl_start = 0x0, 211 .ctrl_start = 0x105F0,
212 .cdt = 0x0, 212 .cdt = 0x10810,
213 .fifo_start = 0x0, 213 .fifo_start = 0x3000,
214 .fifo_size = 0x0, 214 .fifo_size = 0x1000,
215 .ptr1_reg = DMA2_PTR1, 215 .ptr1_reg = DMA2_PTR1,
216 .ptr2_reg = DMA2_PTR2, 216 .ptr2_reg = DMA2_PTR2,
217 .cnt1_reg = DMA2_CNT1, 217 .cnt1_reg = DMA2_CNT1,
@@ -266,12 +266,12 @@ static struct sram_channel cx23887_sram_channels[] = {
266 .cnt2_reg = DMA5_CNT2, 266 .cnt2_reg = DMA5_CNT2,
267 }, 267 },
268 [SRAM_CH07] = { 268 [SRAM_CH07] = {
269 .name = "ch7", 269 .name = "TV Audio",
270 .cmds_start = 0x0, 270 .cmds_start = 0x10190,
271 .ctrl_start = 0x0, 271 .ctrl_start = 0x106B0,
272 .cdt = 0x0, 272 .cdt = 0x10930,
273 .fifo_start = 0x0, 273 .fifo_start = 0x7000,
274 .fifo_size = 0x0, 274 .fifo_size = 0x1000,
275 .ptr1_reg = DMA6_PTR1, 275 .ptr1_reg = DMA6_PTR1,
276 .ptr2_reg = DMA6_PTR2, 276 .ptr2_reg = DMA6_PTR2,
277 .cnt1_reg = DMA6_CNT1, 277 .cnt1_reg = DMA6_CNT1,
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 28d51d89748e..a3906225c493 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -1026,6 +1026,20 @@ static int dvb_register(struct cx23885_tsport *port)
1026 } 1026 }
1027 break; 1027 break;
1028 case CX23885_BOARD_HAUPPAUGE_HVR1850: 1028 case CX23885_BOARD_HAUPPAUGE_HVR1850:
1029 i2c_bus = &dev->i2c_bus[0];
1030 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1031 &hcw_s5h1411_config,
1032 &i2c_bus->i2c_adap);
1033 if (fe0->dvb.frontend != NULL)
1034 dvb_attach(tda18271_attach, fe0->dvb.frontend,
1035 0x60, &dev->i2c_bus[0].i2c_adap,
1036 &hauppauge_tda18271_config);
1037
1038 tda18271_attach(&dev->ts1.analog_fe,
1039 0x60, &dev->i2c_bus[1].i2c_adap,
1040 &hauppauge_tda18271_config);
1041
1042 break;
1029 case CX23885_BOARD_HAUPPAUGE_HVR1290: 1043 case CX23885_BOARD_HAUPPAUGE_HVR1290:
1030 i2c_bus = &dev->i2c_bus[0]; 1044 i2c_bus = &dev->i2c_bus[0];
1031 fe0->dvb.frontend = dvb_attach(s5h1411_attach, 1045 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 7f3b973081a0..e85412daa6dc 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -316,7 +316,7 @@ void cx23885_video_wakeup(struct cx23885_dev *dev,
316 __func__, bc); 316 __func__, bc);
317} 317}
318 318
319static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) 319int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
320{ 320{
321 dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", 321 dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
322 __func__, 322 __func__,
@@ -504,7 +504,8 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
504 INPUT(input)->vmux, 0, 0); 504 INPUT(input)->vmux, 0, 0);
505 505
506 if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1800) || 506 if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1800) ||
507 (dev->board == CX23885_BOARD_MPX885)) { 507 (dev->board == CX23885_BOARD_MPX885) ||
508 (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850)) {
508 /* Configure audio routing */ 509 /* Configure audio routing */
509 v4l2_subdev_call(dev->sd_cx25840, audio, s_routing, 510 v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
510 INPUT(input)->amux, 0, 0); 511 INPUT(input)->amux, 0, 0);
@@ -650,6 +651,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
650 int rc, init_buffer = 0; 651 int rc, init_buffer = 0;
651 u32 line0_offset, line1_offset; 652 u32 line0_offset, line1_offset;
652 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); 653 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
654 int field_tff;
653 655
654 BUG_ON(NULL == fh->fmt); 656 BUG_ON(NULL == fh->fmt);
655 if (fh->width < 48 || fh->width > norm_maxw(dev->tvnorm) || 657 if (fh->width < 48 || fh->width > norm_maxw(dev->tvnorm) ||
@@ -691,15 +693,25 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
691 buf->bpl, 0, buf->vb.height); 693 buf->bpl, 0, buf->vb.height);
692 break; 694 break;
693 case V4L2_FIELD_INTERLACED: 695 case V4L2_FIELD_INTERLACED:
694 if (dev->tvnorm & V4L2_STD_NTSC) { 696 if (dev->tvnorm & V4L2_STD_NTSC)
697 /* NTSC or */
698 field_tff = 1;
699 else
700 field_tff = 0;
701
702 if (cx23885_boards[dev->board].force_bff)
703 /* PAL / SECAM OR 888 in NTSC MODE */
704 field_tff = 0;
705
706 if (field_tff) {
695 /* cx25840 transmits NTSC bottom field first */ 707 /* cx25840 transmits NTSC bottom field first */
696 dprintk(1, "%s() Creating NTSC risc\n", 708 dprintk(1, "%s() Creating TFF/NTSC risc\n",
697 __func__); 709 __func__);
698 line0_offset = buf->bpl; 710 line0_offset = buf->bpl;
699 line1_offset = 0; 711 line1_offset = 0;
700 } else { 712 } else {
701 /* All other formats are top field first */ 713 /* All other formats are top field first */
702 dprintk(1, "%s() Creating PAL/SECAM risc\n", 714 dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n",
703 __func__); 715 __func__);
704 line0_offset = 0; 716 line0_offset = 0;
705 line1_offset = buf->bpl; 717 line1_offset = buf->bpl;
@@ -982,6 +994,8 @@ static int video_release(struct file *file)
982 } 994 }
983 995
984 videobuf_mmap_free(&fh->vidq); 996 videobuf_mmap_free(&fh->vidq);
997 videobuf_mmap_free(&fh->vbiq);
998
985 file->private_data = NULL; 999 file->private_data = NULL;
986 kfree(fh); 1000 kfree(fh);
987 1001
@@ -1003,7 +1017,7 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma)
1003/* ------------------------------------------------------------------ */ 1017/* ------------------------------------------------------------------ */
1004/* VIDEO CTRL IOCTLS */ 1018/* VIDEO CTRL IOCTLS */
1005 1019
1006static int cx23885_get_control(struct cx23885_dev *dev, 1020int cx23885_get_control(struct cx23885_dev *dev,
1007 struct v4l2_control *ctl) 1021 struct v4l2_control *ctl)
1008{ 1022{
1009 dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); 1023 dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
@@ -1011,7 +1025,7 @@ static int cx23885_get_control(struct cx23885_dev *dev,
1011 return 0; 1025 return 0;
1012} 1026}
1013 1027
1014static int cx23885_set_control(struct cx23885_dev *dev, 1028int cx23885_set_control(struct cx23885_dev *dev,
1015 struct v4l2_control *ctl) 1029 struct v4l2_control *ctl)
1016{ 1030{
1017 dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)\n", __func__); 1031 dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)\n", __func__);
@@ -1230,6 +1244,16 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1230 return 0; 1244 return 0;
1231} 1245}
1232 1246
1247static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
1248{
1249 struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
1250 dprintk(1, "%s()\n", __func__);
1251
1252 call_all(dev, core, g_std, id);
1253
1254 return 0;
1255}
1256
1233static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms) 1257static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms)
1234{ 1258{
1235 struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; 1259 struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
@@ -1242,7 +1266,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms)
1242 return 0; 1266 return 0;
1243} 1267}
1244 1268
1245static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) 1269int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
1246{ 1270{
1247 static const char *iname[] = { 1271 static const char *iname[] = {
1248 [CX23885_VMUX_COMPOSITE1] = "Composite1", 1272 [CX23885_VMUX_COMPOSITE1] = "Composite1",
@@ -1290,7 +1314,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
1290 return cx23885_enum_input(dev, i); 1314 return cx23885_enum_input(dev, i);
1291} 1315}
1292 1316
1293static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) 1317int cx23885_get_input(struct file *file, void *priv, unsigned int *i)
1294{ 1318{
1295 struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; 1319 struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
1296 1320
@@ -1299,7 +1323,12 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1299 return 0; 1323 return 0;
1300} 1324}
1301 1325
1302static int vidioc_s_input(struct file *file, void *priv, unsigned int i) 1326static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1327{
1328 return cx23885_get_input(file, priv, i);
1329}
1330
1331int cx23885_set_input(struct file *file, void *priv, unsigned int i)
1303{ 1332{
1304 struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; 1333 struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
1305 1334
@@ -1323,6 +1352,11 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1323 return 0; 1352 return 0;
1324} 1353}
1325 1354
1355static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1356{
1357 return cx23885_set_input(file, priv, i);
1358}
1359
1326static int vidioc_log_status(struct file *file, void *priv) 1360static int vidioc_log_status(struct file *file, void *priv)
1327{ 1361{
1328 struct cx23885_fh *fh = priv; 1362 struct cx23885_fh *fh = priv;
@@ -1330,11 +1364,11 @@ static int vidioc_log_status(struct file *file, void *priv)
1330 1364
1331 printk(KERN_INFO 1365 printk(KERN_INFO
1332 "%s/0: ============ START LOG STATUS ============\n", 1366 "%s/0: ============ START LOG STATUS ============\n",
1333 dev->name); 1367 dev->name);
1334 call_all(dev, core, log_status); 1368 call_all(dev, core, log_status);
1335 printk(KERN_INFO 1369 printk(KERN_INFO
1336 "%s/0: ============= END LOG STATUS =============\n", 1370 "%s/0: ============= END LOG STATUS =============\n",
1337 dev->name); 1371 dev->name);
1338 return 0; 1372 return 0;
1339} 1373}
1340 1374
@@ -1472,6 +1506,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
1472 1506
1473static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f) 1507static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f)
1474{ 1508{
1509 struct v4l2_control ctrl;
1510
1475 if (unlikely(UNSET == dev->tuner_type)) 1511 if (unlikely(UNSET == dev->tuner_type))
1476 return -EINVAL; 1512 return -EINVAL;
1477 if (unlikely(f->tuner != 0)) 1513 if (unlikely(f->tuner != 0))
@@ -1480,29 +1516,102 @@ static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f)
1480 mutex_lock(&dev->lock); 1516 mutex_lock(&dev->lock);
1481 dev->freq = f->frequency; 1517 dev->freq = f->frequency;
1482 1518
1519 /* I need to mute audio here */
1520 ctrl.id = V4L2_CID_AUDIO_MUTE;
1521 ctrl.value = 1;
1522 cx23885_set_control(dev, &ctrl);
1523
1483 call_all(dev, tuner, s_frequency, f); 1524 call_all(dev, tuner, s_frequency, f);
1484 1525
1485 /* When changing channels it is required to reset TVAUDIO */ 1526 /* When changing channels it is required to reset TVAUDIO */
1486 msleep(10); 1527 msleep(100);
1528
1529 /* I need to unmute audio here */
1530 ctrl.value = 0;
1531 cx23885_set_control(dev, &ctrl);
1487 1532
1488 mutex_unlock(&dev->lock); 1533 mutex_unlock(&dev->lock);
1489 1534
1490 return 0; 1535 return 0;
1491} 1536}
1492 1537
1493static int vidioc_s_frequency(struct file *file, void *priv, 1538static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
1494 struct v4l2_frequency *f) 1539 struct v4l2_frequency *f)
1540{
1541 struct v4l2_control ctrl;
1542 struct videobuf_dvb_frontend *vfe;
1543 struct dvb_frontend *fe;
1544 int err = 0;
1545
1546 struct analog_parameters params = {
1547 .mode = V4L2_TUNER_ANALOG_TV,
1548 .audmode = V4L2_TUNER_MODE_STEREO,
1549 .std = dev->tvnorm,
1550 .frequency = f->frequency
1551 };
1552
1553 mutex_lock(&dev->lock);
1554 dev->freq = f->frequency;
1555
1556 /* I need to mute audio here */
1557 ctrl.id = V4L2_CID_AUDIO_MUTE;
1558 ctrl.value = 1;
1559 cx23885_set_control(dev, &ctrl);
1560
1561 /* If HVR1850 */
1562 dprintk(1, "%s() frequency=%d tuner=%d std=0x%llx\n", __func__,
1563 params.frequency, f->tuner, params.std);
1564
1565 vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1);
1566 if (!vfe)
1567 err = -EINVAL;
1568
1569 fe = vfe->dvb.frontend;
1570
1571 if (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850)
1572 fe = &dev->ts1.analog_fe;
1573
1574 if (fe && fe->ops.tuner_ops.set_analog_params) {
1575 call_all(dev, core, s_std, dev->tvnorm);
1576 fe->ops.tuner_ops.set_analog_params(fe, &params);
1577 }
1578 else
1579 printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
1580
1581 /* When changing channels it is required to reset TVAUDIO */
1582 msleep(100);
1583
1584 /* I need to unmute audio here */
1585 ctrl.value = 0;
1586 cx23885_set_control(dev, &ctrl);
1587
1588 mutex_unlock(&dev->lock);
1589
1590 return 0;
1591}
1592
1593int cx23885_set_frequency(struct file *file, void *priv,
1594 struct v4l2_frequency *f)
1495{ 1595{
1496 struct cx23885_fh *fh = priv; 1596 struct cx23885_fh *fh = priv;
1497 struct cx23885_dev *dev = fh->dev; 1597 struct cx23885_dev *dev = fh->dev;
1598 int ret;
1498 1599
1499 if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)) 1600 switch (dev->board) {
1500 return -EINVAL; 1601 case CX23885_BOARD_HAUPPAUGE_HVR1850:
1501 if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) 1602 ret = cx23885_set_freq_via_ops(dev, f);
1502 return -EINVAL; 1603 break;
1604 default:
1605 ret = cx23885_set_freq(dev, f);
1606 }
1503 1607
1504 return 1608 return ret;
1505 cx23885_set_freq(dev, f); 1609}
1610
1611static int vidioc_s_frequency(struct file *file, void *priv,
1612 struct v4l2_frequency *f)
1613{
1614 return cx23885_set_frequency(file, priv, f);
1506} 1615}
1507 1616
1508/* ----------------------------------------------------------- */ 1617/* ----------------------------------------------------------- */
@@ -1614,6 +1723,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1614 .vidioc_qbuf = vidioc_qbuf, 1723 .vidioc_qbuf = vidioc_qbuf,
1615 .vidioc_dqbuf = vidioc_dqbuf, 1724 .vidioc_dqbuf = vidioc_dqbuf,
1616 .vidioc_s_std = vidioc_s_std, 1725 .vidioc_s_std = vidioc_s_std,
1726 .vidioc_g_std = vidioc_g_std,
1727 .vidioc_querystd = vidioc_g_std,
1617 .vidioc_enum_input = vidioc_enum_input, 1728 .vidioc_enum_input = vidioc_enum_input,
1618 .vidioc_g_input = vidioc_g_input, 1729 .vidioc_g_input = vidioc_g_input,
1619 .vidioc_s_input = vidioc_s_input, 1730 .vidioc_s_input = vidioc_s_input,
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 519f40d2af5d..78fdb841cc17 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -227,6 +227,8 @@ struct cx23885_board {
227 u32 clk_freq; 227 u32 clk_freq;
228 struct cx23885_input input[MAX_CX23885_INPUT]; 228 struct cx23885_input input[MAX_CX23885_INPUT];
229 int ci_type; /* for NetUP */ 229 int ci_type; /* for NetUP */
230 /* Force bottom field first during DMA (888 workaround) */
231 u32 force_bff;
230}; 232};
231 233
232struct cx23885_subid { 234struct cx23885_subid {
@@ -311,6 +313,9 @@ struct cx23885_tsport {
311 u32 num_frontends; 313 u32 num_frontends;
312 void (*gate_ctrl)(struct cx23885_tsport *port, int open); 314 void (*gate_ctrl)(struct cx23885_tsport *port, int open);
313 void *port_priv; 315 void *port_priv;
316
317 /* Workaround for a temp dvb_frontend that the tuner can attached to */
318 struct dvb_frontend analog_fe;
314}; 319};
315 320
316struct cx23885_kernel_ir { 321struct cx23885_kernel_ir {
@@ -575,6 +580,13 @@ extern void cx23885_video_unregister(struct cx23885_dev *dev);
575extern int cx23885_video_irq(struct cx23885_dev *dev, u32 status); 580extern int cx23885_video_irq(struct cx23885_dev *dev, u32 status);
576extern void cx23885_video_wakeup(struct cx23885_dev *dev, 581extern void cx23885_video_wakeup(struct cx23885_dev *dev,
577 struct cx23885_dmaqueue *q, u32 count); 582 struct cx23885_dmaqueue *q, u32 count);
583int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i);
584int cx23885_set_input(struct file *file, void *priv, unsigned int i);
585int cx23885_get_input(struct file *file, void *priv, unsigned int *i);
586int cx23885_set_frequency(struct file *file, void *priv, struct v4l2_frequency *f);
587int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl);
588int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl);
589int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm);
578 590
579/* ----------------------------------------------------------- */ 591/* ----------------------------------------------------------- */
580/* cx23885-vbi.c */ 592/* cx23885-vbi.c */