diff options
author | Thierry MERLE <thierry.merle@free.fr> | 2006-12-04 06:31:32 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-10 06:05:51 -0500 |
commit | 3086d6cb0a2ec93f17bc215af3113c54af6080c1 (patch) | |
tree | cca0597af2a6843bc564683a3f1a2657cfee704e /drivers/media | |
parent | 957883d0b56a649389d0652a727324dd8ba2e83c (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/media')
-rw-r--r-- | drivers/media/video/usbvision/usbvision-core.c | 234 |
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 | } |