diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/radio/radio-sf16fmi.c | 262 |
1 files changed, 146 insertions, 116 deletions
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index f4619e4dda4f..dc33f19c0e2c 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
@@ -130,137 +130,155 @@ static inline int fmi_getsigstr(struct fmi_device *dev) | |||
130 | return (res & 2) ? 0 : 0xFFFF; | 130 | return (res & 2) ? 0 : 0xFFFF; |
131 | } | 131 | } |
132 | 132 | ||
133 | static int fmi_do_ioctl(struct inode *inode, struct file *file, | 133 | static int vidioc_querycap(struct file *file, void *priv, |
134 | unsigned int cmd, void *arg) | 134 | struct v4l2_capability *v) |
135 | { | 135 | { |
136 | strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver)); | ||
137 | strlcpy(v->card, "SF16-FMx radio", sizeof(v->card)); | ||
138 | sprintf(v->bus_info, "ISA"); | ||
139 | v->version = RADIO_VERSION; | ||
140 | v->capabilities = V4L2_CAP_TUNER; | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int vidioc_g_tuner(struct file *file, void *priv, | ||
145 | struct v4l2_tuner *v) | ||
146 | { | ||
147 | int mult; | ||
136 | struct video_device *dev = video_devdata(file); | 148 | struct video_device *dev = video_devdata(file); |
137 | struct fmi_device *fmi=dev->priv; | 149 | struct fmi_device *fmi = dev->priv; |
138 | 150 | ||
139 | switch(cmd) | 151 | if (v->index > 0) |
140 | { | 152 | return -EINVAL; |
141 | case VIDIOC_QUERYCAP: | ||
142 | { | ||
143 | struct v4l2_capability *v = arg; | ||
144 | memset(v,0,sizeof(*v)); | ||
145 | strlcpy(v->driver, "radio-sf16fmi", sizeof (v->driver)); | ||
146 | strlcpy(v->card, "SF16-FMx radio", sizeof (v->card)); | ||
147 | sprintf(v->bus_info,"ISA"); | ||
148 | v->version = RADIO_VERSION; | ||
149 | v->capabilities = V4L2_CAP_TUNER; | ||
150 | 153 | ||
151 | return 0; | 154 | strcpy(v->name, "FM"); |
152 | } | 155 | v->type = V4L2_TUNER_RADIO; |
153 | case VIDIOC_G_TUNER: | 156 | mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; |
154 | { | 157 | v->rangelow = RSF16_MINFREQ/mult; |
155 | struct v4l2_tuner *v = arg; | 158 | v->rangehigh = RSF16_MAXFREQ/mult; |
156 | int mult; | 159 | v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO; |
157 | 160 | v->capability = fmi->flags&V4L2_TUNER_CAP_LOW; | |
158 | if (v->index > 0) | 161 | v->audmode = V4L2_TUNER_MODE_STEREO; |
159 | return -EINVAL; | 162 | v->signal = fmi_getsigstr(fmi); |
160 | 163 | return 0; | |
161 | memset(v,0,sizeof(*v)); | 164 | } |
162 | strcpy(v->name, "FM"); | ||
163 | v->type = V4L2_TUNER_RADIO; | ||
164 | |||
165 | mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; | ||
166 | v->rangelow = RSF16_MINFREQ/mult; | ||
167 | v->rangehigh = RSF16_MAXFREQ/mult; | ||
168 | v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO; | ||
169 | v->capability=fmi->flags&V4L2_TUNER_CAP_LOW; | ||
170 | v->audmode = V4L2_TUNER_MODE_STEREO; | ||
171 | v->signal = fmi_getsigstr(fmi); | ||
172 | 165 | ||
173 | return 0; | 166 | static int vidioc_s_tuner(struct file *file, void *priv, |
174 | } | 167 | struct v4l2_tuner *v) |
175 | case VIDIOC_S_TUNER: | 168 | { |
176 | { | 169 | if (v->index > 0) |
177 | struct v4l2_tuner *v = arg; | 170 | return -EINVAL; |
171 | return 0; | ||
172 | } | ||
178 | 173 | ||
179 | if (v->index > 0) | 174 | static int vidioc_s_frequency(struct file *file, void *priv, |
180 | return -EINVAL; | 175 | struct v4l2_frequency *f) |
176 | { | ||
177 | struct video_device *dev = video_devdata(file); | ||
178 | struct fmi_device *fmi = dev->priv; | ||
181 | 179 | ||
182 | return 0; | 180 | if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) |
183 | } | 181 | f->frequency *= 1000; |
184 | case VIDIOC_S_FREQUENCY: | 182 | if (f->frequency < RSF16_MINFREQ || |
185 | { | 183 | f->frequency > RSF16_MAXFREQ ) |
186 | struct v4l2_frequency *f = arg; | 184 | return -EINVAL; |
187 | 185 | /*rounding in steps of 800 to match th freq | |
188 | if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) | 186 | that will be used */ |
189 | f->frequency *= 1000; | 187 | fmi->curfreq = (f->frequency/800)*800; |
190 | if (f->frequency < RSF16_MINFREQ || | 188 | fmi_setfreq(fmi); |
191 | f->frequency > RSF16_MAXFREQ ) | 189 | return 0; |
192 | return -EINVAL; | 190 | } |
193 | /*rounding in steps of 800 to match th freq | ||
194 | that will be used */ | ||
195 | fmi->curfreq = (f->frequency/800)*800; | ||
196 | fmi_setfreq(fmi); | ||
197 | 191 | ||
198 | return 0; | 192 | static int vidioc_g_frequency(struct file *file, void *priv, |
199 | } | 193 | struct v4l2_frequency *f) |
200 | case VIDIOC_G_FREQUENCY: | 194 | { |
201 | { | 195 | struct video_device *dev = video_devdata(file); |
202 | struct v4l2_frequency *f = arg; | 196 | struct fmi_device *fmi = dev->priv; |
203 | 197 | ||
204 | f->type = V4L2_TUNER_RADIO; | 198 | f->type = V4L2_TUNER_RADIO; |
205 | f->frequency = fmi->curfreq; | 199 | f->frequency = fmi->curfreq; |
206 | if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) | 200 | if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) |
207 | f->frequency /= 1000; | 201 | f->frequency /= 1000; |
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
206 | struct v4l2_queryctrl *qc) | ||
207 | { | ||
208 | int i; | ||
208 | 209 | ||
210 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | ||
211 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
212 | memcpy(qc, &(radio_qctrl[i]), | ||
213 | sizeof(*qc)); | ||
209 | return 0; | 214 | return 0; |
210 | } | 215 | } |
211 | case VIDIOC_QUERYCTRL: | ||
212 | { | ||
213 | struct v4l2_queryctrl *qc = arg; | ||
214 | int i; | ||
215 | |||
216 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | ||
217 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
218 | memcpy(qc, &(radio_qctrl[i]), | ||
219 | sizeof(*qc)); | ||
220 | return (0); | ||
221 | } | ||
222 | } | ||
223 | return -EINVAL; | ||
224 | } | ||
225 | case VIDIOC_G_CTRL: | ||
226 | { | ||
227 | struct v4l2_control *ctrl= arg; | ||
228 | |||
229 | switch (ctrl->id) { | ||
230 | case V4L2_CID_AUDIO_MUTE: | ||
231 | ctrl->value=fmi->curvol; | ||
232 | return (0); | ||
233 | } | ||
234 | return -EINVAL; | ||
235 | } | ||
236 | case VIDIOC_S_CTRL: | ||
237 | { | ||
238 | struct v4l2_control *ctrl= arg; | ||
239 | |||
240 | switch (ctrl->id) { | ||
241 | case V4L2_CID_AUDIO_MUTE: | ||
242 | { | ||
243 | if (ctrl->value) | ||
244 | fmi_mute(fmi->port); | ||
245 | else | ||
246 | fmi_unmute(fmi->port); | ||
247 | |||
248 | fmi->curvol=ctrl->value; | ||
249 | return (0); | ||
250 | } | ||
251 | } | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | default: | ||
255 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | ||
256 | fmi_do_ioctl); | ||
257 | } | 216 | } |
217 | return -EINVAL; | ||
218 | } | ||
219 | |||
220 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
221 | struct v4l2_control *ctrl) | ||
222 | { | ||
223 | struct video_device *dev = video_devdata(file); | ||
224 | struct fmi_device *fmi = dev->priv; | ||
225 | |||
226 | switch (ctrl->id) { | ||
227 | case V4L2_CID_AUDIO_MUTE: | ||
228 | ctrl->value = fmi->curvol; | ||
229 | return 0; | ||
230 | } | ||
231 | return -EINVAL; | ||
232 | } | ||
233 | |||
234 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
235 | struct v4l2_control *ctrl) | ||
236 | { | ||
237 | struct video_device *dev = video_devdata(file); | ||
238 | struct fmi_device *fmi = dev->priv; | ||
239 | |||
240 | switch (ctrl->id) { | ||
241 | case V4L2_CID_AUDIO_MUTE: | ||
242 | if (ctrl->value) | ||
243 | fmi_mute(fmi->port); | ||
244 | else | ||
245 | fmi_unmute(fmi->port); | ||
246 | fmi->curvol = ctrl->value; | ||
247 | return 0; | ||
248 | } | ||
249 | return -EINVAL; | ||
258 | } | 250 | } |
259 | 251 | ||
260 | static int fmi_ioctl(struct inode *inode, struct file *file, | 252 | static int vidioc_g_audio(struct file *file, void *priv, |
261 | unsigned int cmd, unsigned long arg) | 253 | struct v4l2_audio *a) |
262 | { | 254 | { |
263 | return video_usercopy(inode, file, cmd, arg, fmi_do_ioctl); | 255 | if (a->index > 1) |
256 | return -EINVAL; | ||
257 | |||
258 | strcpy(a->name, "Radio"); | ||
259 | a->capability = V4L2_AUDCAP_STEREO; | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | ||
264 | { | ||
265 | *i = 0; | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) | ||
270 | { | ||
271 | if (i != 0) | ||
272 | return -EINVAL; | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int vidioc_s_audio(struct file *file, void *priv, | ||
277 | struct v4l2_audio *a) | ||
278 | { | ||
279 | if (a->index != 0) | ||
280 | return -EINVAL; | ||
281 | return 0; | ||
264 | } | 282 | } |
265 | 283 | ||
266 | static struct fmi_device fmi_unit; | 284 | static struct fmi_device fmi_unit; |
@@ -269,7 +287,7 @@ static const struct file_operations fmi_fops = { | |||
269 | .owner = THIS_MODULE, | 287 | .owner = THIS_MODULE, |
270 | .open = video_exclusive_open, | 288 | .open = video_exclusive_open, |
271 | .release = video_exclusive_release, | 289 | .release = video_exclusive_release, |
272 | .ioctl = fmi_ioctl, | 290 | .ioctl = video_ioctl2, |
273 | .compat_ioctl = v4l_compat_ioctl32, | 291 | .compat_ioctl = v4l_compat_ioctl32, |
274 | .llseek = no_llseek, | 292 | .llseek = no_llseek, |
275 | }; | 293 | }; |
@@ -281,6 +299,18 @@ static struct video_device fmi_radio= | |||
281 | .type = VID_TYPE_TUNER, | 299 | .type = VID_TYPE_TUNER, |
282 | .hardware = 0, | 300 | .hardware = 0, |
283 | .fops = &fmi_fops, | 301 | .fops = &fmi_fops, |
302 | .vidioc_querycap = vidioc_querycap, | ||
303 | .vidioc_g_tuner = vidioc_g_tuner, | ||
304 | .vidioc_s_tuner = vidioc_s_tuner, | ||
305 | .vidioc_g_audio = vidioc_g_audio, | ||
306 | .vidioc_s_audio = vidioc_s_audio, | ||
307 | .vidioc_g_input = vidioc_g_input, | ||
308 | .vidioc_s_input = vidioc_s_input, | ||
309 | .vidioc_g_frequency = vidioc_g_frequency, | ||
310 | .vidioc_s_frequency = vidioc_s_frequency, | ||
311 | .vidioc_queryctrl = vidioc_queryctrl, | ||
312 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
313 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
284 | }; | 314 | }; |
285 | 315 | ||
286 | /* ladis: this is my card. does any other types exist? */ | 316 | /* ladis: this is my card. does any other types exist? */ |