Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (10771): tea575x-tuner: convert it to V4L2 API

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

+219 -107
+4 -4
include/sound/tea575x-tuner.h
··· 22 22 * 23 23 */ 24 24 25 - #include <linux/videodev.h> 25 + #include <linux/videodev2.h> 26 26 #include <media/v4l2-dev.h> 27 + #include <media/v4l2-ioctl.h> 27 28 28 29 struct snd_tea575x; 29 30 ··· 36 35 37 36 struct snd_tea575x { 38 37 struct snd_card *card; 39 - struct video_device vd; /* video device */ 40 - struct v4l2_file_operations fops; 38 + struct video_device *vd; /* video device */ 41 39 int dev_nr; /* requested device number + 1 */ 42 - int vd_registered; /* video device is registered */ 43 40 int tea5759; /* 5759 chip is present */ 41 + int mute; /* Device is muted? */ 44 42 unsigned int freq_fixup; /* crystal onboard */ 45 43 unsigned int val; /* hw value */ 46 44 unsigned long freq; /* frequency */
+214 -102
sound/i2c/other/tea575x-tuner.c
··· 24 24 #include <linux/delay.h> 25 25 #include <linux/interrupt.h> 26 26 #include <linux/init.h> 27 + #include <linux/version.h> 27 28 #include <sound/core.h> 28 29 #include <sound/tea575x-tuner.h> 29 30 30 31 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 31 32 MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips"); 32 33 MODULE_LICENSE("GPL"); 34 + 35 + static int radio_nr = -1; 36 + module_param(radio_nr, int, 0); 37 + 38 + #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) 39 + #define FREQ_LO (87 * 16000) 40 + #define FREQ_HI (108 * 16000) 33 41 34 42 /* 35 43 * definitions ··· 60 52 #define TEA575X_BIT_SEARCH_150_1000 (3<<16) /* FM > 150uV, AM > 1000uV */ 61 53 #define TEA575X_BIT_DUMMY (1<<15) /* buffer */ 62 54 #define TEA575X_BIT_FREQ_MASK 0x7fff 55 + 56 + static struct v4l2_queryctrl radio_qctrl[] = { 57 + { 58 + .id = V4L2_CID_AUDIO_MUTE, 59 + .name = "Mute", 60 + .minimum = 0, 61 + .maximum = 1, 62 + .default_value = 1, 63 + .type = V4L2_CTRL_TYPE_BOOLEAN, 64 + } 65 + }; 63 66 64 67 /* 65 68 * lowlevel part ··· 103 84 * Linux Video interface 104 85 */ 105 86 106 - static long snd_tea575x_ioctl(struct file *file, 107 - unsigned int cmd, unsigned long data) 87 + static int vidioc_querycap(struct file *file, void *priv, 88 + struct v4l2_capability *v) 108 89 { 109 90 struct snd_tea575x *tea = video_drvdata(file); 110 - void __user *arg = (void __user *)data; 111 91 112 - switch(cmd) { 113 - case VIDIOCGCAP: 114 - { 115 - struct video_capability v; 116 - v.type = VID_TYPE_TUNER; 117 - v.channels = 1; 118 - v.audios = 1; 119 - /* No we don't do pictures */ 120 - v.maxwidth = 0; 121 - v.maxheight = 0; 122 - v.minwidth = 0; 123 - v.minheight = 0; 124 - strcpy(v.name, tea->tea5759 ? "TEA5759" : "TEA5757"); 125 - if (copy_to_user(arg,&v,sizeof(v))) 126 - return -EFAULT; 127 - return 0; 128 - } 129 - case VIDIOCGTUNER: 130 - { 131 - struct video_tuner v; 132 - if (copy_from_user(&v, arg,sizeof(v))!=0) 133 - return -EFAULT; 134 - if (v.tuner) /* Only 1 tuner */ 135 - return -EINVAL; 136 - v.rangelow = (87*16000); 137 - v.rangehigh = (108*16000); 138 - v.flags = VIDEO_TUNER_LOW; 139 - v.mode = VIDEO_MODE_AUTO; 140 - strcpy(v.name, "FM"); 141 - v.signal = 0xFFFF; 142 - if (copy_to_user(arg, &v, sizeof(v))) 143 - return -EFAULT; 144 - return 0; 145 - } 146 - case VIDIOCSTUNER: 147 - { 148 - struct video_tuner v; 149 - if(copy_from_user(&v, arg, sizeof(v))) 150 - return -EFAULT; 151 - if(v.tuner!=0) 152 - return -EINVAL; 153 - /* Only 1 tuner so no setting needed ! */ 154 - return 0; 155 - } 156 - case VIDIOCGFREQ: 157 - if(copy_to_user(arg, &tea->freq, sizeof(tea->freq))) 158 - return -EFAULT; 159 - return 0; 160 - case VIDIOCSFREQ: 161 - if(copy_from_user(&tea->freq, arg, sizeof(tea->freq))) 162 - return -EFAULT; 163 - snd_tea575x_set_freq(tea); 164 - return 0; 165 - case VIDIOCGAUDIO: 166 - { 167 - struct video_audio v; 168 - memset(&v, 0, sizeof(v)); 169 - strcpy(v.name, "Radio"); 170 - if(copy_to_user(arg,&v, sizeof(v))) 171 - return -EFAULT; 172 - return 0; 173 - } 174 - case VIDIOCSAUDIO: 175 - { 176 - struct video_audio v; 177 - if(copy_from_user(&v, arg, sizeof(v))) 178 - return -EFAULT; 179 - if (tea->ops->mute) 180 - tea->ops->mute(tea, 181 - (v.flags & 182 - VIDEO_AUDIO_MUTE) ? 1 : 0); 183 - if(v.audio) 184 - return -EINVAL; 185 - return 0; 186 - } 187 - default: 188 - return -ENOIOCTLCMD; 189 - } 92 + strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757"); 93 + strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); 94 + strlcpy(v->card, "Maestro Radio", sizeof(v->card)); 95 + sprintf(v->bus_info, "PCI"); 96 + v->version = RADIO_VERSION; 97 + v->capabilities = V4L2_CAP_TUNER; 98 + return 0; 190 99 } 191 100 192 - static void snd_tea575x_release(struct video_device *vfd) 101 + static int vidioc_g_tuner(struct file *file, void *priv, 102 + struct v4l2_tuner *v) 193 103 { 104 + if (v->index > 0) 105 + return -EINVAL; 106 + 107 + strcpy(v->name, "FM"); 108 + v->type = V4L2_TUNER_RADIO; 109 + v->rangelow = FREQ_LO; 110 + v->rangehigh = FREQ_HI; 111 + v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; 112 + v->capability = V4L2_TUNER_CAP_LOW; 113 + v->audmode = V4L2_TUNER_MODE_MONO; 114 + v->signal = 0xffff; 115 + return 0; 116 + } 117 + 118 + static int vidioc_s_tuner(struct file *file, void *priv, 119 + struct v4l2_tuner *v) 120 + { 121 + if (v->index > 0) 122 + return -EINVAL; 123 + return 0; 124 + } 125 + 126 + static int vidioc_g_frequency(struct file *file, void *priv, 127 + struct v4l2_frequency *f) 128 + { 129 + struct snd_tea575x *tea = video_drvdata(file); 130 + 131 + f->type = V4L2_TUNER_RADIO; 132 + f->frequency = tea->freq; 133 + return 0; 134 + } 135 + 136 + static int vidioc_s_frequency(struct file *file, void *priv, 137 + struct v4l2_frequency *f) 138 + { 139 + struct snd_tea575x *tea = video_drvdata(file); 140 + 141 + if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) 142 + return -EINVAL; 143 + 144 + tea->freq = f->frequency; 145 + 146 + snd_tea575x_set_freq(tea); 147 + 148 + return 0; 149 + } 150 + 151 + static int vidioc_g_audio(struct file *file, void *priv, 152 + struct v4l2_audio *a) 153 + { 154 + if (a->index > 1) 155 + return -EINVAL; 156 + 157 + strcpy(a->name, "Radio"); 158 + a->capability = V4L2_AUDCAP_STEREO; 159 + return 0; 160 + } 161 + 162 + static int vidioc_s_audio(struct file *file, void *priv, 163 + struct v4l2_audio *a) 164 + { 165 + if (a->index != 0) 166 + return -EINVAL; 167 + return 0; 168 + } 169 + 170 + static int vidioc_queryctrl(struct file *file, void *priv, 171 + struct v4l2_queryctrl *qc) 172 + { 173 + int i; 174 + 175 + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 176 + if (qc->id && qc->id == radio_qctrl[i].id) { 177 + memcpy(qc, &(radio_qctrl[i]), 178 + sizeof(*qc)); 179 + return 0; 180 + } 181 + } 182 + return -EINVAL; 183 + } 184 + 185 + static int vidioc_g_ctrl(struct file *file, void *priv, 186 + struct v4l2_control *ctrl) 187 + { 188 + struct snd_tea575x *tea = video_drvdata(file); 189 + 190 + switch (ctrl->id) { 191 + case V4L2_CID_AUDIO_MUTE: 192 + if (tea->ops->mute) { 193 + ctrl->value = tea->mute; 194 + return 0; 195 + } 196 + } 197 + return -EINVAL; 198 + } 199 + 200 + static int vidioc_s_ctrl(struct file *file, void *priv, 201 + struct v4l2_control *ctrl) 202 + { 203 + struct snd_tea575x *tea = video_drvdata(file); 204 + 205 + switch (ctrl->id) { 206 + case V4L2_CID_AUDIO_MUTE: 207 + if (tea->ops->mute) { 208 + tea->ops->mute(tea, ctrl->value); 209 + tea->mute = 1; 210 + return 0; 211 + } 212 + } 213 + return -EINVAL; 214 + } 215 + 216 + static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 217 + { 218 + *i = 0; 219 + return 0; 220 + } 221 + 222 + static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 223 + { 224 + if (i != 0) 225 + return -EINVAL; 226 + return 0; 194 227 } 195 228 196 229 static int snd_tea575x_exclusive_open(struct file *file) ··· 260 189 return 0; 261 190 } 262 191 192 + static const struct v4l2_file_operations tea575x_fops = { 193 + .owner = THIS_MODULE, 194 + .open = snd_tea575x_exclusive_open, 195 + .release = snd_tea575x_exclusive_release, 196 + .ioctl = video_ioctl2, 197 + }; 198 + 199 + static const struct v4l2_ioctl_ops tea575x_ioctl_ops = { 200 + .vidioc_querycap = vidioc_querycap, 201 + .vidioc_g_tuner = vidioc_g_tuner, 202 + .vidioc_s_tuner = vidioc_s_tuner, 203 + .vidioc_g_audio = vidioc_g_audio, 204 + .vidioc_s_audio = vidioc_s_audio, 205 + .vidioc_g_input = vidioc_g_input, 206 + .vidioc_s_input = vidioc_s_input, 207 + .vidioc_g_frequency = vidioc_g_frequency, 208 + .vidioc_s_frequency = vidioc_s_frequency, 209 + .vidioc_queryctrl = vidioc_queryctrl, 210 + .vidioc_g_ctrl = vidioc_g_ctrl, 211 + .vidioc_s_ctrl = vidioc_s_ctrl, 212 + }; 213 + 214 + static struct video_device tea575x_radio = { 215 + .name = "tea575x-tuner", 216 + .fops = &tea575x_fops, 217 + .ioctl_ops = &tea575x_ioctl_ops, 218 + .release = video_device_release, 219 + }; 220 + 263 221 /* 264 222 * initialize all the tea575x chips 265 223 */ 266 224 void snd_tea575x_init(struct snd_tea575x *tea) 267 225 { 226 + int retval; 268 227 unsigned int val; 228 + struct video_device *tea575x_radio_inst; 269 229 270 230 val = tea->ops->read(tea); 271 231 if (val == 0x1ffffff || val == 0) { 272 - snd_printk(KERN_ERR "Cannot find TEA575x chip\n"); 232 + snd_printk(KERN_ERR 233 + "tea575x-tuner: Cannot find TEA575x chip\n"); 273 234 return; 274 235 } 275 236 276 - memset(&tea->vd, 0, sizeof(tea->vd)); 277 - strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio"); 278 - tea->vd.release = snd_tea575x_release; 279 - video_set_drvdata(&tea->vd, tea); 280 - tea->vd.fops = &tea->fops; 281 237 tea->in_use = 0; 282 - tea->fops.owner = tea->card->module; 283 - tea->fops.open = snd_tea575x_exclusive_open; 284 - tea->fops.release = snd_tea575x_exclusive_release; 285 - tea->fops.ioctl = snd_tea575x_ioctl; 286 - if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) { 287 - snd_printk(KERN_ERR "unable to register tea575x tuner\n"); 288 - return; 289 - } 290 - tea->vd_registered = 1; 291 - 292 238 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; 293 239 tea->freq = 90500 * 16; /* 90.5Mhz default */ 240 + 241 + tea575x_radio_inst = video_device_alloc(); 242 + if (tea575x_radio_inst == NULL) { 243 + printk(KERN_ERR "tea575x-tuner: not enough memory\n"); 244 + return; 245 + } 246 + 247 + memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio)); 248 + 249 + strcpy(tea575x_radio.name, tea->tea5759 ? 250 + "TEA5759 radio" : "TEA5757 radio"); 251 + 252 + video_set_drvdata(tea575x_radio_inst, tea); 253 + 254 + retval = video_register_device(tea575x_radio_inst, 255 + VFL_TYPE_RADIO, radio_nr); 256 + if (retval) { 257 + printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); 258 + kfree(tea575x_radio_inst); 259 + return; 260 + } 294 261 295 262 snd_tea575x_set_freq(tea); 296 263 297 264 /* mute on init */ 298 - if (tea->ops->mute) 265 + if (tea->ops->mute) { 299 266 tea->ops->mute(tea, 1); 267 + tea->mute = 1; 268 + } 269 + tea->vd = tea575x_radio_inst; 300 270 } 301 271 302 272 void snd_tea575x_exit(struct snd_tea575x *tea) 303 273 { 304 - if (tea->vd_registered) { 305 - video_unregister_device(&tea->vd); 306 - tea->vd_registered = 0; 274 + if (tea->vd) { 275 + video_unregister_device(tea->vd); 276 + tea->vd = NULL; 307 277 } 308 278 } 309 279
+1 -1
sound/pci/Kconfig
··· 507 507 config SND_FM801_TEA575X_BOOL 508 508 bool "ForteMedia FM801 + TEA5757 tuner" 509 509 depends on SND_FM801 510 - depends on VIDEO_V4L1=y || VIDEO_V4L1=SND_FM801 510 + depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801 511 511 help 512 512 Say Y here to include support for soundcards based on the ForteMedia 513 513 FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media