Commit e281db5862743dbe1dab7f8fb423e699537036ee

Authored by Hans Verkuil
Committed by Mauro Carvalho Chehab
1 parent 1e55126666

V4L/DVB (8639): saa6752hs: cleanup and add AC-3 support

Cleaned up the saa6752hs i2c driver.
Add AC-3 support.
Add VIDIOC_CHIP_IDENT support.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 4 changed files with 194 additions and 103 deletions Side-by-side Diff

drivers/media/video/saa7134/saa6752hs.c
  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 25 #include <linux/module.h>
2 26 #include <linux/kernel.h>
3 27 #include <linux/string.h>
... ... @@ -10,6 +34,8 @@
10 34 #include <linux/types.h>
11 35 #include <linux/videodev2.h>
12 36 #include <media/v4l2-common.h>
  37 +#include <media/v4l2-chip-ident.h>
  38 +#include <media/v4l2-i2c-drv-legacy.h>
13 39 #include <linux/init.h>
14 40 #include <linux/crc32.h>
15 41  
... ... @@ -27,9 +53,6 @@
27 53 MODULE_AUTHOR("Andrew de Quincey");
28 54 MODULE_LICENSE("GPL");
29 55  
30   -static struct i2c_driver driver;
31   -static struct i2c_client client_template;
32   -
33 56 enum saa6752hs_videoformat {
34 57 SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */
35 58 SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */
... ... @@ -46,7 +69,9 @@
46 69 __u16 ts_pid_pcr;
47 70  
48 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 76 /* video */
52 77 enum v4l2_mpeg_video_aspect vi_aspect;
... ... @@ -70,7 +95,9 @@
70 95 };
71 96  
72 97 struct saa6752hs_state {
73   - struct i2c_client client;
  98 + int chip;
  99 + u32 revision;
  100 + int has_ac3;
74 101 struct saa6752hs_mpeg_params params;
75 102 enum saa6752hs_videoformat video_format;
76 103 v4l2_std_id standard;
77 104  
... ... @@ -157,7 +184,9 @@
157 184 .vi_bitrate_peak = 6000,
158 185 .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
159 186  
  187 + .au_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
160 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 /* ---------------------------------------------------------------------- */
164 193  
... ... @@ -230,8 +259,9 @@
230 259  
231 260  
232 261 static 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 265 u8 buf[3];
236 266 int tot_bitrate;
237 267  
238 268  
239 269  
... ... @@ -263,11 +293,22 @@
263 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 304 /* set the audio bitrate */
267 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 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 313 /* Note: the total max bitrate is determined by adding the video and audio
273 314 bitrates together and also adding an extra 768kbit/s to stay on the
... ... @@ -332,7 +373,7 @@
332 373 }
333 374  
334 375  
335   -static int handle_ctrl(struct saa6752hs_mpeg_params *params,
  376 +static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
336 377 struct v4l2_ext_control *ctrl, unsigned int cmd)
337 378 {
338 379 int old = 0, new;
... ... @@ -379,8 +420,9 @@
379 420 params->ts_pid_pcr = new;
380 421 break;
381 422 case V4L2_CID_MPEG_AUDIO_ENCODING:
382   - old = V4L2_MPEG_AUDIO_ENCODING_LAYER_2;
383   - if (set && new != old)
  423 + old = params->au_encoding;
  424 + if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
  425 + (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
384 426 return -ERANGE;
385 427 new = old;
386 428 break;
... ... @@ -395,6 +437,19 @@
395 437 new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
396 438 params->au_l2_bitrate = new;
397 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 453 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
399 454 old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
400 455 if (set && new != old)
401 456  
402 457  
... ... @@ -448,17 +503,19 @@
448 503 return 0;
449 504 }
450 505  
451   -static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params,
  506 +static int saa6752hs_qctrl(struct saa6752hs_state *h,
452 507 struct v4l2_queryctrl *qctrl)
453 508 {
  509 + struct saa6752hs_mpeg_params *params = &h->params;
454 510 int err;
455 511  
456 512 switch (qctrl->id) {
457 513 case V4L2_CID_MPEG_AUDIO_ENCODING:
458 514 return v4l2_ctrl_query_fill(qctrl,
459 515 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
460   - V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
461   - V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
  516 + h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 :
  517 + V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
  518 + 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
462 519  
463 520 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
464 521 return v4l2_ctrl_query_fill(qctrl,
... ... @@ -466,6 +523,14 @@
466 523 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
467 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 534 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
470 535 return v4l2_ctrl_query_fill(qctrl,
471 536 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
472 537  
473 538  
474 539  
475 540  
476 541  
... ... @@ -512,38 +577,50 @@
512 577 return -EINVAL;
513 578 }
514 579  
515   -static int saa6752hs_qmenu(struct saa6752hs_mpeg_params *params,
  580 +static int saa6752hs_qmenu(struct saa6752hs_state *h,
516 581 struct v4l2_querymenu *qmenu)
517 582 {
518   - static const char *mpeg_audio_l2_bitrate[] = {
519   - "",
520   - "",
521   - "",
522   - "",
523   - "",
524   - "",
525   - "",
526   - "",
527   - "",
528   - "",
529   - "",
530   - "256 kbps",
531   - "",
532   - "384 kbps",
533   - NULL
  583 + static const u32 mpeg_audio_encoding[] = {
  584 + V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
  585 + V4L2_CTRL_MENU_IDS_END
534 586 };
  587 + static const u32 mpeg_audio_ac3_encoding[] = {
  588 + V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
  589 + V4L2_MPEG_AUDIO_ENCODING_AC3,
  590 + V4L2_CTRL_MENU_IDS_END
  591 + };
  592 + static u32 mpeg_audio_l2_bitrate[] = {
  593 + V4L2_MPEG_AUDIO_L2_BITRATE_256K,
  594 + V4L2_MPEG_AUDIO_L2_BITRATE_384K,
  595 + V4L2_CTRL_MENU_IDS_END
  596 + };
  597 + static u32 mpeg_audio_ac3_bitrate[] = {
  598 + V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
  599 + V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
  600 + V4L2_CTRL_MENU_IDS_END
  601 + };
535 602 struct v4l2_queryctrl qctrl;
536 603 int err;
537 604  
538 605 qctrl.id = qmenu->id;
539   - err = saa6752hs_qctrl(params, &qctrl);
  606 + err = saa6752hs_qctrl(h, &qctrl);
540 607 if (err)
541 608 return err;
542   - if (qmenu->id == V4L2_CID_MPEG_AUDIO_L2_BITRATE)
543   - return v4l2_ctrl_query_menu(qmenu, &qctrl,
  609 + switch (qmenu->id) {
  610 + case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
  611 + return v4l2_ctrl_query_menu_valid_items(qmenu,
544 612 mpeg_audio_l2_bitrate);
545   - return v4l2_ctrl_query_menu(qmenu, &qctrl,
546   - v4l2_ctrl_get_menu(qmenu->id));
  613 + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
  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  
549 626 static int saa6752hs_init(struct i2c_client* client)
... ... @@ -569,7 +646,7 @@
569 646 i2c_master_send(client, buf, 2);
570 647  
571 648 /* set bitrate */
572   - saa6752hs_set_bitrate(client, &h->params);
  649 + saa6752hs_set_bitrate(client, h);
573 650  
574 651 /* Set GOP structure {3, 13} */
575 652 buf[0] = 0x72;
... ... @@ -688,45 +765,6 @@
688 765 return 0;
689 766 }
690 767  
691   -static 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   -
713   -static 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   -
720   -static 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   -
730 768 static int
731 769 saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
732 770 {
... ... @@ -752,7 +790,8 @@
752 790 return -EINVAL;
753 791 params = h->params;
754 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 795 ctrls->error_idx = i;
757 796 return err;
758 797 }
759 798  
... ... @@ -760,9 +799,9 @@
760 799 h->params = params;
761 800 break;
762 801 case VIDIOC_QUERYCTRL:
763   - return saa6752hs_qctrl(&h->params, arg);
  802 + return saa6752hs_qctrl(h, arg);
