]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/pvrusb2/pvrusb2-v4l2.c
V4L/DVB (8898): pvrusb2: Be able to programmatically retrieve a control's default...
[linux-2.6-omap-h63xx.git] / drivers / media / video / pvrusb2 / pvrusb2-v4l2.c
1 /*
2  *
3  *
4  *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
5  *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include <linux/kernel.h>
23 #include <linux/version.h>
24 #include "pvrusb2-context.h"
25 #include "pvrusb2-hdw.h"
26 #include "pvrusb2.h"
27 #include "pvrusb2-debug.h"
28 #include "pvrusb2-v4l2.h"
29 #include "pvrusb2-ioread.h"
30 #include <linux/videodev2.h>
31 #include <media/v4l2-dev.h>
32 #include <media/v4l2-common.h>
33 #include <media/v4l2-ioctl.h>
34
35 struct pvr2_v4l2_dev;
36 struct pvr2_v4l2_fh;
37 struct pvr2_v4l2;
38
39 struct pvr2_v4l2_dev {
40         struct video_device devbase; /* MUST be first! */
41         struct pvr2_v4l2 *v4lp;
42         struct pvr2_context_stream *stream;
43         /* Information about this device: */
44         enum pvr2_config config; /* Expected stream format */
45         int v4l_type; /* V4L defined type for this device node */
46         enum pvr2_v4l_type minor_type; /* pvr2-understood minor device type */
47 };
48
49 struct pvr2_v4l2_fh {
50         struct pvr2_channel channel;
51         struct pvr2_v4l2_dev *dev_info;
52         enum v4l2_priority prio;
53         struct pvr2_ioread *rhp;
54         struct file *file;
55         struct pvr2_v4l2 *vhead;
56         struct pvr2_v4l2_fh *vnext;
57         struct pvr2_v4l2_fh *vprev;
58         wait_queue_head_t wait_data;
59         int fw_mode_flag;
60         /* Map contiguous ordinal value to input id */
61         unsigned char *input_map;
62         unsigned int input_cnt;
63 };
64
65 struct pvr2_v4l2 {
66         struct pvr2_channel channel;
67         struct pvr2_v4l2_fh *vfirst;
68         struct pvr2_v4l2_fh *vlast;
69
70         struct v4l2_prio_state prio;
71
72         /* streams - Note that these must be separately, individually,
73          * allocated pointers.  This is because the v4l core is going to
74          * manage their deletion - separately, individually...  */
75         struct pvr2_v4l2_dev *dev_video;
76         struct pvr2_v4l2_dev *dev_radio;
77 };
78
79 static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
80 module_param_array(video_nr, int, NULL, 0444);
81 MODULE_PARM_DESC(video_nr, "Offset for device's video dev minor");
82 static int radio_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
83 module_param_array(radio_nr, int, NULL, 0444);
84 MODULE_PARM_DESC(radio_nr, "Offset for device's radio dev minor");
85 static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
86 module_param_array(vbi_nr, int, NULL, 0444);
87 MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
88
89 static struct v4l2_capability pvr_capability ={
90         .driver         = "pvrusb2",
91         .card           = "Hauppauge WinTV pvr-usb2",
92         .bus_info       = "usb",
93         .version        = KERNEL_VERSION(0,8,0),
94         .capabilities   = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
95                            V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
96                            V4L2_CAP_READWRITE),
97         .reserved       = {0,0,0,0}
98 };
99
100 static struct v4l2_fmtdesc pvr_fmtdesc [] = {
101         {
102                 .index          = 0,
103                 .type           = V4L2_BUF_TYPE_VIDEO_CAPTURE,
104                 .flags          = V4L2_FMT_FLAG_COMPRESSED,
105                 .description    = "MPEG1/2",
106                 // This should really be V4L2_PIX_FMT_MPEG, but xawtv
107                 // breaks when I do that.
108                 .pixelformat    = 0, // V4L2_PIX_FMT_MPEG,
109                 .reserved       = { 0, 0, 0, 0 }
110         }
111 };
112
113 #define PVR_FORMAT_PIX  0
114 #define PVR_FORMAT_VBI  1
115
116 static struct v4l2_format pvr_format [] = {
117         [PVR_FORMAT_PIX] = {
118                 .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
119                 .fmt    = {
120                         .pix        = {
121                                 .width          = 720,
122                                 .height             = 576,
123                                 // This should really be V4L2_PIX_FMT_MPEG,
124                                 // but xawtv breaks when I do that.
125                                 .pixelformat    = 0, // V4L2_PIX_FMT_MPEG,
126                                 .field          = V4L2_FIELD_INTERLACED,
127                                 .bytesperline   = 0,  // doesn't make sense
128                                                       // here
129                                 //FIXME : Don't know what to put here...
130                                 .sizeimage          = (32*1024),
131                                 .colorspace     = 0, // doesn't make sense here
132                                 .priv           = 0
133                         }
134                 }
135         },
136         [PVR_FORMAT_VBI] = {
137                 .type   = V4L2_BUF_TYPE_VBI_CAPTURE,
138                 .fmt    = {
139                         .vbi        = {
140                                 .sampling_rate = 27000000,
141                                 .offset = 248,
142                                 .samples_per_line = 1443,
143                                 .sample_format = V4L2_PIX_FMT_GREY,
144                                 .start = { 0, 0 },
145                                 .count = { 0, 0 },
146                                 .flags = 0,
147                                 .reserved = { 0, 0 }
148                         }
149                 }
150         }
151 };
152
153
154 static const char *get_v4l_name(int v4l_type)
155 {
156         switch (v4l_type) {
157         case VFL_TYPE_GRABBER: return "video";
158         case VFL_TYPE_RADIO: return "radio";
159         case VFL_TYPE_VBI: return "vbi";
160         default: return "?";
161         }
162 }
163
164
165 /*
166  * pvr_ioctl()
167  *
168  * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
169  *
170  */
171 static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
172                               unsigned int cmd, void *arg)
173 {
174         struct pvr2_v4l2_fh *fh = file->private_data;
175         struct pvr2_v4l2 *vp = fh->vhead;
176         struct pvr2_v4l2_dev *dev_info = fh->dev_info;
177         struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
178         int ret = -EINVAL;
179
180         if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
181                 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd);
182         }
183
184         if (!pvr2_hdw_dev_ok(hdw)) {
185                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
186                            "ioctl failed - bad or no context");
187                 return -EFAULT;
188         }
189
190         /* check priority */
191         switch (cmd) {
192         case VIDIOC_S_CTRL:
193         case VIDIOC_S_STD:
194         case VIDIOC_S_INPUT:
195         case VIDIOC_S_TUNER:
196         case VIDIOC_S_FREQUENCY:
197                 ret = v4l2_prio_check(&vp->prio, &fh->prio);
198                 if (ret)
199                         return ret;
200         }
201
202         switch (cmd) {
203         case VIDIOC_QUERYCAP:
204         {
205                 struct v4l2_capability *cap = arg;
206
207                 memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
208                 strlcpy(cap->bus_info,pvr2_hdw_get_bus_info(hdw),
209                         sizeof(cap->bus_info));
210                 strlcpy(cap->card,pvr2_hdw_get_desc(hdw),sizeof(cap->card));
211
212                 ret = 0;
213                 break;
214         }
215
216         case VIDIOC_G_PRIORITY:
217         {
218                 enum v4l2_priority *p = arg;
219
220                 *p = v4l2_prio_max(&vp->prio);
221                 ret = 0;
222                 break;
223         }
224
225         case VIDIOC_S_PRIORITY:
226         {
227                 enum v4l2_priority *prio = arg;
228
229                 ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio);
230                 break;
231         }
232
233         case VIDIOC_ENUMSTD:
234         {
235                 struct v4l2_standard *vs = (struct v4l2_standard *)arg;
236                 int idx = vs->index;
237                 ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1);
238                 break;
239         }
240
241         case VIDIOC_G_STD:
242         {
243                 int val = 0;
244                 ret = pvr2_ctrl_get_value(
245                         pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val);
246                 *(v4l2_std_id *)arg = val;
247                 break;
248         }
249
250         case VIDIOC_S_STD:
251         {
252                 ret = pvr2_ctrl_set_value(
253                         pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),
254                         *(v4l2_std_id *)arg);
255                 break;
256         }
257
258         case VIDIOC_ENUMINPUT:
259         {
260                 struct pvr2_ctrl *cptr;
261                 struct v4l2_input *vi = (struct v4l2_input *)arg;
262                 struct v4l2_input tmp;
263                 unsigned int cnt;
264                 int val;
265
266                 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
267
268                 memset(&tmp,0,sizeof(tmp));
269                 tmp.index = vi->index;
270                 ret = 0;
271                 if ((vi->index < 0) || (vi->index >= fh->input_cnt)) {
272                         ret = -EINVAL;
273                         break;
274                 }
275                 val = fh->input_map[vi->index];
276                 switch (val) {
277                 case PVR2_CVAL_INPUT_TV:
278                 case PVR2_CVAL_INPUT_DTV:
279                 case PVR2_CVAL_INPUT_RADIO:
280                         tmp.type = V4L2_INPUT_TYPE_TUNER;
281                         break;
282                 case PVR2_CVAL_INPUT_SVIDEO:
283                 case PVR2_CVAL_INPUT_COMPOSITE:
284                         tmp.type = V4L2_INPUT_TYPE_CAMERA;
285                         break;
286                 default:
287                         ret = -EINVAL;
288                         break;
289                 }
290                 if (ret < 0) break;
291
292                 cnt = 0;
293                 pvr2_ctrl_get_valname(cptr,val,
294                                       tmp.name,sizeof(tmp.name)-1,&cnt);
295                 tmp.name[cnt] = 0;
296
297                 /* Don't bother with audioset, since this driver currently
298                    always switches the audio whenever the video is
299                    switched. */
300
301                 /* Handling std is a tougher problem.  It doesn't make
302                    sense in cases where a device might be multi-standard.
303                    We could just copy out the current value for the
304                    standard, but it can change over time.  For now just
305                    leave it zero. */
306
307                 memcpy(vi, &tmp, sizeof(tmp));
308
309                 ret = 0;
310                 break;
311         }
312
313         case VIDIOC_G_INPUT:
314         {
315                 unsigned int idx;
316                 struct pvr2_ctrl *cptr;
317                 struct v4l2_input *vi = (struct v4l2_input *)arg;
318                 int val;
319                 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
320                 val = 0;
321                 ret = pvr2_ctrl_get_value(cptr,&val);
322                 vi->index = 0;
323                 for (idx = 0; idx < fh->input_cnt; idx++) {
324                         if (fh->input_map[idx] == val) {
325                                 vi->index = idx;
326                                 break;
327                         }
328                 }
329                 break;
330         }
331
332         case VIDIOC_S_INPUT:
333         {
334                 struct v4l2_input *vi = (struct v4l2_input *)arg;
335                 if ((vi->index < 0) || (vi->index >= fh->input_cnt)) {
336                         ret = -ERANGE;
337                         break;
338                 }
339                 ret = pvr2_ctrl_set_value(
340                         pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
341                         fh->input_map[vi->index]);
342                 break;
343         }
344
345         case VIDIOC_ENUMAUDIO:
346         {
347                 /* pkt: FIXME: We are returning one "fake" input here
348                    which could very well be called "whatever_we_like".
349                    This is for apps that want to see an audio input
350                    just to feel comfortable, as well as to test if
351                    it can do stereo or sth. There is actually no guarantee
352                    that the actual audio input cannot change behind the app's
353                    back, but most applications should not mind that either.
354
355                    Hopefully, mplayer people will work with us on this (this
356                    whole mess is to support mplayer pvr://), or Hans will come
357                    up with a more standard way to say "we have inputs but we
358                    don 't want you to change them independent of video" which
359                    will sort this mess.
360                  */
361                 struct v4l2_audio *vin = arg;
362                 ret = -EINVAL;
363                 if (vin->index > 0) break;
364                 strncpy(vin->name, "PVRUSB2 Audio",14);
365                 vin->capability = V4L2_AUDCAP_STEREO;
366                 ret = 0;
367                 break;
368                 break;
369         }
370
371         case VIDIOC_G_AUDIO:
372         {
373                 /* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */
374                 struct v4l2_audio *vin = arg;
375                 memset(vin,0,sizeof(*vin));
376                 vin->index = 0;
377                 strncpy(vin->name, "PVRUSB2 Audio",14);
378                 vin->capability = V4L2_AUDCAP_STEREO;
379                 ret = 0;
380                 break;
381         }
382
383         case VIDIOC_S_AUDIO:
384         {
385                 ret = -EINVAL;
386                 break;
387         }
388         case VIDIOC_G_TUNER:
389         {
390                 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
391
392                 if (vt->index != 0) break; /* Only answer for the 1st tuner */
393
394                 pvr2_hdw_execute_tuner_poll(hdw);
395                 ret = pvr2_hdw_get_tuner_status(hdw,vt);
396                 break;
397         }
398
399         case VIDIOC_S_TUNER:
400         {
401                 struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
402
403                 if (vt->index != 0)
404                         break;
405
406                 ret = pvr2_ctrl_set_value(
407                         pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
408                         vt->audmode);
409                 break;
410         }
411
412         case VIDIOC_S_FREQUENCY:
413         {
414                 const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
415                 unsigned long fv;
416                 struct v4l2_tuner vt;
417                 int cur_input;
418                 struct pvr2_ctrl *ctrlp;
419                 ret = pvr2_hdw_get_tuner_status(hdw,&vt);
420                 if (ret != 0) break;
421                 ctrlp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
422                 ret = pvr2_ctrl_get_value(ctrlp,&cur_input);
423                 if (ret != 0) break;
424                 if (vf->type == V4L2_TUNER_RADIO) {
425                         if (cur_input != PVR2_CVAL_INPUT_RADIO) {
426                                 pvr2_ctrl_set_value(ctrlp,
427                                                     PVR2_CVAL_INPUT_RADIO);
428                         }
429                 } else {
430                         if (cur_input == PVR2_CVAL_INPUT_RADIO) {
431                                 pvr2_ctrl_set_value(ctrlp,
432                                                     PVR2_CVAL_INPUT_TV);
433                         }
434                 }
435                 fv = vf->frequency;
436                 if (vt.capability & V4L2_TUNER_CAP_LOW) {
437                         fv = (fv * 125) / 2;
438                 } else {
439                         fv = fv * 62500;
440                 }
441                 ret = pvr2_ctrl_set_value(
442                         pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv);
443                 break;
444         }
445
446         case VIDIOC_G_FREQUENCY:
447         {
448                 struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
449                 int val = 0;
450                 int cur_input;
451                 struct v4l2_tuner vt;
452                 ret = pvr2_hdw_get_tuner_status(hdw,&vt);
453                 if (ret != 0) break;
454                 ret = pvr2_ctrl_get_value(
455                         pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
456                         &val);
457                 if (ret != 0) break;
458                 pvr2_ctrl_get_value(
459                         pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
460                         &cur_input);
461                 if (cur_input == PVR2_CVAL_INPUT_RADIO) {
462                         vf->type = V4L2_TUNER_RADIO;
463                 } else {
464                         vf->type = V4L2_TUNER_ANALOG_TV;
465                 }
466                 if (vt.capability & V4L2_TUNER_CAP_LOW) {
467                         val = (val * 2) / 125;
468                 } else {
469                         val /= 62500;
470                 }
471                 vf->frequency = val;
472                 break;
473         }
474
475         case VIDIOC_ENUM_FMT:
476         {
477                 struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg;
478
479                 /* Only one format is supported : mpeg.*/
480                 if (fd->index != 0)
481                         break;
482
483                 memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
484                 ret = 0;
485                 break;
486         }
487
488         case VIDIOC_G_FMT:
489         {
490                 struct v4l2_format *vf = (struct v4l2_format *)arg;
491                 int val;
492                 switch(vf->type) {
493                 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
494                         memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
495                                sizeof(struct v4l2_format));
496                         val = 0;
497                         pvr2_ctrl_get_value(
498                                 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES),
499                                 &val);
500                         vf->fmt.pix.width = val;
501                         val = 0;
502                         pvr2_ctrl_get_value(
503                                 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES),
504                                 &val);
505                         vf->fmt.pix.height = val;
506                         ret = 0;
507                         break;
508                 case V4L2_BUF_TYPE_VBI_CAPTURE:
509                         // ????? Still need to figure out to do VBI correctly
510                         ret = -EINVAL;
511                         break;
512                 default:
513                         ret = -EINVAL;
514                         break;
515                 }
516                 break;
517         }
518
519         case VIDIOC_TRY_FMT:
520         case VIDIOC_S_FMT:
521         {
522                 struct v4l2_format *vf = (struct v4l2_format *)arg;
523
524                 ret = 0;
525                 switch(vf->type) {
526                 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
527                         int lmin,lmax,ldef;
528                         struct pvr2_ctrl *hcp,*vcp;
529                         int h = vf->fmt.pix.height;
530                         int w = vf->fmt.pix.width;
531                         hcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES);
532                         vcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES);
533
534                         lmin = pvr2_ctrl_get_min(hcp);
535                         lmax = pvr2_ctrl_get_max(hcp);
536                         pvr2_ctrl_get_def(hcp, &ldef);
537                         if (w == -1) {
538                                 w = ldef;
539                         } else if (w < lmin) {
540                                 w = lmin;
541                         } else if (w > lmax) {
542                                 w = lmax;
543                         }
544                         lmin = pvr2_ctrl_get_min(vcp);
545                         lmax = pvr2_ctrl_get_max(vcp);
546                         pvr2_ctrl_get_def(vcp, &ldef);
547                         if (h == -1) {
548                                 h = ldef;
549                         } else if (h < lmin) {
550                                 h = lmin;
551                         } else if (h > lmax) {
552                                 h = lmax;
553                         }
554
555                         memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
556                                sizeof(struct v4l2_format));
557                         vf->fmt.pix.width = w;
558                         vf->fmt.pix.height = h;
559
560                         if (cmd == VIDIOC_S_FMT) {
561                                 pvr2_ctrl_set_value(hcp,vf->fmt.pix.width);
562                                 pvr2_ctrl_set_value(vcp,vf->fmt.pix.height);
563                         }
564                 } break;
565                 case V4L2_BUF_TYPE_VBI_CAPTURE:
566                         // ????? Still need to figure out to do VBI correctly
567                         ret = -EINVAL;
568                         break;
569                 default:
570                         ret = -EINVAL;
571                         break;
572                 }
573                 break;
574         }
575
576         case VIDIOC_STREAMON:
577         {
578                 if (!fh->dev_info->stream) {
579                         /* No stream defined for this node.  This means
580                            that we're not currently allowed to stream from
581                            this node. */
582                         ret = -EPERM;
583                         break;
584                 }
585                 ret = pvr2_hdw_set_stream_type(hdw,dev_info->config);
586                 if (ret < 0) return ret;
587                 ret = pvr2_hdw_set_streaming(hdw,!0);
588                 break;
589         }
590
591         case VIDIOC_STREAMOFF:
592         {
593                 if (!fh->dev_info->stream) {
594                         /* No stream defined for this node.  This means
595                            that we're not currently allowed to stream from
596                            this node. */
597                         ret = -EPERM;
598                         break;
599                 }
600                 ret = pvr2_hdw_set_streaming(hdw,0);
601                 break;
602         }
603
604         case VIDIOC_QUERYCTRL:
605         {
606                 struct pvr2_ctrl *cptr;
607                 int val;
608                 struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg;
609                 ret = 0;
610                 if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
611                         cptr = pvr2_hdw_get_ctrl_nextv4l(
612                                 hdw,(vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
613                         if (cptr) vc->id = pvr2_ctrl_get_v4lid(cptr);
614                 } else {
615                         cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id);
616                 }
617                 if (!cptr) {
618                         pvr2_trace(PVR2_TRACE_V4LIOCTL,
619                                    "QUERYCTRL id=0x%x not implemented here",
620                                    vc->id);
621                         ret = -EINVAL;
622                         break;
623                 }
624
625                 pvr2_trace(PVR2_TRACE_V4LIOCTL,
626                            "QUERYCTRL id=0x%x mapping name=%s (%s)",
627                            vc->id,pvr2_ctrl_get_name(cptr),
628                            pvr2_ctrl_get_desc(cptr));
629                 strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name));
630                 vc->flags = pvr2_ctrl_get_v4lflags(cptr);
631                 pvr2_ctrl_get_def(cptr, &val);
632                 vc->default_value = val;
633                 switch (pvr2_ctrl_get_type(cptr)) {
634                 case pvr2_ctl_enum:
635                         vc->type = V4L2_CTRL_TYPE_MENU;
636                         vc->minimum = 0;
637                         vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
638                         vc->step = 1;
639                         break;
640                 case pvr2_ctl_bool:
641                         vc->type = V4L2_CTRL_TYPE_BOOLEAN;
642                         vc->minimum = 0;
643                         vc->maximum = 1;
644                         vc->step = 1;
645                         break;
646                 case pvr2_ctl_int:
647                         vc->type = V4L2_CTRL_TYPE_INTEGER;
648                         vc->minimum = pvr2_ctrl_get_min(cptr);
649                         vc->maximum = pvr2_ctrl_get_max(cptr);
650                         vc->step = 1;
651                         break;
652                 default:
653                         pvr2_trace(PVR2_TRACE_V4LIOCTL,
654                                    "QUERYCTRL id=0x%x name=%s not mappable",
655                                    vc->id,pvr2_ctrl_get_name(cptr));
656                         ret = -EINVAL;
657                         break;
658                 }
659                 break;
660         }
661
662         case VIDIOC_QUERYMENU:
663         {
664                 struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg;
665                 unsigned int cnt = 0;
666                 ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id),
667                                             vm->index,
668                                             vm->name,sizeof(vm->name)-1,
669                                             &cnt);
670                 vm->name[cnt] = 0;
671                 break;
672         }
673
674         case VIDIOC_G_CTRL:
675         {
676                 struct v4l2_control *vc = (struct v4l2_control *)arg;
677                 int val = 0;
678                 ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
679                                           &val);
680                 vc->value = val;
681                 break;
682         }
683
684         case VIDIOC_S_CTRL:
685         {
686                 struct v4l2_control *vc = (struct v4l2_control *)arg;
687                 ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
688                                           vc->value);
689                 break;
690         }
691
692         case VIDIOC_G_EXT_CTRLS:
693         {
694                 struct v4l2_ext_controls *ctls =
695                         (struct v4l2_ext_controls *)arg;
696                 struct v4l2_ext_control *ctrl;
697                 unsigned int idx;
698                 int val;
699                 ret = 0;
700                 for (idx = 0; idx < ctls->count; idx++) {
701                         ctrl = ctls->controls + idx;
702                         ret = pvr2_ctrl_get_value(
703                                 pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),&val);
704                         if (ret) {
705                                 ctls->error_idx = idx;
706                                 break;
707                         }
708                         /* Ensure that if read as a 64 bit value, the user
709                            will still get a hopefully sane value */
710                         ctrl->value64 = 0;
711                         ctrl->value = val;
712                 }
713                 break;
714         }
715
716         case VIDIOC_S_EXT_CTRLS:
717         {
718                 struct v4l2_ext_controls *ctls =
719                         (struct v4l2_ext_controls *)arg;
720                 struct v4l2_ext_control *ctrl;
721                 unsigned int idx;
722                 ret = 0;
723                 for (idx = 0; idx < ctls->count; idx++) {
724                         ctrl = ctls->controls + idx;
725                         ret = pvr2_ctrl_set_value(
726                                 pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),
727                                 ctrl->value);
728                         if (ret) {
729                                 ctls->error_idx = idx;
730                                 break;
731                         }
732                 }
733                 break;
734         }
735
736         case VIDIOC_TRY_EXT_CTRLS:
737         {
738                 struct v4l2_ext_controls *ctls =
739                         (struct v4l2_ext_controls *)arg;
740                 struct v4l2_ext_control *ctrl;
741                 struct pvr2_ctrl *pctl;
742                 unsigned int idx;
743                 /* For the moment just validate that the requested control
744                    actually exists. */
745                 ret = 0;
746                 for (idx = 0; idx < ctls->count; idx++) {
747                         ctrl = ctls->controls + idx;
748                         pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id);
749                         if (!pctl) {
750                                 ret = -EINVAL;
751                                 ctls->error_idx = idx;
752                                 break;
753                         }
754                 }
755                 break;
756         }
757
758         case VIDIOC_LOG_STATUS:
759         {
760                 pvr2_hdw_trigger_module_log(hdw);
761                 ret = 0;
762                 break;
763         }
764 #ifdef CONFIG_VIDEO_ADV_DEBUG
765         case VIDIOC_DBG_S_REGISTER:
766         case VIDIOC_DBG_G_REGISTER:
767         {
768                 u64 val;
769                 struct v4l2_register *req = (struct v4l2_register *)arg;
770                 if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val;
771                 ret = pvr2_hdw_register_access(
772                         hdw,req->match_type,req->match_chip,req->reg,
773                         cmd == VIDIOC_DBG_S_REGISTER,&val);
774                 if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val;
775                 break;
776         }
777 #endif
778
779         default :
780                 ret = v4l_compat_translate_ioctl(inode,file,cmd,
781                                                  arg,pvr2_v4l2_do_ioctl);
782         }
783
784         pvr2_hdw_commit_ctl(hdw);
785
786         if (ret < 0) {
787                 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
788                         pvr2_trace(PVR2_TRACE_V4LIOCTL,
789                                    "pvr2_v4l2_do_ioctl failure, ret=%d",ret);
790                 } else {
791                         if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
792                                 pvr2_trace(PVR2_TRACE_V4LIOCTL,
793                                            "pvr2_v4l2_do_ioctl failure, ret=%d"
794                                            " command was:",ret);
795                                 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
796                                                 cmd);
797                         }
798                 }
799         } else {
800                 pvr2_trace(PVR2_TRACE_V4LIOCTL,
801                            "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)",
802                            ret,ret);
803         }
804         return ret;
805 }
806
807
808 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
809 {
810         int minor_id = dip->devbase.minor;
811         struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
812         enum pvr2_config cfg = dip->config;
813         int v4l_type = dip->v4l_type;
814
815         pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
816
817         /* Paranoia */
818         dip->v4lp = NULL;
819         dip->stream = NULL;
820
821         /* Actual deallocation happens later when all internal references
822            are gone. */
823         video_unregister_device(&dip->devbase);
824
825         printk(KERN_INFO "pvrusb2: unregistered device %s%u [%s]\n",
826                get_v4l_name(v4l_type),minor_id & 0x1f,
827                pvr2_config_get_name(cfg));
828
829 }
830
831
832 static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
833 {
834         if (vp->dev_video) {
835                 pvr2_v4l2_dev_destroy(vp->dev_video);
836                 vp->dev_video = NULL;
837         }
838         if (vp->dev_radio) {
839                 pvr2_v4l2_dev_destroy(vp->dev_radio);
840                 vp->dev_radio = NULL;
841         }
842
843         pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
844         pvr2_channel_done(&vp->channel);
845         kfree(vp);
846 }
847
848
849 static void pvr2_video_device_release(struct video_device *vdev)
850 {
851         struct pvr2_v4l2_dev *dev;
852         dev = container_of(vdev,struct pvr2_v4l2_dev,devbase);
853         kfree(dev);
854 }
855
856
857 static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
858 {
859         struct pvr2_v4l2 *vp;
860         vp = container_of(chp,struct pvr2_v4l2,channel);
861         if (!vp->channel.mc_head->disconnect_flag) return;
862         if (vp->vfirst) return;
863         pvr2_v4l2_destroy_no_lock(vp);
864 }
865
866
867 static int pvr2_v4l2_ioctl(struct inode *inode, struct file *file,
868                            unsigned int cmd, unsigned long arg)
869 {
870
871 /* Temporary hack : use ivtv api until a v4l2 one is available. */
872 #define IVTV_IOC_G_CODEC        0xFFEE7703
873 #define IVTV_IOC_S_CODEC        0xFFEE7704
874         if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
875         return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl);
876 }
877
878
879 static int pvr2_v4l2_release(struct inode *inode, struct file *file)
880 {
881         struct pvr2_v4l2_fh *fhp = file->private_data;
882         struct pvr2_v4l2 *vp = fhp->vhead;
883         struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw;
884
885         pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
886
887         if (fhp->rhp) {
888                 struct pvr2_stream *sp;
889                 pvr2_hdw_set_streaming(hdw,0);
890                 sp = pvr2_ioread_get_stream(fhp->rhp);
891                 if (sp) pvr2_stream_set_callback(sp,NULL,NULL);
892                 pvr2_ioread_destroy(fhp->rhp);
893                 fhp->rhp = NULL;
894         }
895
896         v4l2_prio_close(&vp->prio, &fhp->prio);
897         file->private_data = NULL;
898
899         if (fhp->vnext) {
900                 fhp->vnext->vprev = fhp->vprev;
901         } else {
902                 vp->vlast = fhp->vprev;
903         }
904         if (fhp->vprev) {
905                 fhp->vprev->vnext = fhp->vnext;
906         } else {
907                 vp->vfirst = fhp->vnext;
908         }
909         fhp->vnext = NULL;
910         fhp->vprev = NULL;
911         fhp->vhead = NULL;
912         pvr2_channel_done(&fhp->channel);
913         pvr2_trace(PVR2_TRACE_STRUCT,
914                    "Destroying pvr_v4l2_fh id=%p",fhp);
915         if (fhp->input_map) {
916                 kfree(fhp->input_map);
917                 fhp->input_map = NULL;
918         }
919         kfree(fhp);
920         if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) {
921                 pvr2_v4l2_destroy_no_lock(vp);
922         }
923         return 0;
924 }
925
926
927 static int pvr2_v4l2_open(struct inode *inode, struct file *file)
928 {
929         struct pvr2_v4l2_dev *dip; /* Our own context pointer */
930         struct pvr2_v4l2_fh *fhp;
931         struct pvr2_v4l2 *vp;
932         struct pvr2_hdw *hdw;
933         unsigned int input_mask = 0;
934         unsigned int input_cnt,idx;
935         int ret = 0;
936
937         dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
938
939         vp = dip->v4lp;
940         hdw = vp->channel.hdw;
941
942         pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
943
944         if (!pvr2_hdw_dev_ok(hdw)) {
945                 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
946                            "pvr2_v4l2_open: hardware not ready");
947                 return -EIO;
948         }
949
950         fhp = kzalloc(sizeof(*fhp),GFP_KERNEL);
951         if (!fhp) {
952                 return -ENOMEM;
953         }
954
955         init_waitqueue_head(&fhp->wait_data);
956         fhp->dev_info = dip;
957
958         pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
959         pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
960
961         if (dip->v4l_type == VFL_TYPE_RADIO) {
962                 /* Opening device as a radio, legal input selection subset
963                    is just the radio. */
964                 input_mask = (1 << PVR2_CVAL_INPUT_RADIO);
965         } else {
966                 /* Opening the main V4L device, legal input selection
967                    subset includes all analog inputs. */
968                 input_mask = ((1 << PVR2_CVAL_INPUT_RADIO) |
969                               (1 << PVR2_CVAL_INPUT_TV) |
970                               (1 << PVR2_CVAL_INPUT_COMPOSITE) |
971                               (1 << PVR2_CVAL_INPUT_SVIDEO));
972         }
973         ret = pvr2_channel_limit_inputs(&fhp->channel,input_mask);
974         if (ret) {
975                 pvr2_channel_done(&fhp->channel);
976                 pvr2_trace(PVR2_TRACE_STRUCT,
977                            "Destroying pvr_v4l2_fh id=%p (input mask error)",
978                            fhp);
979
980                 kfree(fhp);
981                 return ret;
982         }
983
984         input_mask &= pvr2_hdw_get_input_available(hdw);
985         input_cnt = 0;
986         for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
987                 if (input_mask & (1 << idx)) input_cnt++;
988         }
989         fhp->input_cnt = input_cnt;
990         fhp->input_map = kzalloc(input_cnt,GFP_KERNEL);
991         if (!fhp->input_map) {
992                 pvr2_channel_done(&fhp->channel);
993                 pvr2_trace(PVR2_TRACE_STRUCT,
994                            "Destroying pvr_v4l2_fh id=%p (input map failure)",
995                            fhp);
996                 kfree(fhp);
997                 return -ENOMEM;
998         }
999         input_cnt = 0;
1000         for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
1001                 if (!(input_mask & (1 << idx))) continue;
1002                 fhp->input_map[input_cnt++] = idx;
1003         }
1004
1005         fhp->vnext = NULL;
1006         fhp->vprev = vp->vlast;
1007         if (vp->vlast) {
1008                 vp->vlast->vnext = fhp;
1009         } else {
1010                 vp->vfirst = fhp;
1011         }
1012         vp->vlast = fhp;
1013         fhp->vhead = vp;
1014
1015         fhp->file = file;
1016         file->private_data = fhp;
1017         v4l2_prio_open(&vp->prio,&fhp->prio);
1018
1019         fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
1020
1021         return 0;
1022 }
1023
1024
1025 static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
1026 {
1027         wake_up(&fhp->wait_data);
1028 }
1029
1030 static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
1031 {
1032         int ret;
1033         struct pvr2_stream *sp;
1034         struct pvr2_hdw *hdw;
1035         if (fh->rhp) return 0;
1036
1037         if (!fh->dev_info->stream) {
1038                 /* No stream defined for this node.  This means that we're
1039                    not currently allowed to stream from this node. */
1040                 return -EPERM;
1041         }
1042
1043         /* First read() attempt.  Try to claim the stream and start
1044            it... */
1045         if ((ret = pvr2_channel_claim_stream(&fh->channel,
1046                                              fh->dev_info->stream)) != 0) {
1047                 /* Someone else must already have it */
1048                 return ret;
1049         }
1050
1051         fh->rhp = pvr2_channel_create_mpeg_stream(fh->dev_info->stream);
1052         if (!fh->rhp) {
1053                 pvr2_channel_claim_stream(&fh->channel,NULL);
1054                 return -ENOMEM;
1055         }
1056
1057         hdw = fh->channel.mc_head->hdw;
1058         sp = fh->dev_info->stream->stream;
1059         pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
1060         pvr2_hdw_set_stream_type(hdw,fh->dev_info->config);
1061         if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
1062         return pvr2_ioread_set_enabled(fh->rhp,!0);
1063 }
1064
1065
1066 static ssize_t pvr2_v4l2_read(struct file *file,
1067                               char __user *buff, size_t count, loff_t *ppos)
1068 {
1069         struct pvr2_v4l2_fh *fh = file->private_data;
1070         int ret;
1071
1072         if (fh->fw_mode_flag) {
1073                 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
1074                 char *tbuf;
1075                 int c1,c2;
1076                 int tcnt = 0;
1077                 unsigned int offs = *ppos;
1078
1079                 tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
1080                 if (!tbuf) return -ENOMEM;
1081
1082                 while (count) {
1083                         c1 = count;
1084                         if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
1085                         c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
1086                         if (c2 < 0) {
1087                                 tcnt = c2;
1088                                 break;
1089                         }
1090                         if (!c2) break;
1091                         if (copy_to_user(buff,tbuf,c2)) {
1092                                 tcnt = -EFAULT;
1093                                 break;
1094                         }
1095                         offs += c2;
1096                         tcnt += c2;
1097                         buff += c2;
1098                         count -= c2;
1099                         *ppos += c2;
1100                 }
1101                 kfree(tbuf);
1102                 return tcnt;
1103         }
1104
1105         if (!fh->rhp) {
1106                 ret = pvr2_v4l2_iosetup(fh);
1107                 if (ret) {
1108                         return ret;
1109                 }
1110         }
1111
1112         for (;;) {
1113                 ret = pvr2_ioread_read(fh->rhp,buff,count);
1114                 if (ret >= 0) break;
1115                 if (ret != -EAGAIN) break;
1116                 if (file->f_flags & O_NONBLOCK) break;
1117                 /* Doing blocking I/O.  Wait here. */
1118                 ret = wait_event_interruptible(
1119                         fh->wait_data,
1120                         pvr2_ioread_avail(fh->rhp) >= 0);
1121                 if (ret < 0) break;
1122         }
1123
1124         return ret;
1125 }
1126
1127
1128 static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
1129 {
1130         unsigned int mask = 0;
1131         struct pvr2_v4l2_fh *fh = file->private_data;
1132         int ret;
1133
1134         if (fh->fw_mode_flag) {
1135                 mask |= POLLIN | POLLRDNORM;
1136                 return mask;
1137         }
1138
1139         if (!fh->rhp) {
1140                 ret = pvr2_v4l2_iosetup(fh);
1141                 if (ret) return POLLERR;
1142         }
1143
1144         poll_wait(file,&fh->wait_data,wait);
1145
1146         if (pvr2_ioread_avail(fh->rhp) >= 0) {
1147                 mask |= POLLIN | POLLRDNORM;
1148         }
1149
1150         return mask;
1151 }
1152
1153
1154 static const struct file_operations vdev_fops = {
1155         .owner      = THIS_MODULE,
1156         .open       = pvr2_v4l2_open,
1157         .release    = pvr2_v4l2_release,
1158         .read       = pvr2_v4l2_read,
1159         .ioctl      = pvr2_v4l2_ioctl,
1160         .llseek     = no_llseek,
1161         .poll       = pvr2_v4l2_poll,
1162 };
1163
1164
1165 static struct video_device vdev_template = {
1166         .fops       = &vdev_fops,
1167 };
1168
1169
1170 static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1171                                struct pvr2_v4l2 *vp,
1172                                int v4l_type)
1173 {
1174         int mindevnum;
1175         int unit_number;
1176         int *nr_ptr = NULL;
1177         dip->v4lp = vp;
1178
1179
1180         dip->v4l_type = v4l_type;
1181         switch (v4l_type) {
1182         case VFL_TYPE_GRABBER:
1183                 dip->stream = &vp->channel.mc_head->video_stream;
1184                 dip->config = pvr2_config_mpeg;
1185                 dip->minor_type = pvr2_v4l_type_video;
1186                 nr_ptr = video_nr;
1187                 if (!dip->stream) {
1188                         err("Failed to set up pvrusb2 v4l video dev"
1189                             " due to missing stream instance");
1190                         return;
1191                 }
1192                 break;
1193         case VFL_TYPE_VBI:
1194                 dip->config = pvr2_config_vbi;
1195                 dip->minor_type = pvr2_v4l_type_vbi;
1196                 nr_ptr = vbi_nr;
1197                 break;
1198         case VFL_TYPE_RADIO:
1199                 dip->stream = &vp->channel.mc_head->video_stream;
1200                 dip->config = pvr2_config_mpeg;
1201                 dip->minor_type = pvr2_v4l_type_radio;
1202                 nr_ptr = radio_nr;
1203                 break;
1204         default:
1205                 /* Bail out (this should be impossible) */
1206                 err("Failed to set up pvrusb2 v4l dev"
1207                     " due to unrecognized config");
1208                 return;
1209         }
1210
1211         memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template));
1212         dip->devbase.release = pvr2_video_device_release;
1213
1214         mindevnum = -1;
1215         unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
1216         if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
1217                 mindevnum = nr_ptr[unit_number];
1218         }
1219         if ((video_register_device(&dip->devbase,
1220                                    dip->v4l_type, mindevnum) < 0) &&
1221             (video_register_device(&dip->devbase,
1222                                    dip->v4l_type, -1) < 0)) {
1223                 err("Failed to register pvrusb2 v4l device");
1224         }
1225
1226         printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
1227                get_v4l_name(dip->v4l_type),dip->devbase.minor & 0x1f,
1228                pvr2_config_get_name(dip->config));
1229
1230         pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
1231                                         dip->minor_type,dip->devbase.minor);
1232 }
1233
1234
1235 struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1236 {
1237         struct pvr2_v4l2 *vp;
1238
1239         vp = kzalloc(sizeof(*vp),GFP_KERNEL);
1240         if (!vp) return vp;
1241         pvr2_channel_init(&vp->channel,mnp);
1242         pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
1243
1244         vp->channel.check_func = pvr2_v4l2_internal_check;
1245
1246         /* register streams */
1247         vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL);
1248         if (!vp->dev_video) goto fail;
1249         pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER);
1250         if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) &
1251             (1 << PVR2_CVAL_INPUT_RADIO)) {
1252                 vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL);
1253                 if (!vp->dev_radio) goto fail;
1254                 pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO);
1255         }
1256
1257         return vp;
1258  fail:
1259         pvr2_trace(PVR2_TRACE_STRUCT,"Failure creating pvr2_v4l2 id=%p",vp);
1260         pvr2_v4l2_destroy_no_lock(vp);
1261         return NULL;
1262 }
1263
1264 /*
1265   Stuff for Emacs to see, in order to encourage consistent editing style:
1266   *** Local Variables: ***
1267   *** mode: c ***
1268   *** fill-column: 75 ***
1269   *** tab-width: 8 ***
1270   *** c-basic-offset: 8 ***
1271   *** End: ***
1272   */