aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c265
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c22
-rw-r--r--drivers/media/video/v4l2-common.c6
-rw-r--r--include/media/v4l2-chip-ident.h4
4 files changed, 194 insertions, 103 deletions
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 707be175509d..ca725a74ce6a 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -1,3 +1,27 @@
1 /*
2 saa6752hs - i2c-driver for the saa6752hs by Philips
3
4 Copyright (C) 2004 Andrew de Quincey
5
6 AC-3 support:
7
8 Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License vs published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA.
23 */
24
1#include <linux/module.h> 25#include <linux/module.h>
2#include <linux/kernel.h> 26#include <linux/kernel.h>
3#include <linux/string.h> 27#include <linux/string.h>
@@ -10,6 +34,8 @@
10#include <linux/types.h> 34#include <linux/types.h>
11#include <linux/videodev2.h> 35#include <linux/videodev2.h>
12#include <media/v4l2-common.h> 36#include <media/v4l2-common.h>
37#include <media/v4l2-chip-ident.h>
38#include <media/v4l2-i2c-drv-legacy.h>
13#include <linux/init.h> 39#include <linux/init.h>
14#include <linux/crc32.h> 40#include <linux/crc32.h>
15 41
@@ -27,9 +53,6 @@ MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
27MODULE_AUTHOR("Andrew de Quincey"); 53MODULE_AUTHOR("Andrew de Quincey");
28MODULE_LICENSE("GPL"); 54MODULE_LICENSE("GPL");
29 55
30static struct i2c_driver driver;
31static struct i2c_client client_template;
32
33enum saa6752hs_videoformat { 56enum saa6752hs_videoformat {
34 SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */ 57 SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */
35 SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */ 58 SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */
@@ -46,7 +69,9 @@ struct saa6752hs_mpeg_params {
46 __u16 ts_pid_pcr; 69 __u16 ts_pid_pcr;
47 70
48 /* audio */ 71 /* audio */
49 enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate; 72 enum v4l2_mpeg_audio_encoding au_encoding;
73 enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate;
74 enum v4l2_mpeg_audio_ac3_bitrate au_ac3_bitrate;
50 75
51 /* video */ 76 /* video */
52 enum v4l2_mpeg_video_aspect vi_aspect; 77 enum v4l2_mpeg_video_aspect vi_aspect;
@@ -70,7 +95,9 @@ static const struct v4l2_format v4l2_format_table[] =
70}; 95};
71 96
72struct saa6752hs_state { 97struct saa6752hs_state {
73 struct i2c_client client; 98 int chip;
99 u32 revision;
100 int has_ac3;
74 struct saa6752hs_mpeg_params params; 101 struct saa6752hs_mpeg_params params;
75 enum saa6752hs_videoformat video_format; 102 enum saa6752hs_videoformat video_format;
76 v4l2_std_id standard; 103 v4l2_std_id standard;
@@ -157,7 +184,9 @@ static struct saa6752hs_mpeg_params param_defaults =
157 .vi_bitrate_peak = 6000, 184 .vi_bitrate_peak = 6000,
158 .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, 185 .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
159 186
187 .au_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
160 .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K, 188 .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K,
189 .au_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
161}; 190};
162 191
163/* ---------------------------------------------------------------------- */ 192/* ---------------------------------------------------------------------- */
@@ -230,8 +259,9 @@ static int saa6752hs_chip_command(struct i2c_client* client,
230 259
231 260
232static int saa6752hs_set_bitrate(struct i2c_client* client, 261static int saa6752hs_set_bitrate(struct i2c_client* client,
233 struct saa6752hs_mpeg_params* params) 262 struct saa6752hs_state *h)
234{ 263{
264 struct saa6752hs_mpeg_params *params = &h->params;
235 u8 buf[3]; 265 u8 buf[3];
236 int tot_bitrate; 266 int tot_bitrate;
237 267
@@ -263,11 +293,22 @@ static int saa6752hs_set_bitrate(struct i2c_client* client,
263 tot_bitrate = params->vi_bitrate; 293 tot_bitrate = params->vi_bitrate;
264 } 294 }
265 295
296 /* set the audio encoding */
297 buf[0] = 0x93;
298 if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3)
299 buf[1] = 1;
300 else
301 buf[1] = 0;
302 i2c_master_send(client, buf, 2);
303
266 /* set the audio bitrate */ 304 /* set the audio bitrate */
267 buf[0] = 0x94; 305 buf[0] = 0x94;
268 buf[1] = (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 0 : 1; 306 if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3)
307 buf[1] = V4L2_MPEG_AUDIO_AC3_BITRATE_384K == params->au_ac3_bitrate;
308 else
309 buf[1] = V4L2_MPEG_AUDIO_L2_BITRATE_384K == params->au_l2_bitrate;
310 tot_bitrate += buf[1] ? 384 : 256;
269 i2c_master_send(client, buf, 2); 311 i2c_master_send(client, buf, 2);
270 tot_bitrate += (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 256 : 384;
271 312
272 /* Note: the total max bitrate is determined by adding the video and audio 313 /* Note: the total max bitrate is determined by adding the video and audio
273 bitrates together and also adding an extra 768kbit/s to stay on the 314 bitrates together and also adding an extra 768kbit/s to stay on the
@@ -332,7 +373,7 @@ static void saa6752hs_set_subsampling(struct i2c_client* client,
332} 373}
333 374
334 375
335static int handle_ctrl(struct saa6752hs_mpeg_params *params, 376static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
336 struct v4l2_ext_control *ctrl, unsigned int cmd) 377 struct v4l2_ext_control *ctrl, unsigned int cmd)
337{ 378{
338 int old = 0, new; 379 int old = 0, new;
@@ -379,8 +420,9 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params,
379 params->ts_pid_pcr = new; 420 params->ts_pid_pcr = new;
380 break; 421 break;
381 case V4L2_CID_MPEG_AUDIO_ENCODING: 422 case V4L2_CID_MPEG_AUDIO_ENCODING:
382 old = V4L2_MPEG_AUDIO_ENCODING_LAYER_2; 423 old = params->au_encoding;
383 if (set && new != old) 424 if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
425 (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
384 return -ERANGE; 426 return -ERANGE;
385 new = old; 427 new = old;
386 break; 428 break;
@@ -395,6 +437,19 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params,
395 new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; 437 new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
396 params->au_l2_bitrate = new; 438 params->au_l2_bitrate = new;
397 break; 439 break;
440 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
441 if (!has_ac3)
442 return -EINVAL;
443 old = params->au_ac3_bitrate;
444 if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
445 new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
446 return -ERANGE;
447 if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
448 new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
449 else
450 new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
451 params->au_ac3_bitrate = new;
452 break;
398 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: 453 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
399 old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; 454 old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
400 if (set && new != old) 455 if (set && new != old)
@@ -448,17 +503,19 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params,
448 return 0; 503 return 0;
449} 504}
450 505
451static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params, 506static int saa6752hs_qctrl(struct saa6752hs_state *h,
452 struct v4l2_queryctrl *qctrl) 507 struct v4l2_queryctrl *qctrl)
453{ 508{
509 struct saa6752hs_mpeg_params *params = &h->params;
454 int err; 510 int err;
455 511
456 switch (qctrl->id) { 512 switch (qctrl->id) {
457 case V4L2_CID_MPEG_AUDIO_ENCODING: 513 case V4L2_CID_MPEG_AUDIO_ENCODING:
458 return v4l2_ctrl_query_fill(qctrl, 514 return v4l2_ctrl_query_fill(qctrl,
459 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 515 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
460 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1, 516 h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 :
461 V4L2_MPEG_AUDIO_ENCODING_LAYER_2); 517 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
518 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
462 519
463 case V4L2_CID_MPEG_AUDIO_L2_BITRATE: 520 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
464 return v4l2_ctrl_query_fill(qctrl, 521 return v4l2_ctrl_query_fill(qctrl,
@@ -466,6 +523,14 @@ static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params,
466 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, 523 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
467 V4L2_MPEG_AUDIO_L2_BITRATE_256K); 524 V4L2_MPEG_AUDIO_L2_BITRATE_256K);
468 525
526 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
527 if (!h->has_ac3)
528 return -EINVAL;
529 return v4l2_ctrl_query_fill(qctrl,
530 V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
531 V4L2_MPEG_AUDIO_AC3_BITRATE_384K, 1,
532 V4L2_MPEG_AUDIO_AC3_BITRATE_256K);
533
469 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: 534 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
470 return v4l2_ctrl_query_fill(qctrl, 535 return v4l2_ctrl_query_fill(qctrl,
471 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, 536 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
@@ -512,38 +577,50 @@ static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params,
512 return -EINVAL; 577 return -EINVAL;
513} 578}
514 579
515static int saa6752hs_qmenu(struct saa6752hs_mpeg_params *params, 580static int saa6752hs_qmenu(struct saa6752hs_state *h,
516 struct v4l2_querymenu *qmenu) 581 struct v4l2_querymenu *qmenu)
517{ 582{
518 static const char *mpeg_audio_l2_bitrate[] = { 583 static const u32 mpeg_audio_encoding[] = {
519 "", 584 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
520 "", 585 V4L2_CTRL_MENU_IDS_END
521 "", 586 };
522 "", 587 static const u32 mpeg_audio_ac3_encoding[] = {
523 "", 588 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
524 "", 589 V4L2_MPEG_AUDIO_ENCODING_AC3,
525 "", 590 V4L2_CTRL_MENU_IDS_END
526 "", 591 };
527 "", 592 static u32 mpeg_audio_l2_bitrate[] = {
528 "", 593 V4L2_MPEG_AUDIO_L2_BITRATE_256K,
529 "", 594 V4L2_MPEG_AUDIO_L2_BITRATE_384K,
530 "256 kbps", 595 V4L2_CTRL_MENU_IDS_END
531 "", 596 };
532 "384 kbps", 597 static u32 mpeg_audio_ac3_bitrate[] = {
533 NULL 598 V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
599 V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
600 V4L2_CTRL_MENU_IDS_END
534 }; 601 };
535 struct v4l2_queryctrl qctrl; 602 struct v4l2_queryctrl qctrl;
536 int err; 603 int err;
537 604
538 qctrl.id = qmenu->id; 605 qctrl.id = qmenu->id;
539 err = saa6752hs_qctrl(params, &qctrl); 606 err = saa6752hs_qctrl(h, &qctrl);
540 if (err) 607 if (err)
541 return err; 608 return err;
542 if (qmenu->id == V4L2_CID_MPEG_AUDIO_L2_BITRATE) 609 switch (qmenu->id) {
543 return v4l2_ctrl_query_menu(qmenu, &qctrl, 610 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
611 return v4l2_ctrl_query_menu_valid_items(qmenu,
544 mpeg_audio_l2_bitrate); 612 mpeg_audio_l2_bitrate);
545 return v4l2_ctrl_query_menu(qmenu, &qctrl, 613 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
546 v4l2_ctrl_get_menu(qmenu->id)); 614 if (!h->has_ac3)
615 return -EINVAL;
616 return v4l2_ctrl_query_menu_valid_items(qmenu,
617 mpeg_audio_ac3_bitrate);
618 case V4L2_CID_MPEG_AUDIO_ENCODING:
619 return v4l2_ctrl_query_menu_valid_items(qmenu,
620 h->has_ac3 ? mpeg_audio_ac3_encoding :
621 mpeg_audio_encoding);
622 }
623 return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
547} 624}
548 625
549static int saa6752hs_init(struct i2c_client* client) 626static int saa6752hs_init(struct i2c_client* client)
@@ -569,7 +646,7 @@ static int saa6752hs_init(struct i2c_client* client)
569 i2c_master_send(client, buf, 2); 646 i2c_master_send(client, buf, 2);
570 647
571 /* set bitrate */ 648 /* set bitrate */
572 saa6752hs_set_bitrate(client, &h->params); 649 saa6752hs_set_bitrate(client, h);
573 650
574 /* Set GOP structure {3, 13} */ 651 /* Set GOP structure {3, 13} */
575 buf[0] = 0x72; 652 buf[0] = 0x72;
@@ -688,45 +765,6 @@ static int saa6752hs_init(struct i2c_client* client)
688 return 0; 765 return 0;
689} 766}
690 767
691static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
692{
693 struct saa6752hs_state *h;
694
695
696 if (NULL == (h = kzalloc(sizeof(*h), GFP_KERNEL)))
697 return -ENOMEM;
698 h->client = client_template;
699 h->params = param_defaults;
700 h->client.adapter = adap;
701 h->client.addr = addr;
702
703 /* Assume 625 input lines */
704 h->standard = 0;
705
706 i2c_set_clientdata(&h->client, h);
707 i2c_attach_client(&h->client);
708
709 v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1);
710 return 0;
711}
712
713static int saa6752hs_probe(struct i2c_adapter *adap)
714{
715 if (adap->class & I2C_CLASS_TV_ANALOG)
716 return i2c_probe(adap, &addr_data, saa6752hs_attach);
717 return 0;
718}
719
720static int saa6752hs_detach(struct i2c_client *client)
721{
722 struct saa6752hs_state *h;
723
724 h = i2c_get_clientdata(client);
725 i2c_detach_client(client);
726 kfree(h);
727 return 0;
728}
729
730static int 768static int
731saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) 769saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
732{ 770{
@@ -752,7 +790,8 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
752 return -EINVAL; 790 return -EINVAL;
753 params = h->params; 791 params = h->params;
754 for (i = 0; i < ctrls->count; i++) { 792 for (i = 0; i < ctrls->count; i++) {
755 if ((err = handle_ctrl(&params, ctrls->controls + i, cmd))) { 793 err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, cmd);
794 if (err) {
756 ctrls->error_idx = i; 795 ctrls->error_idx = i;
757 return err; 796 return err;
758 } 797 }
@@ -760,9 +799,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
760 h->params = params; 799 h->params = params;
761 break; 800 break;
762 case VIDIOC_QUERYCTRL: 801 case VIDIOC_QUERYCTRL:
763 return saa6752hs_qctrl(&h->params, arg); 802 return saa6752hs_qctrl(h, arg);
764 case VIDIOC_QUERYMENU: 803 case VIDIOC_QUERYMENU:
765 return saa6752hs_qmenu(&h->params, arg); 804 return saa6752hs_qmenu(h, arg);
766 case VIDIOC_G_FMT: 805 case VIDIOC_G_FMT:
767 { 806 {
768 struct v4l2_format *f = arg; 807 struct v4l2_format *f = arg;
@@ -785,6 +824,11 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
785 case VIDIOC_S_STD: 824 case VIDIOC_S_STD:
786 h->standard = *((v4l2_std_id *) arg); 825 h->standard = *((v4l2_std_id *) arg);
787 break; 826 break;
827
828 case VIDIOC_G_CHIP_IDENT:
829 return v4l2_chip_ident_i2c_client(client,
830 arg, h->chip, h->revision);
831
788 default: 832 default:
789 /* nothing */ 833 /* nothing */
790 break; 834 break;
@@ -793,36 +837,55 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
793 return err; 837 return err;
794} 838}
795 839
796/* ----------------------------------------------------------------------- */ 840static int saa6752hs_probe(struct i2c_client *client,
841 const struct i2c_device_id *id)
842{
843 struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
844 u8 addr = 0x13;
845 u8 data[12];
797 846
798static struct i2c_driver driver = { 847 v4l_info(client, "chip found @ 0x%x (%s)\n",
799 .driver = { 848 client->addr << 1, client->adapter->name);
800 .name = "saa6752hs", 849 if (h == NULL)
801 }, 850 return -ENOMEM;
802 .id = I2C_DRIVERID_SAA6752HS,
803 .attach_adapter = saa6752hs_probe,
804 .detach_client = saa6752hs_detach,
805 .command = saa6752hs_command,
806};
807 851
808static struct i2c_client client_template = 852 i2c_master_send(client, &addr, 1);
809{ 853 i2c_master_recv(client, data, sizeof(data));
810 .name = "saa6752hs", 854 h->chip = V4L2_IDENT_SAA6752HS;
811 .driver = &driver, 855 h->revision = (data[8] << 8) | data[9];
812}; 856 h->has_ac3 = 0;
857 if (h->revision == 0x0206) {
858 h->chip = V4L2_IDENT_SAA6752HS_AC3;
859 h->has_ac3 = 1;
860 v4l_info(client, "support AC-3\n");
861 }
862 h->params = param_defaults;
863 h->standard = 0; /* Assume 625 input lines */
813 864
814static int __init saa6752hs_init_module(void) 865 i2c_set_clientdata(client, h);
815{ 866 return 0;
816 return i2c_add_driver(&driver);
817} 867}
818 868
819static void __exit saa6752hs_cleanup_module(void) 869static int saa6752hs_remove(struct i2c_client *client)
820{ 870{
821 i2c_del_driver(&driver); 871 kfree(i2c_get_clientdata(client));
872 return 0;
822} 873}
823 874
824module_init(saa6752hs_init_module); 875static const struct i2c_device_id saa6752hs_id[] = {
825module_exit(saa6752hs_cleanup_module); 876 { "saa6752hs", 0 },
877 { }
878};
879MODULE_DEVICE_TABLE(i2c, saa6752hs_id);
880
881static struct v4l2_i2c_driver_data v4l2_i2c_data = {
882 .name = "saa6752hs",
883 .driverid = I2C_DRIVERID_SAA6752HS,
884 .command = saa6752hs_command,
885 .probe = saa6752hs_probe,
886 .remove = saa6752hs_remove,
887 .id_table = saa6752hs_id,
888};
826 889
827/* 890/*
828 * Overrides for Emacs so that we follow Linus's tabbing style. 891 * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 6f423d116fb4..f5a186a13db2 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -29,6 +29,7 @@
29 29
30#include <media/saa6752hs.h> 30#include <media/saa6752hs.h>
31#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
32#include <media/v4l2-chip-ident.h>
32 33
33/* ------------------------------------------------------------------ */ 34/* ------------------------------------------------------------------ */
34 35
@@ -403,6 +404,25 @@ static int empress_querymenu(struct file *file, void *priv,
403 return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c); 404 return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c);
404} 405}
405 406
407static int empress_g_chip_ident(struct file *file, void *fh,
408 struct v4l2_chip_ident *chip)
409{
410 struct saa7134_dev *dev = file->private_data;
411
412 chip->ident = V4L2_IDENT_NONE;
413 chip->revision = 0;
414 if (dev->mpeg_i2c_client == NULL)
415 return -EINVAL;
416 if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER &&
417 chip->match_chip == I2C_DRIVERID_SAA6752HS)
418 return saa7134_i2c_call_saa6752(dev, VIDIOC_G_CHIP_IDENT, chip);
419 if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR &&
420 chip->match_chip == dev->mpeg_i2c_client->addr)
421 return saa7134_i2c_call_saa6752(dev, VIDIOC_G_CHIP_IDENT, chip);
422 return -EINVAL;
423}
424
425
406static const struct file_operations ts_fops = 426static const struct file_operations ts_fops =
407{ 427{
408 .owner = THIS_MODULE, 428 .owner = THIS_MODULE,
@@ -431,11 +451,11 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = {
431 .vidioc_enum_input = empress_enum_input, 451 .vidioc_enum_input = empress_enum_input,
432 .vidioc_g_input = empress_g_input, 452 .vidioc_g_input = empress_g_input,
433 .vidioc_s_input = empress_s_input, 453 .vidioc_s_input = empress_s_input,
434
435 .vidioc_queryctrl = empress_queryctrl, 454 .vidioc_queryctrl = empress_queryctrl,
436 .vidioc_querymenu = empress_querymenu, 455 .vidioc_querymenu = empress_querymenu,
437 .vidioc_g_ctrl = empress_g_ctrl, 456 .vidioc_g_ctrl = empress_g_ctrl,
438 .vidioc_s_ctrl = empress_s_ctrl, 457 .vidioc_s_ctrl = empress_s_ctrl,
458 .vidioc_g_chip_ident = empress_g_chip_ident,
439}; 459};
440 460
441/* ----------------------------------------------------------- */ 461/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index a523af78bdb1..0c511839f7ee 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -637,13 +637,17 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
637EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); 637EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
638 638
639/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and 639/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
640 the menu. The qctrl pointer may be NULL, in which case it is ignored. */ 640 the menu. The qctrl pointer may be NULL, in which case it is ignored.
641 If menu_items is NULL, then the menu items are retrieved using
642 v4l2_ctrl_get_menu. */
641int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl, 643int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl,
642 const char **menu_items) 644 const char **menu_items)
643{ 645{
644 int i; 646 int i;
645 647
646 qmenu->reserved = 0; 648 qmenu->reserved = 0;
649 if (menu_items == NULL)
650 menu_items = v4l2_ctrl_get_menu(qmenu->id);
647 if (menu_items == NULL || 651 if (menu_items == NULL ||
648 (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum))) 652 (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum)))
649 return -EINVAL; 653 return -EINVAL;
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 41b509babf3f..be782d5fcfa8 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -72,6 +72,10 @@ enum {
72 /* module cs5345: just ident 5345 */ 72 /* module cs5345: just ident 5345 */
73 V4L2_IDENT_CS5345 = 5345, 73 V4L2_IDENT_CS5345 = 5345,
74 74
75 /* module saa6752hs: reserved range 6750-6759 */
76 V4L2_IDENT_SAA6752HS = 6752,
77 V4L2_IDENT_SAA6752HS_AC3 = 6753,
78
75 /* module wm8739: just ident 8739 */ 79 /* module wm8739: just ident 8739 */
76 V4L2_IDENT_WM8739 = 8739, 80 V4L2_IDENT_WM8739 = 8739,
77 81