aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThierry MERLE <thierry.merle@free.fr>2006-12-04 06:31:32 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-12-10 06:05:51 -0500
commit3086d6cb0a2ec93f17bc215af3113c54af6080c1 (patch)
treecca0597af2a6843bc564683a3f1a2657cfee704e /drivers
parent957883d0b56a649389d0652a727324dd8ba2e83c (diff)
V4L/DVB (4933): Usbvision_v4l2: radio interface / tda9887 problem ?
- implement the v4l2 radio interface Signed-off-by: Thierry MERLE <thierry.merle@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c234
1 files changed, 67 insertions, 167 deletions
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index f87bd0afbbfa..0365c7f93972 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -4835,220 +4835,120 @@ static int usbvision_do_radio_ioctl(struct inode *inode, struct file *file,
4835 return -EIO; 4835 return -EIO;
4836 4836
4837 switch (cmd) { 4837 switch (cmd) {
4838 /***************************
4839 * V4L2 IOCTLs *
4840 ***************************/
4841 case VIDIOC_QUERYCAP: 4838 case VIDIOC_QUERYCAP:
4842 { 4839 {
4843 struct v4l2_capability *vc=arg; 4840 struct v4l2_capability *vc=arg;
4844 memset(vc, 0, sizeof(struct v4l2_capability)); 4841
4845 strcpy(vc->driver,"usbvision radio"); 4842 memset(vc, 0, sizeof(*vc));
4846 strcpy(vc->card,usbvision->vcap.card); 4843 strlcpy(vc->driver, "USBVision", sizeof(vc->driver));
4847 strcpy(vc->bus_info,"usb"); 4844 strlcpy(vc->card, usbvision_device_data[usbvision->DevModel].ModelString,
4848 vc->version = USBVISION_DRIVER_VERSION; /* version */ 4845 sizeof(vc->card));
4849 vc->capabilities = V4L2_CAP_TUNER; /* capabilities */ 4846 strlcpy(vc->bus_info, usbvision->dev->dev.bus_id,
4850 PDEBUG(DBG_RIO, "%s: VIDIOC_QUERYCAP", __FUNCTION__); 4847 sizeof(vc->bus_info));
4848 vc->version = USBVISION_DRIVER_VERSION;
4849 vc->capabilities = (usbvision->have_tuner ? V4L2_CAP_TUNER : 0);
4850 PDEBUG(DBG_RIO, "VIDIOC_QUERYCAP");
4851 return 0; 4851 return 0;
4852 } 4852 }
4853 case VIDIOC_QUERYCTRL: 4853 case VIDIOC_QUERYCTRL:
4854 { 4854 {
4855 struct v4l2_queryctrl *qc = arg; 4855 struct v4l2_queryctrl *ctrl = arg;
4856 switch(qc->id) 4856 int id=ctrl->id;
4857 { 4857
4858 case V4L2_CID_AUDIO_VOLUME: 4858 memset(ctrl,0,sizeof(*ctrl));
4859 case V4L2_CID_AUDIO_MUTE: 4859 ctrl->id=id;
4860 return v4l2_ctrl_query_fill_std(qc); 4860
4861 break; 4861 call_i2c_clients(usbvision, cmd, arg);
4862 default: 4862 PDEBUG(DBG_RIO,"VIDIOC_QUERYCTRL id=%x value=%x",ctrl->id,ctrl->type);
4863 return -EINVAL; 4863
4864 } 4864 if (ctrl->type)
4865 return 0; 4865 return 0;
4866 else
4867 return -EINVAL;
4868
4866 } 4869 }
4867 case VIDIOC_G_CTRL: 4870 case VIDIOC_G_CTRL:
4868 { 4871 {
4869 struct v4l2_control *ctrl = arg; 4872 struct v4l2_control *ctrl = arg;
4870 PDEBUG(DBG_IOCTL, "VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value); 4873
4871 switch(ctrl->id) { 4874 call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl);
4872 case V4L2_CID_AUDIO_VOLUME: 4875 PDEBUG(DBG_RIO,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value);
4873 /* ctrl->value = usbvision->volume; */
4874 break;
4875 case V4L2_CID_AUDIO_MUTE:
4876 ctrl->value = usbvision->AudioMute;
4877 break;
4878 default:
4879 return -EINVAL;
4880 }
4881 return 0; 4876 return 0;
4882 } 4877 }
4883 case VIDIOC_S_CTRL: 4878 case VIDIOC_S_CTRL:
4884 { 4879 {
4885 struct v4l2_control *ctrl = arg; 4880 struct v4l2_control *ctrl = arg;
4886 call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl);
4887 4881
4888 PDEBUG(DBG_RIO, "%s: VIDIOC_S_CTRL id=%x value=%x", __FUNCTION__,ctrl->id,ctrl->value); 4882 call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl);
4883 PDEBUG(DBG_RIO, "VIDIOC_S_CTRL id=%x value=%x",ctrl->id,ctrl->value);
4889 return 0; 4884 return 0;
4890 } 4885 }
4891 case VIDIOC_G_TUNER: 4886 case VIDIOC_G_TUNER:
4892 { 4887 {
4893 struct v4l2_tuner *vt = arg; 4888 struct v4l2_tuner *t = arg;
4894 4889
4895 if (!usbvision->have_tuner || vt->index) // Only tuner 0 4890 if (t->index > 0)
4896 return -EINVAL; 4891 return -EINVAL;
4897 strcpy(vt->name, "Radio");
4898 vt->type = V4L2_TUNER_RADIO;
4899 vt->capability = V4L2_TUNER_CAP_STEREO;
4900 // japan: 76.0 MHz - 89.9 MHz
4901 // western europe: 87.5 MHz - 108.0 MHz
4902 // russia: 65.0 MHz - 108.0 MHz
4903 vt->rangelow = (int)(65*16);;
4904 vt->rangehigh = (int)(108*16);
4905 vt->audmode = V4L2_TUNER_MODE_STEREO;
4906 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
4907 call_i2c_clients(usbvision,VIDIOC_G_TUNER,&vt);
4908 4892
4909 PDEBUG(DBG_RIO, "%s: VIDIOC_G_TUNER signal=%d", __FUNCTION__, vt->signal); 4893 memset(t,0,sizeof(*t));
4894 strcpy(t->name, "Radio");
4895 t->type = V4L2_TUNER_RADIO;
4896
4897 /* Let clients fill in the remainder of this struct */
4898 call_i2c_clients(usbvision,VIDIOC_G_TUNER,t);
4899 PDEBUG(DBG_RIO, "VIDIOC_G_TUNER signal=%x, afc=%x",t->signal,t->afc);
4910 return 0; 4900 return 0;
4911 } 4901 }
4912 case VIDIOC_S_TUNER: 4902 case VIDIOC_S_TUNER:
4913 { 4903 {
4914 struct v4l2_tuner *vt = arg; 4904 struct v4l2_tuner *vt = arg;
4915 4905
4916 // Only channel 0 has a tuner 4906 // Only no or one tuner for now
4917 if((vt->index) || (usbvision->channel)) { 4907 if (!usbvision->have_tuner || vt->index)
4918 return -EINVAL; 4908 return -EINVAL;
4919 } 4909 /* let clients handle this */
4920 PDEBUG(DBG_RIO, "%s: VIDIOC_S_TUNER", __FUNCTION__); 4910 call_i2c_clients(usbvision,VIDIOC_S_TUNER,vt);
4911
4912 PDEBUG(DBG_RIO, "VIDIOC_S_TUNER");
4921 return 0; 4913 return 0;
4922 } 4914 }
4923 case VIDIOC_G_AUDIO: 4915 case VIDIOC_G_AUDIO:
4924 { 4916 {
4925 struct v4l2_audio *va = arg; 4917 struct v4l2_audio *a = arg;
4926 memset(va,0, sizeof(va)); 4918
4927 va->capability = V4L2_AUDCAP_STEREO; 4919 memset(a,0,sizeof(*a));
4928 strcpy(va->name, "Radio"); 4920 strcpy(a->name,"Radio");
4929 PDEBUG(DBG_IOCTL, "VIDIOC_G_AUDIO"); 4921 PDEBUG(DBG_RIO, "VIDIOC_G_AUDIO");
4930 return 0; 4922 return 0;
4931 } 4923 }
4932 case VIDIOC_S_AUDIO: 4924 case VIDIOC_S_AUDIO:
4933 { 4925 case VIDIOC_S_INPUT:
4934 struct v4l2_audio *v = arg; 4926 case VIDIOC_S_STD:
4935 if(v->index) { 4927 return 0;
4936 return -EINVAL;
4937 }
4938 PDEBUG(DBG_IOCTL, "VIDIOC_S_AUDIO");
4939 // FIXME: void function ???
4940 return 0;
4941 }
4942 case VIDIOC_G_FREQUENCY:
4943 {
4944 struct v4l2_frequency *freq = arg;
4945 freq->tuner = 0; // Only one tuner
4946 freq->type = V4L2_TUNER_RADIO;
4947 freq->frequency = usbvision->freq;
4948 PDEBUG(DBG_RIO, "VIDIOC_G_FREQUENCY freq=0x%X", (unsigned)freq->frequency);
4949 return 0;
4950 }
4951 case VIDIOC_S_FREQUENCY:
4952 {
4953 struct v4l2_frequency *freq = arg;
4954 usbvision->freq = freq->frequency;
4955 call_i2c_clients(usbvision, cmd, freq);
4956 PDEBUG(DBG_RIO, "VIDIOC_S_FREQUENCY freq=0x%X", (unsigned)freq->frequency);
4957 return 0;
4958 }
4959 4928
4960 /*************************** 4929 case VIDIOC_G_FREQUENCY:
4961 * V4L1 IOCTLs *
4962 ***************************/
4963 case VIDIOCGCAP:
4964 {
4965 struct video_capability *vc = arg;
4966
4967 memset(vc, 0, sizeof(struct video_capability));
4968 strcpy(vc->name,usbvision->vcap.card);
4969 vc->type = VID_TYPE_TUNER;
4970 vc->channels = 1;
4971 vc->audios = 1;
4972 PDEBUG(DBG_RIO, "%s: VIDIOCGCAP", __FUNCTION__);
4973 return 0;
4974 }
4975 case VIDIOCGTUNER:
4976 { 4930 {
4977 struct video_tuner *vt = arg; 4931 struct v4l2_frequency *f = arg;
4978 4932
4979 if((vt->tuner) || (usbvision->channel)) { /* Only tuner 0 */ 4933 memset(f,0,sizeof(*f));
4980 return -EINVAL;
4981 }
4982 strcpy(vt->name, "Radio");
4983 // japan: 76.0 MHz - 89.9 MHz
4984 // western europe: 87.5 MHz - 108.0 MHz
4985 // russia: 65.0 MHz - 108.0 MHz
4986 vt->rangelow=(int)(65*16);
4987 vt->rangehigh=(int)(108*16);
4988 vt->flags= 0;
4989 vt->mode = 0;
4990 call_i2c_clients(usbvision,cmd,vt);
4991 PDEBUG(DBG_RIO, "%s: VIDIOCGTUNER signal=%d", __FUNCTION__, vt->signal);
4992 return 0;
4993 }
4994 case VIDIOCSTUNER:
4995 {
4996 struct video_tuner *vt = arg;
4997 4934
4998 // Only channel 0 has a tuner 4935 f->type = V4L2_TUNER_RADIO;
4999 if((vt->tuner) || (usbvision->channel)) { 4936 f->frequency = usbvision->freq;
5000 return -EINVAL; 4937 call_i2c_clients(usbvision, cmd, f);
5001 } 4938 PDEBUG(DBG_RIO, "VIDIOC_G_FREQUENCY freq=0x%X", (unsigned)f->frequency);
5002 PDEBUG(DBG_RIO, "%s: VIDIOCSTUNER", __FUNCTION__);
5003 return 0;
5004 }
5005 case VIDIOCGAUDIO:
5006 {
5007 struct video_audio *va = arg;
5008 memset(va,0, sizeof(struct video_audio));
5009 call_i2c_clients(usbvision, cmd, va);
5010 va->flags|=VIDEO_AUDIO_MUTABLE;
5011 va->volume=1;
5012 va->step=1;
5013 strcpy(va->name, "Radio");
5014 PDEBUG(DBG_RIO, "%s: VIDIOCGAUDIO", __FUNCTION__);
5015 return 0;
5016 }
5017 case VIDIOCSAUDIO:
5018 {
5019 struct video_audio *va = arg;
5020 if(va->audio) {
5021 return -EINVAL;
5022 }
5023 4939
5024 if(va->flags & VIDEO_AUDIO_MUTE) {
5025 if (usbvision_audio_mute(usbvision)) {
5026 return -EFAULT;
5027 }
5028 }
5029 else {
5030 if (usbvision_audio_on(usbvision)) {
5031 return -EFAULT;
5032 }
5033 }
5034 PDEBUG(DBG_RIO, "%s: VIDIOCSAUDIO flags=0x%x)", __FUNCTION__, va->flags);
5035 return 0; 4940 return 0;
5036 } 4941 }
5037 case VIDIOCGFREQ: 4942 case VIDIOC_S_FREQUENCY:
5038 { 4943 {
5039 unsigned long *freq = arg; 4944 struct v4l2_frequency *f = arg;
5040 4945
5041 *freq = usbvision->freq; 4946 if (f->tuner != 0)
5042 PDEBUG(DBG_RIO, "%s: VIDIOCGFREQ freq = %ld00 kHz", __FUNCTION__, (*freq * 10)>>4); 4947 return -EINVAL;
5043 return 0; 4948 usbvision->freq = f->frequency;
5044 } 4949 call_i2c_clients(usbvision, cmd, f);
5045 case VIDIOCSFREQ: 4950 PDEBUG(DBG_RIO, "VIDIOC_S_FREQUENCY freq=0x%X", (unsigned)f->frequency);
5046 {
5047 unsigned long *freq = arg;
5048 4951
5049 usbvision->freq = *freq;
5050 call_i2c_clients(usbvision, cmd, freq);
5051 PDEBUG(DBG_RIO, "%s: VIDIOCSFREQ freq = %ld00 kHz", __FUNCTION__, (*freq * 10)>>4);
5052 return 0; 4952 return 0;
5053 } 4953 }
5054 default: 4954 default:
@@ -5102,7 +5002,7 @@ static int usbvision_vbi_open(struct inode *inode, struct file *file)
5102 //usbvision->vbi = 1; 5002 //usbvision->vbi = 1;
5103 call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type); 5003 call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type);
5104 freq = 1517; //SWR3 @ 94.8MHz 5004 freq = 1517; //SWR3 @ 94.8MHz
5105 call_i2c_clients(usbvision, VIDIOCSFREQ, &freq); 5005 call_i2c_clients(usbvision, VIDIOC_S_FREQUENCY, &freq);
5106 usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO); 5006 usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO);
5107 usbvision->user++; 5007 usbvision->user++;
5108 } 5008 }