764 803 case VIDIOC_QUERYMENU:
765   - return saa6752hs_qmenu(&h->params, arg);
  804 + return saa6752hs_qmenu(h, arg);
766 805 case VIDIOC_G_FMT:
767 806 {
768 807 struct v4l2_format *f = arg;
... ... @@ -785,6 +824,11 @@
785 824 case VIDIOC_S_STD:
786 825 h->standard = *((v4l2_std_id *) arg);
787 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 832 default:
789 833 /* nothing */
790 834 break;
791 835  
792 836  
793 837  
794 838  
795 839  
796 840  
... ... @@ -793,36 +837,55 @@
793 837 return err;
794 838 }
795 839  
796   -/* ----------------------------------------------------------------------- */
  840 +static 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  
798   -static struct i2c_driver driver = {
799   - .driver = {
800   - .name = "saa6752hs",
801   - },
802   - .id = I2C_DRIVERID_SAA6752HS,
803   - .attach_adapter = saa6752hs_probe,
804   - .detach_client = saa6752hs_detach,
805   - .command = saa6752hs_command,
806   -};
  847 + v4l_info(client, "chip found @ 0x%x (%s)\n",
  848 + client->addr << 1, client->adapter->name);
  849 + if (h == NULL)
  850 + return -ENOMEM;
807 851  
808   -static struct i2c_client client_template =
809   -{
810   - .name = "saa6752hs",
811   - .driver = &driver,
812   -};
  852 + i2c_master_send(client, &addr, 1);
  853 + i2c_master_recv(client, data, sizeof(data));
  854 + h->chip = V4L2_IDENT_SAA6752HS;
  855 + h->revision = (data[8] << 8) | data[9];
  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  
814   -static int __init saa6752hs_init_module(void)
815   -{
816   - return i2c_add_driver(&driver);
  865 + i2c_set_clientdata(client, h);
  866 + return 0;
817 867 }
818 868  
819   -static void __exit saa6752hs_cleanup_module(void)
  869 +static 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  
824   -module_init(saa6752hs_init_module);
825   -module_exit(saa6752hs_cleanup_module);
  875 +static const struct i2c_device_id saa6752hs_id[] = {
  876 + { "saa6752hs", 0 },
  877 + { }
  878 +};
  879 +MODULE_DEVICE_TABLE(i2c, saa6752hs_id);
  880 +
  881 +static 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 891 * Overrides for Emacs so that we follow Linus's tabbing style.
drivers/media/video/saa7134/saa7134-empress.c
... ... @@ -29,6 +29,7 @@
29 29  
30 30 #include <media/saa6752hs.h>
31 31 #include <media/v4l2-common.h>
  32 +#include <media/v4l2-chip-ident.h>
32 33  
33 34 /* ------------------------------------------------------------------ */
34 35  
... ... @@ -403,6 +404,25 @@
403 404 return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c);
404 405 }
405 406  
  407 +static 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 +
406 426 static const struct file_operations ts_fops =
407 427 {
408 428 .owner = THIS_MODULE,
409 429  
... ... @@ -431,11 +451,11 @@
431 451 .vidioc_enum_input = empress_enum_input,
432 452 .vidioc_g_input = empress_g_input,
433 453 .vidioc_s_input = empress_s_input,
434   -
435 454 .vidioc_queryctrl = empress_queryctrl,
436 455 .vidioc_querymenu = empress_querymenu,
437 456 .vidioc_g_ctrl = empress_g_ctrl,
438 457 .vidioc_s_ctrl = empress_s_ctrl,
  458 + .vidioc_g_chip_ident = empress_g_chip_ident,
439 459 };
440 460  
441 461 /* ----------------------------------------------------------- */
drivers/media/video/v4l2-common.c
... ... @@ -637,13 +637,17 @@
637 637 EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
638 638  
639 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. */
641 643 int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl,
642 644 const char **menu_items)
643 645 {
644 646 int i;
645 647  
646 648 qmenu->reserved = 0;
  649 + if (menu_items == NULL)
  650 + menu_items = v4l2_ctrl_get_menu(qmenu->id);
647 651 if (menu_items == NULL ||
648 652 (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum)))
649 653 return -EINVAL;
include/media/v4l2-chip-ident.h
... ... @@ -72,6 +72,10 @@
72 72 /* module cs5345: just ident 5345 */
73 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 79 /* module wm8739: just ident 8739 */
76 80 V4L2_IDENT_WM8739 = 8739,
77 81