diff --git a/[refs] b/[refs] index 03a32747b775..13a557fa0083 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6df419e45d71b8d9a0de8e92a1212bbea460f0e0 +refs/heads/master: 938e05bf131334804e08ec4fcd381edfd2d699f6 diff --git a/trunk/Documentation/DocBook/media/v4l/biblio.xml b/trunk/Documentation/DocBook/media/v4l/biblio.xml index 1078e45f189f..7c49facecd25 100644 --- a/trunk/Documentation/DocBook/media/v4l/biblio.xml +++ b/trunk/Documentation/DocBook/media/v4l/biblio.xml @@ -194,7 +194,7 @@ in the frequency range from 87,5 to 108,0 MHz National Radio Systems Committee (http://www.nrscstandards.org) - NRSC-4: United States RBDS Standard + NTSC-4: United States RBDS Standard diff --git a/trunk/Documentation/DocBook/media/v4l/common.xml b/trunk/Documentation/DocBook/media/v4l/common.xml index b91d25313b63..4101aeb56540 100644 --- a/trunk/Documentation/DocBook/media/v4l/common.xml +++ b/trunk/Documentation/DocBook/media/v4l/common.xml @@ -464,14 +464,14 @@ The type field of the respective tuner field contains the index number of the tuner. - Radio input devices have exactly one tuner with index zero, no + Radio devices have exactly one tuner with index zero, no video inputs. To query and change tuner properties applications use the &VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; ioctl, respectively. The &v4l2-tuner; returned by VIDIOC_G_TUNER also contains signal status information applicable when the tuner of the -current video or radio input is queried. Note that +current video input, or a radio tuner is queried. Note that VIDIOC_S_TUNER does not switch the current tuner, when there is more than one at all. The tuner is solely determined by the current video input. Drivers must support both ioctls and set the @@ -491,17 +491,8 @@ the modulator. The type field of the respective &v4l2-output; returned by the &VIDIOC-ENUMOUTPUT; ioctl is set to V4L2_OUTPUT_TYPE_MODULATOR and its modulator field contains the index number -of the modulator. - - Radio output devices have exactly one modulator with index -zero, no video outputs. - - A video or radio device cannot support both a tuner and a -modulator. Two separate device nodes will have to be used for such -hardware, one that supports the tuner functionality and one that supports -the modulator functionality. The reason is a limitation with the -&VIDIOC-S-FREQUENCY; ioctl where you cannot specify whether the frequency -is for a tuner or a modulator. +of the modulator. This specification does not define radio output +devices. To query and change modulator properties applications use the &VIDIOC-G-MODULATOR; and &VIDIOC-S-MODULATOR; ioctl. Note that diff --git a/trunk/Documentation/DocBook/media/v4l/compat.xml b/trunk/Documentation/DocBook/media/v4l/compat.xml index 97b895151bb0..ea42ef824948 100644 --- a/trunk/Documentation/DocBook/media/v4l/compat.xml +++ b/trunk/Documentation/DocBook/media/v4l/compat.xml @@ -2377,11 +2377,10 @@ that used it. It was originally scheduled for removal in 2.6.35. V4L2_CTRL_FLAG_VOLATILE was added to signal volatile controls to userspace. - Add selection API for extended control over cropping - and composing. Does not affect the compatibility of current - drivers and applications. See selection API for - details. + Add selection API for extended control over cropping and +composing. Does not affect the compatibility of current drivers and +applications. See selection API for +details. @@ -2459,18 +2458,6 @@ that used it. It was originally scheduled for removal in 2.6.35. -
- V4L2 in Linux 3.5 - - - Replaced input in - v4l2_buffer by - reserved2 and removed - V4L2_BUF_FLAG_INPUT. - - -
-
Relation of V4L2 to other Linux multimedia APIs diff --git a/trunk/Documentation/DocBook/media/v4l/dev-subdev.xml b/trunk/Documentation/DocBook/media/v4l/dev-subdev.xml index a3d9dd093268..4afcbbec5eda 100644 --- a/trunk/Documentation/DocBook/media/v4l/dev-subdev.xml +++ b/trunk/Documentation/DocBook/media/v4l/dev-subdev.xml @@ -276,7 +276,7 @@
-
+
Selections: cropping, scaling and composition Many sub-devices support cropping frames on their input or output @@ -290,8 +290,8 @@ size. Both the coordinates and sizes are expressed in pixels. As for pad formats, drivers store try and active - rectangles for the selection targets . + rectangles for the selection targets of ACTUAL type . On sink pads, cropping is applied relative to the current pad format. The pad format represents the image size as @@ -308,7 +308,7 @@ Scaling support is optional. When supported by a subdev, the crop rectangle on the subdev's sink pad is scaled to the size configured using the &VIDIOC-SUBDEV-S-SELECTION; IOCTL - using V4L2_SEL_TGT_COMPOSE + using V4L2_SUBDEV_SEL_COMPOSE_ACTUAL selection target on the same pad. If the subdev supports scaling but not composing, the top and left values are not used and must always be set to zero. @@ -323,32 +323,32 @@ The drivers should always use the closest possible rectangle the user requests on all selection targets, unless specifically told otherwise. - V4L2_SEL_FLAG_GE and - V4L2_SEL_FLAG_LE flags may be + V4L2_SUBDEV_SEL_FLAG_SIZE_GE and + V4L2_SUBDEV_SEL_FLAG_SIZE_LE flags may be used to round the image size either up or down. + linkend="v4l2-subdev-selection-flags">
Types of selection targets
- Actual targets + ACTUAL targets - Actual targets (without a postfix) reflect the actual - hardware configuration at any point of time. There is a BOUNDS - target corresponding to every actual target. + ACTUAL targets reflect the actual hardware configuration + at any point of time. There is a BOUNDS target + corresponding to every ACTUAL.
BOUNDS targets - BOUNDS targets is the smallest rectangle that contains all - valid actual rectangles. It may not be possible to set the actual - rectangle as large as the BOUNDS rectangle, however. This may be - because e.g. a sensor's pixel array is not rectangular but - cross-shaped or round. The maximum size may also be smaller than the - BOUNDS rectangle. + BOUNDS targets is the smallest rectangle that contains + all valid ACTUAL rectangles. It may not be possible to set the + ACTUAL rectangle as large as the BOUNDS rectangle, however. + This may be because e.g. a sensor's pixel array is not + rectangular but cross-shaped or round. The maximum size may + also be smaller than the BOUNDS rectangle.
@@ -362,7 +362,7 @@ performed by the user: the changes made will be propagated to any subsequent stages. If this behaviour is not desired, the user must set - V4L2_SEL_FLAG_KEEP_CONFIG flag. This + V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG flag. This flag causes no propagation of the changes are allowed in any circumstances. This may also cause the accessed rectangle to be adjusted by the driver, depending on the properties of the diff --git a/trunk/Documentation/DocBook/media/v4l/io.xml b/trunk/Documentation/DocBook/media/v4l/io.xml index 1885cc0755cb..fd6aca2922b6 100644 --- a/trunk/Documentation/DocBook/media/v4l/io.xml +++ b/trunk/Documentation/DocBook/media/v4l/io.xml @@ -683,12 +683,14 @@ memory, set by the application. See for details. __u32 - reserved2 + input - A place holder for future extensions and custom -(driver defined) buffer types -V4L2_BUF_TYPE_PRIVATE and higher. Applications -should set this to 0. + Some video capture drivers support rapid and +synchronous video input changes, a function useful for example in +video surveillance applications. For this purpose applications set the +V4L2_BUF_FLAG_INPUT flag, and this field to the +number of a video input as in &v4l2-input; field +index. __u32 @@ -919,6 +921,13 @@ previous key frame. The timecode field is valid. Drivers set or clear this flag when the VIDIOC_DQBUF ioctl is called. + + + V4L2_BUF_FLAG_INPUT + 0x0200 + The input field is valid. +Applications set or clear this flag before calling the +VIDIOC_QBUF ioctl. V4L2_BUF_FLAG_PREPARED diff --git a/trunk/Documentation/DocBook/media/v4l/selection-api.xml b/trunk/Documentation/DocBook/media/v4l/selection-api.xml index e7ed5077834d..b299e4779354 100644 --- a/trunk/Documentation/DocBook/media/v4l/selection-api.xml +++ b/trunk/Documentation/DocBook/media/v4l/selection-api.xml @@ -53,10 +53,10 @@ cropping and composing rectangles have the same size. -
+For complete list of the available selection targets see table - See for more - information. +
@@ -74,7 +74,7 @@ cropping/composing rectangles may have to be aligned, and both the source and the sink may have arbitrary upper and lower size limits. Therefore, as usual, drivers are expected to adjust the requested parameters and return the actual values selected. An application can control the rounding behaviour using constraint flags . +linkend="v4l2-sel-flags"> constraint flags .
@@ -91,7 +91,7 @@ top/left corner at position (0,0) . The rectangle's coordinates are expressed in pixels. The top left corner, width and height of the source rectangle, that is -the area actually sampled, is given by the V4L2_SEL_TGT_CROP +the area actually sampled, is given by the V4L2_SEL_TGT_CROP_ACTIVE target. It uses the same coordinate system as V4L2_SEL_TGT_CROP_BOUNDS . The active cropping area must lie completely inside the capture boundaries. The driver may further adjust the @@ -111,13 +111,13 @@ height are equal to the image size set by VIDIOC_S_FMT . The part of a buffer into which the image is inserted by the hardware is -controlled by the V4L2_SEL_TGT_COMPOSE target. +controlled by the V4L2_SEL_TGT_COMPOSE_ACTIVE target. The rectangle's coordinates are also expressed in the same coordinate system as the bounds rectangle. The composing rectangle must lie completely inside bounds rectangle. The driver must adjust the composing rectangle to fit to the bounding limits. Moreover, the driver can perform other adjustments according to hardware limitations. The application can control rounding behaviour using - constraint flags . + constraint flags . For capture devices the default composing rectangle is queried using V4L2_SEL_TGT_COMPOSE_DEFAULT . It is usually equal to the @@ -125,7 +125,7 @@ bounding rectangle. The part of a buffer that is modified by the hardware is given by V4L2_SEL_TGT_COMPOSE_PADDED . It contains all pixels -defined using V4L2_SEL_TGT_COMPOSE plus all +defined using V4L2_SEL_TGT_COMPOSE_ACTIVE plus all padding data modified by hardware during insertion process. All pixels outside this rectangle must not be changed by the hardware. The content of pixels that lie inside the padded area but outside active area is @@ -153,7 +153,7 @@ specified using VIDIOC_S_FMT ioctl. The top left corner, width and height of the source rectangle, that is the area from which image date are processed by the hardware, is given by the - V4L2_SEL_TGT_CROP . Its coordinates are expressed + V4L2_SEL_TGT_CROP_ACTIVE . Its coordinates are expressed in in the same coordinate system as the bounds rectangle. The active cropping area must lie completely inside the crop boundaries and the driver may further adjust the requested size and/or position according to hardware @@ -165,7 +165,7 @@ bounding rectangle. The part of a video signal or graphics display where the image is inserted by the hardware is controlled by -V4L2_SEL_TGT_COMPOSE target. The rectangle's coordinates +V4L2_SEL_TGT_COMPOSE_ACTIVE target. The rectangle's coordinates are expressed in pixels. The composing rectangle must lie completely inside the bounds rectangle. The driver must adjust the area to fit to the bounding limits. Moreover, the driver can perform other adjustments according to @@ -184,7 +184,7 @@ such a padded area is driver-dependent feature not covered by this document. Driver developers are encouraged to keep padded rectangle equal to active one. The padded target is accessed by the V4L2_SEL_TGT_COMPOSE_PADDED identifier. It must contain all pixels from the -V4L2_SEL_TGT_COMPOSE target. +V4L2_SEL_TGT_COMPOSE_ACTIVE target.
@@ -193,8 +193,8 @@ V4L2_SEL_TGT_COMPOSE target. Scaling control An application can detect if scaling is performed by comparing the width -and the height of rectangles obtained using V4L2_SEL_TGT_CROP - and V4L2_SEL_TGT_COMPOSE targets. If +and the height of rectangles obtained using V4L2_SEL_TGT_CROP_ACTIVE + and V4L2_SEL_TGT_COMPOSE_ACTIVE targets. If these are not equal then the scaling is applied. The application can compute the scaling ratios using these values. @@ -252,7 +252,7 @@ area) ret = ioctl(fd, &VIDIOC-G-SELECTION;, &sel); if (ret) exit(-1); - sel.target = V4L2_SEL_TGT_CROP; + sel.target = V4L2_SEL_TGT_CROP_ACTIVE; ret = ioctl(fd, &VIDIOC-S-SELECTION;, &sel); if (ret) exit(-1); @@ -281,7 +281,7 @@ area) r.left = sel.r.width / 4; r.top = sel.r.height / 4; sel.r = r; - sel.target = V4L2_SEL_TGT_COMPOSE; + sel.target = V4L2_SEL_TGT_COMPOSE_ACTIVE; sel.flags = V4L2_SEL_FLAG_LE; ret = ioctl(fd, &VIDIOC-S-SELECTION;, &sel); if (ret) @@ -298,11 +298,11 @@ V4L2_BUF_TYPE_VIDEO_OUTPUT for other devices &v4l2-selection; compose = { .type = V4L2_BUF_TYPE_VIDEO_OUTPUT, - .target = V4L2_SEL_TGT_COMPOSE, + .target = V4L2_SEL_TGT_COMPOSE_ACTIVE, }; &v4l2-selection; crop = { .type = V4L2_BUF_TYPE_VIDEO_OUTPUT, - .target = V4L2_SEL_TGT_CROP, + .target = V4L2_SEL_TGT_CROP_ACTIVE, }; double hscale, vscale; diff --git a/trunk/Documentation/DocBook/media/v4l/selections-common.xml b/trunk/Documentation/DocBook/media/v4l/selections-common.xml deleted file mode 100644 index 7502f784b8cc..000000000000 --- a/trunk/Documentation/DocBook/media/v4l/selections-common.xml +++ /dev/null @@ -1,164 +0,0 @@ -
- - Common selection definitions - - While the V4L2 selection - API and V4L2 subdev - selection APIs are very similar, there's one fundamental - difference between the two. On sub-device API, the selection - rectangle refers to the media bus format, and is bound to a - sub-device's pad. On the V4L2 interface the selection rectangles - refer to the in-memory pixel format. - - This section defines the common definitions of the - selection interfaces on the two APIs. - -
- - Selection targets - - The precise meaning of the selection targets may be - dependent on which of the two interfaces they are used. - - - Selection target definitions - - - - - - - &cs-def; - - - Target name - id - Definition - Valid for V4L2 - Valid for V4L2 subdev - - - - - V4L2_SEL_TGT_CROP - 0x0000 - Crop rectangle. Defines the cropped area. - Yes - Yes - - - V4L2_SEL_TGT_CROP_DEFAULT - 0x0001 - Suggested cropping rectangle that covers the "whole picture". - Yes - No - - - V4L2_SEL_TGT_CROP_BOUNDS - 0x0002 - Bounds of the crop rectangle. All valid crop - rectangles fit inside the crop bounds rectangle. - - Yes - Yes - - - V4L2_SEL_TGT_COMPOSE - 0x0100 - Compose rectangle. Used to configure scaling - and composition. - Yes - Yes - - - V4L2_SEL_TGT_COMPOSE_DEFAULT - 0x0101 - Suggested composition rectangle that covers the "whole picture". - Yes - No - - - V4L2_SEL_TGT_COMPOSE_BOUNDS - 0x0102 - Bounds of the compose rectangle. All valid compose - rectangles fit inside the compose bounds rectangle. - Yes - Yes - - - V4L2_SEL_TGT_COMPOSE_PADDED - 0x0103 - The active area and all padding pixels that are inserted or - modified by hardware. - Yes - No - - - -
- -
- -
- - Selection flags - - - Selection flag definitions - - - - - - - &cs-def; - - - Flag name - id - Definition - Valid for V4L2 - Valid for V4L2 subdev - - - - - V4L2_SEL_FLAG_GE - (1 << 0) - Suggest the driver it should choose greater or - equal rectangle (in size) than was requested. Albeit the - driver may choose a lesser size, it will only do so due to - hardware limitations. Without this flag (and - V4L2_SEL_FLAG_LE) the - behaviour is to choose the closest possible - rectangle. - Yes - Yes - - - V4L2_SEL_FLAG_LE - (1 << 1) - Suggest the driver it - should choose lesser or equal rectangle (in size) than was - requested. Albeit the driver may choose a greater size, it - will only do so due to hardware limitations. - Yes - Yes - - - V4L2_SEL_FLAG_KEEP_CONFIG - (1 << 2) - The configuration must not be propagated to any - further processing steps. If this flag is not given, the - configuration is propagated inside the subdevice to all - further processing steps. - No - Yes - - - -
- -
- -
diff --git a/trunk/Documentation/DocBook/media/v4l/v4l2.xml b/trunk/Documentation/DocBook/media/v4l/v4l2.xml index 36bafc48e03b..008c2d73a484 100644 --- a/trunk/Documentation/DocBook/media/v4l/v4l2.xml +++ b/trunk/Documentation/DocBook/media/v4l/v4l2.xml @@ -589,11 +589,6 @@ and discussions on the V4L mailing list. &sub-write; - - Common definitions for V4L2 and V4L2 subdev interfaces - &sub-selections-common; - - Video For Linux Two Header File &sub-videodev2-h; diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml index 5e73b1c8d095..a2474ecb574a 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml @@ -97,13 +97,7 @@ information. __u32 count - The number of buffers requested or granted. If count == 0, then - VIDIOC_CREATE_BUFS will set index - to the current number of created buffers, and it will check the validity of - memory and format.type. - If those are invalid -1 is returned and errno is set to &EINVAL;, - otherwise VIDIOC_CREATE_BUFS returns 0. It will - never set errno to &EBUSY; in this particular case. + The number of buffers requested or granted. __u32 diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml index 40e58a42eb26..69c178a4d205 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml @@ -135,12 +135,6 @@ bounds or the value in the type field is wrong. - - EBUSY - - A hardware seek is in progress. - - diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-g-selection.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-g-selection.xml index f76d8a6d9b92..bb04eff75f45 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-g-selection.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-g-selection.xml @@ -65,9 +65,9 @@ Do not use multiplanar buffers. Use V4L2_BUF_TYPE_VIDEO_CAPTURE . Use V4L2_BUF_TYPE_VIDEO_OUTPUT instead of V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE . The next step is setting the value of &v4l2-selection; target field -to V4L2_SEL_TGT_CROP ( -V4L2_SEL_TGT_COMPOSE ). Please refer to table or for additional +to V4L2_SEL_TGT_CROP_ACTIVE ( +V4L2_SEL_TGT_COMPOSE_ACTIVE ). Please refer to table or for additional targets. The flags and reserved fields of &v4l2-selection; are ignored and they must be filled with zeros. The driver fills the rest of the structure or @@ -86,9 +86,9 @@ use multiplanar buffers. Use V4L2_BUF_TYPE_VIDEO_CAPTURE . Use V4L2_BUF_TYPE_VIDEO_OUTPUT instead of V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE . The next step is setting the value of &v4l2-selection; target to -V4L2_SEL_TGT_CROP ( -V4L2_SEL_TGT_COMPOSE ). Please refer to table or for additional +V4L2_SEL_TGT_CROP_ACTIVE ( +V4L2_SEL_TGT_COMPOSE_ACTIVE ). Please refer to table or for additional targets. The &v4l2-rect; r rectangle need to be set to the desired active area. Field &v4l2-selection; reserved is ignored and must be filled with zeros. The driver may adjust @@ -154,8 +154,74 @@ exist no rectangle that satisfies the constraints. - Selection targets and flags are documented in . + + + Selection targets. + + &cs-def; + + + V4L2_SEL_TGT_CROP_ACTIVE + 0x0000 + The area that is currently cropped by hardware. + + + V4L2_SEL_TGT_CROP_DEFAULT + 0x0001 + Suggested cropping rectangle that covers the "whole picture". + + + V4L2_SEL_TGT_CROP_BOUNDS + 0x0002 + Limits for the cropping rectangle. + + + V4L2_SEL_TGT_COMPOSE_ACTIVE + 0x0100 + The area to which data is composed by hardware. + + + V4L2_SEL_TGT_COMPOSE_DEFAULT + 0x0101 + Suggested composing rectangle that covers the "whole picture". + + + V4L2_SEL_TGT_COMPOSE_BOUNDS + 0x0102 + Limits for the composing rectangle. + + + V4L2_SEL_TGT_COMPOSE_PADDED + 0x0103 + The active area and all padding pixels that are inserted or modified by hardware. + + + +
+
+ + + + Selection constraint flags + + &cs-def; + + + V4L2_SEL_FLAG_GE + 0x00000001 + Indicates that the adjusted rectangle must contain the original + &v4l2-selection; r rectangle. + + + V4L2_SEL_FLAG_LE + 0x00000002 + Indicates that the adjusted rectangle must be inside the original + &v4l2-rect; r rectangle. + + + +
+
@@ -186,14 +252,14 @@ exist no rectangle that satisfies the constraints. __u32 target - Used to select between cropping + Used to select between cropping and composing rectangles. __u32 flags Flags controlling the selection rectangle adjustments, refer to - selection flags. + selection flags. &v4l2-rect; diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml index 95d5371c1709..62a1aa200a36 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml @@ -275,18 +275,6 @@ can or must be switched. (B/G PAL tuners for example are typically not see the description of ioctl &VIDIOC-ENUMINPUT; for details. Only V4L2_TUNER_ANALOG_TV tuners can have this capability. - - V4L2_TUNER_CAP_HWSEEK_BOUNDED - 0x0004 - If set, then this tuner supports the hardware seek functionality - where the seek stops when it reaches the end of the frequency range. - - - V4L2_TUNER_CAP_HWSEEK_WRAP - 0x0008 - If set, then this tuner supports the hardware seek functionality - where the seek wraps around when it reaches the end of the frequency range. - V4L2_TUNER_CAP_STEREO 0x0010 diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-qbuf.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-qbuf.xml index 77ff5be0809d..9caa49af580f 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-qbuf.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-qbuf.xml @@ -71,9 +71,12 @@ initialize the bytesused, field and timestamp fields, see for details. -Applications must also set flags to 0. -The reserved2 and -reserved fields must be set to 0. When using +Applications must also set flags to 0. If a driver +supports capturing from specific video inputs and you want to specify a video +input, then flags should be set to +V4L2_BUF_FLAG_INPUT and the field +input must be initialized to the desired input. +The reserved field must be set to 0. When using the multi-planar API, the m.planes field must contain a userspace pointer to a filled-in array of &v4l2-plane; and the length diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml index f4db44d0d95a..407dfceb71f0 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml @@ -58,9 +58,6 @@ To do this applications initialize the tuner, call the VIDIOC_S_HW_FREQ_SEEK ioctl with a pointer to this structure. - If an error is returned, then the original frequency will - be restored. - This ioctl is supported if the V4L2_CAP_HW_FREQ_SEEK capability is set. @@ -90,10 +87,7 @@ field and the &v4l2-tuner; index field. __u32 wrap_around - If non-zero, wrap around when at the end of the frequency range, else stop seeking. - The &v4l2-tuner; capability field will tell you what the - hardware supports. - + If non-zero, wrap around when at the end of the frequency range, else stop seeking. __u32 @@ -124,15 +118,9 @@ wrong. - ENODATA - - The hardware seek found no channels. - - - - EBUSY + EAGAIN - Another hardware seek is already in progress. + The ioctl timed-out. Try again. diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml index f33cc814a01d..208e9f0da3f3 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml @@ -72,10 +72,10 @@
Types of selection targets - There are two types of selection targets: actual and bounds. The - actual targets are the targets which configure the hardware. The BOUNDS - target will return a rectangle that contain all possible actual - rectangles. + There are two types of selection targets: actual and bounds. + The ACTUAL targets are the targets which configure the hardware. + The BOUNDS target will return a rectangle that contain all + possible ACTUAL rectangles.
@@ -87,8 +87,71 @@ EINVAL.
- Selection targets and flags are documented in . +
+ V4L2 subdev selection targets + + &cs-def; + + + V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL + 0x0000 + Actual crop. Defines the cropping + performed by the processing step. + + + V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS + 0x0002 + Bounds of the crop rectangle. + + + V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL + 0x0100 + Actual compose rectangle. Used to configure scaling + on sink pads and composition on source pads. + + + V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS + 0x0102 + Bounds of the compose rectangle. + + + +
+ + + V4L2 subdev selection flags + + &cs-def; + + + V4L2_SUBDEV_SEL_FLAG_SIZE_GE + (1 << 0) Suggest the driver it + should choose greater or equal rectangle (in size) than + was requested. Albeit the driver may choose a lesser size, + it will only do so due to hardware limitations. Without + this flag (and + V4L2_SUBDEV_SEL_FLAG_SIZE_LE) the + behaviour is to choose the closest possible + rectangle. + + + V4L2_SUBDEV_SEL_FLAG_SIZE_LE + (1 << 1) Suggest the driver it + should choose lesser or equal rectangle (in size) than was + requested. Albeit the driver may choose a greater size, it + will only do so due to hardware limitations. + + + V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG + (1 << 2) + The configuration should not be propagated to any + further processing steps. If this flag is not given, the + configuration is propagated inside the subdevice to all + further processing steps. + + + +
struct <structname>v4l2_subdev_selection</structname> @@ -110,13 +173,13 @@ __u32targetTarget selection rectangle. See - . + .. __u32 flags Flags. See - . + . &v4l2-rect; diff --git a/trunk/Documentation/dvb/get_dvb_firmware b/trunk/Documentation/dvb/get_dvb_firmware index 12d3952e83d5..fbb241174486 100755 --- a/trunk/Documentation/dvb/get_dvb_firmware +++ b/trunk/Documentation/dvb/get_dvb_firmware @@ -29,7 +29,7 @@ use IO::Handle; "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395", "lme2510c_s7395_old", "drxk", "drxk_terratec_h5", "drxk_hauppauge_hvr930c", "tda10071", "it9135", "it9137", - "drxk_pctv", "drxk_terratec_htc_stick", "sms1xxx_hcw"); + "drxk_pctv"); # Check args syntax() if (scalar(@ARGV) != 1); @@ -676,24 +676,6 @@ sub drxk_terratec_h5 { "$fwfile" } -sub drxk_terratec_htc_stick { - my $url = "http://ftp.terratec.de/Receiver/Cinergy_HTC_Stick/Updates/"; - my $zipfile = "Cinergy_HTC_Stick_Drv_5.09.1202.00_XP_Vista_7.exe"; - my $hash = "6722a2442a05423b781721fbc069ed5e"; - my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 0); - my $drvfile = "Cinergy HTC Stick/BDA Driver 5.09.1202.00/Windows 32 Bit/emOEM.sys"; - my $fwfile = "dvb-usb-terratec-htc-stick-drxk.fw"; - - checkstandard(); - - wgetfile($zipfile, $url . $zipfile); - verify($zipfile, $hash); - unzip($zipfile, $tmpdir); - extract("$tmpdir/$drvfile", 0x4e5c0, 42692, "$fwfile"); - - "$fwfile" -} - sub it9135 { my $sourcefile = "dvb-usb-it9135.zip"; my $url = "http://www.ite.com.tw/uploads/firmware/v3.6.0.0/$sourcefile"; @@ -766,28 +748,6 @@ sub drxk_pctv { "$fwfile"; } -sub sms1xxx_hcw { - my $url = "http://steventoth.net/linux/sms1xxx/"; - my %files = ( - 'sms1xxx-hcw-55xxx-dvbt-01.fw' => "afb6f9fb9a71d64392e8564ef9577e5a", - 'sms1xxx-hcw-55xxx-dvbt-02.fw' => "b44807098ba26e52cbedeadc052ba58f", - 'sms1xxx-hcw-55xxx-isdbt-02.fw' => "dae934eeea85225acbd63ce6cfe1c9e4", - ); - - checkstandard(); - - my $allfiles; - foreach my $fwfile (keys %files) { - wgetfile($fwfile, "$url/$fwfile"); - verify($fwfile, $files{$fwfile}); - $allfiles .= " $fwfile"; - } - - $allfiles =~ s/^\s//; - - $allfiles; -} - # --------------------------------------------------------------- # Utilities diff --git a/trunk/Documentation/fault-injection/fault-injection.txt b/trunk/Documentation/fault-injection/fault-injection.txt index 4cf1a2a6bd72..ba4be8b77093 100644 --- a/trunk/Documentation/fault-injection/fault-injection.txt +++ b/trunk/Documentation/fault-injection/fault-injection.txt @@ -240,30 +240,3 @@ trap "echo 0 > /sys/kernel/debug/$FAILTYPE/probability" SIGINT SIGTERM EXIT echo "Injecting errors into the module $module... (interrupt to stop)" sleep 1000000 -Tool to run command with failslab or fail_page_alloc ----------------------------------------------------- -In order to make it easier to accomplish the tasks mentioned above, we can use -tools/testing/fault-injection/failcmd.sh. Please run a command -"./tools/testing/fault-injection/failcmd.sh --help" for more information and -see the following examples. - -Examples: - -Run a command "make -C tools/testing/selftests/ run_tests" with injecting slab -allocation failure. - - # ./tools/testing/fault-injection/failcmd.sh \ - -- make -C tools/testing/selftests/ run_tests - -Same as above except to specify 100 times failures at most instead of one time -at most by default. - - # ./tools/testing/fault-injection/failcmd.sh --times=100 \ - -- make -C tools/testing/selftests/ run_tests - -Same as above except to inject page allocation failure instead of slab -allocation failure. - - # env FAILCMD_TYPE=fail_page_alloc \ - ./tools/testing/fault-injection/failcmd.sh --times=100 \ - -- make -C tools/testing/selftests/ run_tests diff --git a/trunk/Documentation/fault-injection/notifier-error-inject.txt b/trunk/Documentation/fault-injection/notifier-error-inject.txt deleted file mode 100644 index c83526c364e5..000000000000 --- a/trunk/Documentation/fault-injection/notifier-error-inject.txt +++ /dev/null @@ -1,99 +0,0 @@ -Notifier error injection -======================== - -Notifier error injection provides the ability to inject artifical errors to -specified notifier chain callbacks. It is useful to test the error handling of -notifier call chain failures which is rarely executed. There are kernel -modules that can be used to test the following notifiers. - - * CPU notifier - * PM notifier - * Memory hotplug notifier - * powerpc pSeries reconfig notifier - -CPU notifier error injection module ------------------------------------ -This feature can be used to test the error handling of the CPU notifiers by -injecting artifical errors to CPU notifier chain callbacks. - -If the notifier call chain should be failed with some events notified, write -the error code to debugfs interface -/sys/kernel/debug/notifier-error-inject/cpu/actions//error - -Possible CPU notifier events to be failed are: - - * CPU_UP_PREPARE - * CPU_UP_PREPARE_FROZEN - * CPU_DOWN_PREPARE - * CPU_DOWN_PREPARE_FROZEN - -Example1: Inject CPU offline error (-1 == -EPERM) - - # cd /sys/kernel/debug/notifier-error-inject/cpu - # echo -1 > actions/CPU_DOWN_PREPARE/error - # echo 0 > /sys/devices/system/cpu/cpu1/online - bash: echo: write error: Operation not permitted - -Example2: inject CPU online error (-2 == -ENOENT) - - # echo -2 > actions/CPU_UP_PREPARE/error - # echo 1 > /sys/devices/system/cpu/cpu1/online - bash: echo: write error: No such file or directory - -PM notifier error injection module ----------------------------------- -This feature is controlled through debugfs interface -/sys/kernel/debug/notifier-error-inject/pm/actions//error - -Possible PM notifier events to be failed are: - - * PM_HIBERNATION_PREPARE - * PM_SUSPEND_PREPARE - * PM_RESTORE_PREPARE - -Example: Inject PM suspend error (-12 = -ENOMEM) - - # cd /sys/kernel/debug/notifier-error-inject/pm/ - # echo -12 > actions/PM_SUSPEND_PREPARE/error - # echo mem > /sys/power/state - bash: echo: write error: Cannot allocate memory - -Memory hotplug notifier error injection module ----------------------------------------------- -This feature is controlled through debugfs interface -/sys/kernel/debug/notifier-error-inject/memory/actions//error - -Possible memory notifier events to be failed are: - - * MEM_GOING_ONLINE - * MEM_GOING_OFFLINE - -Example: Inject memory hotplug offline error (-12 == -ENOMEM) - - # cd /sys/kernel/debug/notifier-error-inject/memory - # echo -12 > actions/MEM_GOING_OFFLINE/error - # echo offline > /sys/devices/system/memory/memoryXXX/state - bash: echo: write error: Cannot allocate memory - -powerpc pSeries reconfig notifier error injection module --------------------------------------------------------- -This feature is controlled through debugfs interface -/sys/kernel/debug/notifier-error-inject/pSeries-reconfig/actions//error - -Possible pSeries reconfig notifier events to be failed are: - - * PSERIES_RECONFIG_ADD - * PSERIES_RECONFIG_REMOVE - * PSERIES_DRCONF_MEM_ADD - * PSERIES_DRCONF_MEM_REMOVE - -For more usage examples ------------------------ -There are tools/testing/selftests using the notifier error injection features -for CPU and memory notifiers. - - * tools/testing/selftests/cpu-hotplug/on-off-test.sh - * tools/testing/selftests/memory-hotplug/on-off-test.sh - -These scripts first do simple online and offline tests and then do fault -injection tests if notifier error injection module is available. diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index e9237fb71950..76112dac7659 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -600,21 +600,3 @@ When: June 2013 Why: Unsupported/unmaintained/unused since 2.6 ---------------------------- - -What: V4L2 selections API target rectangle and flags unification, the - following definitions will be removed: V4L2_SEL_TGT_CROP_ACTIVE, - V4L2_SEL_TGT_COMPOSE_ACTIVE, V4L2_SUBDEV_SEL_*, V4L2_SUBDEV_SEL_FLAG_* - in favor of common V4L2_SEL_TGT_* and V4L2_SEL_FLAG_* definitions. - For more details see include/linux/v4l2-common.h. -When: 3.8 -Why: The regular V4L2 selections and the subdev selection API originally - defined distinct names for the target rectangles and flags - V4L2_SEL_* - and V4L2_SUBDEV_SEL_*. Although, it turned out that the meaning of these - target rectangles is virtually identical and the APIs were consolidated - to use single set of names - V4L2_SEL_*. This didn't involve any ABI - changes. Alias definitions were created for the original ones to avoid - any instabilities in the user space interface. After few cycles these - backward compatibility definitions will be removed. -Who: Sylwester Nawrocki - ----------------------------- diff --git a/trunk/Documentation/printk-formats.txt b/trunk/Documentation/printk-formats.txt index 7561d7ed8e11..5df176ed59b8 100644 --- a/trunk/Documentation/printk-formats.txt +++ b/trunk/Documentation/printk-formats.txt @@ -53,20 +53,9 @@ Struct Resources: For printing struct resources. The 'R' and 'r' specifiers result in a printed resource with ('R') or without ('r') a decoded flags member. -Raw buffer as a hex string: - %*ph 00 01 02 ... 3f - %*phC 00:01:02: ... :3f - %*phD 00-01-02- ... -3f - %*phN 000102 ... 3f - - For printing a small buffers (up to 64 bytes long) as a hex string with - certain separator. For the larger buffers consider to use - print_hex_dump(). - MAC/FDDI addresses: %pM 00:01:02:03:04:05 - %pMR 05:04:03:02:01:00 %pMF 00-01-02-03-04-05 %pm 000102030405 @@ -78,10 +67,6 @@ MAC/FDDI addresses: the 'M' specifier to use dash ('-') separators instead of the default separator. - For Bluetooth addresses the 'R' specifier shall be used after the 'M' - specifier to use reversed byte order suitable for visual interpretation - of Bluetooth addresses which are in the little endian order. - IPv4 addresses: %pI4 1.2.3.4 diff --git a/trunk/Documentation/sysctl/fs.txt b/trunk/Documentation/sysctl/fs.txt index 8c235b6e4246..13d6166d7a27 100644 --- a/trunk/Documentation/sysctl/fs.txt +++ b/trunk/Documentation/sysctl/fs.txt @@ -163,22 +163,16 @@ This value can be used to query and set the core dump mode for setuid or otherwise protected/tainted binaries. The modes are 0 - (default) - traditional behaviour. Any process which has changed - privilege levels or is execute only will not be dumped. + privilege levels or is execute only will not be dumped 1 - (debug) - all processes dump core when possible. The core dump is owned by the current user and no security is applied. This is intended for system debugging situations only. Ptrace is unchecked. - This is insecure as it allows regular users to examine the memory - contents of privileged processes. 2 - (suidsafe) - any binary which normally would not be dumped is dumped - anyway, but only if the "core_pattern" kernel sysctl is set to - either a pipe handler or a fully qualified path. (For more details - on this limitation, see CVE-2006-2451.) This mode is appropriate - when administrators are attempting to debug problems in a normal - environment, and either have a core dump pipe handler that knows - to treat privileged core dumps with care, or specific directory - defined for catching core dumps. If a core dump happens without - a pipe handler or fully qualifid path, a message will be emitted - to syslog warning about the lack of a correct setting. + readable by root only. This allows the end user to remove + such a dump but not access it directly. For security reasons + core dumps in this mode will not overwrite one another or + other files. This mode is appropriate when administrators are + attempting to debug problems in a normal environment. ============================================================== diff --git a/trunk/Documentation/video4linux/v4l2-framework.txt b/trunk/Documentation/video4linux/v4l2-framework.txt index 89318be6c1d2..1f5905270050 100644 --- a/trunk/Documentation/video4linux/v4l2-framework.txt +++ b/trunk/Documentation/video4linux/v4l2-framework.txt @@ -594,15 +594,6 @@ You should also set these fields: unlocked_ioctl file operation is called this lock will be taken by the core and released afterwards. See the next section for more details. -- queue: a pointer to the struct vb2_queue associated with this device node. - If queue is non-NULL, and queue->lock is non-NULL, then queue->lock is - used for the queuing ioctls (VIDIOC_REQBUFS, CREATE_BUFS, QBUF, DQBUF, - QUERYBUF, PREPARE_BUF, STREAMON and STREAMOFF) instead of the lock above. - That way the vb2 queuing framework does not have to wait for other ioctls. - This queue pointer is also used by the vb2 helper functions to check for - queuing ownership (i.e. is the filehandle calling it allowed to do the - operation). - - prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY. If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device. If you want to have a separate priority state per (group of) device node(s), @@ -656,43 +647,47 @@ manually set the struct media_entity type and name fields. A reference to the entity will be automatically acquired/released when the video device is opened/closed. -ioctls and locking ------------------- +v4l2_file_operations and locking +-------------------------------- + +You can set a pointer to a mutex_lock in struct video_device. Usually this +will be either a top-level mutex or a mutex per device node. By default this +lock will be used for unlocked_ioctl, but you can disable locking for +selected ioctls by calling: -The V4L core provides optional locking services. The main service is the -lock field in struct video_device, which is a pointer to a mutex. If you set -this pointer, then that will be used by unlocked_ioctl to serialize all ioctls. + void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd); -If you are using the videobuf2 framework, then there is a second lock that you -can set: video_device->queue->lock. If set, then this lock will be used instead -of video_device->lock to serialize all queuing ioctls (see the previous section -for the full list of those ioctls). +E.g.: v4l2_disable_ioctl_locking(vdev, VIDIOC_DQBUF); -The advantage of using a different lock for the queuing ioctls is that for some -drivers (particularly USB drivers) certain commands such as setting controls -can take a long time, so you want to use a separate lock for the buffer queuing -ioctls. That way your VIDIOC_DQBUF doesn't stall because the driver is busy -changing the e.g. exposure of the webcam. +You have to call this before you register the video_device. -Of course, you can always do all the locking yourself by leaving both lock -pointers at NULL. +Particularly with USB drivers where certain commands such as setting controls +can take a long time you may want to do your own locking for the buffer queuing +ioctls. -If you use the old videobuf then you must pass the video_device lock to the -videobuf queue initialize function: if videobuf has to wait for a frame to -arrive, then it will temporarily unlock the lock and relock it afterwards. If -your driver also waits in the code, then you should do the same to allow other -processes to access the device node while the first process is waiting for -something. +If you want still finer-grained locking then you have to set mutex_lock to NULL +and do you own locking completely. + +It is up to the driver developer to decide which method to use. However, if +your driver has high-latency operations (for example, changing the exposure +of a USB webcam might take a long time), then you might be better off with +doing your own locking if you want to allow the user to do other things with +the device while waiting for the high-latency command to finish. + +If a lock is specified then all ioctl commands will be serialized on that +lock. If you use videobuf then you must pass the same lock to the videobuf +queue initialize function: if videobuf has to wait for a frame to arrive, then +it will temporarily unlock the lock and relock it afterwards. If your driver +also waits in the code, then you should do the same to allow other processes +to access the device node while the first process is waiting for something. In the case of videobuf2 you will need to implement the wait_prepare and -wait_finish callbacks to unlock/lock if applicable. If you use the queue->lock -pointer, then you can use the helper functions vb2_ops_wait_prepare/finish. - -The implementation of a hotplug disconnect should also take the lock from -video_device before calling v4l2_device_disconnect. If you are also using -video_device->queue->lock, then you have to first lock video_device->queue->lock -followed by video_device->lock. That way you can be sure no ioctl is running -when you call v4l2_device_disconnect. +wait_finish callbacks to unlock/lock if applicable. In particular, if you use +the lock in struct video_device then you must unlock/lock this mutex in +wait_prepare and wait_finish. + +The implementation of a hotplug disconnect should also take the lock before +calling v4l2_device_disconnect. video_device registration ------------------------- diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index fb036a062a5d..19f705073942 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -2750,7 +2750,6 @@ M: Jingoo Han L: linux-fbdev@vger.kernel.org S: Maintained F: drivers/video/exynos/exynos_dp* -F: include/video/exynos_dp* EXYNOS MIPI DISPLAY DRIVERS M: Inki Dae @@ -3156,7 +3155,8 @@ S: Maintained F: drivers/media/video/gspca/t613.c GSPCA USB WEBCAM DRIVER -M: Hans de Goede +M: Jean-Francois Moine +W: http://moinejf.free.fr L: linux-media@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git S: Maintained diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index 72f2fa189cc5..8c3d957fa8e2 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -248,14 +248,7 @@ config HAVE_CMPXCHG_LOCAL config HAVE_CMPXCHG_DOUBLE bool -config ARCH_WANT_IPC_PARSE_VERSION - bool - -config ARCH_WANT_COMPAT_IPC_PARSE_VERSION - bool - config ARCH_WANT_OLD_COMPAT_IPC - select ARCH_WANT_COMPAT_IPC_PARSE_VERSION bool config HAVE_ARCH_SECCOMP_FILTER diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index d5b9b5e645cc..3de74c9f9610 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -14,7 +14,6 @@ config ALPHA select AUTO_IRQ_AFFINITY if SMP select GENERIC_IRQ_SHOW select ARCH_WANT_OPTIONAL_GPIOLIB - select ARCH_WANT_IPC_PARSE_VERSION select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_SMP_IDLE_THREAD select GENERIC_CMOS_UPDATE diff --git a/trunk/arch/alpha/include/asm/unistd.h b/trunk/arch/alpha/include/asm/unistd.h index 633b23b0664a..d1f23b722df4 100644 --- a/trunk/arch/alpha/include/asm/unistd.h +++ b/trunk/arch/alpha/include/asm/unistd.h @@ -470,6 +470,7 @@ #define NR_SYSCALLS 504 +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME diff --git a/trunk/arch/alpha/kernel/smc37c669.c b/trunk/arch/alpha/kernel/smc37c669.c index c803fc76ae4f..0435921d41c6 100644 --- a/trunk/arch/alpha/kernel/smc37c669.c +++ b/trunk/arch/alpha/kernel/smc37c669.c @@ -933,6 +933,18 @@ void SMC37c669_display_device_info( * *-- */ +#if 0 +/* $INCLUDE_OPTIONS$ */ +#include "cp$inc:platform_io.h" +/* $INCLUDE_OPTIONS_END$ */ +#include "cp$src:common.h" +#include "cp$inc:prototypes.h" +#include "cp$src:kernel_def.h" +#include "cp$src:msg_def.h" +#include "cp$src:smcc669_def.h" +/* Platform-specific includes */ +#include "cp$src:platform.h" +#endif #ifndef TRUE #define TRUE 1 diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 7980873525b2..6b86bb963a28 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -11,7 +11,6 @@ config ARM select RTC_LIB select SYS_SUPPORTS_APM_EMULATION select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI) - select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_KGDB @@ -39,7 +38,6 @@ config ARM select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select GENERIC_IRQ_PROBE - select ARCH_WANT_IPC_PARSE_VERSION select HARDIRQS_SW_RESEND select CPU_PM if (SUSPEND || CPU_IDLE) select GENERIC_PCI_IOMAP diff --git a/trunk/arch/arm/include/asm/unistd.h b/trunk/arch/arm/include/asm/unistd.h index 0cab47d4a83f..512cd1473454 100644 --- a/trunk/arch/arm/include/asm/unistd.h +++ b/trunk/arch/arm/include/asm/unistd.h @@ -446,6 +446,7 @@ #ifdef __KERNEL__ +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_PAUSE diff --git a/trunk/arch/arm/lib/io-acorn.S b/trunk/arch/arm/lib/io-acorn.S index 69719bad674d..1b197ea7aab3 100644 --- a/trunk/arch/arm/lib/io-acorn.S +++ b/trunk/arch/arm/lib/io-acorn.S @@ -11,14 +11,13 @@ * */ #include -#include #include .text .align .Liosl_warning: - .ascii KERN_WARNING "insl/outsl not implemented, called from %08lX\0" + .ascii "<4>insl/outsl not implemented, called from %08lX\0" .align /* diff --git a/trunk/arch/arm/mach-netx/fb.c b/trunk/arch/arm/mach-netx/fb.c index d122ee6ab991..2cdf6ef69bee 100644 --- a/trunk/arch/arm/mach-netx/fb.c +++ b/trunk/arch/arm/mach-netx/fb.c @@ -69,6 +69,29 @@ void netx_clcd_remove(struct clcd_fb *fb) fb->fb.screen_base, fb->fb.fix.smem_start); } +void clk_disable(struct clk *clk) +{ +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return 0; +} + +int clk_enable(struct clk *clk) +{ + return 0; +} + +struct clk *clk_get(struct device *dev, const char *id) +{ + return dev && strcmp(dev_name(dev), "fb") == 0 ? NULL : ERR_PTR(-ENOENT); +} + +void clk_put(struct clk *clk) +{ +} + static AMBA_AHB_DEVICE(fb, "fb", 0, 0x00104000, { NETX_IRQ_LCD }, NULL); int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel) diff --git a/trunk/arch/arm/vfp/vfphw.S b/trunk/arch/arm/vfp/vfphw.S index d50f0e486cf2..2d30c7f6edd3 100644 --- a/trunk/arch/arm/vfp/vfphw.S +++ b/trunk/arch/arm/vfp/vfphw.S @@ -16,7 +16,6 @@ */ #include #include -#include #include "../kernel/entry-header.S" .macro DBGSTR, str @@ -25,7 +24,7 @@ add r0, pc, #4 bl printk b 1f - .asciz KERN_DEBUG "VFP: \str\n" + .asciz "<7>VFP: \str\n" .balign 4 1: ldmfd sp!, {r0-r3, ip, lr} #endif @@ -38,7 +37,7 @@ add r0, pc, #4 bl printk b 1f - .asciz KERN_DEBUG "VFP: \str\n" + .asciz "<7>VFP: \str\n" .balign 4 1: ldmfd sp!, {r0-r3, ip, lr} #endif @@ -53,7 +52,7 @@ add r0, pc, #4 bl printk b 1f - .asciz KERN_DEBUG "VFP: \str\n" + .asciz "<7>VFP: \str\n" .balign 4 1: ldmfd sp!, {r0-r3, ip, lr} #endif diff --git a/trunk/arch/avr32/Kconfig b/trunk/arch/avr32/Kconfig index 5ade51c8a87f..71d38c76726c 100644 --- a/trunk/arch/avr32/Kconfig +++ b/trunk/arch/avr32/Kconfig @@ -12,7 +12,6 @@ config AVR32 select HARDIRQS_SW_RESEND select GENERIC_IRQ_SHOW select ARCH_HAVE_CUSTOM_GPIO_H - select ARCH_WANT_IPC_PARSE_VERSION select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_CLOCKEVENTS help diff --git a/trunk/arch/avr32/boards/atstk1000/atstk1002.c b/trunk/arch/avr32/boards/atstk1000/atstk1002.c index 6c80aba7bf96..dc5263321480 100644 --- a/trunk/arch/avr32/boards/atstk1000/atstk1002.c +++ b/trunk/arch/avr32/boards/atstk1000/atstk1002.c @@ -97,7 +97,7 @@ static struct atmel_nand_data atstk1006_nand_data __initdata = { .enable_pin = GPIO_PIN_PB(29), .ecc_mode = NAND_ECC_SOFT, .parts = nand_partitions, - .num_parts = ARRAY_SIZE(nand_partitions), + .num_parts = ARRAY_SIZE(num_partitions), }; #endif diff --git a/trunk/arch/avr32/include/asm/unistd.h b/trunk/arch/avr32/include/asm/unistd.h index 1358e366f4be..f714544e5560 100644 --- a/trunk/arch/avr32/include/asm/unistd.h +++ b/trunk/arch/avr32/include/asm/unistd.h @@ -318,6 +318,7 @@ /* SMP stuff */ #define __IGNORE_getcpu +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME diff --git a/trunk/arch/avr32/mm/fault.c b/trunk/arch/avr32/mm/fault.c index b92e60958617..f7040a1e399f 100644 --- a/trunk/arch/avr32/mm/fault.c +++ b/trunk/arch/avr32/mm/fault.c @@ -61,10 +61,10 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) const struct exception_table_entry *fixup; unsigned long address; unsigned long page; + int writeaccess; long signr; int code; int fault; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; if (notify_page_fault(regs, ecr)) return; @@ -86,7 +86,6 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) local_irq_enable(); -retry: down_read(&mm->mmap_sem); vma = find_vma(mm, address); @@ -105,6 +104,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) */ good_area: code = SEGV_ACCERR; + writeaccess = 0; switch (ecr) { case ECR_PROTECTION_X: @@ -121,7 +121,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) case ECR_TLB_MISS_W: if (!(vma->vm_flags & VM_WRITE)) goto bad_area; - flags |= FAULT_FLAG_WRITE; + writeaccess = 1; break; default: panic("Unhandled case %lu in do_page_fault!", ecr); @@ -132,11 +132,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) * sure we exit gracefully rather than endlessly redo the * fault. */ - fault = handle_mm_fault(mm, vma, address, flags); - - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return; - + fault = handle_mm_fault(mm, vma, address, writeaccess ? FAULT_FLAG_WRITE : 0); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -144,23 +140,10 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) goto do_sigbus; BUG(); } - - if (flags & FAULT_FLAG_ALLOW_RETRY) { - if (fault & VM_FAULT_MAJOR) - tsk->maj_flt++; - else - tsk->min_flt++; - if (fault & VM_FAULT_RETRY) { - flags &= ~FAULT_FLAG_ALLOW_RETRY; - - /* - * No need to up_read(&mm->mmap_sem) as we would have - * already released it in __lock_page_or_retry() in - * mm/filemap.c. - */ - goto retry; - } - } + if (fault & VM_FAULT_MAJOR) + tsk->maj_flt++; + else + tsk->min_flt++; up_read(&mm->mmap_sem); return; diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig index f34861920634..ec44fc6c34ca 100644 --- a/trunk/arch/blackfin/Kconfig +++ b/trunk/arch/blackfin/Kconfig @@ -33,7 +33,6 @@ config BLACKFIN select HAVE_PERF_EVENTS select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_WANT_OPTIONAL_GPIOLIB - select ARCH_WANT_IPC_PARSE_VERSION select HAVE_GENERIC_HARDIRQS select GENERIC_ATOMIC64 select GENERIC_IRQ_PROBE diff --git a/trunk/arch/blackfin/include/asm/unistd.h b/trunk/arch/blackfin/include/asm/unistd.h index 5b2a0748d7d3..3287222cba34 100644 --- a/trunk/arch/blackfin/include/asm/unistd.h +++ b/trunk/arch/blackfin/include/asm/unistd.h @@ -434,6 +434,7 @@ #define __IGNORE_getcpu #ifdef __KERNEL__ +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig index e92215428a37..bb344650a14f 100644 --- a/trunk/arch/cris/Kconfig +++ b/trunk/arch/cris/Kconfig @@ -42,7 +42,6 @@ config CRIS select HAVE_IDE select GENERIC_ATOMIC64 select HAVE_GENERIC_HARDIRQS - select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_IRQ_SHOW select GENERIC_IOMAP select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32 diff --git a/trunk/arch/cris/include/asm/unistd.h b/trunk/arch/cris/include/asm/unistd.h index 51873a446f87..f921b8b0f97e 100644 --- a/trunk/arch/cris/include/asm/unistd.h +++ b/trunk/arch/cris/include/asm/unistd.h @@ -347,6 +347,7 @@ #include +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT #define __ARCH_WANT_STAT64 diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index 971c0a19facb..a685910d2d5c 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -9,7 +9,6 @@ config FRV select GENERIC_IRQ_SHOW select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_CPU_DEVICES - select ARCH_WANT_IPC_PARSE_VERSION config ZONE_DMA bool diff --git a/trunk/arch/frv/include/asm/unistd.h b/trunk/arch/frv/include/asm/unistd.h index 67f23a311db6..a569dff7cd59 100644 --- a/trunk/arch/frv/include/asm/unistd.h +++ b/trunk/arch/frv/include/asm/unistd.h @@ -349,6 +349,7 @@ #define NR_syscalls 338 +#define __ARCH_WANT_IPC_PARSE_VERSION /* #define __ARCH_WANT_OLD_READDIR */ #define __ARCH_WANT_OLD_STAT #define __ARCH_WANT_STAT64 diff --git a/trunk/arch/frv/kernel/kernel_thread.S b/trunk/arch/frv/kernel/kernel_thread.S index f0e52943f923..4531c830d20b 100644 --- a/trunk/arch/frv/kernel/kernel_thread.S +++ b/trunk/arch/frv/kernel/kernel_thread.S @@ -10,10 +10,10 @@ */ #include -#include #include #define CLONE_VM 0x00000100 /* set if VM shared between processes */ +#define KERN_ERR "<3>" .section .rodata kernel_thread_emsg: diff --git a/trunk/arch/h8300/Kconfig b/trunk/arch/h8300/Kconfig index 5e8a0d9a09ce..56e890df5053 100644 --- a/trunk/arch/h8300/Kconfig +++ b/trunk/arch/h8300/Kconfig @@ -3,7 +3,6 @@ config H8300 default y select HAVE_IDE select HAVE_GENERIC_HARDIRQS - select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES diff --git a/trunk/arch/h8300/include/asm/unistd.h b/trunk/arch/h8300/include/asm/unistd.h index 5cd882801d79..718511303b4e 100644 --- a/trunk/arch/h8300/include/asm/unistd.h +++ b/trunk/arch/h8300/include/asm/unistd.h @@ -331,6 +331,7 @@ #define NR_syscalls 321 +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT #define __ARCH_WANT_STAT64 diff --git a/trunk/arch/m32r/Kconfig b/trunk/arch/m32r/Kconfig index 49498bbb9616..b638d5bfa14d 100644 --- a/trunk/arch/m32r/Kconfig +++ b/trunk/arch/m32r/Kconfig @@ -7,7 +7,6 @@ config M32R select HAVE_KERNEL_GZIP select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_LZMA - select ARCH_WANT_IPC_PARSE_VERSION select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/trunk/arch/m32r/include/asm/unistd.h b/trunk/arch/m32r/include/asm/unistd.h index d5e66a480782..3e1db561aacc 100644 --- a/trunk/arch/m32r/include/asm/unistd.h +++ b/trunk/arch/m32r/include/asm/unistd.h @@ -336,6 +336,7 @@ #define NR_syscalls 326 +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 0b0f8b8c4a26..147120128260 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -10,7 +10,6 @@ config M68K select GENERIC_STRNCPY_FROM_USER if MMU select GENERIC_STRNLEN_USER if MMU select FPU if MMU - select ARCH_WANT_IPC_PARSE_VERSION select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE config RWSEM_GENERIC_SPINLOCK diff --git a/trunk/arch/m68k/include/asm/unistd.h b/trunk/arch/m68k/include/asm/unistd.h index 045cfd6a9e31..ea0b502f845e 100644 --- a/trunk/arch/m68k/include/asm/unistd.h +++ b/trunk/arch/m68k/include/asm/unistd.h @@ -357,6 +357,7 @@ #define NR_syscalls 347 +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT #define __ARCH_WANT_STAT64 diff --git a/trunk/arch/microblaze/Kconfig b/trunk/arch/microblaze/Kconfig index ab9afcaa7f6a..0bf44231aaf9 100644 --- a/trunk/arch/microblaze/Kconfig +++ b/trunk/arch/microblaze/Kconfig @@ -15,7 +15,6 @@ config MICROBLAZE select TRACING_SUPPORT select OF select OF_EARLY_FLATTREE - select ARCH_WANT_IPC_PARSE_VERSION select IRQ_DOMAIN select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE diff --git a/trunk/arch/microblaze/include/asm/unistd.h b/trunk/arch/microblaze/include/asm/unistd.h index 6985e6e9d826..d20ffbc86beb 100644 --- a/trunk/arch/microblaze/include/asm/unistd.h +++ b/trunk/arch/microblaze/include/asm/unistd.h @@ -400,6 +400,7 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ +#define __ARCH_WANT_IPC_PARSE_VERSION /* #define __ARCH_WANT_OLD_READDIR */ /* #define __ARCH_WANT_OLD_STAT */ #define __ARCH_WANT_STAT64 diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index e3efc06e6409..750429018534 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -20,14 +20,12 @@ config MIPS select ARCH_BINFMT_ELF_RANDOMIZE_PIE select RTC_LIB if !MACH_LOONGSON select GENERIC_ATOMIC64 if !64BIT - select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select HAVE_DMA_ATTRS select HAVE_DMA_API_DEBUG select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select HAVE_ARCH_JUMP_LABEL - select ARCH_WANT_IPC_PARSE_VERSION select IRQ_FORCED_THREADING select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP diff --git a/trunk/arch/mips/include/asm/unistd.h b/trunk/arch/mips/include/asm/unistd.h index bebbde01be92..d8dad5340ea3 100644 --- a/trunk/arch/mips/include/asm/unistd.h +++ b/trunk/arch/mips/include/asm/unistd.h @@ -1034,6 +1034,7 @@ #ifndef __ASSEMBLY__ #define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME diff --git a/trunk/arch/mn10300/Kconfig b/trunk/arch/mn10300/Kconfig index 5cfb086b3903..687f9b4a2ed6 100644 --- a/trunk/arch/mn10300/Kconfig +++ b/trunk/arch/mn10300/Kconfig @@ -3,7 +3,6 @@ config MN10300 select HAVE_OPROFILE select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW - select ARCH_WANT_IPC_PARSE_VERSION select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_KGDB select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER diff --git a/trunk/arch/mn10300/include/asm/unistd.h b/trunk/arch/mn10300/include/asm/unistd.h index 866eb14749d7..9051f921cbc7 100644 --- a/trunk/arch/mn10300/include/asm/unistd.h +++ b/trunk/arch/mn10300/include/asm/unistd.h @@ -358,6 +358,7 @@ /* * specify the deprecated syscalls we want to support on this arch */ +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT #define __ARCH_WANT_STAT64 diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 352f416269ce..9a5d3cdc3e12 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -115,13 +115,11 @@ config PPC select HAVE_OPROFILE select HAVE_SYSCALL_WRAPPERS if PPC64 select GENERIC_ATOMIC64 if PPC32 - select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select HAVE_IRQ_WORK select HAVE_PERF_EVENTS select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64 select HAVE_GENERIC_HARDIRQS - select ARCH_WANT_IPC_PARSE_VERSION select SPARSE_IRQ select IRQ_PER_CPU select IRQ_DOMAIN diff --git a/trunk/arch/powerpc/include/asm/unistd.h b/trunk/arch/powerpc/include/asm/unistd.h index bd377a368611..d3d1b5efd7eb 100644 --- a/trunk/arch/powerpc/include/asm/unistd.h +++ b/trunk/arch/powerpc/include/asm/unistd.h @@ -389,6 +389,7 @@ #include #include +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 296cd32466df..a39b4690c171 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -85,7 +85,6 @@ config S390 select HAVE_ARCH_MUTEX_CPU_RELAX select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 select ARCH_SAVE_PAGE_KEYS if HIBERNATION - select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP select HAVE_CMPXCHG_LOCAL @@ -118,7 +117,6 @@ config S390 select ARCH_INLINE_WRITE_UNLOCK_BH select ARCH_INLINE_WRITE_UNLOCK_IRQ select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE - select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_SMP_IDLE_THREAD select GENERIC_TIME_VSYSCALL select GENERIC_CLOCKEVENTS diff --git a/trunk/arch/s390/include/asm/unistd.h b/trunk/arch/s390/include/asm/unistd.h index 6756e78f4808..2e37157ba6a9 100644 --- a/trunk/arch/s390/include/asm/unistd.h +++ b/trunk/arch/s390/include/asm/unistd.h @@ -388,6 +388,7 @@ #define __IGNORE_recvmmsg #define __IGNORE_sendmmsg +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index 36f5141e8041..a24595d83ad6 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -21,7 +21,6 @@ config SUPERH select HAVE_KERNEL_LZMA select HAVE_KERNEL_XZ select HAVE_KERNEL_LZO - select ARCH_WANT_IPC_PARSE_VERSION select HAVE_SYSCALL_TRACEPOINTS select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_GENERIC_HARDIRQS @@ -51,7 +50,6 @@ config SUPERH32 select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE - select ARCH_WANT_IPC_PARSE_VERSION select HAVE_FUNCTION_GRAPH_TRACER select HAVE_ARCH_KGDB select HAVE_HW_BREAKPOINT diff --git a/trunk/arch/sh/include/asm/unistd.h b/trunk/arch/sh/include/asm/unistd.h index 7bc67076baac..e800a38c9f8d 100644 --- a/trunk/arch/sh/include/asm/unistd.h +++ b/trunk/arch/sh/include/asm/unistd.h @@ -6,6 +6,7 @@ # endif # define __ARCH_WANT_SYS_RT_SIGSUSPEND +# define __ARCH_WANT_IPC_PARSE_VERSION # define __ARCH_WANT_OLD_READDIR # define __ARCH_WANT_OLD_STAT # define __ARCH_WANT_STAT64 diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 67f1f6f5f4e1..e74ff1377626 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -27,7 +27,6 @@ config SPARC select HAVE_ARCH_JUMP_LABEL select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW - select ARCH_WANT_IPC_PARSE_VERSION select USE_GENERIC_SMP_HELPERS if SMP select GENERIC_PCI_IOMAP select HAVE_NMI_WATCHDOG if SPARC64 diff --git a/trunk/arch/sparc/include/asm/unistd.h b/trunk/arch/sparc/include/asm/unistd.h index fb2693464807..c7cb0af0eb59 100644 --- a/trunk/arch/sparc/include/asm/unistd.h +++ b/trunk/arch/sparc/include/asm/unistd.h @@ -423,6 +423,7 @@ #endif #ifdef __KERNEL__ +#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM diff --git a/trunk/arch/sparc/kernel/sys_sparc_64.c b/trunk/arch/sparc/kernel/sys_sparc_64.c index 0dc1f5786081..c38e5aaae56f 100644 --- a/trunk/arch/sparc/kernel/sys_sparc_64.c +++ b/trunk/arch/sparc/kernel/sys_sparc_64.c @@ -470,7 +470,7 @@ SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second switch (call) { case SHMAT: { ulong raddr; - err = do_shmat(first, ptr, (int)second, &raddr, SHMLBA); + err = do_shmat(first, ptr, (int)second, &raddr); if (!err) { if (put_user(raddr, (ulong __user *) third)) diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index ba2657c49217..c70684f859e1 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -70,7 +70,6 @@ config X86 select HAVE_ARCH_JUMP_LABEL select HAVE_TEXT_POKE_SMP select HAVE_GENERIC_HARDIRQS - select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select SPARSE_IRQ select GENERIC_FIND_FIRST_BIT select GENERIC_IRQ_PROBE @@ -85,7 +84,6 @@ config X86 select GENERIC_IOMAP select DCACHE_WORD_ACCESS select GENERIC_SMP_IDLE_THREAD - select ARCH_WANT_IPC_PARSE_VERSION if X86_32 select HAVE_ARCH_SECCOMP_FILTER select BUILDTIME_EXTABLE_SORT select GENERIC_CMOS_UPDATE diff --git a/trunk/arch/x86/include/asm/unistd.h b/trunk/arch/x86/include/asm/unistd.h index 0d9776e9e2dc..4437001d8e3d 100644 --- a/trunk/arch/x86/include/asm/unistd.h +++ b/trunk/arch/x86/include/asm/unistd.h @@ -15,6 +15,7 @@ # ifdef CONFIG_X86_32 # include +# define __ARCH_WANT_IPC_PARSE_VERSION # define __ARCH_WANT_STAT64 # define __ARCH_WANT_SYS_IPC # define __ARCH_WANT_SYS_OLD_MMAP diff --git a/trunk/arch/x86/kernel/e820.c b/trunk/arch/x86/kernel/e820.c index ed858e9e9a74..41857970517f 100644 --- a/trunk/arch/x86/kernel/e820.c +++ b/trunk/arch/x86/kernel/e820.c @@ -944,7 +944,7 @@ void __init e820_reserve_resources(void) for (i = 0; i < e820_saved.nr_map; i++) { struct e820entry *entry = &e820_saved.map[i]; firmware_map_add_early(entry->addr, - entry->addr + entry->size, + entry->addr + entry->size - 1, e820_type_to_string(entry->type)); } } diff --git a/trunk/arch/xtensa/kernel/syscall.c b/trunk/arch/xtensa/kernel/syscall.c index 05b3f093d5d7..816e6d0d686c 100644 --- a/trunk/arch/xtensa/kernel/syscall.c +++ b/trunk/arch/xtensa/kernel/syscall.c @@ -44,7 +44,7 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) unsigned long ret; long err; - err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA); + err = do_shmat(shmid, shmaddr, shmflg, &ret); if (err) return err; return (long)ret; diff --git a/trunk/arch/xtensa/mm/fault.c b/trunk/arch/xtensa/mm/fault.c index 5a74c53bc69c..b17885a0b508 100644 --- a/trunk/arch/xtensa/mm/fault.c +++ b/trunk/arch/xtensa/mm/fault.c @@ -44,7 +44,6 @@ void do_page_fault(struct pt_regs *regs) int is_write, is_exec; int fault; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; info.si_code = SEGV_MAPERR; @@ -72,7 +71,6 @@ void do_page_fault(struct pt_regs *regs) address, exccause, regs->pc, is_write? "w":"", is_exec? "x":""); #endif -retry: down_read(&mm->mmap_sem); vma = find_vma(mm, address); @@ -95,7 +93,6 @@ void do_page_fault(struct pt_regs *regs) if (is_write) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; - flags |= FAULT_FLAG_WRITE; } else if (is_exec) { if (!(vma->vm_flags & VM_EXEC)) goto bad_area; @@ -107,11 +104,7 @@ void do_page_fault(struct pt_regs *regs) * make sure we exit gracefully rather than endlessly redo * the fault. */ - fault = handle_mm_fault(mm, vma, address, flags); - - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return; - + fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -119,22 +112,10 @@ void do_page_fault(struct pt_regs *regs) goto do_sigbus; BUG(); } - if (flags & FAULT_FLAG_ALLOW_RETRY) { - if (fault & VM_FAULT_MAJOR) - current->maj_flt++; - else - current->min_flt++; - if (fault & VM_FAULT_RETRY) { - flags &= ~FAULT_FLAG_ALLOW_RETRY; - - /* No need to up_read(&mm->mmap_sem) as we would - * have already released it in __lock_page_or_retry - * in mm/filemap.c. - */ - - goto retry; - } - } + if (fault & VM_FAULT_MAJOR) + current->maj_flt++; + else + current->min_flt++; up_read(&mm->mmap_sem); return; diff --git a/trunk/drivers/ata/pata_arasan_cf.c b/trunk/drivers/ata/pata_arasan_cf.c index bfaa5cb1629a..ac6a5beb28f3 100644 --- a/trunk/drivers/ata/pata_arasan_cf.c +++ b/trunk/drivers/ata/pata_arasan_cf.c @@ -184,8 +184,10 @@ struct arasan_cf_dev { /* pointer to ata_host structure */ struct ata_host *host; - /* clk structure */ + /* clk structure, only if HAVE_CLK is defined */ +#ifdef CONFIG_HAVE_CLK struct clk *clk; +#endif /* physical base address of controller */ dma_addr_t pbase; @@ -310,11 +312,13 @@ static int cf_init(struct arasan_cf_dev *acdev) unsigned long flags; int ret = 0; +#ifdef CONFIG_HAVE_CLK ret = clk_enable(acdev->clk); if (ret) { dev_dbg(acdev->host->dev, "clock enable failed"); return ret; } +#endif spin_lock_irqsave(&acdev->host->lock, flags); /* configure CF interface clock */ @@ -340,7 +344,9 @@ static void cf_exit(struct arasan_cf_dev *acdev) writel(readl(acdev->vbase + OP_MODE) & ~CFHOST_ENB, acdev->vbase + OP_MODE); spin_unlock_irqrestore(&acdev->host->lock, flags); +#ifdef CONFIG_HAVE_CLK clk_disable(acdev->clk); +#endif } static void dma_callback(void *dev) @@ -822,11 +828,13 @@ static int __devinit arasan_cf_probe(struct platform_device *pdev) return -ENOMEM; } +#ifdef CONFIG_HAVE_CLK acdev->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(acdev->clk)) { dev_warn(&pdev->dev, "Clock not found\n"); return PTR_ERR(acdev->clk); } +#endif /* allocate host */ host = ata_host_alloc(&pdev->dev, 1); @@ -891,7 +899,9 @@ static int __devinit arasan_cf_probe(struct platform_device *pdev) &arasan_cf_sht); free_clk: +#ifdef CONFIG_HAVE_CLK clk_put(acdev->clk); +#endif return ret; } @@ -902,7 +912,9 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev) ata_host_detach(host); cf_exit(acdev); +#ifdef CONFIG_HAVE_CLK clk_put(acdev->clk); +#endif return 0; } diff --git a/trunk/drivers/clk/Kconfig b/trunk/drivers/clk/Kconfig index 7f0b5ca78516..3f99b9099658 100644 --- a/trunk/drivers/clk/Kconfig +++ b/trunk/drivers/clk/Kconfig @@ -25,6 +25,7 @@ menu "Common Clock Framework" config COMMON_CLK_DEBUG bool "DebugFS representation of clock tree" + depends on COMMON_CLK select DEBUG_FS ---help--- Creates a directory hierchy in debugfs for visualizing the clk diff --git a/trunk/drivers/clk/clk.c b/trunk/drivers/clk/clk.c index efdfd009c270..c87fdd710560 100644 --- a/trunk/drivers/clk/clk.c +++ b/trunk/drivers/clk/clk.c @@ -465,9 +465,6 @@ static void __clk_disable(struct clk *clk) if (!clk) return; - if (WARN_ON(IS_ERR(clk))) - return; - if (WARN_ON(clk->enable_count == 0)) return; diff --git a/trunk/drivers/firmware/memmap.c b/trunk/drivers/firmware/memmap.c index c1cdc9236666..adc07102a20d 100644 --- a/trunk/drivers/firmware/memmap.c +++ b/trunk/drivers/firmware/memmap.c @@ -98,7 +98,7 @@ static LIST_HEAD(map_entries); /** * firmware_map_add_entry() - Does the real work to add a firmware memmap entry. * @start: Start of the memory range. - * @end: End of the memory range (exclusive). + * @end: End of the memory range (inclusive). * @type: Type of the memory range. * @entry: Pre-allocated (either kmalloc() or bootmem allocator), uninitialised * entry. @@ -113,7 +113,7 @@ static int firmware_map_add_entry(u64 start, u64 end, BUG_ON(start > end); entry->start = start; - entry->end = end - 1; + entry->end = end; entry->type = type; INIT_LIST_HEAD(&entry->list); kobject_init(&entry->kobj, &memmap_ktype); @@ -148,7 +148,7 @@ static int add_sysfs_fw_map_entry(struct firmware_map_entry *entry) * firmware_map_add_hotplug() - Adds a firmware mapping entry when we do * memory hotplug. * @start: Start of the memory range. - * @end: End of the memory range (exclusive) + * @end: End of the memory range (inclusive). * @type: Type of the memory range. * * Adds a firmware mapping entry. This function is for memory hotplug, it is @@ -175,7 +175,7 @@ int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type) /** * firmware_map_add_early() - Adds a firmware mapping entry. * @start: Start of the memory range. - * @end: End of the memory range. + * @end: End of the memory range (inclusive). * @type: Type of the memory range. * * Adds a firmware mapping entry. This function uses the bootmem allocator diff --git a/trunk/drivers/firmware/pcdp.c b/trunk/drivers/firmware/pcdp.c index a330492e06f9..51e0e2d8fac6 100644 --- a/trunk/drivers/firmware/pcdp.c +++ b/trunk/drivers/firmware/pcdp.c @@ -95,7 +95,7 @@ efi_setup_pcdp_console(char *cmdline) if (efi.hcdp == EFI_INVALID_TABLE_ADDR) return -ENODEV; - pcdp = early_ioremap(efi.hcdp, 4096); + pcdp = ioremap(efi.hcdp, 4096); printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, efi.hcdp); if (strstr(cmdline, "console=hcdp")) { @@ -131,6 +131,6 @@ efi_setup_pcdp_console(char *cmdline) } out: - early_iounmap(pcdp, 4096); + iounmap(pcdp); return rc; } diff --git a/trunk/drivers/i2c/busses/i2c-pxa.c b/trunk/drivers/i2c/busses/i2c-pxa.c index 1034d93fb838..a997c7d3f95d 100644 --- a/trunk/drivers/i2c/busses/i2c-pxa.c +++ b/trunk/drivers/i2c/busses/i2c-pxa.c @@ -41,6 +41,13 @@ #include +#ifndef CONFIG_HAVE_CLK +#define clk_get(dev, id) NULL +#define clk_put(clk) do { } while (0) +#define clk_disable(clk) do { } while (0) +#define clk_enable(clk) do { } while (0) +#endif + struct pxa_reg_layout { u32 ibmr; u32 idbr; diff --git a/trunk/drivers/i2c/i2c-core.c b/trunk/drivers/i2c/i2c-core.c index 2efa56c5ff2c..26488aa893d5 100644 --- a/trunk/drivers/i2c/i2c-core.c +++ b/trunk/drivers/i2c/i2c-core.c @@ -1311,37 +1311,6 @@ module_exit(i2c_exit); * ---------------------------------------------------- */ -/** - * __i2c_transfer - unlocked flavor of i2c_transfer - * @adap: Handle to I2C bus - * @msgs: One or more messages to execute before STOP is issued to - * terminate the operation; each message begins with a START. - * @num: Number of messages to be executed. - * - * Returns negative errno, else the number of messages executed. - * - * Adapter lock must be held when calling this function. No debug logging - * takes place. adap->algo->master_xfer existence isn't checked. - */ -int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) -{ - unsigned long orig_jiffies; - int ret, try; - - /* Retry automatically on arbitration loss */ - orig_jiffies = jiffies; - for (ret = 0, try = 0; try <= adap->retries; try++) { - ret = adap->algo->master_xfer(adap, msgs, num); - if (ret != -EAGAIN) - break; - if (time_after(jiffies, orig_jiffies + adap->timeout)) - break; - } - - return ret; -} -EXPORT_SYMBOL(__i2c_transfer); - /** * i2c_transfer - execute a single or combined I2C message * @adap: Handle to I2C bus @@ -1356,7 +1325,8 @@ EXPORT_SYMBOL(__i2c_transfer); */ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { - int ret; + unsigned long orig_jiffies; + int ret, try; /* REVISIT the fault reporting model here is weak: * @@ -1394,7 +1364,15 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) i2c_lock_adapter(adap); } - ret = __i2c_transfer(adap, msgs, num); + /* Retry automatically on arbitration loss */ + orig_jiffies = jiffies; + for (ret = 0, try = 0; try <= adap->retries; try++) { + ret = adap->algo->master_xfer(adap, msgs, num); + if (ret != -EAGAIN) + break; + if (time_after(jiffies, orig_jiffies + adap->timeout)) + break; + } i2c_unlock_adapter(adap); return ret; diff --git a/trunk/drivers/md/dm-log.c b/trunk/drivers/md/dm-log.c index 627d19186d5a..65ebaebf502b 100644 --- a/trunk/drivers/md/dm-log.c +++ b/trunk/drivers/md/dm-log.c @@ -571,6 +571,16 @@ static void disk_dtr(struct dm_dirty_log *log) destroy_log_context(lc); } +static int count_bits32(uint32_t *addr, unsigned size) +{ + int count = 0, i; + + for (i = 0; i < size; i++) { + count += hweight32(*(addr+i)); + } + return count; +} + static void fail_log_device(struct log_c *lc) { if (lc->log_dev_failed) @@ -619,8 +629,7 @@ static int disk_resume(struct dm_dirty_log *log) /* copy clean across to sync */ memcpy(lc->sync_bits, lc->clean_bits, size); - lc->sync_count = memweight(lc->clean_bits, - lc->bitset_uint32_count * sizeof(uint32_t)); + lc->sync_count = count_bits32(lc->clean_bits, lc->bitset_uint32_count); lc->sync_search = 0; /* set the correct number of regions in the header */ diff --git a/trunk/drivers/media/Kconfig b/trunk/drivers/media/Kconfig index d941581ab921..9575db429df4 100644 --- a/trunk/drivers/media/Kconfig +++ b/trunk/drivers/media/Kconfig @@ -6,82 +6,20 @@ menuconfig MEDIA_SUPPORT tristate "Multimedia support" depends on HAS_IOMEM help - If you want to use Webcams, Video grabber devices and/or TV devices + If you want to use Video for Linux, DVB for Linux, or DAB adapters, enable this option and other options below. - Additional info and docs are available on the web at - if MEDIA_SUPPORT comment "Multimedia core support" -# -# Multimedia support - automatically enable V4L2 and DVB core -# -config MEDIA_CAMERA_SUPPORT - bool "Cameras/video grabbers support" - ---help--- - Enable support for webcams and video grabbers. - - Say Y when you have a webcam or a video capture grabber board. - -config MEDIA_ANALOG_TV_SUPPORT - bool "Analog TV support" - ---help--- - Enable analog TV support. - - Say Y when you have a TV board with analog support or with a - hybrid analog/digital TV chipset. - - Note: There are several DVB cards that are based on chips that - support both analog and digital TV. Disabling this option - will disable support for them. - -config MEDIA_DIGITAL_TV_SUPPORT - bool "Digital TV support" - ---help--- - Enable digital TV support. - - Say Y when you have a board with digital support or a board with - hybrid digital TV and analog TV. - -config MEDIA_RADIO_SUPPORT - bool "AM/FM radio receivers/transmitters support" - ---help--- - Enable AM/FM radio support. - - Additional info and docs are available on the web at - - - Say Y when you have a board with radio support. - - Note: There are several TV cards that are based on chips that - support radio reception. Disabling this option will - disable support for them. - -config MEDIA_RC_SUPPORT - bool "Remote Controller support" - depends on INPUT - ---help--- - Enable support for Remote Controllers on Linux. This is - needed in order to support several video capture adapters, - standalone IR receivers/transmitters, and RF receivers. - - Enable this option if you have a video capture board even - if you don't need IR, as otherwise, you may not be able to - compile the driver for your adapter. - - Say Y when you have a TV or an IR device. - # # Media controller -# Selectable only for webcam/grabbers, as other drivers don't use it # config MEDIA_CONTROLLER bool "Media Controller API (EXPERIMENTAL)" depends on EXPERIMENTAL - depends on MEDIA_CAMERA_SUPPORT ---help--- Enable the media controller API used to query media devices internal topology and configure it dynamically. @@ -89,15 +27,26 @@ config MEDIA_CONTROLLER This API is mostly used by camera interfaces in embedded platforms. # -# Video4Linux support -# Only enables if one of the V4L2 types (ATV, webcam, radio) is selected +# V4L core and enabled API's # config VIDEO_DEV - tristate - depends on MEDIA_SUPPORT - depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT - default y + tristate "Video For Linux" + ---help--- + V4L core support for video capture and overlay devices, webcams and + AM/FM radio cards. + + This kernel includes support for the new Video for Linux Two API, + (V4L2). + + Additional info and docs are available on the web at + + + Documentation for V4L2 is also available on the web at + . + + To compile this driver as a module, choose M here: the + module will be called videodev. config VIDEO_V4L2_COMMON tristate @@ -115,15 +64,25 @@ config VIDEO_V4L2_SUBDEV_API # # DVB Core -# Only enables if one of DTV is selected # config DVB_CORE - tristate - depends on MEDIA_SUPPORT - depends on MEDIA_DIGITAL_TV_SUPPORT - default y + tristate "DVB for Linux" select CRC32 + help + DVB core utility functions for device handling, software fallbacks etc. + + Enable this if you own a DVB/ATSC adapter and want to use it or if + you compile Linux for a digital SetTopBox. + + Say Y when you have a DVB or an ATSC card and want to use it. + + API specs and user tools are available from . + + Please report problems regarding this support to the LinuxDVB + mailing list. + + If unsure say N. config DVB_NET bool "DVB Network Support" @@ -138,7 +97,12 @@ config DVB_NET You may want to disable the network support on embedded devices. If unsure say Y. -comment "Media drivers" +config VIDEO_MEDIA + tristate + default (DVB_CORE && (VIDEO_DEV = n)) || (VIDEO_DEV && (DVB_CORE = n)) || (DVB_CORE && VIDEO_DEV) + +comment "Multimedia drivers" + source "drivers/media/common/Kconfig" source "drivers/media/rc/Kconfig" diff --git a/trunk/drivers/media/common/tuners/Kconfig b/trunk/drivers/media/common/tuners/Kconfig index 94c6ff7a5da3..bbf4945149a9 100644 --- a/trunk/drivers/media/common/tuners/Kconfig +++ b/trunk/drivers/media/common/tuners/Kconfig @@ -1,8 +1,7 @@ config MEDIA_ATTACH bool "Load and attach frontend and tuner driver modules as needed" - depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT + depends on VIDEO_MEDIA depends on MODULES - default y if !EXPERT help Remove the static dependency of DVB card drivers on all frontend modules for all possible card variants. Instead, @@ -20,15 +19,15 @@ config MEDIA_ATTACH config MEDIA_TUNER tristate - depends on (MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT) && I2C - default y + default VIDEO_MEDIA && I2C + depends on VIDEO_MEDIA && I2C select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT && EXPERIMENTAL - select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT + select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE && EXPERIMENTAL + select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE @@ -48,11 +47,10 @@ config MEDIA_TUNER_CUSTOMISE menu "Customize TV tuners" visible if MEDIA_TUNER_CUSTOMISE - depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT config MEDIA_TUNER_SIMPLE tristate "Simple tuner support" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C select MEDIA_TUNER_TDA9887 default m if MEDIA_TUNER_CUSTOMISE help @@ -60,7 +58,7 @@ config MEDIA_TUNER_SIMPLE config MEDIA_TUNER_TDA8290 tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C select MEDIA_TUNER_TDA827X select MEDIA_TUNER_TDA18271 default m if MEDIA_TUNER_CUSTOMISE @@ -69,21 +67,21 @@ config MEDIA_TUNER_TDA8290 config MEDIA_TUNER_TDA827X tristate "Philips TDA827X silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A DVB-T silicon tuner module. Say Y when you want to support this tuner. config MEDIA_TUNER_TDA18271 tristate "NXP TDA18271 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A silicon tuner module. Say Y when you want to support this tuner. config MEDIA_TUNER_TDA9887 tristate "TDA 9885/6/7 analog IF demodulator" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help Say Y here to include support for Philips TDA9885/6/7 @@ -91,7 +89,7 @@ config MEDIA_TUNER_TDA9887 config MEDIA_TUNER_TEA5761 tristate "TEA 5761 radio tuner (EXPERIMENTAL)" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C depends on EXPERIMENTAL default m if MEDIA_TUNER_CUSTOMISE help @@ -99,63 +97,63 @@ config MEDIA_TUNER_TEA5761 config MEDIA_TUNER_TEA5767 tristate "TEA 5767 radio tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help Say Y here to include support for the Philips TEA5767 radio tuner. config MEDIA_TUNER_MT20XX tristate "Microtune 2032 / 2050 tuners" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help Say Y here to include support for the MT2032 / MT2050 tuner. config MEDIA_TUNER_MT2060 tristate "Microtune MT2060 silicon IF tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A driver for the silicon IF tuner MT2060 from Microtune. config MEDIA_TUNER_MT2063 tristate "Microtune MT2063 silicon IF tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A driver for the silicon IF tuner MT2063 from Microtune. config MEDIA_TUNER_MT2266 tristate "Microtune MT2266 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A driver for the silicon baseband tuner MT2266 from Microtune. config MEDIA_TUNER_MT2131 tristate "Microtune MT2131 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A driver for the silicon baseband tuner MT2131 from Microtune. config MEDIA_TUNER_QT1010 tristate "Quantek QT1010 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A driver for the silicon tuner QT1010 from Quantek. config MEDIA_TUNER_XC2028 tristate "XCeive xc2028/xc3028 tuners" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help Say Y here to include support for the xc2028/xc3028 tuners. config MEDIA_TUNER_XC5000 tristate "Xceive XC5000 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A driver for the silicon tuner XC5000 from Xceive. @@ -164,7 +162,7 @@ config MEDIA_TUNER_XC5000 config MEDIA_TUNER_XC4000 tristate "Xceive XC4000 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A driver for the silicon tuner XC4000 from Xceive. @@ -173,70 +171,70 @@ config MEDIA_TUNER_XC4000 config MEDIA_TUNER_MXL5005S tristate "MaxLinear MSL5005S silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A driver for the silicon tuner MXL5005S from MaxLinear. config MEDIA_TUNER_MXL5007T tristate "MaxLinear MxL5007T silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A driver for the silicon tuner MxL5007T from MaxLinear. config MEDIA_TUNER_MC44S803 tristate "Freescale MC44S803 Low Power CMOS Broadband tuners" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help Say Y here to support the Freescale MC44S803 based tuners config MEDIA_TUNER_MAX2165 tristate "Maxim MAX2165 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help A driver for the silicon tuner MAX2165 from Maxim. config MEDIA_TUNER_TDA18218 tristate "NXP TDA18218 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help NXP TDA18218 silicon tuner driver. config MEDIA_TUNER_FC0011 tristate "Fitipower FC0011 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help Fitipower FC0011 silicon tuner driver. config MEDIA_TUNER_FC0012 tristate "Fitipower FC0012 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help Fitipower FC0012 silicon tuner driver. config MEDIA_TUNER_FC0013 tristate "Fitipower FC0013 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help Fitipower FC0013 silicon tuner driver. config MEDIA_TUNER_TDA18212 tristate "NXP TDA18212 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help NXP TDA18212 silicon tuner driver. config MEDIA_TUNER_TUA9001 tristate "Infineon TUA 9001 silicon tuner" - depends on MEDIA_SUPPORT && I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMISE help Infineon TUA 9001 silicon tuner driver. diff --git a/trunk/drivers/media/common/tuners/tuner-xc2028.c b/trunk/drivers/media/common/tuners/tuner-xc2028.c index f88f948efee2..b5ee3ebfcfca 100644 --- a/trunk/drivers/media/common/tuners/tuner-xc2028.c +++ b/trunk/drivers/media/common/tuners/tuner-xc2028.c @@ -90,22 +90,11 @@ struct firmware_properties { int scode_nr; }; -enum xc2028_state { - XC2028_NO_FIRMWARE = 0, - XC2028_WAITING_FIRMWARE, - XC2028_ACTIVE, - XC2028_SLEEP, - XC2028_NODEV, -}; - struct xc2028_data { struct list_head hybrid_tuner_instance_list; struct tuner_i2c_props i2c_props; __u32 frequency; - enum xc2028_state state; - const char *fname; - struct firmware_description *firm; int firm_size; __u16 firm_version; @@ -266,21 +255,6 @@ static v4l2_std_id parse_audio_std_option(void) return 0; } -static int check_device_status(struct xc2028_data *priv) -{ - switch (priv->state) { - case XC2028_NO_FIRMWARE: - case XC2028_WAITING_FIRMWARE: - return -EAGAIN; - case XC2028_ACTIVE: - case XC2028_SLEEP: - return 0; - case XC2028_NODEV: - return -ENODEV; - } - return 0; -} - static void free_firmware(struct xc2028_data *priv) { int i; @@ -296,28 +270,45 @@ static void free_firmware(struct xc2028_data *priv) priv->firm = NULL; priv->firm_size = 0; - priv->state = XC2028_NO_FIRMWARE; memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); } -static int load_all_firmwares(struct dvb_frontend *fe, - const struct firmware *fw) +static int load_all_firmwares(struct dvb_frontend *fe) { struct xc2028_data *priv = fe->tuner_priv; + const struct firmware *fw = NULL; const unsigned char *p, *endp; int rc = 0; int n, n_array; char name[33]; + char *fname; tuner_dbg("%s called\n", __func__); + if (!firmware_name[0]) + fname = priv->ctrl.fname; + else + fname = firmware_name; + + tuner_dbg("Reading firmware %s\n", fname); + rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent); + if (rc < 0) { + if (rc == -ENOENT) + tuner_err("Error: firmware %s not found.\n", + fname); + else + tuner_err("Error %d while requesting firmware %s \n", + rc, fname); + + return rc; + } p = fw->data; endp = p + fw->size; if (fw->size < sizeof(name) - 1 + 2 + 2) { tuner_err("Error: firmware file %s has invalid size!\n", - priv->fname); + fname); goto corrupt; } @@ -332,7 +323,7 @@ static int load_all_firmwares(struct dvb_frontend *fe, p += 2; tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n", - n_array, priv->fname, name, + n_array, fname, name, priv->firm_version >> 8, priv->firm_version & 0xff); priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL); @@ -426,10 +417,9 @@ static int load_all_firmwares(struct dvb_frontend *fe, free_firmware(priv); done: + release_firmware(fw); if (rc == 0) tuner_dbg("Firmware files loaded.\n"); - else - priv->state = XC2028_NODEV; return rc; } @@ -717,15 +707,22 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type, { struct xc2028_data *priv = fe->tuner_priv; struct firmware_properties new_fw; - int rc, retry_count = 0; + int rc = 0, retry_count = 0; u16 version, hwmodel; v4l2_std_id std0; tuner_dbg("%s called\n", __func__); - rc = check_device_status(priv); - if (rc < 0) - return rc; + if (!priv->firm) { + if (!priv->ctrl.fname) { + tuner_info("xc2028/3028 firmware name not set!\n"); + return -EINVAL; + } + + rc = load_all_firmwares(fe); + if (rc < 0) + return rc; + } if (priv->ctrl.mts && !(type & FM)) type |= MTS; @@ -752,13 +749,9 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type, printk("scode_nr %d\n", new_fw.scode_nr); } - /* - * No need to reload base firmware if it matches and if the tuner - * is not at sleep mode - */ - if ((priv->state = XC2028_ACTIVE) && - (((BASE | new_fw.type) & BASE_TYPES) == - (priv->cur_fw.type & BASE_TYPES))) { + /* No need to reload base firmware if it matches */ + if (((BASE | new_fw.type) & BASE_TYPES) == + (priv->cur_fw.type & BASE_TYPES)) { tuner_dbg("BASE firmware not changed.\n"); goto skip_base; } @@ -879,13 +872,10 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type, * 2. Tell whether BASE firmware was just changed the next time through. */ priv->cur_fw.type |= BASE; - priv->state = XC2028_ACTIVE; return 0; fail: - priv->state = XC2028_SLEEP; - memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); if (retry_count < 8) { msleep(50); @@ -903,39 +893,28 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) { struct xc2028_data *priv = fe->tuner_priv; u16 frq_lock, signal = 0; - int rc, i; + int rc; tuner_dbg("%s called\n", __func__); - rc = check_device_status(priv); - if (rc < 0) - return rc; - mutex_lock(&priv->lock); /* Sync Lock Indicator */ - for (i = 0; i < 3; i++) { - rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock); - if (rc < 0) - goto ret; - - if (frq_lock) - break; - msleep(6); - } - - /* Frequency didn't lock */ - if (frq_lock == 2) + rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock); + if (rc < 0) goto ret; + /* Frequency is locked */ + if (frq_lock == 1) + signal = 1 << 11; + /* Get SNR of the video signal */ rc = xc2028_get_reg(priv, XREG_SNR, &signal); if (rc < 0) goto ret; - /* Signal level is 3 bits only */ - - signal = ((1 << 12) - 1) | ((signal & 0x07) << 12); + /* Use both frq_lock and signal to generate the result */ + signal = signal || ((signal & 0x07) << 12); ret: mutex_unlock(&priv->lock); @@ -947,49 +926,6 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) return rc; } -static int xc2028_get_afc(struct dvb_frontend *fe, s32 *afc) -{ - struct xc2028_data *priv = fe->tuner_priv; - int i, rc; - u16 frq_lock = 0; - s16 afc_reg = 0; - - rc = check_device_status(priv); - if (rc < 0) - return rc; - - mutex_lock(&priv->lock); - - /* Sync Lock Indicator */ - for (i = 0; i < 3; i++) { - rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock); - if (rc < 0) - goto ret; - - if (frq_lock) - break; - msleep(6); - } - - /* Frequency didn't lock */ - if (frq_lock == 2) - goto ret; - - /* Get AFC */ - rc = xc2028_get_reg(priv, XREG_FREQ_ERROR, &afc_reg); - if (rc < 0) - return rc; - - *afc = afc_reg * 15625; /* Hz */ - - tuner_dbg("AFC is %d Hz\n", *afc); - -ret: - mutex_unlock(&priv->lock); - - return rc; -} - #define DIV 15625 static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, @@ -1175,16 +1111,11 @@ static int xc2028_set_params(struct dvb_frontend *fe) u32 delsys = c->delivery_system; u32 bw = c->bandwidth_hz; struct xc2028_data *priv = fe->tuner_priv; - int rc; - unsigned int type = 0; + unsigned int type=0; u16 demod = 0; tuner_dbg("%s called\n", __func__); - rc = check_device_status(priv); - if (rc < 0) - return rc; - switch (delsys) { case SYS_DVBT: case SYS_DVBT2: @@ -1270,11 +1201,7 @@ static int xc2028_set_params(struct dvb_frontend *fe) static int xc2028_sleep(struct dvb_frontend *fe) { struct xc2028_data *priv = fe->tuner_priv; - int rc; - - rc = check_device_status(priv); - if (rc < 0) - return rc; + int rc = 0; /* Avoid firmware reload on slow devices or if PM disabled */ if (no_poweroff || priv->ctrl.disable_power_mgmt) @@ -1293,7 +1220,7 @@ static int xc2028_sleep(struct dvb_frontend *fe) else rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00}); - priv->state = XC2028_SLEEP; + priv->cur_fw.type = 0; /* need firmware reload */ mutex_unlock(&priv->lock); @@ -1310,9 +1237,8 @@ static int xc2028_dvb_release(struct dvb_frontend *fe) /* only perform final cleanup if this is the last instance */ if (hybrid_tuner_report_instance_count(priv) == 1) { - free_firmware(priv); kfree(priv->ctrl.fname); - priv->ctrl.fname = NULL; + free_firmware(priv); } if (priv) @@ -1328,42 +1254,14 @@ static int xc2028_dvb_release(struct dvb_frontend *fe) static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct xc2028_data *priv = fe->tuner_priv; - int rc; tuner_dbg("%s called\n", __func__); - rc = check_device_status(priv); - if (rc < 0) - return rc; - *frequency = priv->frequency; return 0; } -static void load_firmware_cb(const struct firmware *fw, - void *context) -{ - struct dvb_frontend *fe = context; - struct xc2028_data *priv = fe->tuner_priv; - int rc; - - tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error"); - if (!fw) { - tuner_err("Could not load firmware %s.\n", priv->fname); - priv->state = XC2028_NODEV; - return; - } - - rc = load_all_firmwares(fe, fw); - - release_firmware(fw); - - if (rc < 0) - return; - priv->state = XC2028_SLEEP; -} - static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) { struct xc2028_data *priv = fe->tuner_priv; @@ -1374,49 +1272,21 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) mutex_lock(&priv->lock); - /* - * Copy the config data. - * For the firmware name, keep a local copy of the string, - * in order to avoid troubles during device release. - */ - if (priv->ctrl.fname) - kfree(priv->ctrl.fname); memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); + if (priv->ctrl.max_len < 9) + priv->ctrl.max_len = 13; + if (p->fname) { + if (priv->ctrl.fname && strcmp(p->fname, priv->ctrl.fname)) { + kfree(priv->ctrl.fname); + free_firmware(priv); + } + priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); if (priv->ctrl.fname == NULL) rc = -ENOMEM; } - /* - * If firmware name changed, frees firmware. As free_firmware will - * reset the status to NO_FIRMWARE, this forces a new request_firmware - */ - if (!firmware_name[0] && p->fname && - priv->fname && strcmp(p->fname, priv->fname)) - free_firmware(priv); - - if (priv->ctrl.max_len < 9) - priv->ctrl.max_len = 13; - - if (priv->state == XC2028_NO_FIRMWARE) { - if (!firmware_name[0]) - priv->fname = priv->ctrl.fname; - else - priv->fname = firmware_name; - - rc = request_firmware_nowait(THIS_MODULE, 1, - priv->fname, - priv->i2c_props.adap->dev.parent, - GFP_KERNEL, - fe, load_firmware_cb); - if (rc < 0) { - tuner_err("Failed to request firmware %s\n", - priv->fname); - priv->state = XC2028_NODEV; - } - priv->state = XC2028_WAITING_FIRMWARE; - } mutex_unlock(&priv->lock); return rc; @@ -1435,7 +1305,6 @@ static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = { .release = xc2028_dvb_release, .get_frequency = xc2028_get_frequency, .get_rf_strength = xc2028_signal, - .get_afc = xc2028_get_afc, .set_params = xc2028_set_params, .sleep = xc2028_sleep, }; @@ -1506,5 +1375,3 @@ MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver"); MODULE_AUTHOR("Michel Ludwig "); MODULE_AUTHOR("Mauro Carvalho Chehab "); MODULE_LICENSE("GPL"); -MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE); -MODULE_FIRMWARE(XC3028L_DEFAULT_FIRMWARE); diff --git a/trunk/drivers/media/common/tuners/xc5000.c b/trunk/drivers/media/common/tuners/xc5000.c index bac8009e1d49..dcca42ca57be 100644 --- a/trunk/drivers/media/common/tuners/xc5000.c +++ b/trunk/drivers/media/common/tuners/xc5000.c @@ -717,12 +717,6 @@ static int xc5000_set_params(struct dvb_frontend *fe) priv->freq_hz = freq - 1750000; priv->video_standard = DTV6; break; - case SYS_ISDBT: - /* All ISDB-T are currently for 6 MHz bw */ - if (!bw) - bw = 6000000; - /* fall to OFDM handling */ - case SYS_DMBTH: case SYS_DVBT: case SYS_DVBT2: dprintk(1, "%s() OFDM\n", __func__); diff --git a/trunk/drivers/media/dvb/ddbridge/ddbridge-core.c b/trunk/drivers/media/dvb/ddbridge/ddbridge-core.c index ebf3f05839d2..131b938e9e81 100644 --- a/trunk/drivers/media/dvb/ddbridge/ddbridge-core.c +++ b/trunk/drivers/media/dvb/ddbridge/ddbridge-core.c @@ -578,7 +578,6 @@ static int demod_attach_drxk(struct ddb_input *input) memset(&config, 0, sizeof(config)); config.microcode_name = "drxk_a3.mc"; - config.qam_demod_parameter_count = 4; config.adr = 0x29 + (input->nr & 1); fe = input->fe = dvb_attach(drxk_attach, &config, i2c); diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h index 7c64c09103a9..e929d5697b87 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -220,7 +220,6 @@ struct dvb_tuner_ops { #define TUNER_STATUS_STEREO 2 int (*get_status)(struct dvb_frontend *fe, u32 *status); int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength); - int (*get_afc)(struct dvb_frontend *fe, s32 *afc); /** These are provided separately from set_params in order to facilitate silicon * tuners which require sophisticated tuning loops, controlling each parameter separately. */ diff --git a/trunk/drivers/media/dvb/dvb-usb/Kconfig b/trunk/drivers/media/dvb/dvb-usb/Kconfig index c2161565023a..a26949336b3d 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Kconfig +++ b/trunk/drivers/media/dvb/dvb-usb/Kconfig @@ -418,12 +418,9 @@ config DVB_USB_RTL28XXU tristate "Realtek RTL28xxU DVB USB support" depends on DVB_USB && EXPERIMENTAL select DVB_RTL2830 - select DVB_RTL2832 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_FC0012 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_FC0013 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the Realtek RTL28xxU DVB USB receiver. diff --git a/trunk/drivers/media/dvb/dvb-usb/az6007.c b/trunk/drivers/media/dvb/dvb-usb/az6007.c index 8ffcad000ad3..4008b9c50fbd 100644 --- a/trunk/drivers/media/dvb/dvb-usb/az6007.c +++ b/trunk/drivers/media/dvb/dvb-usb/az6007.c @@ -593,7 +593,9 @@ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) memcpy(mac, st->data, sizeof(mac)); if (ret > 0) - deb_info("%s: mac is %pM\n", __func__, mac); + deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5]); return ret; } diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 26c44818a5ab..7a6160bf54ba 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -100,7 +100,6 @@ #define USB_PID_CONCEPTRONIC_CTVDIGRCU 0xe397 #define USB_PID_CONEXANT_D680_DMB 0x86d6 #define USB_PID_CREATIX_CTX1921 0x1921 -#define USB_PID_DELOCK_USB2_DVBT 0xb803 #define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 #define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 #define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 @@ -161,7 +160,6 @@ #define USB_PID_TERRATEC_CINERGY_T_STICK 0x0093 #define USB_PID_TERRATEC_CINERGY_T_STICK_RC 0x0097 #define USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC 0x0099 -#define USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1 0x00a9 #define USB_PID_TWINHAN_VP7041_COLD 0x3201 #define USB_PID_TWINHAN_VP7041_WARM 0x3202 #define USB_PID_TWINHAN_VP7020_COLD 0x3203 @@ -247,7 +245,6 @@ #define USB_PID_TERRATEC_H7_2 0x10a3 #define USB_PID_TERRATEC_T3 0x10a0 #define USB_PID_TERRATEC_T5 0x10a1 -#define USB_PID_NOXON_DAB_STICK 0x00b3 #define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e #define USB_PID_PINNACLE_PCTV2000E 0x022c #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 diff --git a/trunk/drivers/media/dvb/dvb-usb/rtl28xxu.c b/trunk/drivers/media/dvb/dvb-usb/rtl28xxu.c index 6bd0bd792437..41e1f5537f44 100644 --- a/trunk/drivers/media/dvb/dvb-usb/rtl28xxu.c +++ b/trunk/drivers/media/dvb/dvb-usb/rtl28xxu.c @@ -3,7 +3,6 @@ * * Copyright (C) 2009 Antti Palosaari * Copyright (C) 2011 Antti Palosaari - * Copyright (C) 2012 Thomas Mair * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,13 +22,10 @@ #include "rtl28xxu.h" #include "rtl2830.h" -#include "rtl2832.h" #include "qt1010.h" #include "mt2060.h" #include "mxl5005s.h" -#include "fc0012.h" -#include "fc0013.h" /* debug */ static int dvb_usb_rtl28xxu_debug; @@ -84,7 +80,7 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req) return ret; } -static int rtl28xx_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len) +static int rtl2831_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len) { struct rtl28xxu_req req; @@ -120,12 +116,12 @@ static int rtl2831_rd_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len) return rtl28xxu_ctrl_msg(d, &req); } -static int rtl28xx_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val) +static int rtl2831_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val) { - return rtl28xx_wr_regs(d, reg, &val, 1); + return rtl2831_wr_regs(d, reg, &val, 1); } -static int rtl28xx_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val) +static int rtl2831_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val) { return rtl2831_rd_regs(d, reg, val, 1); } @@ -312,12 +308,12 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap) */ /* GPIO direction */ - ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a); + ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a); if (ret) goto err; /* enable as output GPIO0, GPIO2, GPIO4 */ - ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15); + ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15); if (ret) goto err; @@ -385,159 +381,34 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap) return ret; } -static struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = { - .i2c_addr = 0x10, /* 0x20 */ - .xtal = 28800000, - .if_dvbt = 0, - .tuner = TUNER_RTL2832_FC0012 -}; - -static struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = { - .i2c_addr = 0x10, /* 0x20 */ - .xtal = 28800000, - .if_dvbt = 0, - .tuner = TUNER_RTL2832_FC0013 -}; - -static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d, - int cmd, int arg) -{ - int ret; - u8 val; - - deb_info("%s cmd=%d arg=%d\n", __func__, cmd, arg); - switch (cmd) { - case FC_FE_CALLBACK_VHF_ENABLE: - /* set output values */ - ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val); - if (ret) - goto err; - - if (arg) - val &= 0xbf; /* set GPIO6 low */ - else - val |= 0x40; /* set GPIO6 high */ - - - ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val); - if (ret) - goto err; - break; - default: - ret = -EINVAL; - goto err; - } - return 0; - -err: - err("%s: failed=%d\n", __func__, ret); - - return ret; -} - - -static int rtl2832u_fc0013_tuner_callback(struct dvb_usb_device *d, - int cmd, int arg) -{ - /* TODO implement*/ - return 0; -} - -static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int arg) -{ - struct rtl28xxu_priv *priv = d->priv; - - switch (priv->tuner) { - case TUNER_RTL2832_FC0012: - return rtl2832u_fc0012_tuner_callback(d, cmd, arg); - - case TUNER_RTL2832_FC0013: - return rtl2832u_fc0013_tuner_callback(d, cmd, arg); - default: - break; - } - - return -ENODEV; -} - -static int rtl2832u_frontend_callback(void *adapter_priv, int component, - int cmd, int arg) -{ - struct i2c_adapter *adap = adapter_priv; - struct dvb_usb_device *d = i2c_get_adapdata(adap); - - switch (component) { - case DVB_FRONTEND_COMPONENT_TUNER: - return rtl2832u_tuner_callback(d, cmd, arg); - default: - break; - } - - return -EINVAL; -} - - - - static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) { int ret; struct rtl28xxu_priv *priv = adap->dev->priv; - struct rtl2832_config *rtl2832_config; - - u8 buf[2], val; + u8 buf[1]; /* open RTL2832U/RTL2832 I2C gate */ struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"}; /* close RTL2832U/RTL2832 I2C gate */ struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"}; - /* for FC0012 tuner probe */ - struct rtl28xxu_req req_fc0012 = {0x00c6, CMD_I2C_RD, 1, buf}; - /* for FC0013 tuner probe */ - struct rtl28xxu_req req_fc0013 = {0x00c6, CMD_I2C_RD, 1, buf}; - /* for MT2266 tuner probe */ - struct rtl28xxu_req req_mt2266 = {0x00c0, CMD_I2C_RD, 1, buf}; /* for FC2580 tuner probe */ struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf}; - /* for MT2063 tuner probe */ - struct rtl28xxu_req req_mt2063 = {0x00c0, CMD_I2C_RD, 1, buf}; - /* for MAX3543 tuner probe */ - struct rtl28xxu_req req_max3543 = {0x00c0, CMD_I2C_RD, 1, buf}; - /* for TUA9001 tuner probe */ - struct rtl28xxu_req req_tua9001 = {0x7ec0, CMD_I2C_RD, 2, buf}; - /* for MXL5007T tuner probe */ - struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf}; - /* for E4000 tuner probe */ - struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf}; - /* for TDA18272 tuner probe */ - struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; deb_info("%s:\n", __func__); - - ret = rtl28xx_rd_reg(adap->dev, SYS_GPIO_DIR, &val); - if (ret) - goto err; - - val &= 0xbf; - - ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_DIR, val); + /* GPIO direction */ + ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a); if (ret) goto err; - - /* enable as output GPIO3 and GPIO6*/ - ret = rtl28xx_rd_reg(adap->dev, SYS_GPIO_OUT_EN, &val); + /* enable as output GPIO0, GPIO2, GPIO4 */ + ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15); if (ret) goto err; - val |= 0x48; - - ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_EN, val); + ret = rtl2831_wr_reg(adap->dev, SYS_DEMOD_CTL, 0xe8); if (ret) goto err; - - /* * Probe used tuner. We need to know used tuner before demod attach * since there is some demod params needed to set according to tuner. @@ -548,108 +419,25 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) if (ret) goto err; - priv->tuner = TUNER_NONE; - - /* check FC0012 ID register; reg=00 val=a1 */ - ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc0012); - if (ret == 0 && buf[0] == 0xa1) { - priv->tuner = TUNER_RTL2832_FC0012; - rtl2832_config = &rtl28xxu_rtl2832_fc0012_config; - info("%s: FC0012 tuner found", __func__); - goto found; - } - - /* check FC0013 ID register; reg=00 val=a3 */ - ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc0013); - if (ret == 0 && buf[0] == 0xa3) { - priv->tuner = TUNER_RTL2832_FC0013; - rtl2832_config = &rtl28xxu_rtl2832_fc0013_config; - info("%s: FC0013 tuner found", __func__); - goto found; - } - - /* check MT2266 ID register; reg=00 val=85 */ - ret = rtl28xxu_ctrl_msg(adap->dev, &req_mt2266); - if (ret == 0 && buf[0] == 0x85) { - priv->tuner = TUNER_RTL2832_MT2266; - /* TODO implement tuner */ - info("%s: MT2266 tuner found", __func__); - goto unsupported; - } - /* check FC2580 ID register; reg=01 val=56 */ ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc2580); if (ret == 0 && buf[0] == 0x56) { priv->tuner = TUNER_RTL2832_FC2580; - /* TODO implement tuner */ - info("%s: FC2580 tuner found", __func__); - goto unsupported; - } - - /* check MT2063 ID register; reg=00 val=9e || 9c */ - ret = rtl28xxu_ctrl_msg(adap->dev, &req_mt2063); - if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) { - priv->tuner = TUNER_RTL2832_MT2063; - /* TODO implement tuner */ - info("%s: MT2063 tuner found", __func__); - goto unsupported; - } - - /* check MAX3543 ID register; reg=00 val=38 */ - ret = rtl28xxu_ctrl_msg(adap->dev, &req_max3543); - if (ret == 0 && buf[0] == 0x38) { - priv->tuner = TUNER_RTL2832_MAX3543; - /* TODO implement tuner */ - info("%s: MAX3534 tuner found", __func__); - goto unsupported; - } - - /* check TUA9001 ID register; reg=7e val=2328 */ - ret = rtl28xxu_ctrl_msg(adap->dev, &req_tua9001); - if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) { - priv->tuner = TUNER_RTL2832_TUA9001; - /* TODO implement tuner */ - info("%s: TUA9001 tuner found", __func__); - goto unsupported; - } - - /* check MXL5007R ID register; reg=d9 val=14 */ - ret = rtl28xxu_ctrl_msg(adap->dev, &req_mxl5007t); - if (ret == 0 && buf[0] == 0x14) { - priv->tuner = TUNER_RTL2832_MXL5007T; - /* TODO implement tuner */ - info("%s: MXL5007T tuner found", __func__); - goto unsupported; - } - - /* check E4000 ID register; reg=02 val=40 */ - ret = rtl28xxu_ctrl_msg(adap->dev, &req_e4000); - if (ret == 0 && buf[0] == 0x40) { - priv->tuner = TUNER_RTL2832_E4000; - /* TODO implement tuner */ - info("%s: E4000 tuner found", __func__); - goto unsupported; - } - - /* check TDA18272 ID register; reg=00 val=c760 */ - ret = rtl28xxu_ctrl_msg(adap->dev, &req_tda18272); - if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) { - priv->tuner = TUNER_RTL2832_TDA18272; - /* TODO implement tuner */ - info("%s: TDA18272 tuner found", __func__); - goto unsupported; + deb_info("%s: FC2580\n", __func__); + goto found; + } else { + deb_info("%s: FC2580 probe failed=%d - %02x\n", + __func__, ret, buf[0]); } -unsupported: /* close demod I2C gate */ ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_close); if (ret) goto err; /* tuner not found */ - deb_info("No compatible tuner found"); ret = -ENODEV; - return ret; + goto err; found: /* close demod I2C gate */ @@ -658,18 +446,9 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) goto err; /* attach demodulator */ - adap->fe_adap[0].fe = dvb_attach(rtl2832_attach, rtl2832_config, - &adap->dev->i2c_adap); - if (adap->fe_adap[0].fe == NULL) { - ret = -ENODEV; - goto err; - } - - /* set fe callbacks */ - adap->fe_adap[0].fe->callback = rtl2832u_frontend_callback; + /* TODO: */ return ret; - err: deb_info("%s: failed=%d\n", __func__, ret); return ret; @@ -752,24 +531,10 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) deb_info("%s:\n", __func__); switch (priv->tuner) { - case TUNER_RTL2832_FC0012: - fe = dvb_attach(fc0012_attach, adap->fe_adap[0].fe, - &adap->dev->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ); - - /* since fc0012 includs reading the signal strength delegate - * that to the tuner driver */ - adap->fe_adap[0].fe->ops.read_signal_strength = adap->fe_adap[0]. - fe->ops.tuner_ops.get_rf_strength; - return 0; + case TUNER_RTL2832_FC2580: + /* TODO: */ + fe = NULL; break; - case TUNER_RTL2832_FC0013: - fe = dvb_attach(fc0013_attach, adap->fe_adap[0].fe, - &adap->dev->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ); - - /* fc0013 also supports signal strength reading */ - adap->fe_adap[0].fe->ops.read_signal_strength = adap->fe_adap[0] - .fe->ops.tuner_ops.get_rf_strength; - return 0; default: fe = NULL; err("unknown tuner=%d", priv->tuner); @@ -786,14 +551,14 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) return ret; } -static int rtl2831u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff) +static int rtl28xxu_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff) { int ret; u8 buf[2], gpio; deb_info("%s: onoff=%d\n", __func__, onoff); - ret = rtl28xx_rd_reg(adap->dev, SYS_GPIO_OUT_VAL, &gpio); + ret = rtl2831_rd_reg(adap->dev, SYS_GPIO_OUT_VAL, &gpio); if (ret) goto err; @@ -807,37 +572,11 @@ static int rtl2831u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff) gpio &= (~0x04); /* LED off */ } - ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_VAL, gpio); + ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_VAL, gpio); if (ret) goto err; - ret = rtl28xx_wr_regs(adap->dev, USB_EPA_CTL, buf, 2); - if (ret) - goto err; - - return ret; -err: - deb_info("%s: failed=%d\n", __func__, ret); - return ret; -} - -static int rtl2832u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff) -{ - int ret; - u8 buf[2]; - - deb_info("%s: onoff=%d\n", __func__, onoff); - - - if (onoff) { - buf[0] = 0x00; - buf[1] = 0x00; - } else { - buf[0] = 0x10; /* stall EPA */ - buf[1] = 0x02; /* reset EPA */ - } - - ret = rtl28xx_wr_regs(adap->dev, USB_EPA_CTL, buf, 2); + ret = rtl2831_wr_regs(adap->dev, USB_EPA_CTL, buf, 2); if (ret) goto err; @@ -847,7 +586,7 @@ static int rtl2832u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff) return ret; } -static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff) +static int rtl28xxu_power_ctrl(struct dvb_usb_device *d, int onoff) { int ret; u8 gpio, sys0; @@ -855,12 +594,12 @@ static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff) deb_info("%s: onoff=%d\n", __func__, onoff); /* demod adc */ - ret = rtl28xx_rd_reg(d, SYS_SYS0, &sys0); + ret = rtl2831_rd_reg(d, SYS_SYS0, &sys0); if (ret) goto err; /* tuner power, read GPIOs */ - ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &gpio); + ret = rtl2831_rd_reg(d, SYS_GPIO_OUT_VAL, &gpio); if (ret) goto err; @@ -880,12 +619,12 @@ static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff) deb_info("%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio); /* demod adc */ - ret = rtl28xx_wr_reg(d, SYS_SYS0, sys0); + ret = rtl2831_wr_reg(d, SYS_SYS0, sys0); if (ret) goto err; /* tuner power, write GPIOs */ - ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, gpio); + ret = rtl2831_wr_reg(d, SYS_GPIO_OUT_VAL, gpio); if (ret) goto err; @@ -895,128 +634,6 @@ static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff) return ret; } -static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - int ret; - u8 val; - - deb_info("%s: onoff=%d\n", __func__, onoff); - - if (onoff) { - /* set output values */ - ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val); - if (ret) - goto err; - - val |= 0x08; - val &= 0xef; - - ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val); - if (ret) - goto err; - - /* demod_ctl_1 */ - ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val); - if (ret) - goto err; - - val &= 0xef; - - ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val); - if (ret) - goto err; - - /* demod control */ - /* PLL enable */ - ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val); - if (ret) - goto err; - - /* bit 7 to 1 */ - val |= 0x80; - - ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val); - if (ret) - goto err; - - /* demod HW reset */ - ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val); - if (ret) - goto err; - /* bit 5 to 0 */ - val &= 0xdf; - - ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val); - if (ret) - goto err; - - ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val); - if (ret) - goto err; - - val |= 0x20; - - ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val); - if (ret) - goto err; - - mdelay(5); - - /*enable ADC_Q and ADC_I */ - ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val); - if (ret) - goto err; - - val |= 0x48; - - ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val); - if (ret) - goto err; - - - } else { - /* demod_ctl_1 */ - ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val); - if (ret) - goto err; - - val |= 0x0c; - - ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val); - if (ret) - goto err; - - /* set output values */ - ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val); - if (ret) - goto err; - - val |= 0x10; - - ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val); - if (ret) - goto err; - - /* demod control */ - ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val); - if (ret) - goto err; - - val &= 0x37; - - ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val); - if (ret) - goto err; - - } - - return ret; -err: - deb_info("%s: failed=%d\n", __func__, ret); - return ret; -} - - static int rtl2831u_rc_query(struct dvb_usb_device *d) { int ret, i; @@ -1043,7 +660,7 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d) /* init remote controller */ if (!priv->rc_active) { for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) { - ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg, + ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg, rc_nec_tab[i].val); if (ret) goto err; @@ -1073,12 +690,12 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d) rc_keydown(d->rc_dev, rc_code, 0); - ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1); + ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1); if (ret) goto err; /* repeated intentionally to avoid extra keypress */ - ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1); + ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1); if (ret) goto err; } @@ -1115,7 +732,7 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) /* init remote controller */ if (!priv->rc_active) { for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) { - ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg, + ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg, rc_nec_tab[i].val); if (ret) goto err; @@ -1123,14 +740,14 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) priv->rc_active = true; } - ret = rtl28xx_rd_reg(d, IR_RX_IF, &buf[0]); + ret = rtl2831_rd_reg(d, IR_RX_IF, &buf[0]); if (ret) goto err; if (buf[0] != 0x83) goto exit; - ret = rtl28xx_rd_reg(d, IR_RX_BC, &buf[0]); + ret = rtl2831_rd_reg(d, IR_RX_BC, &buf[0]); if (ret) goto err; @@ -1139,9 +756,9 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) /* TODO: pass raw IR to Kernel IR decoder */ - ret = rtl28xx_wr_reg(d, IR_RX_IF, 0x03); - ret = rtl28xx_wr_reg(d, IR_RX_BUF_CTRL, 0x80); - ret = rtl28xx_wr_reg(d, IR_RX_CTRL, 0x80); + ret = rtl2831_wr_reg(d, IR_RX_IF, 0x03); + ret = rtl2831_wr_reg(d, IR_RX_BUF_CTRL, 0x80); + ret = rtl2831_wr_reg(d, IR_RX_CTRL, 0x80); exit: return ret; @@ -1154,9 +771,6 @@ enum rtl28xxu_usb_table_entry { RTL2831U_0BDA_2831, RTL2831U_14AA_0160, RTL2831U_14AA_0161, - RTL2832U_0CCD_00A9, - RTL2832U_1F4D_B803, - RTL2832U_0CCD_00B3, }; static struct usb_device_id rtl28xxu_table[] = { @@ -1169,12 +783,6 @@ static struct usb_device_id rtl28xxu_table[] = { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2)}, /* RTL2832U */ - [RTL2832U_0CCD_00A9] = { - USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1)}, - [RTL2832U_1F4D_B803] = { - USB_DEVICE(USB_VID_GTEK, USB_PID_DELOCK_USB2_DVBT)}, - [RTL2832U_0CCD_00B3] = { - USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK)}, {} /* terminating entry */ }; @@ -1197,7 +805,7 @@ static struct dvb_usb_device_properties rtl28xxu_properties[] = { { .frontend_attach = rtl2831u_frontend_attach, .tuner_attach = rtl2831u_tuner_attach, - .streaming_ctrl = rtl2831u_streaming_ctrl, + .streaming_ctrl = rtl28xxu_streaming_ctrl, .stream = { .type = USB_BULK, .count = 6, @@ -1213,7 +821,7 @@ static struct dvb_usb_device_properties rtl28xxu_properties[] = { } }, - .power_ctrl = rtl2831u_power_ctrl, + .power_ctrl = rtl28xxu_power_ctrl, .rc.core = { .protocol = RC_TYPE_NEC, @@ -1259,7 +867,7 @@ static struct dvb_usb_device_properties rtl28xxu_properties[] = { { .frontend_attach = rtl2832u_frontend_attach, .tuner_attach = rtl2832u_tuner_attach, - .streaming_ctrl = rtl2832u_streaming_ctrl, + .streaming_ctrl = rtl28xxu_streaming_ctrl, .stream = { .type = USB_BULK, .count = 6, @@ -1275,7 +883,7 @@ static struct dvb_usb_device_properties rtl28xxu_properties[] = { } }, - .power_ctrl = rtl2832u_power_ctrl, + .power_ctrl = rtl28xxu_power_ctrl, .rc.core = { .protocol = RC_TYPE_NEC, @@ -1288,25 +896,10 @@ static struct dvb_usb_device_properties rtl28xxu_properties[] = { .i2c_algo = &rtl28xxu_i2c_algo, - .num_device_descs = 3, + .num_device_descs = 0, /* disabled as no support for RTL2832 */ .devices = { { - .name = "Terratec Cinergy T Stick Black", - .warm_ids = { - &rtl28xxu_table[RTL2832U_0CCD_00A9], - }, - }, - { - .name = "G-Tek Electronics Group Lifeview LV5TDLX DVB-T", - .warm_ids = { - &rtl28xxu_table[RTL2832U_1F4D_B803], - }, - }, - { - .name = "NOXON DAB/DAB+ USB dongle", - .warm_ids = { - &rtl28xxu_table[RTL2832U_0CCD_00B3], - }, + .name = "Realtek RTL2832U reference design", }, } }, @@ -1317,7 +910,6 @@ static int rtl28xxu_probe(struct usb_interface *intf, const struct usb_device_id *id) { int ret, i; - u8 val; int properties_count = ARRAY_SIZE(rtl28xxu_properties); struct dvb_usb_device *d; struct usb_device *udev; @@ -1362,25 +954,16 @@ static int rtl28xxu_probe(struct usb_interface *intf, if (ret) goto err; - /* init USB endpoints */ - ret = rtl28xx_rd_reg(d, USB_SYSCTL_0, &val); - if (ret) - goto err; - - /* enable DMA and Full Packet Mode*/ - val |= 0x09; - ret = rtl28xx_wr_reg(d, USB_SYSCTL_0, val); + ret = rtl2831_wr_reg(d, USB_SYSCTL_0, 0x09); if (ret) goto err; - /* set EPA maximum packet size to 0x0200 */ - ret = rtl28xx_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4); + ret = rtl2831_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4); if (ret) goto err; - /* change EPA FIFO length */ - ret = rtl28xx_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4); + ret = rtl2831_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4); if (ret) goto err; @@ -1424,5 +1007,4 @@ module_exit(rtl28xxu_module_exit); MODULE_DESCRIPTION("Realtek RTL28xxU DVB USB driver"); MODULE_AUTHOR("Antti Palosaari "); -MODULE_AUTHOR("Thomas Mair "); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/Kconfig b/trunk/drivers/media/dvb/frontends/Kconfig index a08c2152d0ee..b98ebb264e29 100644 --- a/trunk/drivers/media/dvb/frontends/Kconfig +++ b/trunk/drivers/media/dvb/frontends/Kconfig @@ -1,7 +1,6 @@ config DVB_FE_CUSTOMISE bool "Customise the frontend modules to build" depends on DVB_CORE - depends on EXPERT default y if EXPERT help This allows the user to select/deselect frontend drivers for their @@ -433,13 +432,6 @@ config DVB_RTL2830 help Say Y when you want to support this frontend. -config DVB_RTL2832 - tristate "Realtek RTL2832 DVB-T" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - Say Y when you want to support this frontend. - comment "DVB-C (cable) frontends" depends on DVB_CORE diff --git a/trunk/drivers/media/dvb/frontends/Makefile b/trunk/drivers/media/dvb/frontends/Makefile index 185bb8b51952..cd1ac2fd5774 100644 --- a/trunk/drivers/media/dvb/frontends/Makefile +++ b/trunk/drivers/media/dvb/frontends/Makefile @@ -99,7 +99,6 @@ obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o obj-$(CONFIG_DVB_A8293) += a8293.o obj-$(CONFIG_DVB_TDA10071) += tda10071.o obj-$(CONFIG_DVB_RTL2830) += rtl2830.o -obj-$(CONFIG_DVB_RTL2832) += rtl2832.o obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o obj-$(CONFIG_DVB_AF9033) += af9033.o diff --git a/trunk/drivers/media/dvb/frontends/a8293.c b/trunk/drivers/media/dvb/frontends/a8293.c index cff44a389b40..bb56497e940a 100644 --- a/trunk/drivers/media/dvb/frontends/a8293.c +++ b/trunk/drivers/media/dvb/frontends/a8293.c @@ -21,6 +21,24 @@ #include "dvb_frontend.h" #include "a8293.h" +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); + +#define LOG_PREFIX "a8293" + +#undef dbg +#define dbg(f, arg...) \ + if (debug) \ + printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) +#undef err +#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) +#undef info +#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) +#undef warn +#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) + + struct a8293_priv { struct i2c_adapter *i2c; const struct a8293_config *cfg; @@ -47,8 +65,7 @@ static int a8293_i2c(struct a8293_priv *priv, u8 *val, int len, bool rd) if (ret == 1) { ret = 0; } else { - dev_warn(&priv->i2c->dev, "%s: i2c failed=%d rd=%d\n", - KBUILD_MODNAME, ret, rd); + warn("i2c failed=%d rd=%d", ret, rd); ret = -EREMOTEIO; } @@ -71,8 +88,7 @@ static int a8293_set_voltage(struct dvb_frontend *fe, struct a8293_priv *priv = fe->sec_priv; int ret; - dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__, - fe_sec_voltage); + dbg("%s: fe_sec_voltage=%d", __func__, fe_sec_voltage); switch (fe_sec_voltage) { case SEC_VOLTAGE_OFF: @@ -98,12 +114,14 @@ static int a8293_set_voltage(struct dvb_frontend *fe, return ret; err: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } static void a8293_release_sec(struct dvb_frontend *fe) { + dbg("%s:", __func__); + a8293_set_voltage(fe, SEC_VOLTAGE_OFF); kfree(fe->sec_priv); @@ -136,7 +154,7 @@ struct dvb_frontend *a8293_attach(struct dvb_frontend *fe, /* ENB=0 */ priv->reg[0] = 0x10; - ret = a8293_wr(priv, &priv->reg[0], 1); + ret = a8293_wr(priv, &priv->reg[1], 1); if (ret) goto err; @@ -146,17 +164,16 @@ struct dvb_frontend *a8293_attach(struct dvb_frontend *fe, if (ret) goto err; + info("Allegro A8293 SEC attached."); + fe->ops.release_sec = a8293_release_sec; /* override frontend ops */ fe->ops.set_voltage = a8293_set_voltage; - dev_info(&priv->i2c->dev, "%s: Allegro A8293 SEC attached\n", - KBUILD_MODNAME); - return fe; err: - dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); kfree(priv); return NULL; } diff --git a/trunk/drivers/media/dvb/frontends/drxk.h b/trunk/drivers/media/dvb/frontends/drxk.h index d615d7d055a2..9d64e4fea066 100644 --- a/trunk/drivers/media/dvb/frontends/drxk.h +++ b/trunk/drivers/media/dvb/frontends/drxk.h @@ -20,14 +20,6 @@ * means that 1=DVBC, 0 = DVBT. Zero means the opposite. * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength. * @microcode_name: Name of the firmware file with the microcode - * @qam_demod_parameter_count: The number of parameters used for the command - * to set the demodulator parameters. All - * firmwares are using the 2-parameter commmand. - * An exception is the "drxk_a3.mc" firmware, - * which uses the 4-parameter command. - * A value of 0 (default) or lower indicates that - * the correct number of parameters will be - * automatically detected. * * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is * UIO-3. @@ -46,8 +38,7 @@ struct drxk_config { u8 mpeg_out_clk_strength; int chunk_size; - const char *microcode_name; - int qam_demod_parameter_count; + const char *microcode_name; }; #if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \ diff --git a/trunk/drivers/media/dvb/frontends/drxk_hard.c b/trunk/drivers/media/dvb/frontends/drxk_hard.c index 1ab8154542da..60b868faeacf 100644 --- a/trunk/drivers/media/dvb/frontends/drxk_hard.c +++ b/trunk/drivers/media/dvb/frontends/drxk_hard.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "dvb_frontend.h" @@ -309,42 +308,16 @@ static u32 Log10Times100(u32 x) /* I2C **********************************************************************/ /****************************************************************************/ -static int drxk_i2c_lock(struct drxk_state *state) -{ - i2c_lock_adapter(state->i2c); - state->drxk_i2c_exclusive_lock = true; - - return 0; -} - -static void drxk_i2c_unlock(struct drxk_state *state) -{ - if (!state->drxk_i2c_exclusive_lock) - return; - - i2c_unlock_adapter(state->i2c); - state->drxk_i2c_exclusive_lock = false; -} - -static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs, - unsigned len) -{ - if (state->drxk_i2c_exclusive_lock) - return __i2c_transfer(state->i2c, msgs, len); - else - return i2c_transfer(state->i2c, msgs, len); -} - -static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val) +static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val) { struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD, .buf = val, .len = 1} }; - return drxk_i2c_transfer(state, msgs, 1); + return i2c_transfer(adapter, msgs, 1); } -static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) +static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) { int status; struct i2c_msg msg = { @@ -357,7 +330,7 @@ static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) printk(KERN_CONT " %02x", data[i]); printk(KERN_CONT "\n"); } - status = drxk_i2c_transfer(state, &msg, 1); + status = i2c_transfer(adap, &msg, 1); if (status >= 0 && status != 1) status = -EIO; @@ -367,7 +340,7 @@ static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) return status; } -static int i2c_read(struct drxk_state *state, +static int i2c_read(struct i2c_adapter *adap, u8 adr, u8 *msg, int len, u8 *answ, int alen) { int status; @@ -378,7 +351,7 @@ static int i2c_read(struct drxk_state *state, .buf = answ, .len = alen} }; - status = drxk_i2c_transfer(state, msgs, 2); + status = i2c_transfer(adap, msgs, 2); if (status != 2) { if (debug > 2) printk(KERN_CONT ": ERROR!\n"); @@ -421,7 +394,7 @@ static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags) len = 2; } dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); - status = i2c_read(state, adr, mm1, len, mm2, 2); + status = i2c_read(state->i2c, adr, mm1, len, mm2, 2); if (status < 0) return status; if (data) @@ -455,7 +428,7 @@ static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags) len = 2; } dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); - status = i2c_read(state, adr, mm1, len, mm2, 4); + status = i2c_read(state->i2c, adr, mm1, len, mm2, 4); if (status < 0) return status; if (data) @@ -491,7 +464,7 @@ static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags) mm[len + 1] = (data >> 8) & 0xff; dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags); - return i2c_write(state, adr, mm, len + 2); + return i2c_write(state->i2c, adr, mm, len + 2); } static int write16(struct drxk_state *state, u32 reg, u16 data) @@ -522,7 +495,7 @@ static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags) mm[len + 3] = (data >> 24) & 0xff; dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags); - return i2c_write(state, adr, mm, len + 4); + return i2c_write(state->i2c, adr, mm, len + 4); } static int write32(struct drxk_state *state, u32 reg, u32 data) @@ -569,7 +542,7 @@ static int write_block(struct drxk_state *state, u32 Address, printk(KERN_CONT " %02x", pBlock[i]); printk(KERN_CONT "\n"); } - status = i2c_write(state, state->demod_address, + status = i2c_write(state->i2c, state->demod_address, &state->Chunk[0], Chunk + AdrLength); if (status < 0) { printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n", @@ -595,17 +568,17 @@ int PowerUpDevice(struct drxk_state *state) dprintk(1, "\n"); - status = i2c_read1(state, state->demod_address, &data); + status = i2c_read1(state->i2c, state->demod_address, &data); if (status < 0) { do { data = 0; - status = i2c_write(state, state->demod_address, + status = i2c_write(state->i2c, state->demod_address, &data, 1); msleep(10); retryCount++; if (status < 0) continue; - status = i2c_read1(state, state->demod_address, + status = i2c_read1(state->i2c, state->demod_address, &data); } while (status < 0 && (retryCount < DRXK_MAX_RETRIES_POWERUP)); @@ -959,7 +932,7 @@ static int GetDeviceCapabilities(struct drxk_state *state) if (status < 0) goto error; - printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo); +printk(KERN_ERR "drxk: status = 0x%08x\n", sioTopJtagidLo); /* driver 0.9.0 */ switch ((sioTopJtagidLo >> 29) & 0xF) { @@ -2851,7 +2824,7 @@ static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge) dprintk(1, "\n"); if (state->m_DrxkState == DRXK_UNINITIALIZED) - return 0; + goto error; if (state->m_DrxkState == DRXK_POWERED_DOWN) goto error; @@ -3004,7 +2977,7 @@ static int ADCSynchronization(struct drxk_state *state) status = read16(state, IQM_AF_CLKNEG__A, &clkNeg); if (status < 0) goto error; - if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) == + if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) == IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) { clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); clkNeg |= @@ -5388,7 +5361,7 @@ static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus) SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2, Result); if (status < 0) - printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status); if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) { /* 0x0000 NOT LOCKED */ @@ -5415,67 +5388,12 @@ static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus) #define QAM_LOCKRANGE__M 0x10 #define QAM_LOCKRANGE_NORMAL 0x10 -static int QAMDemodulatorCommand(struct drxk_state *state, - int numberOfParameters) -{ - int status; - u16 cmdResult; - u16 setParamParameters[4] = { 0, 0, 0, 0 }; - - setParamParameters[0] = state->m_Constellation; /* modulation */ - setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ - - if (numberOfParameters == 2) { - u16 setEnvParameters[1] = { 0 }; - - if (state->m_OperationMode == OM_QAM_ITU_C) - setEnvParameters[0] = QAM_TOP_ANNEX_C; - else - setEnvParameters[0] = QAM_TOP_ANNEX_A; - - status = scu_command(state, - SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, - 1, setEnvParameters, 1, &cmdResult); - if (status < 0) - goto error; - - status = scu_command(state, - SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, - numberOfParameters, setParamParameters, - 1, &cmdResult); - } else if (numberOfParameters == 4) { - if (state->m_OperationMode == OM_QAM_ITU_C) - setParamParameters[2] = QAM_TOP_ANNEX_C; - else - setParamParameters[2] = QAM_TOP_ANNEX_A; - - setParamParameters[3] |= (QAM_MIRROR_AUTO_ON); - /* Env parameters */ - /* check for LOCKRANGE Extented */ - /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */ - - status = scu_command(state, - SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, - numberOfParameters, setParamParameters, - 1, &cmdResult); - } else { - printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter " - "count %d\n", numberOfParameters); - } - -error: - if (status < 0) - printk(KERN_WARNING "drxk: Warning %d on %s\n", - status, __func__); - return status; -} - static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, s32 tunerFreqOffset) { int status; + u16 setParamParameters[4] = { 0, 0, 0, 0 }; u16 cmdResult; - int qamDemodParamCount = state->qam_demod_parameter_count; dprintk(1, "\n"); /* @@ -5527,42 +5445,34 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, } if (status < 0) goto error; + setParamParameters[0] = state->m_Constellation; /* modulation */ + setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ + if (state->m_OperationMode == OM_QAM_ITU_C) + setParamParameters[2] = QAM_TOP_ANNEX_C; + else + setParamParameters[2] = QAM_TOP_ANNEX_A; + setParamParameters[3] |= (QAM_MIRROR_AUTO_ON); + /* Env parameters */ + /* check for LOCKRANGE Extented */ + /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */ - /* Use the 4-parameter if it's requested or we're probing for - * the correct command. */ - if (state->qam_demod_parameter_count == 4 - || !state->qam_demod_parameter_count) { - qamDemodParamCount = 4; - status = QAMDemodulatorCommand(state, qamDemodParamCount); - } - - /* Use the 2-parameter command if it was requested or if we're - * probing for the correct command and the 4-parameter command - * failed. */ - if (state->qam_demod_parameter_count == 2 - || (!state->qam_demod_parameter_count && status < 0)) { - qamDemodParamCount = 2; - status = QAMDemodulatorCommand(state, qamDemodParamCount); - } - + status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult); if (status < 0) { - dprintk(1, "Could not set demodulator parameters. Make " - "sure qam_demod_parameter_count (%d) is correct for " - "your firmware (%s).\n", - state->qam_demod_parameter_count, - state->microcode_name); - goto error; - } else if (!state->qam_demod_parameter_count) { - dprintk(1, "Auto-probing the correct QAM demodulator command " - "parameters was successful - using %d parameters.\n", - qamDemodParamCount); + /* Fall-back to the simpler call */ + if (state->m_OperationMode == OM_QAM_ITU_C) + setParamParameters[0] = QAM_TOP_ANNEX_C; + else + setParamParameters[0] = QAM_TOP_ANNEX_A; + status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult); + if (status < 0) + goto error; - /* - * One of our commands was successful. We don't need to - * auto-probe anymore, now that we got the correct command. - */ - state->qam_demod_parameter_count = qamDemodParamCount; + setParamParameters[0] = state->m_Constellation; /* modulation */ + setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ + status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult); } + if (status < 0) + goto error; /* * STEP 3: enable the system in a mode where the ADC provides valid @@ -6058,15 +5968,34 @@ static int PowerDownDevice(struct drxk_state *state) return status; } +static int load_microcode(struct drxk_state *state, const char *mc_name) +{ + const struct firmware *fw = NULL; + int err = 0; + + dprintk(1, "\n"); + + err = request_firmware(&fw, mc_name, state->i2c->dev.parent); + if (err < 0) { + printk(KERN_ERR + "drxk: Could not load firmware file %s.\n", mc_name); + printk(KERN_INFO + "drxk: Copy %s to your hotplug directory!\n", mc_name); + return err; + } + err = DownloadMicrocode(state, fw->data, fw->size); + release_firmware(fw); + return err; +} + static int init_drxk(struct drxk_state *state) { - int status = 0, n = 0; + int status = 0; enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM; u16 driverVersion; dprintk(1, "\n"); if ((state->m_DrxkState == DRXK_UNINITIALIZED)) { - drxk_i2c_lock(state); status = PowerUpDevice(state); if (status < 0) goto error; @@ -6144,12 +6073,8 @@ static int init_drxk(struct drxk_state *state) if (status < 0) goto error; - if (state->fw) { - status = DownloadMicrocode(state, state->fw->data, - state->fw->size); - if (status < 0) - goto error; - } + if (state->microcode_name) + load_microcode(state, state->microcode_name); /* disable token-ring bus through OFDM block for possible ucode upload */ status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF); @@ -6242,71 +6167,19 @@ static int init_drxk(struct drxk_state *state) state->m_DrxkState = DRXK_POWERED_DOWN; } else state->m_DrxkState = DRXK_STOPPED; - - /* Initialize the supported delivery systems */ - n = 0; - if (state->m_hasDVBC) { - state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A; - state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C; - strlcat(state->frontend.ops.info.name, " DVB-C", - sizeof(state->frontend.ops.info.name)); - } - if (state->m_hasDVBT) { - state->frontend.ops.delsys[n++] = SYS_DVBT; - strlcat(state->frontend.ops.info.name, " DVB-T", - sizeof(state->frontend.ops.info.name)); - } - drxk_i2c_unlock(state); } error: - if (status < 0) { - state->m_DrxkState = DRXK_NO_DEV; - drxk_i2c_unlock(state); + if (status < 0) printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); - } return status; } -static void load_firmware_cb(const struct firmware *fw, - void *context) -{ - struct drxk_state *state = context; - - dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded"); - if (!fw) { - printk(KERN_ERR - "drxk: Could not load firmware file %s.\n", - state->microcode_name); - printk(KERN_INFO - "drxk: Copy %s to your hotplug directory!\n", - state->microcode_name); - state->microcode_name = NULL; - - /* - * As firmware is now load asynchronous, it is not possible - * anymore to fail at frontend attach. We might silently - * return here, and hope that the driver won't crash. - * We might also change all DVB callbacks to return -ENODEV - * if the device is not initialized. - * As the DRX-K devices have their own internal firmware, - * let's just hope that it will match a firmware revision - * compatible with this driver and proceed. - */ - } - state->fw = fw; - - init_drxk(state); -} - static void drxk_release(struct dvb_frontend *fe) { struct drxk_state *state = fe->demodulator_priv; dprintk(1, "\n"); - if (state->fw) - release_firmware(state->fw); - kfree(state); } @@ -6315,12 +6188,6 @@ static int drxk_sleep(struct dvb_frontend *fe) struct drxk_state *state = fe->demodulator_priv; dprintk(1, "\n"); - - if (state->m_DrxkState == DRXK_NO_DEV) - return -ENODEV; - if (state->m_DrxkState == DRXK_UNINITIALIZED) - return 0; - ShutDown(state); return 0; } @@ -6329,11 +6196,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) { struct drxk_state *state = fe->demodulator_priv; - dprintk(1, ": %s\n", enable ? "enable" : "disable"); - - if (state->m_DrxkState == DRXK_NO_DEV) - return -ENODEV; - + dprintk(1, "%s\n", enable ? "enable" : "disable"); return ConfigureI2CBridge(state, enable ? true : false); } @@ -6346,12 +6209,6 @@ static int drxk_set_parameters(struct dvb_frontend *fe) dprintk(1, "\n"); - if (state->m_DrxkState == DRXK_NO_DEV) - return -ENODEV; - - if (state->m_DrxkState == DRXK_UNINITIALIZED) - return -EAGAIN; - if (!fe->ops.tuner_ops.get_if_frequency) { printk(KERN_ERR "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n"); @@ -6405,12 +6262,6 @@ static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status) u32 stat; dprintk(1, "\n"); - - if (state->m_DrxkState == DRXK_NO_DEV) - return -ENODEV; - if (state->m_DrxkState == DRXK_UNINITIALIZED) - return -EAGAIN; - *status = 0; GetLockStatus(state, &stat, 0); if (stat == MPEG_LOCK) @@ -6424,15 +6275,8 @@ static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status) static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber) { - struct drxk_state *state = fe->demodulator_priv; - dprintk(1, "\n"); - if (state->m_DrxkState == DRXK_NO_DEV) - return -ENODEV; - if (state->m_DrxkState == DRXK_UNINITIALIZED) - return -EAGAIN; - *ber = 0; return 0; } @@ -6444,12 +6288,6 @@ static int drxk_read_signal_strength(struct dvb_frontend *fe, u32 val = 0; dprintk(1, "\n"); - - if (state->m_DrxkState == DRXK_NO_DEV) - return -ENODEV; - if (state->m_DrxkState == DRXK_UNINITIALIZED) - return -EAGAIN; - ReadIFAgc(state, &val); *strength = val & 0xffff; return 0; @@ -6461,12 +6299,6 @@ static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr) s32 snr2; dprintk(1, "\n"); - - if (state->m_DrxkState == DRXK_NO_DEV) - return -ENODEV; - if (state->m_DrxkState == DRXK_UNINITIALIZED) - return -EAGAIN; - GetSignalToNoise(state, &snr2); *snr = snr2 & 0xffff; return 0; @@ -6478,12 +6310,6 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) u16 err; dprintk(1, "\n"); - - if (state->m_DrxkState == DRXK_NO_DEV) - return -ENODEV; - if (state->m_DrxkState == DRXK_UNINITIALIZED) - return -EAGAIN; - DVBTQAMGetAccPktErr(state, &err); *ucblocks = (u32) err; return 0; @@ -6492,16 +6318,9 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *sets) { - struct drxk_state *state = fe->demodulator_priv; struct dtv_frontend_properties *p = &fe->dtv_property_cache; dprintk(1, "\n"); - - if (state->m_DrxkState == DRXK_NO_DEV) - return -ENODEV; - if (state->m_DrxkState == DRXK_UNINITIALIZED) - return -EAGAIN; - switch (p->delivery_system) { case SYS_DVBC_ANNEX_A: case SYS_DVBC_ANNEX_C: @@ -6552,9 +6371,10 @@ static struct dvb_frontend_ops drxk_ops = { struct dvb_frontend *drxk_attach(const struct drxk_config *config, struct i2c_adapter *i2c) { + int n; + struct drxk_state *state = NULL; u8 adr = config->adr; - int status; dprintk(1, "\n"); state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL); @@ -6565,7 +6385,6 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->demod_address = adr; state->single_master = config->single_master; state->microcode_name = config->microcode_name; - state->qam_demod_parameter_count = config->qam_demod_parameter_count; state->no_i2c_bridge = config->no_i2c_bridge; state->antenna_gpio = config->antenna_gpio; state->antenna_dvbt = config->antenna_dvbt; @@ -6606,22 +6425,23 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->frontend.demodulator_priv = state; init_state(state); - - /* Load firmware and initialize DRX-K */ - if (state->microcode_name) { - status = request_firmware_nowait(THIS_MODULE, 1, - state->microcode_name, - state->i2c->dev.parent, - GFP_KERNEL, - state, load_firmware_cb); - if (status < 0) { - printk(KERN_ERR - "drxk: failed to request a firmware\n"); - return NULL; - } - } else if (init_drxk(state) < 0) + if (init_drxk(state) < 0) goto error; + /* Initialize the supported delivery systems */ + n = 0; + if (state->m_hasDVBC) { + state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A; + state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C; + strlcat(state->frontend.ops.info.name, " DVB-C", + sizeof(state->frontend.ops.info.name)); + } + if (state->m_hasDVBT) { + state->frontend.ops.delsys[n++] = SYS_DVBT; + strlcat(state->frontend.ops.info.name, " DVB-T", + sizeof(state->frontend.ops.info.name)); + } + printk(KERN_INFO "drxk: frontend initialized.\n"); return &state->frontend; diff --git a/trunk/drivers/media/dvb/frontends/drxk_hard.h b/trunk/drivers/media/dvb/frontends/drxk_hard.h index 6bb9fc4a7b96..4bbf841de83a 100644 --- a/trunk/drivers/media/dvb/frontends/drxk_hard.h +++ b/trunk/drivers/media/dvb/frontends/drxk_hard.h @@ -94,15 +94,7 @@ enum DRXPowerMode { enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF }; -enum EDrxkState { - DRXK_UNINITIALIZED = 0, - DRXK_STOPPED, - DRXK_DTV_STARTED, - DRXK_ATV_STARTED, - DRXK_POWERED_DOWN, - DRXK_NO_DEV /* If drxk init failed */ -}; - +enum EDrxkState { DRXK_UNINITIALIZED = 0, DRXK_STOPPED, DRXK_DTV_STARTED, DRXK_ATV_STARTED, DRXK_POWERED_DOWN }; enum EDrxkCoefArrayIndex { DRXK_COEF_IDX_MN = 0, DRXK_COEF_IDX_FM , @@ -333,9 +325,6 @@ struct drxk_state { enum DRXPowerMode m_currentPowerMode; - /* when true, avoids other devices to use the I2C bus */ - bool drxk_i2c_exclusive_lock; - /* * Configurable parameters at the driver. They stores the values found * at struct drxk_config. @@ -349,11 +338,7 @@ struct drxk_state { bool antenna_dvbt; u16 antenna_gpio; - /* Firmware */ const char *microcode_name; - struct completion fw_wait_load; - const struct firmware *fw; - int qam_demod_parameter_count; }; #define NEVER_LOCK 0 diff --git a/trunk/drivers/media/dvb/frontends/rtl2832.c b/trunk/drivers/media/dvb/frontends/rtl2832.c deleted file mode 100644 index 2da592fb38ad..000000000000 --- a/trunk/drivers/media/dvb/frontends/rtl2832.c +++ /dev/null @@ -1,789 +0,0 @@ -/* - * Realtek RTL2832 DVB-T demodulator driver - * - * Copyright (C) 2012 Thomas Mair - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "rtl2832_priv.h" -#include - -int rtl2832_debug; -module_param_named(debug, rtl2832_debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -#define REG_MASK(b) (BIT(b + 1) - 1) - -static const struct rtl2832_reg_entry registers[] = { - [DVBT_SOFT_RST] = {0x1, 0x1, 2, 2}, - [DVBT_IIC_REPEAT] = {0x1, 0x1, 3, 3}, - [DVBT_TR_WAIT_MIN_8K] = {0x1, 0x88, 11, 2}, - [DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0}, - [DVBT_EN_BK_TRK] = {0x1, 0xa6, 7, 7}, - [DVBT_AD_EN_REG] = {0x0, 0x8, 7, 7}, - [DVBT_AD_EN_REG1] = {0x0, 0x8, 6, 6}, - [DVBT_EN_BBIN] = {0x1, 0xb1, 0, 0}, - [DVBT_MGD_THD0] = {0x1, 0x95, 7, 0}, - [DVBT_MGD_THD1] = {0x1, 0x96, 7, 0}, - [DVBT_MGD_THD2] = {0x1, 0x97, 7, 0}, - [DVBT_MGD_THD3] = {0x1, 0x98, 7, 0}, - [DVBT_MGD_THD4] = {0x1, 0x99, 7, 0}, - [DVBT_MGD_THD5] = {0x1, 0x9a, 7, 0}, - [DVBT_MGD_THD6] = {0x1, 0x9b, 7, 0}, - [DVBT_MGD_THD7] = {0x1, 0x9c, 7, 0}, - [DVBT_EN_CACQ_NOTCH] = {0x1, 0x61, 4, 4}, - [DVBT_AD_AV_REF] = {0x0, 0x9, 6, 0}, - [DVBT_REG_PI] = {0x0, 0xa, 2, 0}, - [DVBT_PIP_ON] = {0x0, 0x21, 3, 3}, - [DVBT_SCALE1_B92] = {0x2, 0x92, 7, 0}, - [DVBT_SCALE1_B93] = {0x2, 0x93, 7, 0}, - [DVBT_SCALE1_BA7] = {0x2, 0xa7, 7, 0}, - [DVBT_SCALE1_BA9] = {0x2, 0xa9, 7, 0}, - [DVBT_SCALE1_BAA] = {0x2, 0xaa, 7, 0}, - [DVBT_SCALE1_BAB] = {0x2, 0xab, 7, 0}, - [DVBT_SCALE1_BAC] = {0x2, 0xac, 7, 0}, - [DVBT_SCALE1_BB0] = {0x2, 0xb0, 7, 0}, - [DVBT_SCALE1_BB1] = {0x2, 0xb1, 7, 0}, - [DVBT_KB_P1] = {0x1, 0x64, 3, 1}, - [DVBT_KB_P2] = {0x1, 0x64, 6, 4}, - [DVBT_KB_P3] = {0x1, 0x65, 2, 0}, - [DVBT_OPT_ADC_IQ] = {0x0, 0x6, 5, 4}, - [DVBT_AD_AVI] = {0x0, 0x9, 1, 0}, - [DVBT_AD_AVQ] = {0x0, 0x9, 3, 2}, - [DVBT_K1_CR_STEP12] = {0x2, 0xad, 9, 4}, - [DVBT_TRK_KS_P2] = {0x1, 0x6f, 2, 0}, - [DVBT_TRK_KS_I2] = {0x1, 0x70, 5, 3}, - [DVBT_TR_THD_SET2] = {0x1, 0x72, 3, 0}, - [DVBT_TRK_KC_P2] = {0x1, 0x73, 5, 3}, - [DVBT_TRK_KC_I2] = {0x1, 0x75, 2, 0}, - [DVBT_CR_THD_SET2] = {0x1, 0x76, 7, 6}, - [DVBT_PSET_IFFREQ] = {0x1, 0x19, 21, 0}, - [DVBT_SPEC_INV] = {0x1, 0x15, 0, 0}, - [DVBT_RSAMP_RATIO] = {0x1, 0x9f, 27, 2}, - [DVBT_CFREQ_OFF_RATIO] = {0x1, 0x9d, 23, 4}, - [DVBT_FSM_STAGE] = {0x3, 0x51, 6, 3}, - [DVBT_RX_CONSTEL] = {0x3, 0x3c, 3, 2}, - [DVBT_RX_HIER] = {0x3, 0x3c, 6, 4}, - [DVBT_RX_C_RATE_LP] = {0x3, 0x3d, 2, 0}, - [DVBT_RX_C_RATE_HP] = {0x3, 0x3d, 5, 3}, - [DVBT_GI_IDX] = {0x3, 0x51, 1, 0}, - [DVBT_FFT_MODE_IDX] = {0x3, 0x51, 2, 2}, - [DVBT_RSD_BER_EST] = {0x3, 0x4e, 15, 0}, - [DVBT_CE_EST_EVM] = {0x4, 0xc, 15, 0}, - [DVBT_RF_AGC_VAL] = {0x3, 0x5b, 13, 0}, - [DVBT_IF_AGC_VAL] = {0x3, 0x59, 13, 0}, - [DVBT_DAGC_VAL] = {0x3, 0x5, 7, 0}, - [DVBT_SFREQ_OFF] = {0x3, 0x18, 13, 0}, - [DVBT_CFREQ_OFF] = {0x3, 0x5f, 17, 0}, - [DVBT_POLAR_RF_AGC] = {0x0, 0xe, 1, 1}, - [DVBT_POLAR_IF_AGC] = {0x0, 0xe, 0, 0}, - [DVBT_AAGC_HOLD] = {0x1, 0x4, 5, 5}, - [DVBT_EN_RF_AGC] = {0x1, 0x4, 6, 6}, - [DVBT_EN_IF_AGC] = {0x1, 0x4, 7, 7}, - [DVBT_IF_AGC_MIN] = {0x1, 0x8, 7, 0}, - [DVBT_IF_AGC_MAX] = {0x1, 0x9, 7, 0}, - [DVBT_RF_AGC_MIN] = {0x1, 0xa, 7, 0}, - [DVBT_RF_AGC_MAX] = {0x1, 0xb, 7, 0}, - [DVBT_IF_AGC_MAN] = {0x1, 0xc, 6, 6}, - [DVBT_IF_AGC_MAN_VAL] = {0x1, 0xc, 13, 0}, - [DVBT_RF_AGC_MAN] = {0x1, 0xe, 6, 6}, - [DVBT_RF_AGC_MAN_VAL] = {0x1, 0xe, 13, 0}, - [DVBT_DAGC_TRG_VAL] = {0x1, 0x12, 7, 0}, - [DVBT_AGC_TARG_VAL_0] = {0x1, 0x2, 0, 0}, - [DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3, 7, 0}, - [DVBT_AAGC_LOOP_GAIN] = {0x1, 0xc7, 5, 1}, - [DVBT_LOOP_GAIN2_3_0] = {0x1, 0x4, 4, 1}, - [DVBT_LOOP_GAIN2_4] = {0x1, 0x5, 7, 7}, - [DVBT_LOOP_GAIN3] = {0x1, 0xc8, 4, 0}, - [DVBT_VTOP1] = {0x1, 0x6, 5, 0}, - [DVBT_VTOP2] = {0x1, 0xc9, 5, 0}, - [DVBT_VTOP3] = {0x1, 0xca, 5, 0}, - [DVBT_KRF1] = {0x1, 0xcb, 7, 0}, - [DVBT_KRF2] = {0x1, 0x7, 7, 0}, - [DVBT_KRF3] = {0x1, 0xcd, 7, 0}, - [DVBT_KRF4] = {0x1, 0xce, 7, 0}, - [DVBT_EN_GI_PGA] = {0x1, 0xe5, 0, 0}, - [DVBT_THD_LOCK_UP] = {0x1, 0xd9, 8, 0}, - [DVBT_THD_LOCK_DW] = {0x1, 0xdb, 8, 0}, - [DVBT_THD_UP1] = {0x1, 0xdd, 7, 0}, - [DVBT_THD_DW1] = {0x1, 0xde, 7, 0}, - [DVBT_INTER_CNT_LEN] = {0x1, 0xd8, 3, 0}, - [DVBT_GI_PGA_STATE] = {0x1, 0xe6, 3, 3}, - [DVBT_EN_AGC_PGA] = {0x1, 0xd7, 0, 0}, - [DVBT_CKOUTPAR] = {0x1, 0x7b, 5, 5}, - [DVBT_CKOUT_PWR] = {0x1, 0x7b, 6, 6}, - [DVBT_SYNC_DUR] = {0x1, 0x7b, 7, 7}, - [DVBT_ERR_DUR] = {0x1, 0x7c, 0, 0}, - [DVBT_SYNC_LVL] = {0x1, 0x7c, 1, 1}, - [DVBT_ERR_LVL] = {0x1, 0x7c, 2, 2}, - [DVBT_VAL_LVL] = {0x1, 0x7c, 3, 3}, - [DVBT_SERIAL] = {0x1, 0x7c, 4, 4}, - [DVBT_SER_LSB] = {0x1, 0x7c, 5, 5}, - [DVBT_CDIV_PH0] = {0x1, 0x7d, 3, 0}, - [DVBT_CDIV_PH1] = {0x1, 0x7d, 7, 4}, - [DVBT_MPEG_IO_OPT_2_2] = {0x0, 0x6, 7, 7}, - [DVBT_MPEG_IO_OPT_1_0] = {0x0, 0x7, 7, 6}, - [DVBT_CKOUTPAR_PIP] = {0x0, 0xb7, 4, 4}, - [DVBT_CKOUT_PWR_PIP] = {0x0, 0xb7, 3, 3}, - [DVBT_SYNC_LVL_PIP] = {0x0, 0xb7, 2, 2}, - [DVBT_ERR_LVL_PIP] = {0x0, 0xb7, 1, 1}, - [DVBT_VAL_LVL_PIP] = {0x0, 0xb7, 0, 0}, - [DVBT_CKOUTPAR_PID] = {0x0, 0xb9, 4, 4}, - [DVBT_CKOUT_PWR_PID] = {0x0, 0xb9, 3, 3}, - [DVBT_SYNC_LVL_PID] = {0x0, 0xb9, 2, 2}, - [DVBT_ERR_LVL_PID] = {0x0, 0xb9, 1, 1}, - [DVBT_VAL_LVL_PID] = {0x0, 0xb9, 0, 0}, - [DVBT_SM_PASS] = {0x1, 0x93, 11, 0}, - [DVBT_AD7_SETTING] = {0x0, 0x11, 15, 0}, - [DVBT_RSSI_R] = {0x3, 0x1, 6, 0}, - [DVBT_ACI_DET_IND] = {0x3, 0x12, 0, 0}, - [DVBT_REG_MON] = {0x0, 0xd, 1, 0}, - [DVBT_REG_MONSEL] = {0x0, 0xd, 2, 2}, - [DVBT_REG_GPE] = {0x0, 0xd, 7, 7}, - [DVBT_REG_GPO] = {0x0, 0x10, 0, 0}, - [DVBT_REG_4MSEL] = {0x0, 0x13, 0, 0}, -}; - -/* write multiple hardware registers */ -static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len) -{ - int ret; - u8 buf[1+len]; - struct i2c_msg msg[1] = { - { - .addr = priv->cfg.i2c_addr, - .flags = 0, - .len = 1+len, - .buf = buf, - } - }; - - buf[0] = reg; - memcpy(&buf[1], val, len); - - ret = i2c_transfer(priv->i2c, msg, 1); - if (ret == 1) { - ret = 0; - } else { - warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len); - ret = -EREMOTEIO; - } - return ret; -} - -/* read multiple hardware registers */ -static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len) -{ - int ret; - struct i2c_msg msg[2] = { - { - .addr = priv->cfg.i2c_addr, - .flags = 0, - .len = 1, - .buf = ®, - }, { - .addr = priv->cfg.i2c_addr, - .flags = I2C_M_RD, - .len = len, - .buf = val, - } - }; - - ret = i2c_transfer(priv->i2c, msg, 2); - if (ret == 2) { - ret = 0; - } else { - warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len); - ret = -EREMOTEIO; -} -return ret; -} - -/* write multiple registers */ -static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val, - int len) -{ - int ret; - - - /* switch bank if needed */ - if (page != priv->page) { - ret = rtl2832_wr(priv, 0x00, &page, 1); - if (ret) - return ret; - - priv->page = page; -} - -return rtl2832_wr(priv, reg, val, len); -} - -/* read multiple registers */ -static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val, - int len) -{ - int ret; - - /* switch bank if needed */ - if (page != priv->page) { - ret = rtl2832_wr(priv, 0x00, &page, 1); - if (ret) - return ret; - - priv->page = page; - } - - return rtl2832_rd(priv, reg, val, len); -} - -#if 0 /* currently not used */ -/* write single register */ -static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val) -{ - return rtl2832_wr_regs(priv, reg, page, &val, 1); -} -#endif - -/* read single register */ -static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val) -{ - return rtl2832_rd_regs(priv, reg, page, val, 1); -} - -int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val) -{ - int ret; - - u8 reg_start_addr; - u8 msb, lsb; - u8 page; - u8 reading[4]; - u32 reading_tmp; - int i; - - u8 len; - u32 mask; - - reg_start_addr = registers[reg].start_address; - msb = registers[reg].msb; - lsb = registers[reg].lsb; - page = registers[reg].page; - - len = (msb >> 3) + 1; - mask = REG_MASK(msb - lsb); - - ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len); - if (ret) - goto err; - - reading_tmp = 0; - for (i = 0; i < len; i++) - reading_tmp |= reading[i] << ((len - 1 - i) * 8); - - *val = (reading_tmp >> lsb) & mask; - - return ret; - -err: - dbg("%s: failed=%d", __func__, ret); - return ret; - -} - -int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val) -{ - int ret, i; - u8 len; - u8 reg_start_addr; - u8 msb, lsb; - u8 page; - u32 mask; - - - u8 reading[4]; - u8 writing[4]; - u32 reading_tmp; - u32 writing_tmp; - - - reg_start_addr = registers[reg].start_address; - msb = registers[reg].msb; - lsb = registers[reg].lsb; - page = registers[reg].page; - - len = (msb >> 3) + 1; - mask = REG_MASK(msb - lsb); - - - ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len); - if (ret) - goto err; - - reading_tmp = 0; - for (i = 0; i < len; i++) - reading_tmp |= reading[i] << ((len - 1 - i) * 8); - - writing_tmp = reading_tmp & ~(mask << lsb); - writing_tmp |= ((val & mask) << lsb); - - - for (i = 0; i < len; i++) - writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff; - - ret = rtl2832_wr_regs(priv, reg_start_addr, page, &writing[0], len); - if (ret) - goto err; - - return ret; - -err: - dbg("%s: failed=%d", __func__, ret); - return ret; - -} - - -static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - int ret; - struct rtl2832_priv *priv = fe->demodulator_priv; - - dbg("%s: enable=%d", __func__, enable); - - /* gate already open or close */ - if (priv->i2c_gate_state == enable) - return 0; - - ret = rtl2832_wr_demod_reg(priv, DVBT_IIC_REPEAT, (enable ? 0x1 : 0x0)); - if (ret) - goto err; - - priv->i2c_gate_state = enable; - - return ret; -err: - dbg("%s: failed=%d", __func__, ret); - return ret; -} - - - -static int rtl2832_init(struct dvb_frontend *fe) -{ - struct rtl2832_priv *priv = fe->demodulator_priv; - int i, ret; - - u8 en_bbin; - u64 pset_iffreq; - - /* initialization values for the demodulator registers */ - struct rtl2832_reg_value rtl2832_initial_regs[] = { - {DVBT_AD_EN_REG, 0x1}, - {DVBT_AD_EN_REG1, 0x1}, - {DVBT_RSD_BER_FAIL_VAL, 0x2800}, - {DVBT_MGD_THD0, 0x10}, - {DVBT_MGD_THD1, 0x20}, - {DVBT_MGD_THD2, 0x20}, - {DVBT_MGD_THD3, 0x40}, - {DVBT_MGD_THD4, 0x22}, - {DVBT_MGD_THD5, 0x32}, - {DVBT_MGD_THD6, 0x37}, - {DVBT_MGD_THD7, 0x39}, - {DVBT_EN_BK_TRK, 0x0}, - {DVBT_EN_CACQ_NOTCH, 0x0}, - {DVBT_AD_AV_REF, 0x2a}, - {DVBT_REG_PI, 0x6}, - {DVBT_PIP_ON, 0x0}, - {DVBT_CDIV_PH0, 0x8}, - {DVBT_CDIV_PH1, 0x8}, - {DVBT_SCALE1_B92, 0x4}, - {DVBT_SCALE1_B93, 0xb0}, - {DVBT_SCALE1_BA7, 0x78}, - {DVBT_SCALE1_BA9, 0x28}, - {DVBT_SCALE1_BAA, 0x59}, - {DVBT_SCALE1_BAB, 0x83}, - {DVBT_SCALE1_BAC, 0xd4}, - {DVBT_SCALE1_BB0, 0x65}, - {DVBT_SCALE1_BB1, 0x43}, - {DVBT_KB_P1, 0x1}, - {DVBT_KB_P2, 0x4}, - {DVBT_KB_P3, 0x7}, - {DVBT_K1_CR_STEP12, 0xa}, - {DVBT_REG_GPE, 0x1}, - {DVBT_SERIAL, 0x0}, - {DVBT_CDIV_PH0, 0x9}, - {DVBT_CDIV_PH1, 0x9}, - {DVBT_MPEG_IO_OPT_2_2, 0x0}, - {DVBT_MPEG_IO_OPT_1_0, 0x0}, - {DVBT_TRK_KS_P2, 0x4}, - {DVBT_TRK_KS_I2, 0x7}, - {DVBT_TR_THD_SET2, 0x6}, - {DVBT_TRK_KC_I2, 0x5}, - {DVBT_CR_THD_SET2, 0x1}, - {DVBT_SPEC_INV, 0x0}, - {DVBT_DAGC_TRG_VAL, 0x5a}, - {DVBT_AGC_TARG_VAL_0, 0x0}, - {DVBT_AGC_TARG_VAL_8_1, 0x5a}, - {DVBT_AAGC_LOOP_GAIN, 0x16}, - {DVBT_LOOP_GAIN2_3_0, 0x6}, - {DVBT_LOOP_GAIN2_4, 0x1}, - {DVBT_LOOP_GAIN3, 0x16}, - {DVBT_VTOP1, 0x35}, - {DVBT_VTOP2, 0x21}, - {DVBT_VTOP3, 0x21}, - {DVBT_KRF1, 0x0}, - {DVBT_KRF2, 0x40}, - {DVBT_KRF3, 0x10}, - {DVBT_KRF4, 0x10}, - {DVBT_IF_AGC_MIN, 0x80}, - {DVBT_IF_AGC_MAX, 0x7f}, - {DVBT_RF_AGC_MIN, 0x80}, - {DVBT_RF_AGC_MAX, 0x7f}, - {DVBT_POLAR_RF_AGC, 0x0}, - {DVBT_POLAR_IF_AGC, 0x0}, - {DVBT_AD7_SETTING, 0xe9bf}, - {DVBT_EN_GI_PGA, 0x0}, - {DVBT_THD_LOCK_UP, 0x0}, - {DVBT_THD_LOCK_DW, 0x0}, - {DVBT_THD_UP1, 0x11}, - {DVBT_THD_DW1, 0xef}, - {DVBT_INTER_CNT_LEN, 0xc}, - {DVBT_GI_PGA_STATE, 0x0}, - {DVBT_EN_AGC_PGA, 0x1}, - {DVBT_IF_AGC_MAN, 0x0}, - }; - - - dbg("%s", __func__); - - en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0); - - /* - * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22) - * / CrystalFreqHz) - */ - pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal; - pset_iffreq *= 0x400000; - pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal); - pset_iffreq = pset_iffreq & 0x3fffff; - - - - for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) { - ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg, - rtl2832_initial_regs[i].value); - if (ret) - goto err; - } - - /* if frequency settings */ - ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin); - if (ret) - goto err; - - ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq); - if (ret) - goto err; - - priv->sleeping = false; - - return ret; - -err: - dbg("%s: failed=%d", __func__, ret); - return ret; -} - -static int rtl2832_sleep(struct dvb_frontend *fe) -{ - struct rtl2832_priv *priv = fe->demodulator_priv; - - dbg("%s", __func__); - priv->sleeping = true; - return 0; -} - -int rtl2832_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *s) -{ - dbg("%s", __func__); - s->min_delay_ms = 1000; - s->step_size = fe->ops.info.frequency_stepsize * 2; - s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; - return 0; -} - -static int rtl2832_set_frontend(struct dvb_frontend *fe) -{ - struct rtl2832_priv *priv = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret, i, j; - u64 bw_mode, num, num2; - u32 resamp_ratio, cfreq_off_ratio; - - - static u8 bw_params[3][32] = { - /* 6 MHz bandwidth */ - { - 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f, - 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2, - 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67, - 0x19, 0xe0, - }, - - /* 7 MHz bandwidth */ - { - 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf, - 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30, - 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22, - 0x19, 0x10, - }, - - /* 8 MHz bandwidth */ - { - 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf, - 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7, - 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8, - 0x19, 0xe0, - }, - }; - - - dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__, - c->frequency, c->bandwidth_hz, c->inversion); - - - /* program tuner */ - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe); - - - switch (c->bandwidth_hz) { - case 6000000: - i = 0; - bw_mode = 48000000; - break; - case 7000000: - i = 1; - bw_mode = 56000000; - break; - case 8000000: - i = 2; - bw_mode = 64000000; - break; - default: - dbg("invalid bandwidth"); - return -EINVAL; - } - - for (j = 0; j < sizeof(bw_params[j]); j++) { - ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1); - if (ret) - goto err; - } - - /* calculate and set resample ratio - * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22) - * / ConstWithBandwidthMode) - */ - num = priv->cfg.xtal * 7; - num *= 0x400000; - num = div_u64(num, bw_mode); - resamp_ratio = num & 0x3ffffff; - ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio); - if (ret) - goto err; - - /* calculate and set cfreq off ratio - * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20) - * / (CrystalFreqHz * 7)) - */ - num = bw_mode << 20; - num2 = priv->cfg.xtal * 7; - num = div_u64(num, num2); - num = -num; - cfreq_off_ratio = num & 0xfffff; - ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio); - if (ret) - goto err; - - - /* soft reset */ - ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1); - if (ret) - goto err; - - ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0); - if (ret) - goto err; - - return ret; -err: - info("%s: failed=%d", __func__, ret); - return ret; -} - -static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct rtl2832_priv *priv = fe->demodulator_priv; - int ret; - u32 tmp; - *status = 0; - - - dbg("%s", __func__); - if (priv->sleeping) - return 0; - - ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp); - if (ret) - goto err; - - if (tmp == 11) { - *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - } - /* TODO find out if this is also true for rtl2832? */ - /*else if (tmp == 10) { - *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI; - }*/ - - return ret; -err: - info("%s: failed=%d", __func__, ret); - return ret; -} - -static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - *snr = 0; - return 0; -} - -static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - *ber = 0; - return 0; -} - -static int rtl2832_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - return 0; -} - - -static int rtl2832_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - *strength = 0; - return 0; -} - -static struct dvb_frontend_ops rtl2832_ops; - -static void rtl2832_release(struct dvb_frontend *fe) -{ - struct rtl2832_priv *priv = fe->demodulator_priv; - - dbg("%s", __func__); - kfree(priv); -} - -struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg, - struct i2c_adapter *i2c) -{ - struct rtl2832_priv *priv = NULL; - int ret = 0; - u8 tmp; - - dbg("%s", __func__); - - /* allocate memory for the internal state */ - priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL); - if (priv == NULL) - goto err; - - /* setup the priv */ - priv->i2c = i2c; - priv->tuner = cfg->tuner; - memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config)); - - /* check if the demod is there */ - ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp); - if (ret) - goto err; - - /* create dvb_frontend */ - memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops)); - priv->fe.demodulator_priv = priv; - - /* TODO implement sleep mode */ - priv->sleeping = true; - - return &priv->fe; -err: - dbg("%s: failed=%d", __func__, ret); - kfree(priv); - return NULL; -} -EXPORT_SYMBOL(rtl2832_attach); - -static struct dvb_frontend_ops rtl2832_ops = { - .delsys = { SYS_DVBT }, - .info = { - .name = "Realtek RTL2832 (DVB-T)", - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 166667, - .caps = FE_CAN_FEC_1_2 | - FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | - FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | - FE_CAN_QAM_16 | - FE_CAN_QAM_64 | - FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - - .release = rtl2832_release, - - .init = rtl2832_init, - .sleep = rtl2832_sleep, - - .get_tune_settings = rtl2832_get_tune_settings, - - .set_frontend = rtl2832_set_frontend, - - .read_status = rtl2832_read_status, - .read_snr = rtl2832_read_snr, - .read_ber = rtl2832_read_ber, - .read_ucblocks = rtl2832_read_ucblocks, - .read_signal_strength = rtl2832_read_signal_strength, - .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl, -}; - -MODULE_AUTHOR("Thomas Mair "); -MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("0.5"); diff --git a/trunk/drivers/media/dvb/frontends/rtl2832.h b/trunk/drivers/media/dvb/frontends/rtl2832.h deleted file mode 100644 index d94dc9a3fa62..000000000000 --- a/trunk/drivers/media/dvb/frontends/rtl2832.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Realtek RTL2832 DVB-T demodulator driver - * - * Copyright (C) 2012 Thomas Mair - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef RTL2832_H -#define RTL2832_H - -#include - -struct rtl2832_config { - /* - * Demodulator I2C address. - */ - u8 i2c_addr; - - /* - * Xtal frequency. - * Hz - * 4000000, 16000000, 25000000, 28800000 - */ - u32 xtal; - - /* - * IFs for all used modes. - * Hz - * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000 - */ - u32 if_dvbt; - - /* - */ - u8 tuner; -}; - - -#if defined(CONFIG_DVB_RTL2832) || \ - (defined(CONFIG_DVB_RTL2832_MODULE) && defined(MODULE)) -extern struct dvb_frontend *rtl2832_attach( - const struct rtl2832_config *cfg, - struct i2c_adapter *i2c -); - -extern struct i2c_adapter *rtl2832_get_tuner_i2c_adapter( - struct dvb_frontend *fe -); -#else -static inline struct dvb_frontend *rtl2832_attach( - const struct rtl2832_config *config, - struct i2c_adapter *i2c -) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - - -#endif /* RTL2832_H */ diff --git a/trunk/drivers/media/dvb/frontends/rtl2832_priv.h b/trunk/drivers/media/dvb/frontends/rtl2832_priv.h deleted file mode 100644 index 0ce9502da8ba..000000000000 --- a/trunk/drivers/media/dvb/frontends/rtl2832_priv.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Realtek RTL2832 DVB-T demodulator driver - * - * Copyright (C) 2012 Thomas Mair - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef RTL2832_PRIV_H -#define RTL2832_PRIV_H - -#include "dvb_frontend.h" -#include "rtl2832.h" - -#define LOG_PREFIX "rtl2832" - -#undef dbg -#define dbg(f, arg...) \ -do { \ - if (rtl2832_debug) \ - printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg); \ -} while (0) -#undef err -#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) -#undef info -#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) -#undef warn -#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) - -struct rtl2832_priv { - struct i2c_adapter *i2c; - struct dvb_frontend fe; - struct rtl2832_config cfg; - - bool i2c_gate_state; - bool sleeping; - - u8 tuner; - u8 page; /* active register page */ -}; - -struct rtl2832_reg_entry { - u8 page; - u8 start_address; - u8 msb; - u8 lsb; -}; - -struct rtl2832_reg_value { - int reg; - u32 value; -}; - - -/* Demod register bit names */ -enum DVBT_REG_BIT_NAME { - DVBT_SOFT_RST, - DVBT_IIC_REPEAT, - DVBT_TR_WAIT_MIN_8K, - DVBT_RSD_BER_FAIL_VAL, - DVBT_EN_BK_TRK, - DVBT_REG_PI, - DVBT_REG_PFREQ_1_0, - DVBT_PD_DA8, - DVBT_LOCK_TH, - DVBT_BER_PASS_SCAL, - DVBT_CE_FFSM_BYPASS, - DVBT_ALPHAIIR_N, - DVBT_ALPHAIIR_DIF, - DVBT_EN_TRK_SPAN, - DVBT_LOCK_TH_LEN, - DVBT_CCI_THRE, - DVBT_CCI_MON_SCAL, - DVBT_CCI_M0, - DVBT_CCI_M1, - DVBT_CCI_M2, - DVBT_CCI_M3, - DVBT_SPEC_INIT_0, - DVBT_SPEC_INIT_1, - DVBT_SPEC_INIT_2, - DVBT_AD_EN_REG, - DVBT_AD_EN_REG1, - DVBT_EN_BBIN, - DVBT_MGD_THD0, - DVBT_MGD_THD1, - DVBT_MGD_THD2, - DVBT_MGD_THD3, - DVBT_MGD_THD4, - DVBT_MGD_THD5, - DVBT_MGD_THD6, - DVBT_MGD_THD7, - DVBT_EN_CACQ_NOTCH, - DVBT_AD_AV_REF, - DVBT_PIP_ON, - DVBT_SCALE1_B92, - DVBT_SCALE1_B93, - DVBT_SCALE1_BA7, - DVBT_SCALE1_BA9, - DVBT_SCALE1_BAA, - DVBT_SCALE1_BAB, - DVBT_SCALE1_BAC, - DVBT_SCALE1_BB0, - DVBT_SCALE1_BB1, - DVBT_KB_P1, - DVBT_KB_P2, - DVBT_KB_P3, - DVBT_OPT_ADC_IQ, - DVBT_AD_AVI, - DVBT_AD_AVQ, - DVBT_K1_CR_STEP12, - DVBT_TRK_KS_P2, - DVBT_TRK_KS_I2, - DVBT_TR_THD_SET2, - DVBT_TRK_KC_P2, - DVBT_TRK_KC_I2, - DVBT_CR_THD_SET2, - DVBT_PSET_IFFREQ, - DVBT_SPEC_INV, - DVBT_BW_INDEX, - DVBT_RSAMP_RATIO, - DVBT_CFREQ_OFF_RATIO, - DVBT_FSM_STAGE, - DVBT_RX_CONSTEL, - DVBT_RX_HIER, - DVBT_RX_C_RATE_LP, - DVBT_RX_C_RATE_HP, - DVBT_GI_IDX, - DVBT_FFT_MODE_IDX, - DVBT_RSD_BER_EST, - DVBT_CE_EST_EVM, - DVBT_RF_AGC_VAL, - DVBT_IF_AGC_VAL, - DVBT_DAGC_VAL, - DVBT_SFREQ_OFF, - DVBT_CFREQ_OFF, - DVBT_POLAR_RF_AGC, - DVBT_POLAR_IF_AGC, - DVBT_AAGC_HOLD, - DVBT_EN_RF_AGC, - DVBT_EN_IF_AGC, - DVBT_IF_AGC_MIN, - DVBT_IF_AGC_MAX, - DVBT_RF_AGC_MIN, - DVBT_RF_AGC_MAX, - DVBT_IF_AGC_MAN, - DVBT_IF_AGC_MAN_VAL, - DVBT_RF_AGC_MAN, - DVBT_RF_AGC_MAN_VAL, - DVBT_DAGC_TRG_VAL, - DVBT_AGC_TARG_VAL, - DVBT_LOOP_GAIN_3_0, - DVBT_LOOP_GAIN_4, - DVBT_VTOP, - DVBT_KRF, - DVBT_AGC_TARG_VAL_0, - DVBT_AGC_TARG_VAL_8_1, - DVBT_AAGC_LOOP_GAIN, - DVBT_LOOP_GAIN2_3_0, - DVBT_LOOP_GAIN2_4, - DVBT_LOOP_GAIN3, - DVBT_VTOP1, - DVBT_VTOP2, - DVBT_VTOP3, - DVBT_KRF1, - DVBT_KRF2, - DVBT_KRF3, - DVBT_KRF4, - DVBT_EN_GI_PGA, - DVBT_THD_LOCK_UP, - DVBT_THD_LOCK_DW, - DVBT_THD_UP1, - DVBT_THD_DW1, - DVBT_INTER_CNT_LEN, - DVBT_GI_PGA_STATE, - DVBT_EN_AGC_PGA, - DVBT_CKOUTPAR, - DVBT_CKOUT_PWR, - DVBT_SYNC_DUR, - DVBT_ERR_DUR, - DVBT_SYNC_LVL, - DVBT_ERR_LVL, - DVBT_VAL_LVL, - DVBT_SERIAL, - DVBT_SER_LSB, - DVBT_CDIV_PH0, - DVBT_CDIV_PH1, - DVBT_MPEG_IO_OPT_2_2, - DVBT_MPEG_IO_OPT_1_0, - DVBT_CKOUTPAR_PIP, - DVBT_CKOUT_PWR_PIP, - DVBT_SYNC_LVL_PIP, - DVBT_ERR_LVL_PIP, - DVBT_VAL_LVL_PIP, - DVBT_CKOUTPAR_PID, - DVBT_CKOUT_PWR_PID, - DVBT_SYNC_LVL_PID, - DVBT_ERR_LVL_PID, - DVBT_VAL_LVL_PID, - DVBT_SM_PASS, - DVBT_UPDATE_REG_2, - DVBT_BTHD_P3, - DVBT_BTHD_D3, - DVBT_FUNC4_REG0, - DVBT_FUNC4_REG1, - DVBT_FUNC4_REG2, - DVBT_FUNC4_REG3, - DVBT_FUNC4_REG4, - DVBT_FUNC4_REG5, - DVBT_FUNC4_REG6, - DVBT_FUNC4_REG7, - DVBT_FUNC4_REG8, - DVBT_FUNC4_REG9, - DVBT_FUNC4_REG10, - DVBT_FUNC5_REG0, - DVBT_FUNC5_REG1, - DVBT_FUNC5_REG2, - DVBT_FUNC5_REG3, - DVBT_FUNC5_REG4, - DVBT_FUNC5_REG5, - DVBT_FUNC5_REG6, - DVBT_FUNC5_REG7, - DVBT_FUNC5_REG8, - DVBT_FUNC5_REG9, - DVBT_FUNC5_REG10, - DVBT_FUNC5_REG11, - DVBT_FUNC5_REG12, - DVBT_FUNC5_REG13, - DVBT_FUNC5_REG14, - DVBT_FUNC5_REG15, - DVBT_FUNC5_REG16, - DVBT_FUNC5_REG17, - DVBT_FUNC5_REG18, - DVBT_AD7_SETTING, - DVBT_RSSI_R, - DVBT_ACI_DET_IND, - DVBT_REG_MON, - DVBT_REG_MONSEL, - DVBT_REG_GPE, - DVBT_REG_GPO, - DVBT_REG_4MSEL, - DVBT_TEST_REG_1, - DVBT_TEST_REG_2, - DVBT_TEST_REG_3, - DVBT_TEST_REG_4, - DVBT_REG_BIT_NAME_ITEM_TERMINATOR, -}; - -#endif /* RTL2832_PRIV_H */ diff --git a/trunk/drivers/media/dvb/frontends/s5h1420.c b/trunk/drivers/media/dvb/frontends/s5h1420.c index e2fec9ebf947..2322257c69ae 100644 --- a/trunk/drivers/media/dvb/frontends/s5h1420.c +++ b/trunk/drivers/media/dvb/frontends/s5h1420.c @@ -634,6 +634,7 @@ static int s5h1420_set_frontend(struct dvb_frontend *fe) struct s5h1420_state* state = fe->demodulator_priv; int frequency_delta; struct dvb_frontend_tune_settings fesettings; + uint8_t clock_setting; dprintk("enter %s\n", __func__); @@ -678,6 +679,25 @@ static int s5h1420_set_frontend(struct dvb_frontend *fe) else state->fclk = 44000000; + /* Clock */ + switch (state->fclk) { + default: + case 88000000: + clock_setting = 80; + break; + case 86000000: + clock_setting = 78; + break; + case 80000000: + clock_setting = 72; + break; + case 59000000: + clock_setting = 51; + break; + case 44000000: + clock_setting = 36; + break; + } dprintk("pll01: %d, ToneFreq: %d\n", state->fclk/1000000 - 8, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); s5h1420_writereg(state, PLL01, state->fclk/1000000 - 8); s5h1420_writereg(state, PLL02, 0x40); diff --git a/trunk/drivers/media/dvb/frontends/stb0899_drv.c b/trunk/drivers/media/dvb/frontends/stb0899_drv.c index 5d7f8a9b451b..8b0dc74a3298 100644 --- a/trunk/drivers/media/dvb/frontends/stb0899_drv.c +++ b/trunk/drivers/media/dvb/frontends/stb0899_drv.c @@ -1129,6 +1129,7 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) struct stb0899_internal *internal = &state->internal; u8 lsb, msb; + u32 i; *ber = 0; @@ -1136,9 +1137,14 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) case SYS_DVBS: case SYS_DSS: if (internal->lock) { - lsb = stb0899_read_reg(state, STB0899_ECNT1L); - msb = stb0899_read_reg(state, STB0899_ECNT1M); - *ber = MAKEWORD16(msb, lsb); + /* average 5 BER values */ + for (i = 0; i < 5; i++) { + msleep(100); + lsb = stb0899_read_reg(state, STB0899_ECNT1L); + msb = stb0899_read_reg(state, STB0899_ECNT1M); + *ber += MAKEWORD16(msb, lsb); + } + *ber /= 5; /* Viterbi Check */ if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) { /* Error Rate */ @@ -1151,9 +1157,13 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) break; case SYS_DVBS2: if (internal->lock) { - lsb = stb0899_read_reg(state, STB0899_ECNT1L); - msb = stb0899_read_reg(state, STB0899_ECNT1M); - *ber = MAKEWORD16(msb, lsb); + /* Average 5 PER values */ + for (i = 0; i < 5; i++) { + msleep(100); + lsb = stb0899_read_reg(state, STB0899_ECNT1L); + msb = stb0899_read_reg(state, STB0899_ECNT1M); + *ber += MAKEWORD16(msb, lsb); + } /* ber = ber * 10 ^ 7 */ *ber *= 10000000; *ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl)))); diff --git a/trunk/drivers/media/dvb/frontends/stv0367.c b/trunk/drivers/media/dvb/frontends/stv0367.c index 2a8aaeb1112d..fdd20c7737b5 100644 --- a/trunk/drivers/media/dvb/frontends/stv0367.c +++ b/trunk/drivers/media/dvb/frontends/stv0367.c @@ -1584,7 +1584,7 @@ static int stv0367ter_algo(struct dvb_frontend *fe) struct stv0367ter_state *ter_state = state->ter_state; int offset = 0, tempo = 0; u8 u_var; - u8 /*constell,*/ counter; + u8 /*constell,*/ counter, tps_rcvd[2]; s8 step; s32 timing_offset = 0; u32 trl_nomrate = 0, InternalFreq = 0, temp = 0; @@ -1709,6 +1709,9 @@ static int stv0367ter_algo(struct dvb_frontend *fe) return 0; ter_state->state = FE_TER_LOCKOK; + /* update results */ + tps_rcvd[0] = stv0367_readreg(state, R367TER_TPS_RCVD2); + tps_rcvd[1] = stv0367_readreg(state, R367TER_TPS_RCVD3); ter_state->mode = stv0367_readbits(state, F367TER_SYR_MODE); ter_state->guard = stv0367_readbits(state, F367TER_SYR_GUARD); diff --git a/trunk/drivers/media/dvb/frontends/stv090x.c b/trunk/drivers/media/dvb/frontends/stv090x.c index ea86a5603e57..d79e69f65cbb 100644 --- a/trunk/drivers/media/dvb/frontends/stv090x.c +++ b/trunk/drivers/media/dvb/frontends/stv090x.c @@ -3172,7 +3172,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) enum stv090x_signal_state signal_state = STV090x_NOCARRIER; u32 reg; s32 agc1_power, power_iq = 0, i; - int lock = 0, low_sr = 0; + int lock = 0, low_sr = 0, no_signal = 0; reg = STV090x_READ_DEMOD(state, TSCFGH); STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */ @@ -3413,7 +3413,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) goto err; } else { signal_state = STV090x_NODATA; - stv090x_chk_signal(state); + no_signal = stv090x_chk_signal(state); } } return signal_state; diff --git a/trunk/drivers/media/dvb/frontends/tda10071.c b/trunk/drivers/media/dvb/frontends/tda10071.c index 703c3d05f9f4..c21bc92d2811 100644 --- a/trunk/drivers/media/dvb/frontends/tda10071.c +++ b/trunk/drivers/media/dvb/frontends/tda10071.c @@ -20,6 +20,10 @@ #include "tda10071_priv.h" +int tda10071_debug; +module_param_named(debug, tda10071_debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + static struct dvb_frontend_ops tda10071_ops; /* write multiple registers */ @@ -44,8 +48,7 @@ static int tda10071_wr_regs(struct tda10071_priv *priv, u8 reg, u8 *val, if (ret == 1) { ret = 0; } else { - dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \ - "len=%d\n", KBUILD_MODNAME, ret, reg, len); + warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len); ret = -EREMOTEIO; } return ret; @@ -76,8 +79,7 @@ static int tda10071_rd_regs(struct tda10071_priv *priv, u8 reg, u8 *val, memcpy(val, buf, len); ret = 0; } else { - dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \ - "len=%d\n", KBUILD_MODNAME, ret, reg, len); + warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len); ret = -EREMOTEIO; } return ret; @@ -168,7 +170,7 @@ static int tda10071_cmd_execute(struct tda10071_priv *priv, usleep_range(200, 5000); } - dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); + dbg("%s: loop=%d", __func__, i); if (i == 0) { ret = -ETIMEDOUT; @@ -177,7 +179,7 @@ static int tda10071_cmd_execute(struct tda10071_priv *priv, return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -194,8 +196,7 @@ static int tda10071_set_tone(struct dvb_frontend *fe, goto error; } - dev_dbg(&priv->i2c->dev, "%s: tone_mode=%d\n", __func__, - fe_sec_tone_mode); + dbg("%s: tone_mode=%d", __func__, fe_sec_tone_mode); switch (fe_sec_tone_mode) { case SEC_TONE_ON: @@ -205,25 +206,24 @@ static int tda10071_set_tone(struct dvb_frontend *fe, tone = 0; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_tone_mode\n", - __func__); + dbg("%s: invalid fe_sec_tone_mode", __func__); ret = -EINVAL; goto error; } - cmd.args[0] = CMD_LNB_PCB_CONFIG; - cmd.args[1] = 0; - cmd.args[2] = 0x00; - cmd.args[3] = 0x00; - cmd.args[4] = tone; - cmd.len = 5; + cmd.args[0x00] = CMD_LNB_PCB_CONFIG; + cmd.args[0x01] = 0; + cmd.args[0x02] = 0x00; + cmd.args[0x03] = 0x00; + cmd.args[0x04] = tone; + cmd.len = 0x05; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -240,7 +240,7 @@ static int tda10071_set_voltage(struct dvb_frontend *fe, goto error; } - dev_dbg(&priv->i2c->dev, "%s: voltage=%d\n", __func__, fe_sec_voltage); + dbg("%s: voltage=%d", __func__, fe_sec_voltage); switch (fe_sec_voltage) { case SEC_VOLTAGE_13: @@ -253,23 +253,22 @@ static int tda10071_set_voltage(struct dvb_frontend *fe, voltage = 0; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_voltage\n", - __func__); + dbg("%s: invalid fe_sec_voltage", __func__); ret = -EINVAL; goto error; }; - cmd.args[0] = CMD_LNB_SET_DC_LEVEL; - cmd.args[1] = 0; - cmd.args[2] = voltage; - cmd.len = 3; + cmd.args[0x00] = CMD_LNB_SET_DC_LEVEL; + cmd.args[0x01] = 0; + cmd.args[0x02] = voltage; + cmd.len = 0x03; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -286,10 +285,9 @@ static int tda10071_diseqc_send_master_cmd(struct dvb_frontend *fe, goto error; } - dev_dbg(&priv->i2c->dev, "%s: msg_len=%d\n", __func__, - diseqc_cmd->msg_len); + dbg("%s: msg_len=%d", __func__, diseqc_cmd->msg_len); - if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 6) { + if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 16) { ret = -EINVAL; goto error; } @@ -303,7 +301,7 @@ static int tda10071_diseqc_send_master_cmd(struct dvb_frontend *fe, usleep_range(10000, 20000); } - dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); + dbg("%s: loop=%d", __func__, i); if (i == 0) { ret = -ETIMEDOUT; @@ -314,22 +312,22 @@ static int tda10071_diseqc_send_master_cmd(struct dvb_frontend *fe, if (ret) goto error; - cmd.args[0] = CMD_LNB_SEND_DISEQC; - cmd.args[1] = 0; - cmd.args[2] = 0; - cmd.args[3] = 0; - cmd.args[4] = 2; - cmd.args[5] = 0; - cmd.args[6] = diseqc_cmd->msg_len; - memcpy(&cmd.args[7], diseqc_cmd->msg, diseqc_cmd->msg_len); - cmd.len = 7 + diseqc_cmd->msg_len; + cmd.args[0x00] = CMD_LNB_SEND_DISEQC; + cmd.args[0x01] = 0; + cmd.args[0x02] = 0; + cmd.args[0x03] = 0; + cmd.args[0x04] = 2; + cmd.args[0x05] = 0; + cmd.args[0x06] = diseqc_cmd->msg_len; + memcpy(&cmd.args[0x07], diseqc_cmd->msg, diseqc_cmd->msg_len); + cmd.len = 0x07 + diseqc_cmd->msg_len; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -346,7 +344,7 @@ static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe, goto error; } - dev_dbg(&priv->i2c->dev, "%s:\n", __func__); + dbg("%s:", __func__); /* wait LNB RX */ for (i = 500, tmp = 0; i && !tmp; i--) { @@ -357,7 +355,7 @@ static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe, usleep_range(10000, 20000); } - dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); + dbg("%s: loop=%d", __func__, i); if (i == 0) { ret = -ETIMEDOUT; @@ -374,9 +372,9 @@ static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe, reply->msg_len = sizeof(reply->msg); /* truncate API max */ /* read reply */ - cmd.args[0] = CMD_LNB_UPDATE_REPLY; - cmd.args[1] = 0; - cmd.len = 2; + cmd.args[0x00] = CMD_LNB_UPDATE_REPLY; + cmd.args[0x01] = 0; + cmd.len = 0x02; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; @@ -387,7 +385,7 @@ static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe, return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -404,8 +402,7 @@ static int tda10071_diseqc_send_burst(struct dvb_frontend *fe, goto error; } - dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__, - fe_sec_mini_cmd); + dbg("%s: fe_sec_mini_cmd=%d", __func__, fe_sec_mini_cmd); switch (fe_sec_mini_cmd) { case SEC_MINI_A: @@ -415,8 +412,7 @@ static int tda10071_diseqc_send_burst(struct dvb_frontend *fe, burst = 1; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_mini_cmd\n", - __func__); + dbg("%s: invalid fe_sec_mini_cmd", __func__); ret = -EINVAL; goto error; } @@ -430,7 +426,7 @@ static int tda10071_diseqc_send_burst(struct dvb_frontend *fe, usleep_range(10000, 20000); } - dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); + dbg("%s: loop=%d", __func__, i); if (i == 0) { ret = -ETIMEDOUT; @@ -441,17 +437,17 @@ static int tda10071_diseqc_send_burst(struct dvb_frontend *fe, if (ret) goto error; - cmd.args[0] = CMD_LNB_SEND_TONEBURST; - cmd.args[1] = 0; - cmd.args[2] = burst; - cmd.len = 3; + cmd.args[0x00] = CMD_LNB_SEND_TONEBURST; + cmd.args[0x01] = 0; + cmd.args[0x02] = burst; + cmd.len = 0x03; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -485,7 +481,7 @@ static int tda10071_read_status(struct dvb_frontend *fe, fe_status_t *status) return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -510,7 +506,7 @@ static int tda10071_read_snr(struct dvb_frontend *fe, u16 *snr) return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -527,9 +523,9 @@ static int tda10071_read_signal_strength(struct dvb_frontend *fe, u16 *strength) goto error; } - cmd.args[0] = CMD_GET_AGCACC; - cmd.args[1] = 0; - cmd.len = 2; + cmd.args[0x00] = CMD_GET_AGCACC; + cmd.args[0x01] = 0; + cmd.len = 0x02; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; @@ -549,7 +545,7 @@ static int tda10071_read_signal_strength(struct dvb_frontend *fe, u16 *strength) return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -587,18 +583,17 @@ static int tda10071_read_ber(struct dvb_frontend *fe, u32 *ber) goto error; if (priv->meas_count[i] == tmp) { - dev_dbg(&priv->i2c->dev, "%s: meas not ready=%02x\n", __func__, - tmp); + dbg("%s: meas not ready=%02x", __func__, tmp); *ber = priv->ber; return 0; } else { priv->meas_count[i] = tmp; } - cmd.args[0] = CMD_BER_UPDATE_COUNTERS; - cmd.args[1] = 0; - cmd.args[2] = i; - cmd.len = 3; + cmd.args[0x00] = CMD_BER_UPDATE_COUNTERS; + cmd.args[0x01] = 0; + cmd.args[0x02] = i; + cmd.len = 0x03; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; @@ -617,7 +612,7 @@ static int tda10071_read_ber(struct dvb_frontend *fe, u32 *ber) return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -637,7 +632,7 @@ static int tda10071_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -649,11 +644,10 @@ static int tda10071_set_frontend(struct dvb_frontend *fe) int ret, i; u8 mode, rolloff, pilot, inversion, div; - dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d modulation=%d " \ - "frequency=%d symbol_rate=%d inversion=%d pilot=%d " \ - "rolloff=%d\n", __func__, c->delivery_system, c->modulation, - c->frequency, c->symbol_rate, c->inversion, c->pilot, - c->rolloff); + dbg("%s: delivery_system=%d modulation=%d frequency=%d " \ + "symbol_rate=%d inversion=%d pilot=%d rolloff=%d", __func__, + c->delivery_system, c->modulation, c->frequency, + c->symbol_rate, c->inversion, c->pilot, c->rolloff); priv->delivery_system = SYS_UNDEFINED; @@ -675,7 +669,7 @@ static int tda10071_set_frontend(struct dvb_frontend *fe) inversion = 3; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n", __func__); + dbg("%s: invalid inversion", __func__); ret = -EINVAL; goto error; } @@ -698,8 +692,7 @@ static int tda10071_set_frontend(struct dvb_frontend *fe) break; case ROLLOFF_AUTO: default: - dev_dbg(&priv->i2c->dev, "%s: invalid rolloff\n", - __func__); + dbg("%s: invalid rolloff", __func__); ret = -EINVAL; goto error; } @@ -715,15 +708,13 @@ static int tda10071_set_frontend(struct dvb_frontend *fe) pilot = 2; break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid pilot\n", - __func__); + dbg("%s: invalid pilot", __func__); ret = -EINVAL; goto error; } break; default: - dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n", - __func__); + dbg("%s: invalid delivery_system", __func__); ret = -EINVAL; goto error; } @@ -733,15 +724,13 @@ static int tda10071_set_frontend(struct dvb_frontend *fe) c->modulation == TDA10071_MODCOD[i].modulation && c->fec_inner == TDA10071_MODCOD[i].fec) { mode = TDA10071_MODCOD[i].val; - dev_dbg(&priv->i2c->dev, "%s: mode found=%02x\n", - __func__, mode); + dbg("%s: mode found=%02x", __func__, mode); break; } } if (mode == 0xff) { - dev_dbg(&priv->i2c->dev, "%s: invalid parameter combination\n", - __func__); + dbg("%s: invalid parameter combination", __func__); ret = -EINVAL; goto error; } @@ -759,22 +748,22 @@ static int tda10071_set_frontend(struct dvb_frontend *fe) if (ret) goto error; - cmd.args[0] = CMD_CHANGE_CHANNEL; - cmd.args[1] = 0; - cmd.args[2] = mode; - cmd.args[3] = (c->frequency >> 16) & 0xff; - cmd.args[4] = (c->frequency >> 8) & 0xff; - cmd.args[5] = (c->frequency >> 0) & 0xff; - cmd.args[6] = ((c->symbol_rate / 1000) >> 8) & 0xff; - cmd.args[7] = ((c->symbol_rate / 1000) >> 0) & 0xff; - cmd.args[8] = (tda10071_ops.info.frequency_tolerance >> 8) & 0xff; - cmd.args[9] = (tda10071_ops.info.frequency_tolerance >> 0) & 0xff; - cmd.args[10] = rolloff; - cmd.args[11] = inversion; - cmd.args[12] = pilot; - cmd.args[13] = 0x00; - cmd.args[14] = 0x00; - cmd.len = 15; + cmd.args[0x00] = CMD_CHANGE_CHANNEL; + cmd.args[0x01] = 0; + cmd.args[0x02] = mode; + cmd.args[0x03] = (c->frequency >> 16) & 0xff; + cmd.args[0x04] = (c->frequency >> 8) & 0xff; + cmd.args[0x05] = (c->frequency >> 0) & 0xff; + cmd.args[0x06] = ((c->symbol_rate / 1000) >> 8) & 0xff; + cmd.args[0x07] = ((c->symbol_rate / 1000) >> 0) & 0xff; + cmd.args[0x08] = (tda10071_ops.info.frequency_tolerance >> 8) & 0xff; + cmd.args[0x09] = (tda10071_ops.info.frequency_tolerance >> 0) & 0xff; + cmd.args[0x0a] = rolloff; + cmd.args[0x0b] = inversion; + cmd.args[0x0c] = pilot; + cmd.args[0x0d] = 0x00; + cmd.args[0x0e] = 0x00; + cmd.len = 0x0f; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; @@ -783,7 +772,7 @@ static int tda10071_set_frontend(struct dvb_frontend *fe) return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -840,7 +829,7 @@ static int tda10071_get_frontend(struct dvb_frontend *fe) return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -926,10 +915,10 @@ static int tda10071_init(struct dvb_frontend *fe) goto error; } - cmd.args[0] = CMD_SET_SLEEP_MODE; - cmd.args[1] = 0; - cmd.args[2] = 0; - cmd.len = 3; + cmd.args[0x00] = CMD_SET_SLEEP_MODE; + cmd.args[0x01] = 0; + cmd.args[0x02] = 0; + cmd.len = 0x03; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; @@ -940,11 +929,10 @@ static int tda10071_init(struct dvb_frontend *fe) /* request the firmware, this will block and timeout */ ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent); if (ret) { - dev_err(&priv->i2c->dev, "%s: did not find the " \ - "firmware file. (%s) Please see " \ - "linux/Documentation/dvb/ for more " \ - "details on firmware-problems. (%d)\n", - KBUILD_MODNAME, fw_file, ret); + err("did not find the firmware file. (%s) " + "Please see linux/Documentation/dvb/ for more" \ + " details on firmware-problems. (%d)", + fw_file, ret); goto error; } @@ -973,11 +961,10 @@ static int tda10071_init(struct dvb_frontend *fe) if (ret) goto error_release_firmware; - dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state, " \ - "will try to load a firmware\n", KBUILD_MODNAME, - tda10071_ops.info.name); - dev_info(&priv->i2c->dev, "%s: downloading firmware from " \ - "file '%s'\n", KBUILD_MODNAME, fw_file); + info("found a '%s' in cold state, will try to load a firmware", + tda10071_ops.info.name); + + info("downloading firmware from file '%s'", fw_file); /* do not download last byte */ fw_size = fw->size - 1; @@ -991,9 +978,7 @@ static int tda10071_init(struct dvb_frontend *fe) ret = tda10071_wr_regs(priv, 0xfa, (u8 *) &fw->data[fw_size - remaining], len); if (ret) { - dev_err(&priv->i2c->dev, "%s: firmware " \ - "download failed=%d\n", - KBUILD_MODNAME, ret); + err("firmware download failed=%d", ret); if (ret) goto error_release_firmware; } @@ -1017,16 +1002,15 @@ static int tda10071_init(struct dvb_frontend *fe) goto error; if (tmp) { - dev_info(&priv->i2c->dev, "%s: firmware did not run\n", - KBUILD_MODNAME); + info("firmware did not run"); ret = -EFAULT; goto error; } else { priv->warm = 1; } - cmd.args[0] = CMD_GET_FW_VERSION; - cmd.len = 1; + cmd.args[0x00] = CMD_GET_FW_VERSION; + cmd.len = 0x01; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; @@ -1035,55 +1019,54 @@ static int tda10071_init(struct dvb_frontend *fe) if (ret) goto error; - dev_info(&priv->i2c->dev, "%s: firmware version %d.%d.%d.%d\n", - KBUILD_MODNAME, buf[0], buf[1], buf[2], buf[3]); - dev_info(&priv->i2c->dev, "%s: found a '%s' in warm state\n", - KBUILD_MODNAME, tda10071_ops.info.name); + info("firmware version %d.%d.%d.%d", + buf[0], buf[1], buf[2], buf[3]); + info("found a '%s' in warm state.", tda10071_ops.info.name); ret = tda10071_rd_regs(priv, 0x81, buf, 2); if (ret) goto error; - cmd.args[0] = CMD_DEMOD_INIT; - cmd.args[1] = ((priv->cfg.xtal / 1000) >> 8) & 0xff; - cmd.args[2] = ((priv->cfg.xtal / 1000) >> 0) & 0xff; - cmd.args[3] = buf[0]; - cmd.args[4] = buf[1]; - cmd.args[5] = priv->cfg.pll_multiplier; - cmd.args[6] = priv->cfg.spec_inv; - cmd.args[7] = 0x00; - cmd.len = 8; + cmd.args[0x00] = CMD_DEMOD_INIT; + cmd.args[0x01] = ((priv->cfg.xtal / 1000) >> 8) & 0xff; + cmd.args[0x02] = ((priv->cfg.xtal / 1000) >> 0) & 0xff; + cmd.args[0x03] = buf[0]; + cmd.args[0x04] = buf[1]; + cmd.args[0x05] = priv->cfg.pll_multiplier; + cmd.args[0x06] = priv->cfg.spec_inv; + cmd.args[0x07] = 0x00; + cmd.len = 0x08; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; - cmd.args[0] = CMD_TUNER_INIT; - cmd.args[1] = 0x00; - cmd.args[2] = 0x00; - cmd.args[3] = 0x00; - cmd.args[4] = 0x00; - cmd.args[5] = 0x14; - cmd.args[6] = 0x00; - cmd.args[7] = 0x03; - cmd.args[8] = 0x02; - cmd.args[9] = 0x02; - cmd.args[10] = 0x00; - cmd.args[11] = 0x00; - cmd.args[12] = 0x00; - cmd.args[13] = 0x00; - cmd.args[14] = 0x00; - cmd.len = 15; + cmd.args[0x00] = CMD_TUNER_INIT; + cmd.args[0x01] = 0x00; + cmd.args[0x02] = 0x00; + cmd.args[0x03] = 0x00; + cmd.args[0x04] = 0x00; + cmd.args[0x05] = 0x14; + cmd.args[0x06] = 0x00; + cmd.args[0x07] = 0x03; + cmd.args[0x08] = 0x02; + cmd.args[0x09] = 0x02; + cmd.args[0x0a] = 0x00; + cmd.args[0x0b] = 0x00; + cmd.args[0x0c] = 0x00; + cmd.args[0x0d] = 0x00; + cmd.args[0x0e] = 0x00; + cmd.len = 0x0f; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; - cmd.args[0] = CMD_MPEG_CONFIG; - cmd.args[1] = 0; - cmd.args[2] = priv->cfg.ts_mode; - cmd.args[3] = 0x00; - cmd.args[4] = 0x04; - cmd.args[5] = 0x00; - cmd.len = 6; + cmd.args[0x00] = CMD_MPEG_CONFIG; + cmd.args[0x01] = 0; + cmd.args[0x02] = priv->cfg.ts_mode; + cmd.args[0x03] = 0x00; + cmd.args[0x04] = 0x04; + cmd.args[0x05] = 0x00; + cmd.len = 0x06; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; @@ -1092,27 +1075,27 @@ static int tda10071_init(struct dvb_frontend *fe) if (ret) goto error; - cmd.args[0] = CMD_LNB_CONFIG; - cmd.args[1] = 0; - cmd.args[2] = 150; - cmd.args[3] = 3; - cmd.args[4] = 22; - cmd.args[5] = 1; - cmd.args[6] = 1; - cmd.args[7] = 30; - cmd.args[8] = 30; - cmd.args[9] = 30; - cmd.args[10] = 30; - cmd.len = 11; + cmd.args[0x00] = CMD_LNB_CONFIG; + cmd.args[0x01] = 0; + cmd.args[0x02] = 150; + cmd.args[0x03] = 3; + cmd.args[0x04] = 22; + cmd.args[0x05] = 1; + cmd.args[0x06] = 1; + cmd.args[0x07] = 30; + cmd.args[0x08] = 30; + cmd.args[0x09] = 30; + cmd.args[0x0a] = 30; + cmd.len = 0x0b; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; - cmd.args[0] = CMD_BER_CONTROL; - cmd.args[1] = 0; - cmd.args[2] = 14; - cmd.args[3] = 14; - cmd.len = 4; + cmd.args[0x00] = CMD_BER_CONTROL; + cmd.args[0x01] = 0; + cmd.args[0x02] = 14; + cmd.args[0x03] = 14; + cmd.len = 0x04; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; @@ -1122,7 +1105,7 @@ static int tda10071_init(struct dvb_frontend *fe) error_release_firmware: release_firmware(fw); error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -1149,10 +1132,10 @@ static int tda10071_sleep(struct dvb_frontend *fe) goto error; } - cmd.args[0] = CMD_SET_SLEEP_MODE; - cmd.args[1] = 0; - cmd.args[2] = 1; - cmd.len = 3; + cmd.args[0x00] = CMD_SET_SLEEP_MODE; + cmd.args[0x01] = 0; + cmd.args[0x02] = 1; + cmd.len = 0x03; ret = tda10071_cmd_execute(priv, &cmd); if (ret) goto error; @@ -1166,7 +1149,7 @@ static int tda10071_sleep(struct dvb_frontend *fe) return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); return ret; } @@ -1225,7 +1208,7 @@ struct dvb_frontend *tda10071_attach(const struct tda10071_config *config, return &priv->fe; error: - dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); + dbg("%s: failed=%d", __func__, ret); kfree(priv); return NULL; } diff --git a/trunk/drivers/media/dvb/frontends/tda10071_priv.h b/trunk/drivers/media/dvb/frontends/tda10071_priv.h index 0fa85cfa70c2..93c5e6317f07 100644 --- a/trunk/drivers/media/dvb/frontends/tda10071_priv.h +++ b/trunk/drivers/media/dvb/frontends/tda10071_priv.h @@ -25,6 +25,19 @@ #include "tda10071.h" #include +#define LOG_PREFIX "tda10071" + +#undef dbg +#define dbg(f, arg...) \ + if (tda10071_debug) \ + printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) +#undef err +#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) +#undef info +#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) +#undef warn +#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) + struct tda10071_priv { struct i2c_adapter *i2c; struct dvb_frontend fe; @@ -99,7 +112,7 @@ struct tda10071_reg_val_mask { #define CMD_BER_UPDATE_COUNTERS 0x3f /* firmare command struct */ -#define TDA10071_ARGLEN 30 +#define TDA10071_ARGLEN 0x1e struct tda10071_cmd { u8 args[TDA10071_ARGLEN]; u8 len; diff --git a/trunk/drivers/media/dvb/ngene/ngene-cards.c b/trunk/drivers/media/dvb/ngene/ngene-cards.c index 72ee8de02260..7539a5d71029 100644 --- a/trunk/drivers/media/dvb/ngene/ngene-cards.c +++ b/trunk/drivers/media/dvb/ngene/ngene-cards.c @@ -217,7 +217,6 @@ static int demod_attach_drxk(struct ngene_channel *chan, memset(&config, 0, sizeof(config)); config.microcode_name = "drxk_a3.mc"; - config.qam_demod_parameter_count = 4; config.adr = 0x29 + (chan->number ^ 2); chan->fe = dvb_attach(drxk_attach, &config, i2c); diff --git a/trunk/drivers/media/radio/Kconfig b/trunk/drivers/media/radio/Kconfig index 24ce5a47f955..c257da13d766 100644 --- a/trunk/drivers/media/radio/Kconfig +++ b/trunk/drivers/media/radio/Kconfig @@ -5,7 +5,6 @@ menuconfig RADIO_ADAPTERS bool "Radio Adapters" depends on VIDEO_V4L2 - depends on MEDIA_RADIO_SUPPORT default y ---help--- Say Y here to enable selecting AM/FM radio adapters. diff --git a/trunk/drivers/media/radio/lm7000.h b/trunk/drivers/media/radio/lm7000.h deleted file mode 100644 index 139cd6b68824..000000000000 --- a/trunk/drivers/media/radio/lm7000.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __LM7000_H -#define __LM7000_H - -/* Sanyo LM7000 tuner chip control - * - * Copyright 2012 Ondrej Zary - * based on radio-aimslab.c by M. Kirkwood - * and radio-sf16fmi.c by M. Kirkwood and Petr Vandrovec - */ - -#define LM7000_DATA (1 << 0) -#define LM7000_CLK (1 << 1) -#define LM7000_CE (1 << 2) - -#define LM7000_FM_100 (0 << 20) -#define LM7000_FM_50 (1 << 20) -#define LM7000_FM_25 (2 << 20) -#define LM7000_BIT_FM (1 << 23) - -static inline void lm7000_set_freq(u32 freq, void *handle, - void (*set_pins)(void *handle, u8 pins)) -{ - int i; - u8 data; - u32 val; - - freq += 171200; /* Add 10.7 MHz IF */ - freq /= 400; /* Convert to 25 kHz units */ - val = freq | LM7000_FM_25 | LM7000_BIT_FM; - /* write the 24-bit register, starting with LSB */ - for (i = 0; i < 24; i++) { - data = val & (1 << i) ? LM7000_DATA : 0; - set_pins(handle, data | LM7000_CE); - udelay(2); - set_pins(handle, data | LM7000_CE | LM7000_CLK); - udelay(2); - set_pins(handle, data | LM7000_CE); - udelay(2); - } - set_pins(handle, 0); -} - -#endif /* __LM7000_H */ diff --git a/trunk/drivers/media/radio/radio-aimslab.c b/trunk/drivers/media/radio/radio-aimslab.c index 12c70e876f58..98e0c8c20312 100644 --- a/trunk/drivers/media/radio/radio-aimslab.c +++ b/trunk/drivers/media/radio/radio-aimslab.c @@ -37,7 +37,6 @@ #include #include #include "radio-isa.h" -#include "lm7000.h" MODULE_AUTHOR("M. Kirkwood"); MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card."); @@ -73,38 +72,55 @@ static struct radio_isa_card *rtrack_alloc(void) return rt ? &rt->isa : NULL; } -#define AIMS_BIT_TUN_CE (1 << 0) -#define AIMS_BIT_TUN_CLK (1 << 1) -#define AIMS_BIT_TUN_DATA (1 << 2) -#define AIMS_BIT_VOL_CE (1 << 3) -#define AIMS_BIT_TUN_STRQ (1 << 4) -/* bit 5 is not connected */ -#define AIMS_BIT_VOL_UP (1 << 6) /* active low */ -#define AIMS_BIT_VOL_DN (1 << 7) /* active low */ +/* The 128+64 on these outb's is to keep the volume stable while tuning. + * Without them, the volume _will_ creep up with each frequency change + * and bit 4 (+16) is to keep the signal strength meter enabled. + */ -void rtrack_set_pins(void *handle, u8 pins) +static void send_0_byte(struct radio_isa_card *isa, int on) { - struct radio_isa_card *isa = handle; - struct rtrack *rt = container_of(isa, struct rtrack, isa); - u8 bits = AIMS_BIT_VOL_DN | AIMS_BIT_VOL_UP | AIMS_BIT_TUN_STRQ; - - if (!v4l2_ctrl_g_ctrl(rt->isa.mute)) - bits |= AIMS_BIT_VOL_CE; - - if (pins & LM7000_DATA) - bits |= AIMS_BIT_TUN_DATA; - if (pins & LM7000_CLK) - bits |= AIMS_BIT_TUN_CLK; - if (pins & LM7000_CE) - bits |= AIMS_BIT_TUN_CE; + outb_p(128+64+16+on+1, isa->io); /* wr-enable + data low */ + outb_p(128+64+16+on+2+1, isa->io); /* clock */ + msleep(1); +} - outb_p(bits, rt->isa.io); +static void send_1_byte(struct radio_isa_card *isa, int on) +{ + outb_p(128+64+16+on+4+1, isa->io); /* wr-enable+data high */ + outb_p(128+64+16+on+4+2+1, isa->io); /* clock */ + msleep(1); } static int rtrack_s_frequency(struct radio_isa_card *isa, u32 freq) { - lm7000_set_freq(freq, isa, rtrack_set_pins); + int on = v4l2_ctrl_g_ctrl(isa->mute) ? 0 : 8; + int i; + + freq += 171200; /* Add 10.7 MHz IF */ + freq /= 800; /* Convert to 50 kHz units */ + + send_0_byte(isa, on); /* 0: LSB of frequency */ + + for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ + if (freq & (1 << i)) + send_1_byte(isa, on); + else + send_0_byte(isa, on); + + send_0_byte(isa, on); /* 14: test bit - always 0 */ + send_0_byte(isa, on); /* 15: test bit - always 0 */ + + send_0_byte(isa, on); /* 16: band data 0 - always 0 */ + send_0_byte(isa, on); /* 17: band data 1 - always 0 */ + send_0_byte(isa, on); /* 18: band data 2 - always 0 */ + send_0_byte(isa, on); /* 19: time base - always 0 */ + + send_0_byte(isa, on); /* 20: spacing (0 = 25 kHz) */ + send_1_byte(isa, on); /* 21: spacing (1 = 25 kHz) */ + send_0_byte(isa, on); /* 22: spacing (0 = 25 kHz) */ + send_1_byte(isa, on); /* 23: AM/FM (FM = 1, always) */ + outb(0xd0 + on, isa->io); /* volume steady + sigstr */ return 0; } diff --git a/trunk/drivers/media/radio/radio-mr800.c b/trunk/drivers/media/radio/radio-mr800.c index 3182b26d6efa..94cb6bc690f5 100644 --- a/trunk/drivers/media/radio/radio-mr800.c +++ b/trunk/drivers/media/radio/radio-mr800.c @@ -295,8 +295,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, v->type = V4L2_TUNER_RADIO; v->rangelow = FREQ_MIN * FREQ_MUL; v->rangehigh = FREQ_MAX * FREQ_MUL; - v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_HWSEEK_WRAP; + v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; v->rxsubchans = is_stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; v->audmode = radio->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; @@ -373,7 +372,7 @@ static int vidioc_s_hw_freq_seek(struct file *file, void *priv, timeout = jiffies + msecs_to_jiffies(30000); for (;;) { if (time_after(jiffies, timeout)) { - retval = -ENODATA; + retval = -EAGAIN; break; } if (schedule_timeout_interruptible(msecs_to_jiffies(10))) { diff --git a/trunk/drivers/media/radio/radio-sf16fmi.c b/trunk/drivers/media/radio/radio-sf16fmi.c index 8185d5fbfa89..a81d723b8c77 100644 --- a/trunk/drivers/media/radio/radio-sf16fmi.c +++ b/trunk/drivers/media/radio/radio-sf16fmi.c @@ -27,7 +27,6 @@ #include /* outb, outb_p */ #include #include -#include "lm7000.h" MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); MODULE_DESCRIPTION("A driver for the SF16-FMI, SF16-FMP and SF16-FMD radio."); @@ -55,33 +54,31 @@ static struct fmi fmi_card; static struct pnp_dev *dev; bool pnp_attached; +/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ +/* It is only useful to give freq in interval of 800 (=0.05Mhz), + * other bits will be truncated, e.g 92.7400016 -> 92.7, but + * 92.7400017 -> 92.75 + */ +#define RSF16_ENCODE(x) ((x) / 800 + 214) #define RSF16_MINFREQ (87 * 16000) #define RSF16_MAXFREQ (108 * 16000) -#define FMI_BIT_TUN_CE (1 << 0) -#define FMI_BIT_TUN_CLK (1 << 1) -#define FMI_BIT_TUN_DATA (1 << 2) -#define FMI_BIT_VOL_SW (1 << 3) -#define FMI_BIT_TUN_STRQ (1 << 4) - -void fmi_set_pins(void *handle, u8 pins) +static void outbits(int bits, unsigned int data, int io) { - struct fmi *fmi = handle; - u8 bits = FMI_BIT_TUN_STRQ; - - if (!fmi->mute) - bits |= FMI_BIT_VOL_SW; - - if (pins & LM7000_DATA) - bits |= FMI_BIT_TUN_DATA; - if (pins & LM7000_CLK) - bits |= FMI_BIT_TUN_CLK; - if (pins & LM7000_CE) - bits |= FMI_BIT_TUN_CE; - - mutex_lock(&fmi->lock); - outb_p(bits, fmi->io); - mutex_unlock(&fmi->lock); + while (bits--) { + if (data & 1) { + outb(5, io); + udelay(6); + outb(7, io); + udelay(6); + } else { + outb(1, io); + udelay(6); + outb(3, io); + udelay(6); + } + data >>= 1; + } } static inline void fmi_mute(struct fmi *fmi) @@ -98,6 +95,20 @@ static inline void fmi_unmute(struct fmi *fmi) mutex_unlock(&fmi->lock); } +static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq) +{ + mutex_lock(&fmi->lock); + fmi->curfreq = freq; + + outbits(16, RSF16_ENCODE(freq), fmi->io); + outbits(8, 0xC0, fmi->io); + msleep(143); /* was schedule_timeout(HZ/7) */ + mutex_unlock(&fmi->lock); + if (!fmi->mute) + fmi_unmute(fmi); + return 0; +} + static inline int fmi_getsigstr(struct fmi *fmi) { int val; @@ -162,7 +173,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, return -EINVAL; /* rounding in steps of 800 to match the freq that will be used */ - lm7000_set_freq((f->frequency / 800) * 800, fmi, fmi_set_pins); + fmi_setfreq(fmi, (f->frequency / 800) * 800); return 0; } diff --git a/trunk/drivers/media/radio/radio-wl1273.c b/trunk/drivers/media/radio/radio-wl1273.c index e8428f573ccd..f1b607099b6c 100644 --- a/trunk/drivers/media/radio/radio-wl1273.c +++ b/trunk/drivers/media/radio/radio-wl1273.c @@ -1514,8 +1514,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv, tuner->rangehigh = WL1273_FREQ(WL1273_BAND_OTHER_HIGH); tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_RDS | - V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO | - V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP; + V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO; if (radio->stereo) tuner->audmode = V4L2_TUNER_MODE_STEREO; diff --git a/trunk/drivers/media/radio/si470x/radio-si470x-common.c b/trunk/drivers/media/radio/si470x/radio-si470x-common.c index d485b79222fd..969cf494d85b 100644 --- a/trunk/drivers/media/radio/si470x/radio-si470x-common.c +++ b/trunk/drivers/media/radio/si470x/radio-si470x-common.c @@ -363,7 +363,7 @@ static int si470x_set_seek(struct si470x_device *radio, /* try again, if timed out */ if (retval == 0 && timed_out) - return -ENODATA; + return -EAGAIN; return retval; } @@ -596,9 +596,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, strcpy(tuner->name, "FM"); tuner->type = V4L2_TUNER_RADIO; tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | - V4L2_TUNER_CAP_HWSEEK_BOUNDED | - V4L2_TUNER_CAP_HWSEEK_WRAP; + V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO; /* range limits */ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { diff --git a/trunk/drivers/media/radio/wl128x/fmdrv_rx.c b/trunk/drivers/media/radio/wl128x/fmdrv_rx.c index 3dd9fc097c47..43fb72291bea 100644 --- a/trunk/drivers/media/radio/wl128x/fmdrv_rx.c +++ b/trunk/drivers/media/radio/wl128x/fmdrv_rx.c @@ -251,7 +251,7 @@ int fm_rx_seek(struct fmdev *fmdev, u32 seek_upward, if (!timeleft) { fmerr("Timeout(%d sec),didn't get tune ended int\n", jiffies_to_msecs(FM_DRV_RX_SEEK_TIMEOUT) / 1000); - return -ENODATA; + return -ETIMEDOUT; } int_reason = fmdev->irq_info.flag & (FM_TUNE_COMPLETE | FM_BAND_LIMIT); diff --git a/trunk/drivers/media/radio/wl128x/fmdrv_v4l2.c b/trunk/drivers/media/radio/wl128x/fmdrv_v4l2.c index 49a11ec1f449..080b96a61f1a 100644 --- a/trunk/drivers/media/radio/wl128x/fmdrv_v4l2.c +++ b/trunk/drivers/media/radio/wl128x/fmdrv_v4l2.c @@ -285,9 +285,7 @@ static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv, tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO | ((fmdev->rx.rds.flag == FM_RDS_ENABLE) ? V4L2_TUNER_SUB_RDS : 0); tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS | - V4L2_TUNER_CAP_LOW | - V4L2_TUNER_CAP_HWSEEK_BOUNDED | - V4L2_TUNER_CAP_HWSEEK_WRAP; + V4L2_TUNER_CAP_LOW; tuner->audmode = (stereo_mono_mode ? V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO); diff --git a/trunk/drivers/media/rc/Kconfig b/trunk/drivers/media/rc/Kconfig index 908ef70430e9..f97eeb870455 100644 --- a/trunk/drivers/media/rc/Kconfig +++ b/trunk/drivers/media/rc/Kconfig @@ -1,20 +1,21 @@ -config RC_CORE - tristate - depends on MEDIA_RC_SUPPORT +menuconfig RC_CORE + tristate "Remote Controller adapters" depends on INPUT - default y + default INPUT + ---help--- + Enable support for Remote Controllers on Linux. This is + needed in order to support several video capture adapters, + standalone IR receivers/transmitters, and RF receivers. -source "drivers/media/rc/keymaps/Kconfig" + Enable this option if you have a video capture board even + if you don't need IR, as otherwise, you may not be able to + compile the driver for your adapter. -menuconfig RC_DECODERS - bool "Remote controller decoders" - depends on RC_CORE - default y +if RC_CORE -if RC_DECODERS config LIRC - tristate "LIRC interface driver" - depends on RC_CORE + tristate + default y ---help--- Enable this option to build the Linux Infrared Remote @@ -23,16 +24,7 @@ config LIRC LIRC daemon handles protocol decoding for IR reception and encoding for IR transmitting (aka "blasting"). -config IR_LIRC_CODEC - tristate "Enable IR to LIRC bridge" - depends on RC_CORE - depends on LIRC - default y - - ---help--- - Enable this option to pass raw IR to and from userspace via - the LIRC interface. - +source "drivers/media/rc/keymaps/Kconfig" config IR_NEC_DECODER tristate "Enable IR raw decoder for the NEC protocol" @@ -116,13 +108,16 @@ config IR_MCE_KBD_DECODER Enable this option if you have a Microsoft Remote Keyboard for Windows Media Center Edition, which you would like to use with a raw IR receiver in your system. -endif #RC_DECODERS -menuconfig RC_DEVICES - bool "Remote Controller devices" +config IR_LIRC_CODEC + tristate "Enable IR to LIRC bridge" depends on RC_CORE + depends on LIRC + default y -if RC_DEVICES + ---help--- + Enable this option to pass raw IR to and from userspace via + the LIRC interface. config RC_ATI_REMOTE tristate "ATI / X10 based USB RF remote controls" @@ -281,4 +276,4 @@ config IR_GPIO_CIR To compile this driver as a module, choose M here: the module will be called gpio-ir-recv. -endif #RC_DEVICES +endif #RC_CORE diff --git a/trunk/drivers/media/rc/ene_ir.c b/trunk/drivers/media/rc/ene_ir.c index 647dd951b0e8..bef5296173c9 100644 --- a/trunk/drivers/media/rc/ene_ir.c +++ b/trunk/drivers/media/rc/ene_ir.c @@ -1018,8 +1018,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) spin_lock_init(&dev->hw_lock); - dev->hw_io = pnp_port_start(pnp_dev, 0); - pnp_set_drvdata(pnp_dev, dev); dev->pnp_dev = pnp_dev; @@ -1074,6 +1072,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) /* claim the resources */ error = -EBUSY; + dev->hw_io = pnp_port_start(pnp_dev, 0); if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { dev->hw_io = -1; dev->irq = -1; diff --git a/trunk/drivers/media/rc/fintek-cir.c b/trunk/drivers/media/rc/fintek-cir.c index ab30c64f8124..6aabf7ae3a31 100644 --- a/trunk/drivers/media/rc/fintek-cir.c +++ b/trunk/drivers/media/rc/fintek-cir.c @@ -23,8 +23,6 @@ * USA */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -112,32 +110,30 @@ static u8 fintek_cir_reg_read(struct fintek_dev *fintek, u8 offset) return val; } +#define pr_reg(text, ...) \ + printk(KERN_INFO KBUILD_MODNAME ": " text, ## __VA_ARGS__) + /* dump current cir register contents */ static void cir_dump_regs(struct fintek_dev *fintek) { fintek_config_mode_enable(fintek); fintek_select_logical_dev(fintek, fintek->logical_dev_cir); - pr_info("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME); - pr_info(" * CR CIR BASE ADDR: 0x%x\n", - (fintek_cr_read(fintek, CIR_CR_BASE_ADDR_HI) << 8) | + pr_reg("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME); + pr_reg(" * CR CIR BASE ADDR: 0x%x\n", + (fintek_cr_read(fintek, CIR_CR_BASE_ADDR_HI) << 8) | fintek_cr_read(fintek, CIR_CR_BASE_ADDR_LO)); - pr_info(" * CR CIR IRQ NUM: 0x%x\n", - fintek_cr_read(fintek, CIR_CR_IRQ_SEL)); + pr_reg(" * CR CIR IRQ NUM: 0x%x\n", + fintek_cr_read(fintek, CIR_CR_IRQ_SEL)); fintek_config_mode_disable(fintek); - pr_info("%s: Dump CIR registers:\n", FINTEK_DRIVER_NAME); - pr_info(" * STATUS: 0x%x\n", - fintek_cir_reg_read(fintek, CIR_STATUS)); - pr_info(" * CONTROL: 0x%x\n", - fintek_cir_reg_read(fintek, CIR_CONTROL)); - pr_info(" * RX_DATA: 0x%x\n", - fintek_cir_reg_read(fintek, CIR_RX_DATA)); - pr_info(" * TX_CONTROL: 0x%x\n", - fintek_cir_reg_read(fintek, CIR_TX_CONTROL)); - pr_info(" * TX_DATA: 0x%x\n", - fintek_cir_reg_read(fintek, CIR_TX_DATA)); + pr_reg("%s: Dump CIR registers:\n", FINTEK_DRIVER_NAME); + pr_reg(" * STATUS: 0x%x\n", fintek_cir_reg_read(fintek, CIR_STATUS)); + pr_reg(" * CONTROL: 0x%x\n", fintek_cir_reg_read(fintek, CIR_CONTROL)); + pr_reg(" * RX_DATA: 0x%x\n", fintek_cir_reg_read(fintek, CIR_RX_DATA)); + pr_reg(" * TX_CONTROL: 0x%x\n", fintek_cir_reg_read(fintek, CIR_TX_CONTROL)); + pr_reg(" * TX_DATA: 0x%x\n", fintek_cir_reg_read(fintek, CIR_TX_DATA)); } /* detect hardware features */ diff --git a/trunk/drivers/media/rc/gpio-ir-recv.c b/trunk/drivers/media/rc/gpio-ir-recv.c index 04cb272db16a..0d875450c5ce 100644 --- a/trunk/drivers/media/rc/gpio-ir-recv.c +++ b/trunk/drivers/media/rc/gpio-ir-recv.c @@ -82,21 +82,12 @@ static int __devinit gpio_ir_recv_probe(struct platform_device *pdev) goto err_allocate_device; } - rcdev->priv = gpio_dev; rcdev->driver_type = RC_DRIVER_IR_RAW; + rcdev->allowed_protos = RC_TYPE_ALL; rcdev->input_name = GPIO_IR_DEVICE_NAME; - rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0"; rcdev->input_id.bustype = BUS_HOST; - rcdev->input_id.vendor = 0x0001; - rcdev->input_id.product = 0x0001; - rcdev->input_id.version = 0x0100; - rcdev->dev.parent = &pdev->dev; rcdev->driver_name = GPIO_IR_DRIVER_NAME; - if (pdata->allowed_protos) - rcdev->allowed_protos = pdata->allowed_protos; - else - rcdev->allowed_protos = RC_TYPE_ALL; - rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY; + rcdev->map_name = RC_MAP_EMPTY; gpio_dev->rcdev = rcdev; gpio_dev->gpio_nr = pdata->gpio_nr; @@ -197,7 +188,18 @@ static struct platform_driver gpio_ir_recv_driver = { #endif }, }; -module_platform_driver(gpio_ir_recv_driver); + +static int __init gpio_ir_recv_init(void) +{ + return platform_driver_register(&gpio_ir_recv_driver); +} +module_init(gpio_ir_recv_init); + +static void __exit gpio_ir_recv_exit(void) +{ + platform_driver_unregister(&gpio_ir_recv_driver); +} +module_exit(gpio_ir_recv_exit); MODULE_DESCRIPTION("GPIO IR Receiver driver"); MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/media/rc/nuvoton-cir.c b/trunk/drivers/media/rc/nuvoton-cir.c index 699eef39128b..dc8a7dddccd4 100644 --- a/trunk/drivers/media/rc/nuvoton-cir.c +++ b/trunk/drivers/media/rc/nuvoton-cir.c @@ -25,8 +25,6 @@ * USA */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -125,40 +123,43 @@ static u8 nvt_cir_wake_reg_read(struct nvt_dev *nvt, u8 offset) return val; } +#define pr_reg(text, ...) \ + printk(KERN_INFO KBUILD_MODNAME ": " text, ## __VA_ARGS__) + /* dump current cir register contents */ static void cir_dump_regs(struct nvt_dev *nvt) { nvt_efm_enable(nvt); nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); - pr_info("%s: Dump CIR logical device registers:\n", NVT_DRIVER_NAME); - pr_info(" * CR CIR ACTIVE : 0x%x\n", - nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); - pr_info(" * CR CIR BASE ADDR: 0x%x\n", - (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | + pr_reg("%s: Dump CIR logical device registers:\n", NVT_DRIVER_NAME); + pr_reg(" * CR CIR ACTIVE : 0x%x\n", + nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); + pr_reg(" * CR CIR BASE ADDR: 0x%x\n", + (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO)); - pr_info(" * CR CIR IRQ NUM: 0x%x\n", - nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); + pr_reg(" * CR CIR IRQ NUM: 0x%x\n", + nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); nvt_efm_disable(nvt); - pr_info("%s: Dump CIR registers:\n", NVT_DRIVER_NAME); - pr_info(" * IRCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRCON)); - pr_info(" * IRSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRSTS)); - pr_info(" * IREN: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IREN)); - pr_info(" * RXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_RXFCONT)); - pr_info(" * CP: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CP)); - pr_info(" * CC: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CC)); - pr_info(" * SLCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCH)); - pr_info(" * SLCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCL)); - pr_info(" * FIFOCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FIFOCON)); - pr_info(" * IRFIFOSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFIFOSTS)); - pr_info(" * SRXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SRXFIFO)); - pr_info(" * TXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_TXFCONT)); - pr_info(" * STXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_STXFIFO)); - pr_info(" * FCCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCH)); - pr_info(" * FCCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCL)); - pr_info(" * IRFSM: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFSM)); + pr_reg("%s: Dump CIR registers:\n", NVT_DRIVER_NAME); + pr_reg(" * IRCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRCON)); + pr_reg(" * IRSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRSTS)); + pr_reg(" * IREN: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IREN)); + pr_reg(" * RXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_RXFCONT)); + pr_reg(" * CP: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CP)); + pr_reg(" * CC: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CC)); + pr_reg(" * SLCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCH)); + pr_reg(" * SLCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCL)); + pr_reg(" * FIFOCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FIFOCON)); + pr_reg(" * IRFIFOSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFIFOSTS)); + pr_reg(" * SRXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SRXFIFO)); + pr_reg(" * TXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_TXFCONT)); + pr_reg(" * STXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_STXFIFO)); + pr_reg(" * FCCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCH)); + pr_reg(" * FCCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCL)); + pr_reg(" * IRFSM: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFSM)); } /* dump current cir wake register contents */ @@ -169,59 +170,59 @@ static void cir_wake_dump_regs(struct nvt_dev *nvt) nvt_efm_enable(nvt); nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); - pr_info("%s: Dump CIR WAKE logical device registers:\n", - NVT_DRIVER_NAME); - pr_info(" * CR CIR WAKE ACTIVE : 0x%x\n", - nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); - pr_info(" * CR CIR WAKE BASE ADDR: 0x%x\n", - (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | + pr_reg("%s: Dump CIR WAKE logical device registers:\n", + NVT_DRIVER_NAME); + pr_reg(" * CR CIR WAKE ACTIVE : 0x%x\n", + nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); + pr_reg(" * CR CIR WAKE BASE ADDR: 0x%x\n", + (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO)); - pr_info(" * CR CIR WAKE IRQ NUM: 0x%x\n", - nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); + pr_reg(" * CR CIR WAKE IRQ NUM: 0x%x\n", + nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); nvt_efm_disable(nvt); - pr_info("%s: Dump CIR WAKE registers\n", NVT_DRIVER_NAME); - pr_info(" * IRCON: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON)); - pr_info(" * IRSTS: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS)); - pr_info(" * IREN: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN)); - pr_info(" * FIFO CMP DEEP: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_DEEP)); - pr_info(" * FIFO CMP TOL: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_TOL)); - pr_info(" * FIFO COUNT: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT)); - pr_info(" * SLCH: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCH)); - pr_info(" * SLCL: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCL)); - pr_info(" * FIFOCON: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON)); - pr_info(" * SRXFSTS: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_SRXFSTS)); - pr_info(" * SAMPLE RX FIFO: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_SAMPLE_RX_FIFO)); - pr_info(" * WR FIFO DATA: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_WR_FIFO_DATA)); - pr_info(" * RD FIFO ONLY: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); - pr_info(" * RD FIFO ONLY IDX: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)); - pr_info(" * FIFO IGNORE: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_IGNORE)); - pr_info(" * IRFSM: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRFSM)); + pr_reg("%s: Dump CIR WAKE registers\n", NVT_DRIVER_NAME); + pr_reg(" * IRCON: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON)); + pr_reg(" * IRSTS: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS)); + pr_reg(" * IREN: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN)); + pr_reg(" * FIFO CMP DEEP: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_DEEP)); + pr_reg(" * FIFO CMP TOL: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_TOL)); + pr_reg(" * FIFO COUNT: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT)); + pr_reg(" * SLCH: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCH)); + pr_reg(" * SLCL: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCL)); + pr_reg(" * FIFOCON: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON)); + pr_reg(" * SRXFSTS: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SRXFSTS)); + pr_reg(" * SAMPLE RX FIFO: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SAMPLE_RX_FIFO)); + pr_reg(" * WR FIFO DATA: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_WR_FIFO_DATA)); + pr_reg(" * RD FIFO ONLY: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); + pr_reg(" * RD FIFO ONLY IDX: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)); + pr_reg(" * FIFO IGNORE: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_IGNORE)); + pr_reg(" * IRFSM: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRFSM)); fifo_len = nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT); - pr_info("%s: Dump CIR WAKE FIFO (len %d)\n", NVT_DRIVER_NAME, fifo_len); - pr_info("* Contents ="); + pr_reg("%s: Dump CIR WAKE FIFO (len %d)\n", NVT_DRIVER_NAME, fifo_len); + pr_reg("* Contents = "); for (i = 0; i < fifo_len; i++) - pr_cont(" %02x", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); - pr_cont("\n"); + printk(KERN_CONT "%02x ", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); + printk(KERN_CONT "\n"); } /* detect hardware features */ diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index c128fac0ce2c..99937c94d7df 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -5,7 +5,7 @@ config VIDEO_V4L2 tristate depends on VIDEO_DEV && VIDEO_V4L2_COMMON - default y + default VIDEO_DEV && VIDEO_V4L2_COMMON config VIDEOBUF_GEN tristate @@ -73,7 +73,6 @@ config VIDEOBUF2_DMA_SG menuconfig VIDEO_CAPTURE_DRIVERS bool "Video capture adapters" depends on VIDEO_V4L2 - depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT default y ---help--- Say Y here to enable selecting the video adapters for @@ -462,15 +461,6 @@ config VIDEO_ADV7343 To compile this driver as a module, choose M here: the module will be called adv7343. -config VIDEO_ADV7393 - tristate "ADV7393 video encoder" - depends on I2C - help - Support for Analog Devices I2C bus based ADV7393 encoder. - - To compile this driver as a module, choose M here: the - module will be called adv7393. - config VIDEO_AK881X tristate "AK8813/AK8814 video encoders" depends on I2C @@ -488,7 +478,6 @@ config VIDEO_SMIAPP_PLL config VIDEO_OV7670 tristate "OmniVision OV7670 sensor support" depends on I2C && VIDEO_V4L2 - depends on MEDIA_CAMERA_SUPPORT ---help--- This is a Video4Linux2 sensor-level driver for the OmniVision OV7670 VGA camera. It currently only works with the M88ALP01 @@ -497,7 +486,6 @@ config VIDEO_OV7670 config VIDEO_VS6624 tristate "ST VS6624 sensor support" depends on VIDEO_V4L2 && I2C - depends on MEDIA_CAMERA_SUPPORT ---help--- This is a Video4Linux2 sensor-level driver for the ST VS6624 camera. @@ -508,7 +496,6 @@ config VIDEO_VS6624 config VIDEO_MT9M032 tristate "MT9M032 camera sensor support" depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API - depends on MEDIA_CAMERA_SUPPORT select VIDEO_APTINA_PLL ---help--- This driver supports MT9M032 camera sensors from Aptina, monochrome @@ -517,7 +504,6 @@ config VIDEO_MT9M032 config VIDEO_MT9P031 tristate "Aptina MT9P031 support" depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API - depends on MEDIA_CAMERA_SUPPORT select VIDEO_APTINA_PLL ---help--- This is a Video4Linux2 sensor-level driver for the Aptina @@ -526,7 +512,6 @@ config VIDEO_MT9P031 config VIDEO_MT9T001 tristate "Aptina MT9T001 support" depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API - depends on MEDIA_CAMERA_SUPPORT ---help--- This is a Video4Linux2 sensor-level driver for the Aptina (Micron) mt0t001 3 Mpixel camera. @@ -534,7 +519,6 @@ config VIDEO_MT9T001 config VIDEO_MT9V011 tristate "Micron mt9v011 sensor support" depends on I2C && VIDEO_V4L2 - depends on MEDIA_CAMERA_SUPPORT ---help--- This is a Video4Linux2 sensor-level driver for the Micron mt0v011 1.3 Mpixel camera. It currently only works with the @@ -543,7 +527,6 @@ config VIDEO_MT9V011 config VIDEO_MT9V032 tristate "Micron MT9V032 sensor support" depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API - depends on MEDIA_CAMERA_SUPPORT ---help--- This is a Video4Linux2 sensor-level driver for the Micron MT9V032 752x480 CMOS sensor. @@ -551,7 +534,6 @@ config VIDEO_MT9V032 config VIDEO_TCM825X tristate "TCM825x camera sensor support" depends on I2C && VIDEO_V4L2 - depends on MEDIA_CAMERA_SUPPORT ---help--- This is a driver for the Toshiba TCM825x VGA camera sensor. It is used for example in Nokia N800. @@ -559,14 +541,12 @@ config VIDEO_TCM825X config VIDEO_SR030PC30 tristate "Siliconfile SR030PC30 sensor support" depends on I2C && VIDEO_V4L2 - depends on MEDIA_CAMERA_SUPPORT ---help--- This driver supports SR030PC30 VGA camera from Siliconfile config VIDEO_NOON010PC30 tristate "Siliconfile NOON010PC30 sensor support" depends on I2C && VIDEO_V4L2 && EXPERIMENTAL && VIDEO_V4L2_SUBDEV_API - depends on MEDIA_CAMERA_SUPPORT ---help--- This driver supports NOON010PC30 CIF camera from Siliconfile @@ -574,7 +554,6 @@ source "drivers/media/video/m5mols/Kconfig" config VIDEO_S5K6AA tristate "Samsung S5K6AAFX sensor support" - depends on MEDIA_CAMERA_SUPPORT depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API ---help--- This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M @@ -587,7 +566,6 @@ comment "Flash devices" config VIDEO_ADP1653 tristate "ADP1653 flash support" depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER - depends on MEDIA_CAMERA_SUPPORT ---help--- This is a driver for the ADP1653 flash controller. It is used for example in Nokia N900. @@ -595,7 +573,6 @@ config VIDEO_ADP1653 config VIDEO_AS3645A tristate "AS3645A flash driver support" depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER - depends on MEDIA_CAMERA_SUPPORT ---help--- This is a driver for the AS3645A and LM3555 flash controllers. It has build in control for flash, torch and indicator LEDs. @@ -670,14 +647,30 @@ menuconfig V4L_USB_DRIVERS depends on USB default y -if V4L_USB_DRIVERS && MEDIA_CAMERA_SUPPORT +if V4L_USB_DRIVERS - comment "Webcam devices" +source "drivers/media/video/au0828/Kconfig" source "drivers/media/video/uvc/Kconfig" source "drivers/media/video/gspca/Kconfig" +source "drivers/media/video/pvrusb2/Kconfig" + +source "drivers/media/video/hdpvr/Kconfig" + +source "drivers/media/video/em28xx/Kconfig" + +source "drivers/media/video/tlg2300/Kconfig" + +source "drivers/media/video/cx231xx/Kconfig" + +source "drivers/media/video/tm6000/Kconfig" + +source "drivers/media/video/usbvision/Kconfig" + +source "drivers/media/video/sn9c102/Kconfig" + source "drivers/media/video/pwc/Kconfig" source "drivers/media/video/cpia2/Kconfig" @@ -718,46 +711,15 @@ config USB_S2255 Say Y here if you want support for the Sensoray 2255 USB device. This driver can be compiled as a module, called s2255drv. -source "drivers/media/video/sn9c102/Kconfig" - -endif # V4L_USB_DRIVERS && MEDIA_CAMERA_SUPPORT - -if V4L_USB_DRIVERS - - comment "Webcam and/or TV USB devices" - -source "drivers/media/video/em28xx/Kconfig" - -endif - -if V4L_USB_DRIVERS && MEDIA_ANALOG_TV_SUPPORT - - comment "TV USB devices" - -source "drivers/media/video/au0828/Kconfig" - -source "drivers/media/video/pvrusb2/Kconfig" - -source "drivers/media/video/hdpvr/Kconfig" - -source "drivers/media/video/tlg2300/Kconfig" - -source "drivers/media/video/cx231xx/Kconfig" - -source "drivers/media/video/tm6000/Kconfig" - -source "drivers/media/video/usbvision/Kconfig" - endif # V4L_USB_DRIVERS # -# PCI drivers configuration - No devices here are for webcams +# PCI drivers configuration # menuconfig V4L_PCI_DRIVERS bool "V4L PCI(e) devices" depends on PCI - depends on MEDIA_ANALOG_TV_SUPPORT default y ---help--- Say Y here to enable support for these PCI(e) drivers. @@ -852,13 +814,11 @@ endif # V4L_PCI_DRIVERS # # ISA & parallel port drivers configuration -# All devices here are webcam or grabber devices # menuconfig V4L_ISA_PARPORT_DRIVERS bool "V4L ISA and parallel port devices" depends on ISA || PARPORT - depends on MEDIA_CAMERA_SUPPORT default n ---help--- Say Y here to enable support for these ISA and parallel port drivers. @@ -911,13 +871,8 @@ config VIDEO_W9966 endif # V4L_ISA_PARPORT_DRIVERS -# -# Platform drivers -# All drivers here are currently for webcam support - menuconfig V4L_PLATFORM_DRIVERS bool "V4L platform devices" - depends on MEDIA_CAMERA_SUPPORT default n ---help--- Say Y here to enable support for platform-specific V4L drivers. diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile index b7da9faa3b0a..d209de0e0ca8 100644 --- a/trunk/drivers/media/video/Makefile +++ b/trunk/drivers/media/video/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o obj-$(CONFIG_VIDEO_ADV7183) += adv7183.o obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o -obj-$(CONFIG_VIDEO_ADV7393) += adv7393.o obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o obj-$(CONFIG_VIDEO_VS6624) += vs6624.o obj-$(CONFIG_VIDEO_BT819) += bt819.o diff --git a/trunk/drivers/media/video/adv7393.c b/trunk/drivers/media/video/adv7393.c deleted file mode 100644 index 3dc6098c7267..000000000000 --- a/trunk/drivers/media/video/adv7393.c +++ /dev/null @@ -1,487 +0,0 @@ -/* - * adv7393 - ADV7393 Video Encoder Driver - * - * The encoder hardware does not support SECAM. - * - * Copyright (C) 2010-2012 ADVANSEE - http://www.advansee.com/ - * Benoît Thébaudeau - * - * Based on ADV7343 driver, - * - * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed .as is. WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "adv7393_regs.h" - -MODULE_DESCRIPTION("ADV7393 video encoder driver"); -MODULE_LICENSE("GPL"); - -static bool debug; -module_param(debug, bool, 0644); -MODULE_PARM_DESC(debug, "Debug level 0-1"); - -struct adv7393_state { - struct v4l2_subdev sd; - struct v4l2_ctrl_handler hdl; - u8 reg00; - u8 reg01; - u8 reg02; - u8 reg35; - u8 reg80; - u8 reg82; - u32 output; - v4l2_std_id std; -}; - -static inline struct adv7393_state *to_state(struct v4l2_subdev *sd) -{ - return container_of(sd, struct adv7393_state, sd); -} - -static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) -{ - return &container_of(ctrl->handler, struct adv7393_state, hdl)->sd; -} - -static inline int adv7393_write(struct v4l2_subdev *sd, u8 reg, u8 value) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return i2c_smbus_write_byte_data(client, reg, value); -} - -static const u8 adv7393_init_reg_val[] = { - ADV7393_SOFT_RESET, ADV7393_SOFT_RESET_DEFAULT, - ADV7393_POWER_MODE_REG, ADV7393_POWER_MODE_REG_DEFAULT, - - ADV7393_HD_MODE_REG1, ADV7393_HD_MODE_REG1_DEFAULT, - ADV7393_HD_MODE_REG2, ADV7393_HD_MODE_REG2_DEFAULT, - ADV7393_HD_MODE_REG3, ADV7393_HD_MODE_REG3_DEFAULT, - ADV7393_HD_MODE_REG4, ADV7393_HD_MODE_REG4_DEFAULT, - ADV7393_HD_MODE_REG5, ADV7393_HD_MODE_REG5_DEFAULT, - ADV7393_HD_MODE_REG6, ADV7393_HD_MODE_REG6_DEFAULT, - ADV7393_HD_MODE_REG7, ADV7393_HD_MODE_REG7_DEFAULT, - - ADV7393_SD_MODE_REG1, ADV7393_SD_MODE_REG1_DEFAULT, - ADV7393_SD_MODE_REG2, ADV7393_SD_MODE_REG2_DEFAULT, - ADV7393_SD_MODE_REG3, ADV7393_SD_MODE_REG3_DEFAULT, - ADV7393_SD_MODE_REG4, ADV7393_SD_MODE_REG4_DEFAULT, - ADV7393_SD_MODE_REG5, ADV7393_SD_MODE_REG5_DEFAULT, - ADV7393_SD_MODE_REG6, ADV7393_SD_MODE_REG6_DEFAULT, - ADV7393_SD_MODE_REG7, ADV7393_SD_MODE_REG7_DEFAULT, - ADV7393_SD_MODE_REG8, ADV7393_SD_MODE_REG8_DEFAULT, - - ADV7393_SD_TIMING_REG0, ADV7393_SD_TIMING_REG0_DEFAULT, - - ADV7393_SD_HUE_ADJUST, ADV7393_SD_HUE_ADJUST_DEFAULT, - ADV7393_SD_CGMS_WSS0, ADV7393_SD_CGMS_WSS0_DEFAULT, - ADV7393_SD_BRIGHTNESS_WSS, ADV7393_SD_BRIGHTNESS_WSS_DEFAULT, -}; - -/* - * 2^32 - * FSC(reg) = FSC (HZ) * -------- - * 27000000 - */ -static const struct adv7393_std_info stdinfo[] = { - { - /* FSC(Hz) = 4,433,618.75 Hz */ - SD_STD_NTSC, 705268427, V4L2_STD_NTSC_443, - }, { - /* FSC(Hz) = 3,579,545.45 Hz */ - SD_STD_NTSC, 569408542, V4L2_STD_NTSC, - }, { - /* FSC(Hz) = 3,575,611.00 Hz */ - SD_STD_PAL_M, 568782678, V4L2_STD_PAL_M, - }, { - /* FSC(Hz) = 3,582,056.00 Hz */ - SD_STD_PAL_N, 569807903, V4L2_STD_PAL_Nc, - }, { - /* FSC(Hz) = 4,433,618.75 Hz */ - SD_STD_PAL_N, 705268427, V4L2_STD_PAL_N, - }, { - /* FSC(Hz) = 4,433,618.75 Hz */ - SD_STD_PAL_M, 705268427, V4L2_STD_PAL_60, - }, { - /* FSC(Hz) = 4,433,618.75 Hz */ - SD_STD_PAL_BDGHI, 705268427, V4L2_STD_PAL, - }, -}; - -static int adv7393_setstd(struct v4l2_subdev *sd, v4l2_std_id std) -{ - struct adv7393_state *state = to_state(sd); - const struct adv7393_std_info *std_info; - int num_std; - u8 reg; - u32 val; - int err = 0; - int i; - - num_std = ARRAY_SIZE(stdinfo); - - for (i = 0; i < num_std; i++) { - if (stdinfo[i].stdid & std) - break; - } - - if (i == num_std) { - v4l2_dbg(1, debug, sd, - "Invalid std or std is not supported: %llx\n", - (unsigned long long)std); - return -EINVAL; - } - - std_info = &stdinfo[i]; - - /* Set the standard */ - val = state->reg80 & ~SD_STD_MASK; - val |= std_info->standard_val3; - err = adv7393_write(sd, ADV7393_SD_MODE_REG1, val); - if (err < 0) - goto setstd_exit; - - state->reg80 = val; - - /* Configure the input mode register */ - val = state->reg01 & ~INPUT_MODE_MASK; - val |= SD_INPUT_MODE; - err = adv7393_write(sd, ADV7393_MODE_SELECT_REG, val); - if (err < 0) - goto setstd_exit; - - state->reg01 = val; - - /* Program the sub carrier frequency registers */ - val = std_info->fsc_val; - for (reg = ADV7393_FSC_REG0; reg <= ADV7393_FSC_REG3; reg++) { - err = adv7393_write(sd, reg, val); - if (err < 0) - goto setstd_exit; - val >>= 8; - } - - val = state->reg82; - - /* Pedestal settings */ - if (std & (V4L2_STD_NTSC | V4L2_STD_NTSC_443)) - val |= SD_PEDESTAL_EN; - else - val &= SD_PEDESTAL_DI; - - err = adv7393_write(sd, ADV7393_SD_MODE_REG2, val); - if (err < 0) - goto setstd_exit; - - state->reg82 = val; - -setstd_exit: - if (err != 0) - v4l2_err(sd, "Error setting std, write failed\n"); - - return err; -} - -static int adv7393_setoutput(struct v4l2_subdev *sd, u32 output_type) -{ - struct adv7393_state *state = to_state(sd); - u8 val; - int err = 0; - - if (output_type > ADV7393_SVIDEO_ID) { - v4l2_dbg(1, debug, sd, - "Invalid output type or output type not supported:%d\n", - output_type); - return -EINVAL; - } - - /* Enable Appropriate DAC */ - val = state->reg00 & 0x03; - - if (output_type == ADV7393_COMPOSITE_ID) - val |= ADV7393_COMPOSITE_POWER_VALUE; - else if (output_type == ADV7393_COMPONENT_ID) - val |= ADV7393_COMPONENT_POWER_VALUE; - else - val |= ADV7393_SVIDEO_POWER_VALUE; - - err = adv7393_write(sd, ADV7393_POWER_MODE_REG, val); - if (err < 0) - goto setoutput_exit; - - state->reg00 = val; - - /* Enable YUV output */ - val = state->reg02 | YUV_OUTPUT_SELECT; - err = adv7393_write(sd, ADV7393_MODE_REG0, val); - if (err < 0) - goto setoutput_exit; - - state->reg02 = val; - - /* configure SD DAC Output 1 bit */ - val = state->reg82; - if (output_type == ADV7393_COMPONENT_ID) - val &= SD_DAC_OUT1_DI; - else - val |= SD_DAC_OUT1_EN; - err = adv7393_write(sd, ADV7393_SD_MODE_REG2, val); - if (err < 0) - goto setoutput_exit; - - state->reg82 = val; - - /* configure ED/HD Color DAC Swap bit to zero */ - val = state->reg35 & HD_DAC_SWAP_DI; - err = adv7393_write(sd, ADV7393_HD_MODE_REG6, val); - if (err < 0) - goto setoutput_exit; - - state->reg35 = val; - -setoutput_exit: - if (err != 0) - v4l2_err(sd, "Error setting output, write failed\n"); - - return err; -} - -static int adv7393_log_status(struct v4l2_subdev *sd) -{ - struct adv7393_state *state = to_state(sd); - - v4l2_info(sd, "Standard: %llx\n", (unsigned long long)state->std); - v4l2_info(sd, "Output: %s\n", (state->output == 0) ? "Composite" : - ((state->output == 1) ? "Component" : "S-Video")); - return 0; -} - -static int adv7393_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct v4l2_subdev *sd = to_sd(ctrl); - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - return adv7393_write(sd, ADV7393_SD_BRIGHTNESS_WSS, - ctrl->val & SD_BRIGHTNESS_VALUE_MASK); - - case V4L2_CID_HUE: - return adv7393_write(sd, ADV7393_SD_HUE_ADJUST, - ctrl->val - ADV7393_HUE_MIN); - - case V4L2_CID_GAIN: - return adv7393_write(sd, ADV7393_DAC123_OUTPUT_LEVEL, - ctrl->val); - } - return -EINVAL; -} - -static int adv7393_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7393, 0); -} - -static const struct v4l2_ctrl_ops adv7393_ctrl_ops = { - .s_ctrl = adv7393_s_ctrl, -}; - -static const struct v4l2_subdev_core_ops adv7393_core_ops = { - .log_status = adv7393_log_status, - .g_chip_ident = adv7393_g_chip_ident, - .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, - .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, - .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, - .g_ctrl = v4l2_subdev_g_ctrl, - .s_ctrl = v4l2_subdev_s_ctrl, - .queryctrl = v4l2_subdev_queryctrl, - .querymenu = v4l2_subdev_querymenu, -}; - -static int adv7393_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) -{ - struct adv7393_state *state = to_state(sd); - int err = 0; - - if (state->std == std) - return 0; - - err = adv7393_setstd(sd, std); - if (!err) - state->std = std; - - return err; -} - -static int adv7393_s_routing(struct v4l2_subdev *sd, - u32 input, u32 output, u32 config) -{ - struct adv7393_state *state = to_state(sd); - int err = 0; - - if (state->output == output) - return 0; - - err = adv7393_setoutput(sd, output); - if (!err) - state->output = output; - - return err; -} - -static const struct v4l2_subdev_video_ops adv7393_video_ops = { - .s_std_output = adv7393_s_std_output, - .s_routing = adv7393_s_routing, -}; - -static const struct v4l2_subdev_ops adv7393_ops = { - .core = &adv7393_core_ops, - .video = &adv7393_video_ops, -}; - -static int adv7393_initialize(struct v4l2_subdev *sd) -{ - struct adv7393_state *state = to_state(sd); - int err = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(adv7393_init_reg_val); i += 2) { - - err = adv7393_write(sd, adv7393_init_reg_val[i], - adv7393_init_reg_val[i+1]); - if (err) { - v4l2_err(sd, "Error initializing\n"); - return err; - } - } - - /* Configure for default video standard */ - err = adv7393_setoutput(sd, state->output); - if (err < 0) { - v4l2_err(sd, "Error setting output during init\n"); - return -EINVAL; - } - - err = adv7393_setstd(sd, state->std); - if (err < 0) { - v4l2_err(sd, "Error setting std during init\n"); - return -EINVAL; - } - - return err; -} - -static int adv7393_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct adv7393_state *state; - int err; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - - state = kzalloc(sizeof(struct adv7393_state), GFP_KERNEL); - if (state == NULL) - return -ENOMEM; - - state->reg00 = ADV7393_POWER_MODE_REG_DEFAULT; - state->reg01 = 0x00; - state->reg02 = 0x20; - state->reg35 = ADV7393_HD_MODE_REG6_DEFAULT; - state->reg80 = ADV7393_SD_MODE_REG1_DEFAULT; - state->reg82 = ADV7393_SD_MODE_REG2_DEFAULT; - - state->output = ADV7393_COMPOSITE_ID; - state->std = V4L2_STD_NTSC; - - v4l2_i2c_subdev_init(&state->sd, client, &adv7393_ops); - - v4l2_ctrl_handler_init(&state->hdl, 3); - v4l2_ctrl_new_std(&state->hdl, &adv7393_ctrl_ops, - V4L2_CID_BRIGHTNESS, ADV7393_BRIGHTNESS_MIN, - ADV7393_BRIGHTNESS_MAX, 1, - ADV7393_BRIGHTNESS_DEF); - v4l2_ctrl_new_std(&state->hdl, &adv7393_ctrl_ops, - V4L2_CID_HUE, ADV7393_HUE_MIN, - ADV7393_HUE_MAX, 1, - ADV7393_HUE_DEF); - v4l2_ctrl_new_std(&state->hdl, &adv7393_ctrl_ops, - V4L2_CID_GAIN, ADV7393_GAIN_MIN, - ADV7393_GAIN_MAX, 1, - ADV7393_GAIN_DEF); - state->sd.ctrl_handler = &state->hdl; - if (state->hdl.error) { - int err = state->hdl.error; - - v4l2_ctrl_handler_free(&state->hdl); - kfree(state); - return err; - } - v4l2_ctrl_handler_setup(&state->hdl); - - err = adv7393_initialize(&state->sd); - if (err) { - v4l2_ctrl_handler_free(&state->hdl); - kfree(state); - } - return err; -} - -static int adv7393_remove(struct i2c_client *client) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct adv7393_state *state = to_state(sd); - - v4l2_device_unregister_subdev(sd); - v4l2_ctrl_handler_free(&state->hdl); - kfree(state); - - return 0; -} - -static const struct i2c_device_id adv7393_id[] = { - {"adv7393", 0}, - {}, -}; -MODULE_DEVICE_TABLE(i2c, adv7393_id); - -static struct i2c_driver adv7393_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "adv7393", - }, - .probe = adv7393_probe, - .remove = adv7393_remove, - .id_table = adv7393_id, -}; -module_i2c_driver(adv7393_driver); diff --git a/trunk/drivers/media/video/adv7393_regs.h b/trunk/drivers/media/video/adv7393_regs.h deleted file mode 100644 index 78968330f0be..000000000000 --- a/trunk/drivers/media/video/adv7393_regs.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * ADV7393 encoder related structure and register definitions - * - * Copyright (C) 2010-2012 ADVANSEE - http://www.advansee.com/ - * Benoît Thébaudeau - * - * Based on ADV7343 driver, - * - * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed .as is. WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef ADV7393_REGS_H -#define ADV7393_REGS_H - -struct adv7393_std_info { - u32 standard_val3; - u32 fsc_val; - v4l2_std_id stdid; -}; - -/* Register offset macros */ -#define ADV7393_POWER_MODE_REG (0x00) -#define ADV7393_MODE_SELECT_REG (0x01) -#define ADV7393_MODE_REG0 (0x02) - -#define ADV7393_DAC123_OUTPUT_LEVEL (0x0B) - -#define ADV7393_SOFT_RESET (0x17) - -#define ADV7393_HD_MODE_REG1 (0x30) -#define ADV7393_HD_MODE_REG2 (0x31) -#define ADV7393_HD_MODE_REG3 (0x32) -#define ADV7393_HD_MODE_REG4 (0x33) -#define ADV7393_HD_MODE_REG5 (0x34) -#define ADV7393_HD_MODE_REG6 (0x35) - -#define ADV7393_HD_MODE_REG7 (0x39) - -#define ADV7393_SD_MODE_REG1 (0x80) -#define ADV7393_SD_MODE_REG2 (0x82) -#define ADV7393_SD_MODE_REG3 (0x83) -#define ADV7393_SD_MODE_REG4 (0x84) -#define ADV7393_SD_MODE_REG5 (0x86) -#define ADV7393_SD_MODE_REG6 (0x87) -#define ADV7393_SD_MODE_REG7 (0x88) -#define ADV7393_SD_MODE_REG8 (0x89) - -#define ADV7393_SD_TIMING_REG0 (0x8A) - -#define ADV7393_FSC_REG0 (0x8C) -#define ADV7393_FSC_REG1 (0x8D) -#define ADV7393_FSC_REG2 (0x8E) -#define ADV7393_FSC_REG3 (0x8F) - -#define ADV7393_SD_CGMS_WSS0 (0x99) - -#define ADV7393_SD_HUE_ADJUST (0xA0) -#define ADV7393_SD_BRIGHTNESS_WSS (0xA1) - -/* Default values for the registers */ -#define ADV7393_POWER_MODE_REG_DEFAULT (0x10) -#define ADV7393_HD_MODE_REG1_DEFAULT (0x3C) /* Changed Default - 720p EAV/SAV code*/ -#define ADV7393_HD_MODE_REG2_DEFAULT (0x01) /* Changed Pixel data - valid */ -#define ADV7393_HD_MODE_REG3_DEFAULT (0x00) /* Color delay 0 clks */ -#define ADV7393_HD_MODE_REG4_DEFAULT (0xEC) /* Changed */ -#define ADV7393_HD_MODE_REG5_DEFAULT (0x08) -#define ADV7393_HD_MODE_REG6_DEFAULT (0x00) -#define ADV7393_HD_MODE_REG7_DEFAULT (0x00) -#define ADV7393_SOFT_RESET_DEFAULT (0x02) -#define ADV7393_COMPOSITE_POWER_VALUE (0x10) -#define ADV7393_COMPONENT_POWER_VALUE (0x1C) -#define ADV7393_SVIDEO_POWER_VALUE (0x0C) -#define ADV7393_SD_HUE_ADJUST_DEFAULT (0x80) -#define ADV7393_SD_BRIGHTNESS_WSS_DEFAULT (0x00) - -#define ADV7393_SD_CGMS_WSS0_DEFAULT (0x10) - -#define ADV7393_SD_MODE_REG1_DEFAULT (0x10) -#define ADV7393_SD_MODE_REG2_DEFAULT (0xC9) -#define ADV7393_SD_MODE_REG3_DEFAULT (0x00) -#define ADV7393_SD_MODE_REG4_DEFAULT (0x00) -#define ADV7393_SD_MODE_REG5_DEFAULT (0x02) -#define ADV7393_SD_MODE_REG6_DEFAULT (0x8C) -#define ADV7393_SD_MODE_REG7_DEFAULT (0x14) -#define ADV7393_SD_MODE_REG8_DEFAULT (0x00) - -#define ADV7393_SD_TIMING_REG0_DEFAULT (0x0C) - -/* Bit masks for Mode Select Register */ -#define INPUT_MODE_MASK (0x70) -#define SD_INPUT_MODE (0x00) -#define HD_720P_INPUT_MODE (0x10) -#define HD_1080I_INPUT_MODE (0x10) - -/* Bit masks for Mode Register 0 */ -#define TEST_PATTERN_BLACK_BAR_EN (0x04) -#define YUV_OUTPUT_SELECT (0x20) -#define RGB_OUTPUT_SELECT (0xDF) - -/* Bit masks for SD brightness/WSS */ -#define SD_BRIGHTNESS_VALUE_MASK (0x7F) -#define SD_BLANK_WSS_DATA_MASK (0x80) - -/* Bit masks for soft reset register */ -#define SOFT_RESET (0x02) - -/* Bit masks for HD Mode Register 1 */ -#define OUTPUT_STD_MASK (0x03) -#define OUTPUT_STD_SHIFT (0) -#define OUTPUT_STD_EIA0_2 (0x00) -#define OUTPUT_STD_EIA0_1 (0x01) -#define OUTPUT_STD_FULL (0x02) -#define EMBEDDED_SYNC (0x04) -#define EXTERNAL_SYNC (0xFB) -#define STD_MODE_MASK (0x1F) -#define STD_MODE_SHIFT (3) -#define STD_MODE_720P (0x05) -#define STD_MODE_720P_25 (0x08) -#define STD_MODE_720P_30 (0x07) -#define STD_MODE_720P_50 (0x06) -#define STD_MODE_1080I (0x0D) -#define STD_MODE_1080I_25 (0x0E) -#define STD_MODE_1080P_24 (0x11) -#define STD_MODE_1080P_25 (0x10) -#define STD_MODE_1080P_30 (0x0F) -#define STD_MODE_525P (0x00) -#define STD_MODE_625P (0x03) - -/* Bit masks for SD Mode Register 1 */ -#define SD_STD_MASK (0x03) -#define SD_STD_NTSC (0x00) -#define SD_STD_PAL_BDGHI (0x01) -#define SD_STD_PAL_M (0x02) -#define SD_STD_PAL_N (0x03) -#define SD_LUMA_FLTR_MASK (0x07) -#define SD_LUMA_FLTR_SHIFT (2) -#define SD_CHROMA_FLTR_MASK (0x07) -#define SD_CHROMA_FLTR_SHIFT (5) - -/* Bit masks for SD Mode Register 2 */ -#define SD_PRPB_SSAF_EN (0x01) -#define SD_PRPB_SSAF_DI (0xFE) -#define SD_DAC_OUT1_EN (0x02) -#define SD_DAC_OUT1_DI (0xFD) -#define SD_PEDESTAL_EN (0x08) -#define SD_PEDESTAL_DI (0xF7) -#define SD_SQUARE_PIXEL_EN (0x10) -#define SD_SQUARE_PIXEL_DI (0xEF) -#define SD_PIXEL_DATA_VALID (0x40) -#define SD_ACTIVE_EDGE_EN (0x80) -#define SD_ACTIVE_EDGE_DI (0x7F) - -/* Bit masks for HD Mode Register 6 */ -#define HD_PRPB_SYNC_EN (0x04) -#define HD_PRPB_SYNC_DI (0xFB) -#define HD_DAC_SWAP_EN (0x08) -#define HD_DAC_SWAP_DI (0xF7) -#define HD_GAMMA_CURVE_A (0xEF) -#define HD_GAMMA_CURVE_B (0x10) -#define HD_GAMMA_EN (0x20) -#define HD_GAMMA_DI (0xDF) -#define HD_ADPT_FLTR_MODEA (0xBF) -#define HD_ADPT_FLTR_MODEB (0x40) -#define HD_ADPT_FLTR_EN (0x80) -#define HD_ADPT_FLTR_DI (0x7F) - -#define ADV7393_BRIGHTNESS_MAX (63) -#define ADV7393_BRIGHTNESS_MIN (-64) -#define ADV7393_BRIGHTNESS_DEF (0) -#define ADV7393_HUE_MAX (127) -#define ADV7393_HUE_MIN (-128) -#define ADV7393_HUE_DEF (0) -#define ADV7393_GAIN_MAX (64) -#define ADV7393_GAIN_MIN (-64) -#define ADV7393_GAIN_DEF (0) - -#endif diff --git a/trunk/drivers/media/video/bt8xx/bttv-cards.c b/trunk/drivers/media/video/bt8xx/bttv-cards.c index 5f3a00c2c4f6..856ab962cd63 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-cards.c +++ b/trunk/drivers/media/video/bt8xx/bttv-cards.c @@ -676,7 +676,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .has_remote = 1, - .has_radio = 1, /* not every card has radio */ }, [BTTV_BOARD_VOBIS_BOOSTAR] = { .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", diff --git a/trunk/drivers/media/video/bt8xx/bttv-driver.c b/trunk/drivers/media/video/bt8xx/bttv-driver.c index b58ff87db771..ff7a589d8e0f 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-driver.c +++ b/trunk/drivers/media/video/bt8xx/bttv-driver.c @@ -557,6 +557,12 @@ static const struct bttv_format formats[] = { .btformat = BT848_COLOR_FMT_YUY2, .depth = 16, .flags = FORMAT_FLAGS_PACKED, + },{ + .name = "4:2:2, packed, YUYV", + .fourcc = V4L2_PIX_FMT_YUYV, + .btformat = BT848_COLOR_FMT_YUY2, + .depth = 16, + .flags = FORMAT_FLAGS_PACKED, },{ .name = "4:2:2, packed, UYVY", .fourcc = V4L2_PIX_FMT_UYVY, diff --git a/trunk/drivers/media/video/cpia2/cpia2_v4l.c b/trunk/drivers/media/video/cpia2/cpia2_v4l.c index a62a7b739991..55e92902a76c 100644 --- a/trunk/drivers/media/video/cpia2/cpia2_v4l.c +++ b/trunk/drivers/media/video/cpia2/cpia2_v4l.c @@ -932,7 +932,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) buf->sequence = cam->buffers[buf->index].seq; buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; buf->length = cam->frame_size; - buf->reserved2 = 0; + buf->input = 0; buf->reserved = 0; memset(&buf->timecode, 0, sizeof(buf->timecode)); diff --git a/trunk/drivers/media/video/cs8420.h b/trunk/drivers/media/video/cs8420.h new file mode 100644 index 000000000000..621c0c6678ea --- /dev/null +++ b/trunk/drivers/media/video/cs8420.h @@ -0,0 +1,50 @@ +/* cs8420.h - cs8420 initializations + Copyright (C) 1999 Nathan Laredo (laredo@gnu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ +#ifndef __CS8420_H__ +#define __CS8420_H__ + +/* Initialization Sequence */ + +static __u8 init8420[] = { + 1, 0x01, 2, 0x02, 3, 0x00, 4, 0x46, + 5, 0x24, 6, 0x84, 18, 0x18, 19, 0x13, +}; + +#define INIT8420LEN (sizeof(init8420)/2) + +static __u8 mode8420pro[] = { /* professional output mode */ + 32, 0xa1, 33, 0x00, 34, 0x00, 35, 0x00, + 36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00, + 40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00, + 44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00, + 48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00, + 52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00, +}; +#define MODE8420LEN (sizeof(mode8420pro)/2) + +static __u8 mode8420con[] = { /* consumer output mode */ + 32, 0x20, 33, 0x00, 34, 0x00, 35, 0x48, + 36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00, + 40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00, + 44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00, + 48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00, + 52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00, +}; + +#endif diff --git a/trunk/drivers/media/video/cx18/cx18-ioctl.c b/trunk/drivers/media/video/cx18/cx18-ioctl.c index e9912db3b496..35fde4e931f5 100644 --- a/trunk/drivers/media/video/cx18/cx18-ioctl.c +++ b/trunk/drivers/media/video/cx18/cx18-ioctl.c @@ -1142,6 +1142,24 @@ static long cx18_default(struct file *file, void *fh, bool valid_prio, return 0; } +long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct video_device *vfd = video_devdata(filp); + struct cx18_open_id *id = file2id(filp); + struct cx18 *cx = id->cx; + long res; + + mutex_lock(&cx->serialize_lock); + + if (cx18_debug & CX18_DBGFLG_IOCTL) + vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; + res = video_ioctl2(filp, cmd, arg); + vfd->debug = 0; + mutex_unlock(&cx->serialize_lock); + return res; +} + static const struct v4l2_ioctl_ops cx18_ioctl_ops = { .vidioc_querycap = cx18_querycap, .vidioc_s_audio = cx18_s_audio, diff --git a/trunk/drivers/media/video/cx18/cx18-ioctl.h b/trunk/drivers/media/video/cx18/cx18-ioctl.h index 2f9dd591ee0f..dcb2559ad520 100644 --- a/trunk/drivers/media/video/cx18/cx18-ioctl.h +++ b/trunk/drivers/media/video/cx18/cx18-ioctl.h @@ -29,3 +29,5 @@ void cx18_set_funcs(struct video_device *vdev); int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std); int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); int cx18_s_input(struct file *file, void *fh, unsigned int inp); +long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); diff --git a/trunk/drivers/media/video/cx18/cx18-streams.c b/trunk/drivers/media/video/cx18/cx18-streams.c index 9d598ab88615..4185bcb80ca3 100644 --- a/trunk/drivers/media/video/cx18/cx18-streams.c +++ b/trunk/drivers/media/video/cx18/cx18-streams.c @@ -40,7 +40,8 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = { .owner = THIS_MODULE, .read = cx18_v4l2_read, .open = cx18_v4l2_open, - .unlocked_ioctl = video_ioctl2, + /* FIXME change to video_ioctl2 if serialization lock can be removed */ + .unlocked_ioctl = cx18_v4l2_ioctl, .release = cx18_v4l2_close, .poll = cx18_v4l2_enc_poll, .mmap = cx18_v4l2_mmap, @@ -375,7 +376,6 @@ static int cx18_prep_dev(struct cx18 *cx, int type) s->video_dev->fops = &cx18_v4l2_enc_fops; s->video_dev->release = video_device_release; s->video_dev->tvnorms = V4L2_STD_ALL; - s->video_dev->lock = &cx->serialize_lock; set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags); cx18_set_funcs(s->video_dev); return 0; diff --git a/trunk/drivers/media/video/cx231xx/cx231xx-avcore.c b/trunk/drivers/media/video/cx231xx/cx231xx-avcore.c index 447148eff958..b085a3c6dc04 100644 --- a/trunk/drivers/media/video/cx231xx/cx231xx-avcore.c +++ b/trunk/drivers/media/video/cx231xx/cx231xx-avcore.c @@ -89,7 +89,7 @@ void initGPIO(struct cx231xx *dev) verve_read_byte(dev, 0x07, &val); cx231xx_info(" verve_read_byte address0x07=0x%x\n", val); - cx231xx_capture_start(dev, 1, Vbi); + cx231xx_capture_start(dev, 1, 2); cx231xx_mode_register(dev, EP_MODE_SET, 0x0500FE00); cx231xx_mode_register(dev, GBULK_BIT_EN, 0xFFFDFFFF); @@ -99,7 +99,7 @@ void uninitGPIO(struct cx231xx *dev) { u8 value[4] = { 0, 0, 0, 0 }; - cx231xx_capture_start(dev, 0, Vbi); + cx231xx_capture_start(dev, 0, 2); verve_write_byte(dev, 0x07, 0x14); cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, 0x68, value, 4); @@ -2516,29 +2516,29 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) if (dev->udev->speed == USB_SPEED_HIGH) { switch (media_type) { - case Audio: + case 81: /* audio */ cx231xx_info("%s: Audio enter HANC\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x9300); break; - case Vbi: + case 2: /* vbi */ cx231xx_info("%s: set vanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300); break; - case Sliced_cc: + case 3: /* sliced cc */ cx231xx_info("%s: set hanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x1300); break; - case Raw_Video: + case 0: /* video */ cx231xx_info("%s: set video registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); break; - case TS1_serial_mode: + case 4: /* ts1 */ cx231xx_info("%s: set ts1 registers", __func__); if (dev->board.has_417) { @@ -2569,7 +2569,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) } break; - case TS1_parallel_mode: + case 6: /* ts1 parallel mode */ cx231xx_info("%s: set ts1 parallel mode registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); @@ -2592,28 +2592,52 @@ int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type) /* get EP for media type */ pcb_config = (struct pcb_config *)&dev->current_pcb_config; - if (pcb_config->config_num) { + if (pcb_config->config_num == 1) { switch (media_type) { - case Raw_Video: + case 0: /* Video */ ep_mask = ENABLE_EP4; /* ep4 [00:1000] */ break; - case Audio: + case 1: /* Audio */ ep_mask = ENABLE_EP3; /* ep3 [00:0100] */ break; - case Vbi: + case 2: /* Vbi */ ep_mask = ENABLE_EP5; /* ep5 [01:0000] */ break; - case Sliced_cc: + case 3: /* Sliced_cc */ ep_mask = ENABLE_EP6; /* ep6 [10:0000] */ break; - case TS1_serial_mode: - case TS1_parallel_mode: + case 4: /* ts1 */ + case 6: /* ts1 parallel mode */ ep_mask = ENABLE_EP1; /* ep1 [00:0001] */ break; - case TS2: + case 5: /* ts2 */ ep_mask = ENABLE_EP2; /* ep2 [00:0010] */ break; } + + } else if (pcb_config->config_num > 1) { + switch (media_type) { + case 0: /* Video */ + ep_mask = ENABLE_EP4; /* ep4 [00:1000] */ + break; + case 1: /* Audio */ + ep_mask = ENABLE_EP3; /* ep3 [00:0100] */ + break; + case 2: /* Vbi */ + ep_mask = ENABLE_EP5; /* ep5 [01:0000] */ + break; + case 3: /* Sliced_cc */ + ep_mask = ENABLE_EP6; /* ep6 [10:0000] */ + break; + case 4: /* ts1 */ + case 6: /* ts1 parallel mode */ + ep_mask = ENABLE_EP1; /* ep1 [00:0001] */ + break; + case 5: /* ts2 */ + ep_mask = ENABLE_EP2; /* ep2 [00:0010] */ + break; + } + } if (start) { diff --git a/trunk/drivers/media/video/cx231xx/cx231xx-cards.c b/trunk/drivers/media/video/cx231xx/cx231xx-cards.c index 02d4d36735d3..8ed460d692e0 100644 --- a/trunk/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/trunk/drivers/media/video/cx231xx/cx231xx-cards.c @@ -1023,6 +1023,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, int nr = 0, ifnum; int i, isoc_pipe = 0; char *speed; + char descr[255] = ""; struct usb_interface_assoc_descriptor *assoc_desc; udev = usb_get_dev(interface_to_usbdev(interface)); @@ -1097,10 +1098,20 @@ static int cx231xx_usb_probe(struct usb_interface *interface, speed = "unknown"; } - cx231xx_info("New device %s %s @ %s Mbps " + if (udev->manufacturer) + strlcpy(descr, udev->manufacturer, sizeof(descr)); + + if (udev->product) { + if (*descr) + strlcat(descr, " ", sizeof(descr)); + strlcat(descr, udev->product, sizeof(descr)); + } + if (*descr) + strlcat(descr, " ", sizeof(descr)); + + cx231xx_info("New device %s@ %s Mbps " "(%04x:%04x) with %d interfaces\n", - udev->manufacturer ? udev->manufacturer : "", - udev->product ? udev->product : "", + descr, speed, le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), diff --git a/trunk/drivers/media/video/cx88/cx88-alsa.c b/trunk/drivers/media/video/cx88/cx88-alsa.c index dfac6e34859f..04bf6627d362 100644 --- a/trunk/drivers/media/video/cx88/cx88-alsa.c +++ b/trunk/drivers/media/video/cx88/cx88-alsa.c @@ -585,10 +585,13 @@ static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol, { snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core = chip->core; + struct v4l2_control client_ctl; int left = value->value.integer.value[0]; int right = value->value.integer.value[1]; int v, b; + memset(&client_ctl, 0, sizeof(client_ctl)); + /* Pass volume & balance onto any WM8775 */ if (left >= right) { v = left << 10; @@ -597,8 +600,13 @@ static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol, v = right << 10; b = right ? 0xffff - (0x8000 * left) / right : 0x8000; } - wm8775_s_ctrl(core, V4L2_CID_AUDIO_VOLUME, v); - wm8775_s_ctrl(core, V4L2_CID_AUDIO_BALANCE, b); + client_ctl.value = v; + client_ctl.id = V4L2_CID_AUDIO_VOLUME; + call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); + + client_ctl.value = b; + client_ctl.id = V4L2_CID_AUDIO_BALANCE; + call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); } /* OK - TODO: test it */ @@ -679,8 +687,14 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); /* Pass mute onto any WM8775 */ if ((core->board.audio_chip == V4L2_IDENT_WM8775) && - ((1<<6) == bit)) - wm8775_s_ctrl(core, V4L2_CID_AUDIO_MUTE, 0 != (vol & bit)); + ((1<<6) == bit)) { + struct v4l2_control client_ctl; + + memset(&client_ctl, 0, sizeof(client_ctl)); + client_ctl.value = 0 != (vol & bit); + client_ctl.id = V4L2_CID_AUDIO_MUTE; + call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); + } ret = 1; } spin_unlock_irq(&chip->reg_lock); @@ -710,10 +724,13 @@ static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol, { snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); struct cx88_core *core = chip->core; - s32 val; + struct v4l2_control client_ctl; + + memset(&client_ctl, 0, sizeof(client_ctl)); + client_ctl.id = V4L2_CID_AUDIO_LOUDNESS; + call_hw(core, WM8775_GID, core, g_ctrl, &client_ctl); + value->value.integer.value[0] = client_ctl.value ? 1 : 0; - val = wm8775_g_ctrl(core, V4L2_CID_AUDIO_LOUDNESS); - value->value.integer.value[0] = val ? 1 : 0; return 0; } diff --git a/trunk/drivers/media/video/cx88/cx88-blackbird.c b/trunk/drivers/media/video/cx88/cx88-blackbird.c index 843ffd9e533b..ed7b2aa1ed83 100644 --- a/trunk/drivers/media/video/cx88/cx88-blackbird.c +++ b/trunk/drivers/media/video/cx88/cx88-blackbird.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include "cx88.h" @@ -524,10 +523,11 @@ static void blackbird_codec_settings(struct cx8802_dev *dev) blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, dev->height, dev->width); - dev->cxhdl.width = dev->width; - dev->cxhdl.height = dev->height; - cx2341x_handler_set_50hz(&dev->cxhdl, dev->core->tvnorm & V4L2_STD_625_50); - cx2341x_handler_setup(&dev->cxhdl); + dev->params.width = dev->width; + dev->params.height = dev->height; + dev->params.is_50hz = (dev->core->tvnorm & V4L2_STD_625_50) != 0; + + cx2341x_update(dev, blackbird_mbox_func, NULL, &dev->params); } static int blackbird_initialize_codec(struct cx8802_dev *dev) @@ -618,8 +618,6 @@ static int blackbird_start_codec(struct file *file, void *priv) /* initialize the video input */ blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0); - cx2341x_handler_set_busy(&dev->cxhdl, 1); - /* start capturing to the host interface */ blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, BLACKBIRD_MPEG_CAPTURE, @@ -638,8 +636,6 @@ static int blackbird_stop_codec(struct cx8802_dev *dev) BLACKBIRD_RAW_BITS_NONE ); - cx2341x_handler_set_busy(&dev->cxhdl, 0); - dev->mpeg_active = 0; return 0; } @@ -689,15 +685,58 @@ static struct videobuf_queue_ops blackbird_qops = { /* ------------------------------------------------------------------ */ -static int vidioc_querycap(struct file *file, void *priv, +static const u32 *ctrl_classes[] = { + cx88_user_ctrls, + cx2341x_mpeg_ctrls, + NULL +}; + +static int blackbird_queryctrl(struct cx8802_dev *dev, struct v4l2_queryctrl *qctrl) +{ + qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); + if (qctrl->id == 0) + return -EINVAL; + + /* Standard V4L2 controls */ + if (cx8800_ctrl_query(dev->core, qctrl) == 0) + return 0; + + /* MPEG V4L2 controls */ + if (cx2341x_ctrl_query(&dev->params, qctrl)) + qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; + return 0; +} + +/* ------------------------------------------------------------------ */ +/* IOCTL Handlers */ + +static int vidioc_querymenu (struct file *file, void *priv, + struct v4l2_querymenu *qmenu) +{ + struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; + struct v4l2_queryctrl qctrl; + + qctrl.id = qmenu->id; + blackbird_queryctrl(dev, &qctrl); + return v4l2_ctrl_query_menu(qmenu, &qctrl, + cx2341x_ctrl_get_menu(&dev->params, qmenu->id)); +} + +static int vidioc_querycap (struct file *file, void *priv, struct v4l2_capability *cap) { struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; struct cx88_core *core = dev->core; strcpy(cap->driver, "cx88_blackbird"); - sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); - cx88_querycap(file, core, cap); + strlcpy(cap->card, core->board.name, sizeof(cap->card)); + sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); + cap->capabilities = + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING; + if (UNSET != core->board.tuner_type) + cap->capabilities |= V4L2_CAP_TUNER; return 0; } @@ -709,7 +748,6 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, strlcpy(f->description, "MPEG", sizeof(f->description)); f->pixelformat = V4L2_PIX_FMT_MPEG; - f->flags = V4L2_FMT_FLAG_COMPRESSED; return 0; } @@ -721,12 +759,12 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */; - f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */ + f->fmt.pix.colorspace = 0; f->fmt.pix.width = dev->width; f->fmt.pix.height = dev->height; f->fmt.pix.field = fh->mpegq.field; - dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", + dprintk(0,"VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", dev->width, dev->height, fh->mpegq.field ); return 0; } @@ -739,9 +777,9 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */; - f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", + f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */; + f->fmt.pix.colorspace = 0; + dprintk(0,"VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", dev->width, dev->height, fh->mpegq.field ); return 0; } @@ -755,15 +793,15 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */; - f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */; + f->fmt.pix.colorspace = 0; dev->width = f->fmt.pix.width; dev->height = f->fmt.pix.height; fh->mpegq.field = f->fmt.pix.field; cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, f->fmt.pix.height, f->fmt.pix.width); - dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", + dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field ); return 0; } @@ -796,21 +834,60 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p) static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { struct cx8802_fh *fh = priv; - struct cx8802_dev *dev = fh->dev; - - if (!dev->mpeg_active) - blackbird_start_codec(file, fh); return videobuf_streamon(&fh->mpegq); } static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) { struct cx8802_fh *fh = priv; - struct cx8802_dev *dev = fh->dev; + return videobuf_streamoff(&fh->mpegq); +} + +static int vidioc_g_ext_ctrls (struct file *file, void *priv, + struct v4l2_ext_controls *f) +{ + struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; + + if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + return cx2341x_ext_ctrls(&dev->params, 0, f, VIDIOC_G_EXT_CTRLS); +} + +static int vidioc_s_ext_ctrls (struct file *file, void *priv, + struct v4l2_ext_controls *f) +{ + struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; + struct cx2341x_mpeg_params p; + int err; + + if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; if (dev->mpeg_active) blackbird_stop_codec(dev); - return videobuf_streamoff(&fh->mpegq); + + p = dev->params; + err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS); + if (!err) { + err = cx2341x_update(dev, blackbird_mbox_func, &dev->params, &p); + dev->params = p; + } + return err; +} + +static int vidioc_try_ext_ctrls (struct file *file, void *priv, + struct v4l2_ext_controls *f) +{ + struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; + struct cx2341x_mpeg_params p; + int err; + + if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + p = dev->params; + err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS); + + return err; } static int vidioc_s_frequency (struct file *file, void *priv, @@ -820,10 +897,6 @@ static int vidioc_s_frequency (struct file *file, void *priv, struct cx8802_dev *dev = fh->dev; struct cx88_core *core = dev->core; - if (unlikely(UNSET == core->board.tuner_type)) - return -EINVAL; - if (unlikely(f->tuner != 0)) - return -EINVAL; if (dev->mpeg_active) blackbird_stop_codec(dev); @@ -841,11 +914,29 @@ static int vidioc_log_status (struct file *file, void *priv) char name[32 + 2]; snprintf(name, sizeof(name), "%s/2", core->name); + printk("%s/2: ============ START LOG STATUS ============\n", + core->name); call_all(core, core, log_status); - v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, name); + cx2341x_log_status(&dev->params, name); + printk("%s/2: ============= END LOG STATUS =============\n", + core->name); return 0; } +static int vidioc_queryctrl (struct file *file, void *priv, + struct v4l2_queryctrl *qctrl) +{ + struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; + + if (blackbird_queryctrl(dev, qctrl) == 0) + return 0; + + qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); + if (unlikely(qctrl->id == 0)) + return -EINVAL; + return cx8800_ctrl_query(dev->core, qctrl); +} + static int vidioc_enum_input (struct file *file, void *priv, struct v4l2_input *i) { @@ -853,6 +944,22 @@ static int vidioc_enum_input (struct file *file, void *priv, return cx88_enum_input (core,i); } +static int vidioc_g_ctrl (struct file *file, void *priv, + struct v4l2_control *ctl) +{ + struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; + return + cx88_get_control(core,ctl); +} + +static int vidioc_s_ctrl (struct file *file, void *priv, + struct v4l2_control *ctl) +{ + struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; + return + cx88_set_control(core,ctl); +} + static int vidioc_g_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { @@ -861,9 +968,8 @@ static int vidioc_g_frequency (struct file *file, void *priv, if (unlikely(UNSET == core->board.tuner_type)) return -EINVAL; - if (unlikely(f->tuner != 0)) - return -EINVAL; + f->type = V4L2_TUNER_ANALOG_TV; f->frequency = core->freq; call_all(core, tuner, g_frequency, f); @@ -884,8 +990,6 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i) if (i >= 4) return -EINVAL; - if (0 == INPUT(i).type) - return -EINVAL; mutex_lock(&core->lock); cx88_newstation(core); @@ -906,9 +1010,9 @@ static int vidioc_g_tuner (struct file *file, void *priv, return -EINVAL; strcpy(t->name, "Television"); + t->type = V4L2_TUNER_ANALOG_TV; t->capability = V4L2_TUNER_CAP_NORM; t->rangehigh = 0xffffffffUL; - call_all(core, tuner, g_tuner, t); cx88_get_stereo(core ,t); reg = cx_read(MO_DEVICE_STATUS); @@ -930,14 +1034,6 @@ static int vidioc_s_tuner (struct file *file, void *priv, return 0; } -static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm) -{ - struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; - - *tvnorm = core->tvnorm; - return 0; -} - static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) { struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; @@ -991,7 +1087,6 @@ static int mpeg_open(struct file *file) mutex_unlock(&dev->core->lock); return -ENOMEM; } - v4l2_fh_init(&fh->fh, vdev); file->private_data = fh; fh->dev = dev; @@ -1008,7 +1103,6 @@ static int mpeg_open(struct file *file) dev->core->mpeg_users++; mutex_unlock(&dev->core->lock); - v4l2_fh_add(&fh->fh); return 0; } @@ -1029,8 +1123,6 @@ static int mpeg_release(struct file *file) videobuf_mmap_free(&fh->mpegq); - v4l2_fh_del(&fh->fh); - v4l2_fh_exit(&fh->fh); file->private_data = NULL; kfree(fh); @@ -1063,14 +1155,13 @@ mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos) static unsigned int mpeg_poll(struct file *file, struct poll_table_struct *wait) { - unsigned long req_events = poll_requested_events(wait); struct cx8802_fh *fh = file->private_data; struct cx8802_dev *dev = fh->dev; - if (!dev->mpeg_active && (req_events & (POLLIN | POLLRDNORM))) + if (!dev->mpeg_active) blackbird_start_codec(file, fh); - return v4l2_ctrl_poll(file, wait) | videobuf_poll_stream(file, &fh->mpegq, wait); + return videobuf_poll_stream(file, &fh->mpegq, wait); } static int @@ -1089,10 +1180,11 @@ static const struct v4l2_file_operations mpeg_fops = .read = mpeg_read, .poll = mpeg_poll, .mmap = mpeg_mmap, - .unlocked_ioctl = video_ioctl2, + .ioctl = video_ioctl2, }; static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { + .vidioc_querymenu = vidioc_querymenu, .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1104,18 +1196,21 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_dqbuf = vidioc_dqbuf, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, + .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, + .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, + .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, .vidioc_s_frequency = vidioc_s_frequency, .vidioc_log_status = vidioc_log_status, + .vidioc_queryctrl = vidioc_queryctrl, .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_std = vidioc_g_std, .vidioc_s_std = vidioc_s_std, - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device cx8802_mpeg_template = { @@ -1123,6 +1218,7 @@ static struct video_device cx8802_mpeg_template = { .fops = &mpeg_fops, .ioctl_ops = &mpeg_ioctl_ops, .tvnorms = CX88_NORMS, + .current_norm = V4L2_STD_NTSC_M, }; /* ------------------------------------------------------------------ */ @@ -1190,7 +1286,6 @@ static int blackbird_register_video(struct cx8802_dev *dev) dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci, &cx8802_mpeg_template,"mpeg"); - dev->mpeg_dev->ctrl_handler = &dev->cxhdl.hdl; video_set_drvdata(dev->mpeg_dev, dev); err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1); if (err < 0) { @@ -1223,20 +1318,17 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) goto fail_core; dev->width = 720; + dev->height = 576; + cx2341x_fill_defaults(&dev->params); + dev->params.port = CX2341X_PORT_STREAMING; + + cx8802_mpeg_template.current_norm = core->tvnorm; + if (core->tvnorm & V4L2_STD_525_60) { dev->height = 480; } else { dev->height = 576; } - dev->cxhdl.port = CX2341X_PORT_STREAMING; - dev->cxhdl.width = dev->width; - dev->cxhdl.height = dev->height; - dev->cxhdl.func = blackbird_mbox_func; - dev->cxhdl.priv = dev; - err = cx2341x_handler_init(&dev->cxhdl, 36); - if (err) - goto fail_core; - v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl); /* blackbird stuff */ printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n", @@ -1244,14 +1336,12 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) host_setup(dev->core); blackbird_initialize_codec(dev); + blackbird_register_video(dev); /* initial device configuration: needed ? */ // init_controls(core); cx88_set_tvnorm(core,core->tvnorm); cx88_video_mux(core,0); - cx2341x_handler_set_50hz(&dev->cxhdl, dev->height == 576); - cx2341x_handler_setup(&dev->cxhdl); - blackbird_register_video(dev); return 0; @@ -1261,12 +1351,8 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) static int cx8802_blackbird_remove(struct cx8802_driver *drv) { - struct cx88_core *core = drv->core; - struct cx8802_dev *dev = core->dvbdev; - /* blackbird */ blackbird_unregister_video(drv->core->dvbdev); - v4l2_ctrl_handler_free(&dev->cxhdl.hdl); return 0; } diff --git a/trunk/drivers/media/video/cx88/cx88-cards.c b/trunk/drivers/media/video/cx88/cx88-cards.c index 4e9d4f722960..cbd5d119a2c6 100644 --- a/trunk/drivers/media/video/cx88/cx88-cards.c +++ b/trunk/drivers/media/video/cx88/cx88-cards.c @@ -3693,22 +3693,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) return NULL; } - if (v4l2_ctrl_handler_init(&core->video_hdl, 13)) { - v4l2_device_unregister(&core->v4l2_dev); - kfree(core); - return NULL; - } - - if (v4l2_ctrl_handler_init(&core->audio_hdl, 13)) { - v4l2_ctrl_handler_free(&core->video_hdl); - v4l2_device_unregister(&core->v4l2_dev); - kfree(core); - return NULL; - } - if (0 != cx88_get_resources(core, pci)) { - v4l2_ctrl_handler_free(&core->video_hdl); - v4l2_ctrl_handler_free(&core->audio_hdl); v4l2_device_unregister(&core->v4l2_dev); kfree(core); return NULL; @@ -3721,11 +3706,6 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) core->bmmio = (u8 __iomem *)core->lmmio; if (core->lmmio == NULL) { - release_mem_region(pci_resource_start(pci, 0), - pci_resource_len(pci, 0)); - v4l2_ctrl_handler_free(&core->video_hdl); - v4l2_ctrl_handler_free(&core->audio_hdl); - v4l2_device_unregister(&core->v4l2_dev); kfree(core); return NULL; } diff --git a/trunk/drivers/media/video/cx88/cx88-core.c b/trunk/drivers/media/video/cx88/cx88-core.c index e81c735f012a..fbfdd8067937 100644 --- a/trunk/drivers/media/video/cx88/cx88-core.c +++ b/trunk/drivers/media/video/cx88/cx88-core.c @@ -1012,9 +1012,6 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) // tell i2c chips call_all(core, core, s_std, norm); - /* The chroma_agc control should be inaccessible if the video format is SECAM */ - v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM); - // done return 0; } @@ -1033,10 +1030,10 @@ struct video_device *cx88_vdev_init(struct cx88_core *core, return NULL; *vfd = *template_; vfd->v4l2_dev = &core->v4l2_dev; + vfd->parent = &pci->dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", core->name, type, core->board.name); - set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); return vfd; } @@ -1089,8 +1086,6 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) iounmap(core->lmmio); cx88_devcount--; mutex_unlock(&devlist); - v4l2_ctrl_handler_free(&core->video_hdl); - v4l2_ctrl_handler_free(&core->audio_hdl); v4l2_device_unregister(&core->v4l2_dev); kfree(core); } diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index f6fcc7e763ab..921c56d115d6 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -40,7 +40,6 @@ #include "cx88.h" #include #include -#include #include MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); @@ -156,147 +155,219 @@ static const struct cx8800_fmt* format_by_fourcc(unsigned int fourcc) /* ------------------------------------------------------------------- */ -struct cx88_ctrl { - /* control information */ - u32 id; - s32 minimum; - s32 maximum; - u32 step; - s32 default_value; - - /* control register information */ - u32 off; - u32 reg; - u32 sreg; - u32 mask; - u32 shift; +static const struct v4l2_queryctrl no_ctl = { + .name = "42", + .flags = V4L2_CTRL_FLAG_DISABLED, }; -static const struct cx88_ctrl cx8800_vid_ctls[] = { +static const struct cx88_ctrl cx8800_ctls[] = { /* --- video --- */ { - .id = V4L2_CID_BRIGHTNESS, - .minimum = 0x00, - .maximum = 0xff, - .step = 1, - .default_value = 0x7f, - .off = 128, - .reg = MO_CONTR_BRIGHT, - .mask = 0x00ff, - .shift = 0, + .v = { + .id = V4L2_CID_BRIGHTNESS, + .name = "Brightness", + .minimum = 0x00, + .maximum = 0xff, + .step = 1, + .default_value = 0x7f, + .type = V4L2_CTRL_TYPE_INTEGER, + }, + .off = 128, + .reg = MO_CONTR_BRIGHT, + .mask = 0x00ff, + .shift = 0, },{ - .id = V4L2_CID_CONTRAST, - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x3f, - .off = 0, - .reg = MO_CONTR_BRIGHT, - .mask = 0xff00, - .shift = 8, + .v = { + .id = V4L2_CID_CONTRAST, + .name = "Contrast", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0x3f, + .type = V4L2_CTRL_TYPE_INTEGER, + }, + .off = 0, + .reg = MO_CONTR_BRIGHT, + .mask = 0xff00, + .shift = 8, },{ - .id = V4L2_CID_HUE, - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x7f, - .off = 128, - .reg = MO_HUE, - .mask = 0x00ff, - .shift = 0, + .v = { + .id = V4L2_CID_HUE, + .name = "Hue", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0x7f, + .type = V4L2_CTRL_TYPE_INTEGER, + }, + .off = 128, + .reg = MO_HUE, + .mask = 0x00ff, + .shift = 0, },{ /* strictly, this only describes only U saturation. * V saturation is handled specially through code. */ - .id = V4L2_CID_SATURATION, - .minimum = 0, - .maximum = 0xff, - .step = 1, - .default_value = 0x7f, - .off = 0, - .reg = MO_UV_SATURATION, - .mask = 0x00ff, - .shift = 0, + .v = { + .id = V4L2_CID_SATURATION, + .name = "Saturation", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0x7f, + .type = V4L2_CTRL_TYPE_INTEGER, + }, + .off = 0, + .reg = MO_UV_SATURATION, + .mask = 0x00ff, + .shift = 0, }, { - .id = V4L2_CID_SHARPNESS, - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0x0, - .off = 0, + .v = { + .id = V4L2_CID_SHARPNESS, + .name = "Sharpness", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0x0, + .type = V4L2_CTRL_TYPE_INTEGER, + }, + .off = 0, /* NOTE: the value is converted and written to both even and odd registers in the code */ - .reg = MO_FILTER_ODD, - .mask = 7 << 7, - .shift = 7, + .reg = MO_FILTER_ODD, + .mask = 7 << 7, + .shift = 7, }, { - .id = V4L2_CID_CHROMA_AGC, - .minimum = 0, - .maximum = 1, - .default_value = 0x1, - .reg = MO_INPUT_FORMAT, - .mask = 1 << 10, - .shift = 10, + .v = { + .id = V4L2_CID_CHROMA_AGC, + .name = "Chroma AGC", + .minimum = 0, + .maximum = 1, + .default_value = 0x1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + }, + .reg = MO_INPUT_FORMAT, + .mask = 1 << 10, + .shift = 10, }, { - .id = V4L2_CID_COLOR_KILLER, - .minimum = 0, - .maximum = 1, - .default_value = 0x1, - .reg = MO_INPUT_FORMAT, - .mask = 1 << 9, - .shift = 9, + .v = { + .id = V4L2_CID_COLOR_KILLER, + .name = "Color killer", + .minimum = 0, + .maximum = 1, + .default_value = 0x1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + }, + .reg = MO_INPUT_FORMAT, + .mask = 1 << 9, + .shift = 9, }, { - .id = V4L2_CID_BAND_STOP_FILTER, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0x0, - .off = 0, - .reg = MO_HTOTAL, - .mask = 3 << 11, - .shift = 11, - } -}; - -static const struct cx88_ctrl cx8800_aud_ctls[] = { - { - /* --- audio --- */ - .id = V4L2_CID_AUDIO_MUTE, - .minimum = 0, - .maximum = 1, - .default_value = 1, - .reg = AUD_VOL_CTL, - .sreg = SHADOW_AUD_VOL_CTL, - .mask = (1 << 6), - .shift = 6, + .v = { + .id = V4L2_CID_BAND_STOP_FILTER, + .name = "Notch filter", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0x0, + .type = V4L2_CTRL_TYPE_INTEGER, + }, + .off = 0, + .reg = MO_HTOTAL, + .mask = 3 << 11, + .shift = 11, + }, { + /* --- audio --- */ + .v = { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + }, + .reg = AUD_VOL_CTL, + .sreg = SHADOW_AUD_VOL_CTL, + .mask = (1 << 6), + .shift = 6, },{ - .id = V4L2_CID_AUDIO_VOLUME, - .minimum = 0, - .maximum = 0x3f, - .step = 1, - .default_value = 0x3f, - .reg = AUD_VOL_CTL, - .sreg = SHADOW_AUD_VOL_CTL, - .mask = 0x3f, - .shift = 0, + .v = { + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 0x3f, + .step = 1, + .default_value = 0x3f, + .type = V4L2_CTRL_TYPE_INTEGER, + }, + .reg = AUD_VOL_CTL, + .sreg = SHADOW_AUD_VOL_CTL, + .mask = 0x3f, + .shift = 0, },{ - .id = V4L2_CID_AUDIO_BALANCE, - .minimum = 0, - .maximum = 0x7f, - .step = 1, - .default_value = 0x40, - .reg = AUD_BAL_CTL, - .sreg = SHADOW_AUD_BAL_CTL, - .mask = 0x7f, - .shift = 0, + .v = { + .id = V4L2_CID_AUDIO_BALANCE, + .name = "Balance", + .minimum = 0, + .maximum = 0x7f, + .step = 1, + .default_value = 0x40, + .type = V4L2_CTRL_TYPE_INTEGER, + }, + .reg = AUD_BAL_CTL, + .sreg = SHADOW_AUD_BAL_CTL, + .mask = 0x7f, + .shift = 0, } }; +enum { CX8800_CTLS = ARRAY_SIZE(cx8800_ctls) }; + +/* Must be sorted from low to high control ID! */ +const u32 cx88_user_ctrls[] = { + V4L2_CID_USER_CLASS, + V4L2_CID_BRIGHTNESS, + V4L2_CID_CONTRAST, + V4L2_CID_SATURATION, + V4L2_CID_HUE, + V4L2_CID_AUDIO_VOLUME, + V4L2_CID_AUDIO_BALANCE, + V4L2_CID_AUDIO_MUTE, + V4L2_CID_SHARPNESS, + V4L2_CID_CHROMA_AGC, + V4L2_CID_COLOR_KILLER, + V4L2_CID_BAND_STOP_FILTER, + 0 +}; +EXPORT_SYMBOL(cx88_user_ctrls); -enum { - CX8800_VID_CTLS = ARRAY_SIZE(cx8800_vid_ctls), - CX8800_AUD_CTLS = ARRAY_SIZE(cx8800_aud_ctls), +static const u32 * const ctrl_classes[] = { + cx88_user_ctrls, + NULL }; +int cx8800_ctrl_query(struct cx88_core *core, struct v4l2_queryctrl *qctrl) +{ + int i; + + if (qctrl->id < V4L2_CID_BASE || + qctrl->id >= V4L2_CID_LASTP1) + return -EINVAL; + for (i = 0; i < CX8800_CTLS; i++) + if (cx8800_ctls[i].v.id == qctrl->id) + break; + if (i == CX8800_CTLS) { + *qctrl = no_ctl; + return 0; + } + *qctrl = cx8800_ctls[i].v; + /* Report chroma AGC as inactive when SECAM is selected */ + if (cx8800_ctls[i].v.id == V4L2_CID_CHROMA_AGC && + core->tvnorm & V4L2_STD_SECAM) + qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; + + return 0; +} +EXPORT_SYMBOL(cx8800_ctrl_query); + /* ------------------------------------------------------------------- */ /* resource management */ @@ -520,9 +591,8 @@ static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) { struct cx8800_fh *fh = q->priv_data; - struct cx8800_dev *dev = fh->dev; - *size = dev->fmt->depth * dev->width * dev->height >> 3; + *size = fh->fmt->depth*fh->width*fh->height >> 3; if (0 == *count) *count = 32; if (*size * *count > vid_limit * 1024 * 1024) @@ -541,21 +611,21 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); int rc, init_buffer = 0; - BUG_ON(NULL == dev->fmt); - if (dev->width < 48 || dev->width > norm_maxw(core->tvnorm) || - dev->height < 32 || dev->height > norm_maxh(core->tvnorm)) + BUG_ON(NULL == fh->fmt); + if (fh->width < 48 || fh->width > norm_maxw(core->tvnorm) || + fh->height < 32 || fh->height > norm_maxh(core->tvnorm)) return -EINVAL; - buf->vb.size = (dev->width * dev->height * dev->fmt->depth) >> 3; + buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) return -EINVAL; - if (buf->fmt != dev->fmt || - buf->vb.width != dev->width || - buf->vb.height != dev->height || + if (buf->fmt != fh->fmt || + buf->vb.width != fh->width || + buf->vb.height != fh->height || buf->vb.field != field) { - buf->fmt = dev->fmt; - buf->vb.width = dev->width; - buf->vb.height = dev->height; + buf->fmt = fh->fmt; + buf->vb.width = fh->width; + buf->vb.height = fh->height; buf->vb.field = field; init_buffer = 1; } @@ -605,7 +675,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, } dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", buf, buf->vb.i, - dev->width, dev->height, dev->fmt->depth, dev->fmt->name, + fh->width, fh->height, fh->fmt->depth, fh->fmt->name, (unsigned long)buf->risc.dma); buf->vb.state = VIDEOBUF_PREPARED; @@ -685,15 +755,12 @@ static const struct videobuf_queue_ops cx8800_video_qops = { /* ------------------------------------------------------------------ */ -static struct videobuf_queue *get_queue(struct file *file) +static struct videobuf_queue* get_queue(struct cx8800_fh *fh) { - struct video_device *vdev = video_devdata(file); - struct cx8800_fh *fh = file->private_data; - - switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: + switch (fh->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: return &fh->vidq; - case VFL_TYPE_VBI: + case V4L2_BUF_TYPE_VBI_CAPTURE: return &fh->vbiq; default: BUG(); @@ -701,14 +768,12 @@ static struct videobuf_queue *get_queue(struct file *file) } } -static int get_resource(struct file *file) +static int get_ressource(struct cx8800_fh *fh) { - struct video_device *vdev = video_devdata(file); - - switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: + switch (fh->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: return RESOURCE_VIDEO; - case VFL_TYPE_VBI: + case V4L2_BUF_TYPE_VBI_CAPTURE: return RESOURCE_VBI; default: BUG(); @@ -745,9 +810,13 @@ static int video_open(struct file *file) if (unlikely(!fh)) return -ENOMEM; - v4l2_fh_init(&fh->fh, vdev); file->private_data = fh; fh->dev = dev; + fh->radio = radio; + fh->type = type; + fh->width = 320; + fh->height = 240; + fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); mutex_lock(&core->lock); @@ -764,7 +833,7 @@ static int video_open(struct file *file) sizeof(struct cx88_buffer), fh, NULL); - if (vdev->vfl_type == VFL_TYPE_RADIO) { + if (fh->radio) { dprintk(1,"video_open: setting radio device\n"); cx_write(MO_GP3_IO, core->board.radio.gpio3); cx_write(MO_GP0_IO, core->board.radio.gpio0); @@ -790,7 +859,6 @@ static int video_open(struct file *file) core->users++; mutex_unlock(&core->lock); - v4l2_fh_add(&fh->fh); return 0; } @@ -798,16 +866,15 @@ static int video_open(struct file *file) static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { - struct video_device *vdev = video_devdata(file); struct cx8800_fh *fh = file->private_data; - switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: + switch (fh->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (res_locked(fh->dev,RESOURCE_VIDEO)) return -EBUSY; return videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK); - case VFL_TYPE_VBI: + case V4L2_BUF_TYPE_VBI_CAPTURE: if (!res_get(fh->dev,fh,RESOURCE_VBI)) return -EBUSY; return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1, @@ -821,16 +888,16 @@ video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) static unsigned int video_poll(struct file *file, struct poll_table_struct *wait) { - struct video_device *vdev = video_devdata(file); struct cx8800_fh *fh = file->private_data; struct cx88_buffer *buf; - unsigned int rc = v4l2_ctrl_poll(file, wait); + unsigned int rc = POLLERR; - if (vdev->vfl_type == VFL_TYPE_VBI) { + if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { if (!res_get(fh->dev,fh,RESOURCE_VBI)) - return rc | POLLERR; - return rc | videobuf_poll_stream(file, &fh->vbiq, wait); + return POLLERR; + return videobuf_poll_stream(file, &fh->vbiq, wait); } + mutex_lock(&fh->vidq.vb_lock); if (res_check(fh,RESOURCE_VIDEO)) { /* streaming capture */ @@ -846,7 +913,9 @@ video_poll(struct file *file, struct poll_table_struct *wait) poll_wait(file, &buf->vb.done, wait); if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) - rc |= POLLIN|POLLRDNORM; + rc = POLLIN|POLLRDNORM; + else + rc = 0; done: mutex_unlock(&fh->vidq.vb_lock); return rc; @@ -883,8 +952,6 @@ static int video_release(struct file *file) videobuf_mmap_free(&fh->vbiq); mutex_lock(&dev->core->lock); - v4l2_fh_del(&fh->fh); - v4l2_fh_exit(&fh->fh); file->private_data = NULL; kfree(fh); @@ -899,104 +966,156 @@ static int video_release(struct file *file) static int video_mmap(struct file *file, struct vm_area_struct * vma) { - return videobuf_mmap_mapper(get_queue(file), vma); + struct cx8800_fh *fh = file->private_data; + + return videobuf_mmap_mapper(get_queue(fh), vma); } /* ------------------------------------------------------------------ */ /* VIDEO CTRL IOCTLS */ -static int cx8800_s_vid_ctrl(struct v4l2_ctrl *ctrl) +int cx88_get_control (struct cx88_core *core, struct v4l2_control *ctl) { - struct cx88_core *core = - container_of(ctrl->handler, struct cx88_core, video_hdl); - const struct cx88_ctrl *cc = ctrl->priv; - u32 value, mask; - - mask = cc->mask; - switch (ctrl->id) { - case V4L2_CID_SATURATION: - /* special v_sat handling */ + const struct cx88_ctrl *c = NULL; + u32 value; + int i; - value = ((ctrl->val - cc->off) << cc->shift) & cc->mask; + for (i = 0; i < CX8800_CTLS; i++) + if (cx8800_ctls[i].v.id == ctl->id) + c = &cx8800_ctls[i]; + if (unlikely(NULL == c)) + return -EINVAL; - if (core->tvnorm & V4L2_STD_SECAM) { - /* For SECAM, both U and V sat should be equal */ - value = value << 8 | value; - } else { - /* Keeps U Saturation proportional to V Sat */ - value = (value * 0x5a) / 0x7f << 8 | value; - } - mask = 0xffff; + value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg); + switch (ctl->id) { + case V4L2_CID_AUDIO_BALANCE: + ctl->value = ((value & 0x7f) < 0x40) ? ((value & 0x7f) + 0x40) + : (0x7f - (value & 0x7f)); break; - case V4L2_CID_SHARPNESS: - /* 0b000, 0b100, 0b101, 0b110, or 0b111 */ - value = (ctrl->val < 1 ? 0 : ((ctrl->val + 3) << 7)); - /* needs to be set for both fields */ - cx_andor(MO_FILTER_EVEN, mask, value); + case V4L2_CID_AUDIO_VOLUME: + ctl->value = 0x3f - (value & 0x3f); break; - case V4L2_CID_CHROMA_AGC: - value = ((ctrl->val - cc->off) << cc->shift) & cc->mask; + case V4L2_CID_SHARPNESS: + ctl->value = ((value & 0x0200) ? (((value & 0x0180) >> 7) + 1) + : 0); break; default: - value = ((ctrl->val - cc->off) << cc->shift) & cc->mask; + ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; break; } - dprintk(1, "set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", - ctrl->id, ctrl->name, ctrl->val, cc->reg, value, - mask, cc->sreg ? " [shadowed]" : ""); - if (cc->sreg) - cx_sandor(cc->sreg, cc->reg, mask, value); - else - cx_andor(cc->reg, mask, value); + dprintk(1,"get_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", + ctl->id, c->v.name, ctl->value, c->reg, + value,c->mask, c->sreg ? " [shadowed]" : ""); return 0; } +EXPORT_SYMBOL(cx88_get_control); -static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl) +int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl) { - struct cx88_core *core = - container_of(ctrl->handler, struct cx88_core, audio_hdl); - const struct cx88_ctrl *cc = ctrl->priv; + const struct cx88_ctrl *c = NULL; u32 value,mask; + int i; + + for (i = 0; i < CX8800_CTLS; i++) { + if (cx8800_ctls[i].v.id == ctl->id) { + c = &cx8800_ctls[i]; + } + } + if (unlikely(NULL == c)) + return -EINVAL; + + if (ctl->value < c->v.minimum) + ctl->value = c->v.minimum; + if (ctl->value > c->v.maximum) + ctl->value = c->v.maximum; /* Pass changes onto any WM8775 */ if (core->board.audio_chip == V4L2_IDENT_WM8775) { - switch (ctrl->id) { + struct v4l2_control client_ctl; + memset(&client_ctl, 0, sizeof(client_ctl)); + client_ctl.id = ctl->id; + + switch (ctl->id) { case V4L2_CID_AUDIO_MUTE: - wm8775_s_ctrl(core, ctrl->id, ctrl->val); + client_ctl.value = ctl->value; break; case V4L2_CID_AUDIO_VOLUME: - wm8775_s_ctrl(core, ctrl->id, (ctrl->val) ? - (0x90 + ctrl->val) << 8 : 0); + client_ctl.value = (ctl->value) ? + (0x90 + ctl->value) << 8 : 0; break; case V4L2_CID_AUDIO_BALANCE: - wm8775_s_ctrl(core, ctrl->id, ctrl->val << 9); + client_ctl.value = ctl->value << 9; break; default: + client_ctl.id = 0; break; } + if (client_ctl.id) + call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); } - mask = cc->mask; - switch (ctrl->id) { + mask=c->mask; + switch (ctl->id) { case V4L2_CID_AUDIO_BALANCE: - value = (ctrl->val < 0x40) ? (0x7f - ctrl->val) : (ctrl->val - 0x40); + value = (ctl->value < 0x40) ? (0x7f - ctl->value) : (ctl->value - 0x40); break; case V4L2_CID_AUDIO_VOLUME: - value = 0x3f - (ctrl->val & 0x3f); + value = 0x3f - (ctl->value & 0x3f); + break; + case V4L2_CID_SATURATION: + /* special v_sat handling */ + + value = ((ctl->value - c->off) << c->shift) & c->mask; + + if (core->tvnorm & V4L2_STD_SECAM) { + /* For SECAM, both U and V sat should be equal */ + value=value<<8|value; + } else { + /* Keeps U Saturation proportional to V Sat */ + value=(value*0x5a)/0x7f<<8|value; + } + mask=0xffff; + break; + case V4L2_CID_SHARPNESS: + /* 0b000, 0b100, 0b101, 0b110, or 0b111 */ + value = (ctl->value < 1 ? 0 : ((ctl->value + 3) << 7)); + /* needs to be set for both fields */ + cx_andor(MO_FILTER_EVEN, mask, value); + break; + case V4L2_CID_CHROMA_AGC: + /* Do not allow chroma AGC to be enabled for SECAM */ + value = ((ctl->value - c->off) << c->shift) & c->mask; + if (core->tvnorm & V4L2_STD_SECAM && value) + return -EINVAL; break; default: - value = ((ctrl->val - cc->off) << cc->shift) & cc->mask; + value = ((ctl->value - c->off) << c->shift) & c->mask; break; } dprintk(1,"set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", - ctrl->id, ctrl->name, ctrl->val, cc->reg, value, - mask, cc->sreg ? " [shadowed]" : ""); - if (cc->sreg) - cx_sandor(cc->sreg, cc->reg, mask, value); - else - cx_andor(cc->reg, mask, value); + ctl->id, c->v.name, ctl->value, c->reg, value, + mask, c->sreg ? " [shadowed]" : ""); + if (c->sreg) { + cx_sandor(c->sreg, c->reg, mask, value); + } else { + cx_andor(c->reg, mask, value); + } return 0; } +EXPORT_SYMBOL(cx88_set_control); + +static void init_controls(struct cx88_core *core) +{ + struct v4l2_control ctrl; + int i; + + for (i = 0; i < CX8800_CTLS; i++) { + ctrl.id=cx8800_ctls[i].v.id; + ctrl.value=cx8800_ctls[i].v.default_value; + + cx88_set_control(core, &ctrl); + } +} /* ------------------------------------------------------------------ */ /* VIDEO IOCTLS */ @@ -1005,17 +1124,15 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx8800_fh *fh = priv; - struct cx8800_dev *dev = fh->dev; - f->fmt.pix.width = dev->width; - f->fmt.pix.height = dev->height; + f->fmt.pix.width = fh->width; + f->fmt.pix.height = fh->height; f->fmt.pix.field = fh->vidq.field; - f->fmt.pix.pixelformat = dev->fmt->fourcc; + f->fmt.pix.pixelformat = fh->fmt->fourcc; f->fmt.pix.bytesperline = - (f->fmt.pix.width * dev->fmt->depth) >> 3; + (f->fmt.pix.width * fh->fmt->depth) >> 3; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; - f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; } @@ -1067,54 +1184,33 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx8800_fh *fh = priv; - struct cx8800_dev *dev = fh->dev; int err = vidioc_try_fmt_vid_cap (file,priv,f); if (0 != err) return err; - dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); - dev->width = f->fmt.pix.width; - dev->height = f->fmt.pix.height; + fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); + fh->width = f->fmt.pix.width; + fh->height = f->fmt.pix.height; fh->vidq.field = f->fmt.pix.field; return 0; } -void cx88_querycap(struct file *file, struct cx88_core *core, - struct v4l2_capability *cap) -{ - struct video_device *vdev = video_devdata(file); - - strlcpy(cap->card, core->board.name, sizeof(cap->card)); - cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - if (UNSET != core->board.tuner_type) - cap->device_caps |= V4L2_CAP_TUNER; - switch (vdev->vfl_type) { - case VFL_TYPE_RADIO: - cap->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER; - break; - case VFL_TYPE_GRABBER: - cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; - break; - case VFL_TYPE_VBI: - cap->device_caps |= V4L2_CAP_VBI_CAPTURE; - break; - } - cap->capabilities = cap->device_caps | V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_VBI_CAPTURE | V4L2_CAP_DEVICE_CAPS; - if (core->board.radio.type == CX88_RADIO) - cap->capabilities |= V4L2_CAP_RADIO; -} -EXPORT_SYMBOL(cx88_querycap); - -static int vidioc_querycap(struct file *file, void *priv, +static int vidioc_querycap (struct file *file, void *priv, struct v4l2_capability *cap) { struct cx8800_dev *dev = ((struct cx8800_fh *)priv)->dev; struct cx88_core *core = dev->core; strcpy(cap->driver, "cx8800"); - sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); - cx88_querycap(file, core, cap); + strlcpy(cap->card, core->board.name, sizeof(cap->card)); + sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); + cap->capabilities = + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING | + V4L2_CAP_VBI_CAPTURE; + if (UNSET != core->board.tuner_type) + cap->capabilities |= V4L2_CAP_TUNER; return 0; } @@ -1132,67 +1228,69 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p) { - return videobuf_reqbufs(get_queue(file), p); + struct cx8800_fh *fh = priv; + return (videobuf_reqbufs(get_queue(fh), p)); } static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p) { - return videobuf_querybuf(get_queue(file), p); + struct cx8800_fh *fh = priv; + return (videobuf_querybuf(get_queue(fh), p)); } static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p) { - return videobuf_qbuf(get_queue(file), p); + struct cx8800_fh *fh = priv; + return (videobuf_qbuf(get_queue(fh), p)); } static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p) { - return videobuf_dqbuf(get_queue(file), p, - file->f_flags & O_NONBLOCK); + struct cx8800_fh *fh = priv; + return (videobuf_dqbuf(get_queue(fh), p, + file->f_flags & O_NONBLOCK)); } static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { - struct video_device *vdev = video_devdata(file); struct cx8800_fh *fh = priv; struct cx8800_dev *dev = fh->dev; - if ((vdev->vfl_type == VFL_TYPE_GRABBER && i != V4L2_BUF_TYPE_VIDEO_CAPTURE) || - (vdev->vfl_type == VFL_TYPE_VBI && i != V4L2_BUF_TYPE_VBI_CAPTURE)) + /* We should remember that this driver also supports teletext, */ + /* so we have to test if the v4l2_buf_type is VBI capture data. */ + if (unlikely((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && + (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))) + return -EINVAL; + + if (unlikely(i != fh->type)) return -EINVAL; - if (unlikely(!res_get(dev, fh, get_resource(file)))) + if (unlikely(!res_get(dev,fh,get_ressource(fh)))) return -EBUSY; - return videobuf_streamon(get_queue(file)); + return videobuf_streamon(get_queue(fh)); } static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) { - struct video_device *vdev = video_devdata(file); struct cx8800_fh *fh = priv; struct cx8800_dev *dev = fh->dev; int err, res; - if ((vdev->vfl_type == VFL_TYPE_GRABBER && i != V4L2_BUF_TYPE_VIDEO_CAPTURE) || - (vdev->vfl_type == VFL_TYPE_VBI && i != V4L2_BUF_TYPE_VBI_CAPTURE)) + if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && + (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)) return -EINVAL; - res = get_resource(file); - err = videobuf_streamoff(get_queue(file)); + if (i != fh->type) + return -EINVAL; + + res = get_ressource(fh); + err = videobuf_streamoff(get_queue(fh)); if (err < 0) return err; res_free(dev,fh,res); return 0; } -static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm) -{ - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; - - *tvnorm = core->tvnorm; - return 0; -} - static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *tvnorms) { struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; @@ -1229,8 +1327,8 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) if ((CX88_VMUX_TELEVISION == INPUT(n).type) || (CX88_VMUX_CABLE == INPUT(n).type)) { i->type = V4L2_INPUT_TYPE_TUNER; + i->std = CX88_NORMS; } - i->std = CX88_NORMS; return 0; } EXPORT_SYMBOL(cx88_enum_input); @@ -1256,8 +1354,6 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i) if (i >= 4) return -EINVAL; - if (0 == INPUT(i).type) - return -EINVAL; mutex_lock(&core->lock); cx88_newstation(core); @@ -1266,6 +1362,35 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i) return 0; } + + +static int vidioc_queryctrl (struct file *file, void *priv, + struct v4l2_queryctrl *qctrl) +{ + struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + + qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); + if (unlikely(qctrl->id == 0)) + return -EINVAL; + return cx8800_ctrl_query(core, qctrl); +} + +static int vidioc_g_ctrl (struct file *file, void *priv, + struct v4l2_control *ctl) +{ + struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + return + cx88_get_control(core,ctl); +} + +static int vidioc_s_ctrl (struct file *file, void *priv, + struct v4l2_control *ctl) +{ + struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + return + cx88_set_control(core,ctl); +} + static int vidioc_g_tuner (struct file *file, void *priv, struct v4l2_tuner *t) { @@ -1278,9 +1403,9 @@ static int vidioc_g_tuner (struct file *file, void *priv, return -EINVAL; strcpy(t->name, "Television"); + t->type = V4L2_TUNER_ANALOG_TV; t->capability = V4L2_TUNER_CAP_NORM; t->rangehigh = 0xffffffffUL; - call_all(core, tuner, g_tuner, t); cx88_get_stereo(core ,t); reg = cx_read(MO_DEVICE_STATUS); @@ -1310,9 +1435,9 @@ static int vidioc_g_frequency (struct file *file, void *priv, if (unlikely(UNSET == core->board.tuner_type)) return -EINVAL; - if (f->tuner) - return -EINVAL; + /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */ + f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; f->frequency = core->freq; call_all(core, tuner, g_frequency, f); @@ -1329,10 +1454,9 @@ int cx88_set_freq (struct cx88_core *core, return -EINVAL; mutex_lock(&core->lock); + core->freq = f->frequency; cx88_newstation(core); call_all(core, tuner, s_frequency, f); - call_all(core, tuner, g_frequency, f); - core->freq = f->frequency; /* When changing channels it is required to reset TVAUDIO */ msleep (10); @@ -1350,17 +1474,13 @@ static int vidioc_s_frequency (struct file *file, void *priv, struct cx8800_fh *fh = priv; struct cx88_core *core = fh->dev->core; - return cx88_set_freq(core, f); -} - -static int vidioc_g_chip_ident(struct file *file, void *priv, - struct v4l2_dbg_chip_ident *chip) -{ - if (!v4l2_chip_match_host(&chip->match)) + if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)) return -EINVAL; - chip->revision = 0; - chip->ident = V4L2_IDENT_UNKNOWN; - return 0; + if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) + return -EINVAL; + + return + cx88_set_freq (core,f); } #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -1393,6 +1513,19 @@ static int vidioc_s_register (struct file *file, void *fh, /* RADIO ESPECIFIC IOCTLS */ /* ----------------------------------------------------------- */ +static int radio_querycap (struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct cx8800_dev *dev = ((struct cx8800_fh *)priv)->dev; + struct cx88_core *core = dev->core; + + strcpy(cap->driver, "cx8800"); + strlcpy(cap->card, core->board.name, sizeof(cap->card)); + sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); + cap->capabilities = V4L2_CAP_TUNER; + return 0; +} + static int radio_g_tuner (struct file *file, void *priv, struct v4l2_tuner *t) { @@ -1402,11 +1535,32 @@ static int radio_g_tuner (struct file *file, void *priv, return -EINVAL; strcpy(t->name, "Radio"); + t->type = V4L2_TUNER_RADIO; call_all(core, tuner, g_tuner, t); return 0; } +static int radio_enum_input (struct file *file, void *priv, + struct v4l2_input *i) +{ + if (i->index != 0) + return -EINVAL; + strcpy(i->name,"Radio"); + i->type = V4L2_INPUT_TYPE_TUNER; + + return 0; +} + +static int radio_g_audio (struct file *file, void *priv, struct v4l2_audio *a) +{ + if (unlikely(a->index)) + return -EINVAL; + + strcpy(a->name,"Radio"); + return 0; +} + /* FIXME: Should add a standard for radio */ static int radio_s_tuner (struct file *file, void *priv, @@ -1416,14 +1570,46 @@ static int radio_s_tuner (struct file *file, void *priv, if (0 != t->index) return -EINVAL; - if (t->audmode > V4L2_TUNER_MODE_STEREO) - t->audmode = V4L2_TUNER_MODE_STEREO; call_all(core, tuner, s_tuner, t); return 0; } +static int radio_s_audio (struct file *file, void *fh, + struct v4l2_audio *a) +{ + return 0; +} + +static int radio_s_input (struct file *file, void *fh, unsigned int i) +{ + return 0; +} + +static int radio_queryctrl (struct file *file, void *priv, + struct v4l2_queryctrl *c) +{ + int i; + + if (c->id < V4L2_CID_BASE || + c->id >= V4L2_CID_LASTP1) + return -EINVAL; + if (c->id == V4L2_CID_AUDIO_MUTE || + c->id == V4L2_CID_AUDIO_VOLUME || + c->id == V4L2_CID_AUDIO_BALANCE) { + for (i = 0; i < CX8800_CTLS; i++) { + if (cx8800_ctls[i].v.id == c->id) + break; + } + if (i == CX8800_CTLS) + return -EINVAL; + *c = cx8800_ctls[i].v; + } else + *c = no_ctl; + return 0; +} + /* ----------------------------------------------------------- */ static void cx8800_vid_timeout(unsigned long data) @@ -1566,39 +1752,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_g_std = vidioc_g_std, - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, - .vidioc_g_chip_ident = vidioc_g_chip_ident, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = vidioc_g_register, - .vidioc_s_register = vidioc_s_register, -#endif -}; - -static const struct video_device cx8800_video_template = { - .name = "cx8800-video", - .fops = &video_fops, - .ioctl_ops = &video_ioctl_ops, - .tvnorms = CX88_NORMS, -}; - -static const struct v4l2_ioctl_ops vbi_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, .vidioc_g_fmt_vbi_cap = cx8800_vbi_fmt, .vidioc_try_fmt_vbi_cap = cx8800_vbi_fmt, .vidioc_s_fmt_vbi_cap = cx8800_vbi_fmt, @@ -1606,49 +1759,56 @@ static const struct v4l2_ioctl_ops vbi_ioctl_ops = { .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_g_std = vidioc_g_std, .vidioc_s_std = vidioc_s_std, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_g_chip_ident = vidioc_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif }; -static const struct video_device cx8800_vbi_template = { - .name = "cx8800-vbi", +static struct video_device cx8800_vbi_template; + +static const struct video_device cx8800_video_template = { + .name = "cx8800-video", .fops = &video_fops, - .ioctl_ops = &vbi_ioctl_ops, + .ioctl_ops = &video_ioctl_ops, .tvnorms = CX88_NORMS, + .current_norm = V4L2_STD_NTSC_M, }; static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, .open = video_open, - .poll = v4l2_ctrl_poll, .release = video_release, .unlocked_ioctl = video_ioctl2, }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, + .vidioc_querycap = radio_querycap, .vidioc_g_tuner = radio_g_tuner, + .vidioc_enum_input = radio_enum_input, + .vidioc_g_audio = radio_g_audio, .vidioc_s_tuner = radio_s_tuner, + .vidioc_s_audio = radio_s_audio, + .vidioc_s_input = radio_s_input, + .vidioc_queryctrl = radio_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, - .vidioc_g_chip_ident = vidioc_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, @@ -1661,14 +1821,6 @@ static const struct video_device cx8800_radio_template = { .ioctl_ops = &radio_ioctl_ops, }; -static const struct v4l2_ctrl_ops cx8800_ctrl_vid_ops = { - .s_ctrl = cx8800_s_vid_ctrl, -}; - -static const struct v4l2_ctrl_ops cx8800_ctrl_aud_ops = { - .s_ctrl = cx8800_s_aud_ctrl, -}; - /* ----------------------------------------------------------- */ static void cx8800_unregister_video(struct cx8800_dev *dev) @@ -1701,8 +1853,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, { struct cx8800_dev *dev; struct cx88_core *core; + int err; - int i; dev = kzalloc(sizeof(*dev),GFP_KERNEL); if (NULL == dev) @@ -1736,9 +1888,14 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, goto fail_core; } + /* Initialize VBI template */ + memcpy( &cx8800_vbi_template, &cx8800_video_template, + sizeof(cx8800_vbi_template) ); + strcpy(cx8800_vbi_template.name,"cx8800-vbi"); + /* initialize driver struct */ spin_lock_init(&dev->slock); - core->tvnorm = V4L2_STD_NTSC_M; + core->tvnorm = cx8800_video_template.current_norm; /* init video dma queues */ INIT_LIST_HEAD(&dev->vidq.active); @@ -1768,35 +1925,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, } cx_set(MO_PCI_INTMSK, core->pci_irqmask); - for (i = 0; i < CX8800_AUD_CTLS; i++) { - const struct cx88_ctrl *cc = &cx8800_aud_ctls[i]; - struct v4l2_ctrl *vc; - - vc = v4l2_ctrl_new_std(&core->audio_hdl, &cx8800_ctrl_aud_ops, - cc->id, cc->minimum, cc->maximum, cc->step, cc->default_value); - if (vc == NULL) { - err = core->audio_hdl.error; - goto fail_core; - } - vc->priv = (void *)cc; - } - - for (i = 0; i < CX8800_VID_CTLS; i++) { - const struct cx88_ctrl *cc = &cx8800_vid_ctls[i]; - struct v4l2_ctrl *vc; - - vc = v4l2_ctrl_new_std(&core->video_hdl, &cx8800_ctrl_vid_ops, - cc->id, cc->minimum, cc->maximum, cc->step, cc->default_value); - if (vc == NULL) { - err = core->video_hdl.error; - goto fail_core; - } - vc->priv = (void *)cc; - if (vc->id == V4L2_CID_CHROMA_AGC) - core->chroma_agc = vc; - } - v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl); - /* load and configure helper modules */ if (core->board.audio_chip == V4L2_IDENT_WM8775) { @@ -1814,10 +1942,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, sd = v4l2_i2c_new_subdev_board(&core->v4l2_dev, &core->i2c_adap, &wm8775_info, NULL); - if (sd != NULL) { - core->sd_wm8775 = sd; + if (sd != NULL) sd->grp_id = WM8775_GID; - } } if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) { @@ -1845,22 +1971,16 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, /* Sets device info at pci_dev */ pci_set_drvdata(pci_dev, dev); - dev->width = 320; - dev->height = 240; - dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); - /* initial device configuration */ mutex_lock(&core->lock); cx88_set_tvnorm(core, core->tvnorm); - v4l2_ctrl_handler_setup(&core->video_hdl); - v4l2_ctrl_handler_setup(&core->audio_hdl); + init_controls(core); cx88_video_mux(core, 0); /* register v4l devices */ dev->video_dev = cx88_vdev_init(core,dev->pci, &cx8800_video_template,"video"); video_set_drvdata(dev->video_dev, dev); - dev->video_dev->ctrl_handler = &core->video_hdl; err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, video_nr[core->nr]); if (err < 0) { @@ -1887,7 +2007,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, dev->radio_dev = cx88_vdev_init(core,dev->pci, &cx8800_radio_template,"radio"); video_set_drvdata(dev->radio_dev, dev); - dev->radio_dev->ctrl_handler = &core->audio_hdl; err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, radio_nr[core->nr]); if (err < 0) { diff --git a/trunk/drivers/media/video/cx88/cx88.h b/trunk/drivers/media/video/cx88/cx88.h index 0cae0fd9e164..c9659def2a78 100644 --- a/trunk/drivers/media/video/cx88/cx88.h +++ b/trunk/drivers/media/video/cx88/cx88.h @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -116,6 +115,15 @@ struct cx8800_fmt { u32 cxformat; }; +struct cx88_ctrl { + struct v4l2_queryctrl v; + u32 off; + u32 reg; + u32 sreg; + u32 mask; + u32 shift; +}; + /* ----------------------------------------------------------- */ /* SRAM memory management data (see cx88-core.c) */ @@ -351,10 +359,6 @@ struct cx88_core { /* config info -- analog */ struct v4l2_device v4l2_dev; - struct v4l2_ctrl_handler video_hdl; - struct v4l2_ctrl *chroma_agc; - struct v4l2_ctrl_handler audio_hdl; - struct v4l2_subdev *sd_wm8775; struct i2c_client *i2c_rtc; unsigned int boardnr; struct cx88_board board; @@ -405,6 +409,8 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev) return container_of(v4l2_dev, struct cx88_core, v4l2_dev); } +#define WM8775_GID (1 << 0) + #define call_hw(core, grpid, o, f, args...) \ do { \ if (!core->i2c_rc) { \ @@ -418,36 +424,6 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev) #define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args) -#define WM8775_GID (1 << 0) - -#define wm8775_s_ctrl(core, id, val) \ - do { \ - struct v4l2_ctrl *ctrl_ = \ - v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id); \ - if (ctrl_ && !core->i2c_rc) { \ - if (core->gate_ctrl) \ - core->gate_ctrl(core, 1); \ - v4l2_ctrl_s_ctrl(ctrl_, val); \ - if (core->gate_ctrl) \ - core->gate_ctrl(core, 0); \ - } \ - } while (0) - -#define wm8775_g_ctrl(core, id) \ - ({ \ - struct v4l2_ctrl *ctrl_ = \ - v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id); \ - s32 val = 0; \ - if (ctrl_ && !core->i2c_rc) { \ - if (core->gate_ctrl) \ - core->gate_ctrl(core, 1); \ - val = v4l2_ctrl_g_ctrl(ctrl_); \ - if (core->gate_ctrl) \ - core->gate_ctrl(core, 0); \ - } \ - val; \ - }) - struct cx8800_dev; struct cx8802_dev; @@ -455,11 +431,19 @@ struct cx8802_dev; /* function 0: video stuff */ struct cx8800_fh { - struct v4l2_fh fh; struct cx8800_dev *dev; + enum v4l2_buf_type type; + int radio; unsigned int resources; + /* video overlay */ + struct v4l2_window win; + struct v4l2_clip *clips; + unsigned int nclips; + /* video capture */ + const struct cx8800_fmt *fmt; + unsigned int width,height; struct videobuf_queue vidq; /* vbi capture */ @@ -484,8 +468,6 @@ struct cx8800_dev { struct pci_dev *pci; unsigned char pci_rev,pci_lat; - const struct cx8800_fmt *fmt; - unsigned int width, height; /* capture queues */ struct cx88_dmaqueue vidq; @@ -506,7 +488,6 @@ struct cx8800_dev { /* function 2: mpeg stuff */ struct cx8802_fh { - struct v4l2_fh fh; struct cx8802_dev *dev; struct videobuf_queue mpegq; }; @@ -571,7 +552,7 @@ struct cx8802_dev { unsigned char mpeg_active; /* nonzero if mpeg encoder is active */ /* mpeg params */ - struct cx2341x_handler cxhdl; + struct cx2341x_mpeg_params params; #endif #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) @@ -741,8 +722,11 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev); /* ----------------------------------------------------------- */ /* cx88-video.c*/ +extern const u32 cx88_user_ctrls[]; +extern int cx8800_ctrl_query(struct cx88_core *core, + struct v4l2_queryctrl *qctrl); int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i); int cx88_set_freq (struct cx88_core *core,struct v4l2_frequency *f); +int cx88_get_control(struct cx88_core *core, struct v4l2_control *ctl); +int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl); int cx88_video_mux(struct cx88_core *core, unsigned int input); -void cx88_querycap(struct file *file, struct cx88_core *core, - struct v4l2_capability *cap); diff --git a/trunk/drivers/media/video/em28xx/em28xx-audio.c b/trunk/drivers/media/video/em28xx/em28xx-audio.c index 07dc594e79f0..d7e2a3dc5525 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-audio.c +++ b/trunk/drivers/media/video/em28xx/em28xx-audio.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include "em28xx.h" @@ -680,19 +679,19 @@ static int em28xx_audio_init(struct em28xx *dev) INIT_WORK(&dev->wq_trigger, audio_trigger); if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { - em28xx_cvol_new(card, dev, "Video", AC97_VIDEO); - em28xx_cvol_new(card, dev, "Line In", AC97_LINE); - em28xx_cvol_new(card, dev, "Phone", AC97_PHONE); - em28xx_cvol_new(card, dev, "Microphone", AC97_MIC); - em28xx_cvol_new(card, dev, "CD", AC97_CD); - em28xx_cvol_new(card, dev, "AUX", AC97_AUX); - em28xx_cvol_new(card, dev, "PCM", AC97_PCM); - - em28xx_cvol_new(card, dev, "Master", AC97_MASTER); - em28xx_cvol_new(card, dev, "Line", AC97_HEADPHONE); - em28xx_cvol_new(card, dev, "Mono", AC97_MASTER_MONO); - em28xx_cvol_new(card, dev, "LFE", AC97_CENTER_LFE_MASTER); - em28xx_cvol_new(card, dev, "Surround", AC97_SURROUND_MASTER); + em28xx_cvol_new(card, dev, "Video", AC97_VIDEO_VOL); + em28xx_cvol_new(card, dev, "Line In", AC97_LINEIN_VOL); + em28xx_cvol_new(card, dev, "Phone", AC97_PHONE_VOL); + em28xx_cvol_new(card, dev, "Microphone", AC97_PHONE_VOL); + em28xx_cvol_new(card, dev, "CD", AC97_CD_VOL); + em28xx_cvol_new(card, dev, "AUX", AC97_AUX_VOL); + em28xx_cvol_new(card, dev, "PCM", AC97_PCM_OUT_VOL); + + em28xx_cvol_new(card, dev, "Master", AC97_MASTER_VOL); + em28xx_cvol_new(card, dev, "Line", AC97_LINE_LEVEL_VOL); + em28xx_cvol_new(card, dev, "Mono", AC97_MASTER_MONO_VOL); + em28xx_cvol_new(card, dev, "LFE", AC97_LFE_MASTER_VOL); + em28xx_cvol_new(card, dev, "Surround", AC97_SURR_MASTER_VOL); } err = snd_card_register(card); diff --git a/trunk/drivers/media/video/em28xx/em28xx-cards.c b/trunk/drivers/media/video/em28xx/em28xx-cards.c index ca62b9981380..862c6575c557 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-cards.c +++ b/trunk/drivers/media/video/em28xx/em28xx-cards.c @@ -975,7 +975,12 @@ struct em28xx_board em28xx_boards[] = { .name = "Terratec Cinergy HTC Stick", .has_dvb = 1, .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, - .tuner_type = TUNER_ABSENT, +#if 0 + .tuner_type = TUNER_PHILIPS_TDA8290, + .tuner_addr = 0x41, + .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ + .tuner_gpio = terratec_h5_gpio, +#endif .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, diff --git a/trunk/drivers/media/video/em28xx/em28xx-core.c b/trunk/drivers/media/video/em28xx/em28xx-core.c index de2cb20ad2cc..5717bdee8f1b 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-core.c +++ b/trunk/drivers/media/video/em28xx/em28xx-core.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "em28xx.h" @@ -327,13 +326,13 @@ struct em28xx_vol_itable { }; static struct em28xx_vol_itable inputs[] = { - { EM28XX_AMUX_VIDEO, AC97_VIDEO }, - { EM28XX_AMUX_LINE_IN, AC97_LINE }, - { EM28XX_AMUX_PHONE, AC97_PHONE }, - { EM28XX_AMUX_MIC, AC97_MIC }, - { EM28XX_AMUX_CD, AC97_CD }, - { EM28XX_AMUX_AUX, AC97_AUX }, - { EM28XX_AMUX_PCM_OUT, AC97_PCM }, + { EM28XX_AMUX_VIDEO, AC97_VIDEO_VOL }, + { EM28XX_AMUX_LINE_IN, AC97_LINEIN_VOL }, + { EM28XX_AMUX_PHONE, AC97_PHONE_VOL }, + { EM28XX_AMUX_MIC, AC97_MIC_VOL }, + { EM28XX_AMUX_CD, AC97_CD_VOL }, + { EM28XX_AMUX_AUX, AC97_AUX_VOL }, + { EM28XX_AMUX_PCM_OUT, AC97_PCM_OUT_VOL }, }; static int set_ac97_input(struct em28xx *dev) @@ -416,11 +415,11 @@ struct em28xx_vol_otable { }; static const struct em28xx_vol_otable outputs[] = { - { EM28XX_AOUT_MASTER, AC97_MASTER }, - { EM28XX_AOUT_LINE, AC97_HEADPHONE }, - { EM28XX_AOUT_MONO, AC97_MASTER_MONO }, - { EM28XX_AOUT_LFE, AC97_CENTER_LFE_MASTER }, - { EM28XX_AOUT_SURR, AC97_SURROUND_MASTER }, + { EM28XX_AOUT_MASTER, AC97_MASTER_VOL }, + { EM28XX_AOUT_LINE, AC97_LINE_LEVEL_VOL }, + { EM28XX_AOUT_MONO, AC97_MASTER_MONO_VOL }, + { EM28XX_AOUT_LFE, AC97_LFE_MASTER_VOL }, + { EM28XX_AOUT_SURR, AC97_SURR_MASTER_VOL }, }; int em28xx_audio_analog_set(struct em28xx *dev) @@ -460,9 +459,9 @@ int em28xx_audio_analog_set(struct em28xx *dev) if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { int vol; - em28xx_write_ac97(dev, AC97_POWERDOWN, 0x4200); - em28xx_write_ac97(dev, AC97_EXTENDED_STATUS, 0x0031); - em28xx_write_ac97(dev, AC97_PCM_LR_ADC_RATE, 0xbb80); + em28xx_write_ac97(dev, AC97_POWER_DOWN_CTRL, 0x4200); + em28xx_write_ac97(dev, AC97_EXT_AUD_CTRL, 0x0031); + em28xx_write_ac97(dev, AC97_PCM_IN_SRATE, 0xbb80); /* LSB: left channel - both channels with the same level */ vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8); @@ -488,7 +487,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) channels */ sel |= (sel << 8); - em28xx_write_ac97(dev, AC97_REC_SEL, sel); + em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel); } } diff --git a/trunk/drivers/media/video/em28xx/em28xx-dvb.c b/trunk/drivers/media/video/em28xx/em28xx-dvb.c index a16531fa937a..16410ac20092 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-dvb.c +++ b/trunk/drivers/media/video/em28xx/em28xx-dvb.c @@ -310,47 +310,31 @@ static struct drxd_config em28xx_drxd = { .disable_i2c_gate_ctrl = 1, }; -static struct drxk_config terratec_h5_drxk = { +struct drxk_config terratec_h5_drxk = { .adr = 0x29, .single_master = 1, .no_i2c_bridge = 1, .microcode_name = "dvb-usb-terratec-h5-drxk.fw", - .qam_demod_parameter_count = 2, }; -static struct drxk_config hauppauge_930c_drxk = { +struct drxk_config hauppauge_930c_drxk = { .adr = 0x29, .single_master = 1, .no_i2c_bridge = 1, .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw", .chunk_size = 56, - .qam_demod_parameter_count = 2, }; -struct drxk_config terratec_htc_stick_drxk = { +struct drxk_config maxmedia_ub425_tc_drxk = { .adr = 0x29, .single_master = 1, .no_i2c_bridge = 1, - .microcode_name = "dvb-usb-terratec-htc-stick-drxk.fw", - .chunk_size = 54, - .qam_demod_parameter_count = 2, - /* Required for the antenna_gpio to disable LNA. */ - .antenna_dvbt = true, - /* The windows driver uses the same. This will disable LNA. */ - .antenna_gpio = 0x6, }; -static struct drxk_config maxmedia_ub425_tc_drxk = { - .adr = 0x29, - .single_master = 1, - .no_i2c_bridge = 1, -}; - -static struct drxk_config pctv_520e_drxk = { +struct drxk_config pctv_520e_drxk = { .adr = 0x29, .single_master = 1, .microcode_name = "dvb-demod-drxk-pctv.fw", - .qam_demod_parameter_count = 2, .chunk_size = 58, .antenna_dvbt = true, /* disable LNA */ .antenna_gpio = (1 << 2), /* disable LNA */ @@ -489,57 +473,6 @@ static void terratec_h5_init(struct em28xx *dev) em28xx_gpio_set(dev, terratec_h5_end); }; -static void terratec_htc_stick_init(struct em28xx *dev) -{ - int i; - - /* - * GPIO configuration: - * 0xff: unknown (does not affect DVB-T). - * 0xf6: DRX-K (demodulator). - * 0xe6: unknown (does not affect DVB-T). - * 0xb6: unknown (does not affect DVB-T). - */ - struct em28xx_reg_seq terratec_htc_stick_init[] = { - {EM28XX_R08_GPIO, 0xff, 0xff, 10}, - {EM2874_R80_GPIO, 0xf6, 0xff, 100}, - {EM2874_R80_GPIO, 0xe6, 0xff, 50}, - {EM2874_R80_GPIO, 0xf6, 0xff, 100}, - { -1, -1, -1, -1}, - }; - struct em28xx_reg_seq terratec_htc_stick_end[] = { - {EM2874_R80_GPIO, 0xb6, 0xff, 100}, - {EM2874_R80_GPIO, 0xf6, 0xff, 50}, - { -1, -1, -1, -1}, - }; - - /* Init the analog decoder? */ - struct { - unsigned char r[4]; - int len; - } regs[] = { - {{ 0x06, 0x02, 0x00, 0x31 }, 4}, - {{ 0x01, 0x02 }, 2}, - {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, - {{ 0x01, 0x00 }, 2}, - {{ 0x01, 0x00, 0xff, 0xaf }, 4}, - }; - - em28xx_gpio_set(dev, terratec_htc_stick_init); - - em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); - msleep(10); - em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); - msleep(10); - - dev->i2c_client.addr = 0x82 >> 1; - - for (i = 0; i < ARRAY_SIZE(regs); i++) - i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); - - em28xx_gpio_set(dev, terratec_htc_stick_end); -}; - static void pctv_520e_init(struct em28xx *dev) { /* @@ -1011,6 +944,7 @@ static int em28xx_dvb_init(struct em28xx *dev) break; } case EM2884_BOARD_TERRATEC_H5: + case EM2884_BOARD_CINERGY_HTC_STICK: terratec_h5_init(dev); dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap); @@ -1087,25 +1021,6 @@ static int em28xx_dvb_init(struct em28xx *dev) } } break; - case EM2884_BOARD_CINERGY_HTC_STICK: - terratec_htc_stick_init(dev); - - /* attach demodulator */ - dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk, - &dev->i2c_adap); - if (!dvb->fe[0]) { - result = -EINVAL; - goto out_free; - } - - /* Attach the demodulator. */ - if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, - &dev->i2c_adap, - &em28xx_cxd2820r_tda18271_config)) { - result = -EINVAL; - goto out_free; - } - break; default: em28xx_errdev("/2: The frontend of your DVB/ATSC card" " isn't supported yet\n"); diff --git a/trunk/drivers/media/video/em28xx/em28xx-i2c.c b/trunk/drivers/media/video/em28xx/em28xx-i2c.c index 1683bd9d51ee..185db65b766e 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-i2c.c +++ b/trunk/drivers/media/video/em28xx/em28xx-i2c.c @@ -475,7 +475,6 @@ static struct i2c_client em28xx_client_template = { */ static char *i2c_devs[128] = { [0x4a >> 1] = "saa7113h", - [0x52 >> 1] = "drxk", [0x60 >> 1] = "remote IR sensor", [0x8e >> 1] = "remote IR sensor", [0x86 >> 1] = "tda9887", diff --git a/trunk/drivers/media/video/em28xx/em28xx-input.c b/trunk/drivers/media/video/em28xx/em28xx-input.c index 97d36b4f19db..5e30c4f3f248 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-input.c +++ b/trunk/drivers/media/video/em28xx/em28xx-input.c @@ -345,7 +345,7 @@ static void em28xx_ir_stop(struct rc_dev *rc) cancel_delayed_work_sync(&ir->work); } -static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type) +int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type) { int rc = 0; struct em28xx_IR *ir = rc_dev->priv; diff --git a/trunk/drivers/media/video/em28xx/em28xx-reg.h b/trunk/drivers/media/video/em28xx/em28xx-reg.h index 6ff368297f6e..2f6268505726 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-reg.h +++ b/trunk/drivers/media/video/em28xx/em28xx-reg.h @@ -211,9 +211,58 @@ enum em28xx_chip_id { }; /* - * Registers used by em202 + * Registers used by em202 and other AC97 chips */ +/* Standard AC97 registers */ +#define AC97_RESET 0x00 + + /* Output volumes */ +#define AC97_MASTER_VOL 0x02 +#define AC97_LINE_LEVEL_VOL 0x04 /* Some devices use for headphones */ +#define AC97_MASTER_MONO_VOL 0x06 + + /* Input volumes */ +#define AC97_PC_BEEP_VOL 0x0a +#define AC97_PHONE_VOL 0x0c +#define AC97_MIC_VOL 0x0e +#define AC97_LINEIN_VOL 0x10 +#define AC97_CD_VOL 0x12 +#define AC97_VIDEO_VOL 0x14 +#define AC97_AUX_VOL 0x16 +#define AC97_PCM_OUT_VOL 0x18 + + /* capture registers */ +#define AC97_RECORD_SELECT 0x1a +#define AC97_RECORD_GAIN 0x1c + + /* control registers */ +#define AC97_GENERAL_PURPOSE 0x20 +#define AC97_3D_CTRL 0x22 +#define AC97_AUD_INT_AND_PAG 0x24 +#define AC97_POWER_DOWN_CTRL 0x26 +#define AC97_EXT_AUD_ID 0x28 +#define AC97_EXT_AUD_CTRL 0x2a + +/* Supported rate varies for each AC97 device + if write an unsupported value, it will return the closest one + */ +#define AC97_PCM_OUT_FRONT_SRATE 0x2c +#define AC97_PCM_OUT_SURR_SRATE 0x2e +#define AC97_PCM_OUT_LFE_SRATE 0x30 +#define AC97_PCM_IN_SRATE 0x32 + + /* For devices with more than 2 channels, extra output volumes */ +#define AC97_LFE_MASTER_VOL 0x36 +#define AC97_SURR_MASTER_VOL 0x38 + + /* Digital SPDIF output control */ +#define AC97_SPDIF_OUT_CTRL 0x3a + + /* Vendor ID identifier */ +#define AC97_VENDOR_ID1 0x7c +#define AC97_VENDOR_ID2 0x7e + /* EMP202 vendor registers */ #define EM202_EXT_MODEM_CTRL 0x3e #define EM202_GPIO_CONF 0x4c diff --git a/trunk/drivers/media/video/ibmmpeg2.h b/trunk/drivers/media/video/ibmmpeg2.h new file mode 100644 index 000000000000..68e10387c498 --- /dev/null +++ b/trunk/drivers/media/video/ibmmpeg2.h @@ -0,0 +1,94 @@ +/* ibmmpeg2.h - IBM MPEGCD21 definitions */ + +#ifndef __IBM_MPEG2__ +#define __IBM_MPEG2__ + +/* Define all MPEG Decoder registers */ +/* Chip Control and Status */ +#define IBM_MP2_CHIP_CONTROL 0x200*2 +#define IBM_MP2_CHIP_MODE 0x201*2 +/* Timer Control and Status */ +#define IBM_MP2_SYNC_STC2 0x202*2 +#define IBM_MP2_SYNC_STC1 0x203*2 +#define IBM_MP2_SYNC_STC0 0x204*2 +#define IBM_MP2_SYNC_PTS2 0x205*2 +#define IBM_MP2_SYNC_PTS1 0x206*2 +#define IBM_MP2_SYNC_PTS0 0x207*2 +/* Video FIFO Control */ +#define IBM_MP2_FIFO 0x208*2 +#define IBM_MP2_FIFOW 0x100*2 +#define IBM_MP2_FIFO_STAT 0x209*2 +#define IBM_MP2_RB_THRESHOLD 0x22b*2 +/* Command buffer */ +#define IBM_MP2_COMMAND 0x20a*2 +#define IBM_MP2_CMD_DATA 0x20b*2 +#define IBM_MP2_CMD_STAT 0x20c*2 +#define IBM_MP2_CMD_ADDR 0x20d*2 +/* Internal Processor Control and Status */ +#define IBM_MP2_PROC_IADDR 0x20e*2 +#define IBM_MP2_PROC_IDATA 0x20f*2 +#define IBM_MP2_WR_PROT 0x235*2 +/* DRAM Access */ +#define IBM_MP2_DRAM_ADDR 0x210*2 +#define IBM_MP2_DRAM_DATA 0x212*2 +#define IBM_MP2_DRAM_CMD_STAT 0x213*2 +#define IBM_MP2_BLOCK_SIZE 0x23b*2 +#define IBM_MP2_SRC_ADDR 0x23c*2 +/* Onscreen Display */ +#define IBM_MP2_OSD_ADDR 0x214*2 +#define IBM_MP2_OSD_DATA 0x215*2 +#define IBM_MP2_OSD_MODE 0x217*2 +#define IBM_MP2_OSD_LINK_ADDR 0x229*2 +#define IBM_MP2_OSD_SIZE 0x22a*2 +/* Interrupt Control */ +#define IBM_MP2_HOST_INT 0x218*2 +#define IBM_MP2_MASK0 0x219*2 +#define IBM_MP2_HOST_INT1 0x23e*2 +#define IBM_MP2_MASK1 0x23f*2 +/* Audio Control */ +#define IBM_MP2_AUD_IADDR 0x21a*2 +#define IBM_MP2_AUD_IDATA 0x21b*2 +#define IBM_MP2_AUD_FIFO 0x21c*2 +#define IBM_MP2_AUD_FIFOW 0x101*2 +#define IBM_MP2_AUD_CTL 0x21d*2 +#define IBM_MP2_BEEP_CTL 0x21e*2 +#define IBM_MP2_FRNT_ATTEN 0x22d*2 +/* Display Control */ +#define IBM_MP2_DISP_MODE 0x220*2 +#define IBM_MP2_DISP_DLY 0x221*2 +#define IBM_MP2_VBI_CTL 0x222*2 +#define IBM_MP2_DISP_LBOR 0x223*2 +#define IBM_MP2_DISP_TBOR 0x224*2 +/* Polarity Control */ +#define IBM_MP2_INFC_CTL 0x22c*2 + +/* control commands */ +#define IBM_MP2_PLAY 0 +#define IBM_MP2_PAUSE 1 +#define IBM_MP2_SINGLE_FRAME 2 +#define IBM_MP2_FAST_FORWARD 3 +#define IBM_MP2_SLOW_MOTION 4 +#define IBM_MP2_IMED_NORM_PLAY 5 +#define IBM_MP2_RESET_WINDOW 6 +#define IBM_MP2_FREEZE_FRAME 7 +#define IBM_MP2_RESET_VID_RATE 8 +#define IBM_MP2_CONFIG_DECODER 9 +#define IBM_MP2_CHANNEL_SWITCH 10 +#define IBM_MP2_RESET_AUD_RATE 11 +#define IBM_MP2_PRE_OP_CHN_SW 12 +#define IBM_MP2_SET_STILL_MODE 14 + +/* Define Xilinx FPGA Internal Registers */ + +/* general control register 0 */ +#define XILINX_CTL0 0x600 +/* genlock delay resister 1 */ +#define XILINX_GLDELAY 0x602 +/* send 16 bits to CS3310 port */ +#define XILINX_CS3310 0x604 +/* send 16 bits to CS3310 and complete */ +#define XILINX_CS3310_CMPLT 0x60c +/* pulse width modulator control */ +#define XILINX_PWM 0x606 + +#endif diff --git a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c index 32a591062d0b..f7d57b3f2842 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1830,6 +1830,18 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio, return 0; } +long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct video_device *vfd = video_devdata(filp); + long ret; + + if (ivtv_debug & IVTV_DBGFLG_IOCTL) + vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; + ret = video_ioctl2(filp, cmd, arg); + vfd->debug = 0; + return ret; +} + static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { .vidioc_querycap = ivtv_querycap, .vidioc_s_audio = ivtv_s_audio, diff --git a/trunk/drivers/media/video/ivtv/ivtv-ioctl.h b/trunk/drivers/media/video/ivtv/ivtv-ioctl.h index 7c553d16579b..89185caeafae 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-ioctl.h +++ b/trunk/drivers/media/video/ivtv/ivtv-ioctl.h @@ -31,5 +31,6 @@ void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std); void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std); int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); int ivtv_s_input(struct file *file, void *fh, unsigned int inp); +long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); #endif diff --git a/trunk/drivers/media/video/ivtv/ivtv-streams.c b/trunk/drivers/media/video/ivtv/ivtv-streams.c index 87990c5f0910..6738592aa35d 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-streams.c +++ b/trunk/drivers/media/video/ivtv/ivtv-streams.c @@ -50,7 +50,7 @@ static const struct v4l2_file_operations ivtv_v4l2_enc_fops = { .read = ivtv_v4l2_read, .write = ivtv_v4l2_write, .open = ivtv_v4l2_open, - .unlocked_ioctl = video_ioctl2, + .unlocked_ioctl = ivtv_v4l2_ioctl, .release = ivtv_v4l2_close, .poll = ivtv_v4l2_enc_poll, }; @@ -60,7 +60,7 @@ static const struct v4l2_file_operations ivtv_v4l2_dec_fops = { .read = ivtv_v4l2_read, .write = ivtv_v4l2_write, .open = ivtv_v4l2_open, - .unlocked_ioctl = video_ioctl2, + .unlocked_ioctl = ivtv_v4l2_ioctl, .release = ivtv_v4l2_close, .poll = ivtv_v4l2_dec_poll, }; diff --git a/trunk/drivers/media/video/m5mols/Kconfig b/trunk/drivers/media/video/m5mols/Kconfig index dc8c2505907e..302dc3d70193 100644 --- a/trunk/drivers/media/video/m5mols/Kconfig +++ b/trunk/drivers/media/video/m5mols/Kconfig @@ -1,6 +1,5 @@ config VIDEO_M5MOLS tristate "Fujitsu M-5MOLS 8MP sensor support" depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API - depends on MEDIA_CAMERA_SUPPORT ---help--- This driver supports Fujitsu M-5MOLS camera sensor with ISP diff --git a/trunk/drivers/media/video/mem2mem_testdev.c b/trunk/drivers/media/video/mem2mem_testdev.c index f08cf38a496d..3945556f5733 100644 --- a/trunk/drivers/media/video/mem2mem_testdev.c +++ b/trunk/drivers/media/video/mem2mem_testdev.c @@ -60,10 +60,6 @@ MODULE_VERSION("0.1.1"); #define MEM2MEM_COLOR_STEP (0xff >> 4) #define MEM2MEM_NUM_TILES 8 -/* Flags that indicate processing mode */ -#define MEM2MEM_HFLIP (1 << 0) -#define MEM2MEM_VFLIP (1 << 1) - #define dprintk(dev, fmt, arg...) \ v4l2_dbg(1, 1, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg) @@ -119,24 +115,6 @@ enum { static struct v4l2_queryctrl m2mtest_ctrls[] = { { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - .flags = 0, - }, { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Vertical Mirror", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - .flags = 0, - }, { .id = V4L2_CID_TRANS_TIME_MSEC, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Transaction time (msec)", @@ -203,9 +181,6 @@ struct m2mtest_ctx { /* Abort requested by m2m */ int aborting; - /* Processing mode */ - int mode; - struct v4l2_m2m_ctx *m2m_ctx; /* Source and destination queue data */ @@ -274,84 +249,19 @@ static int device_process(struct m2mtest_ctx *ctx, bytes_left = bytesperline - tile_w * MEM2MEM_NUM_TILES; w = 0; - switch (ctx->mode) { - case MEM2MEM_HFLIP | MEM2MEM_VFLIP: - p_out += bytesperline * height - bytes_left; - for (y = 0; y < height; ++y) { - for (t = 0; t < MEM2MEM_NUM_TILES; ++t) { - if (w & 0x1) { - for (x = 0; x < tile_w; ++x) - *--p_out = *p_in++ + - MEM2MEM_COLOR_STEP; - } else { - for (x = 0; x < tile_w; ++x) - *--p_out = *p_in++ - - MEM2MEM_COLOR_STEP; - } - ++w; + for (y = 0; y < height; ++y) { + for (t = 0; t < MEM2MEM_NUM_TILES; ++t) { + if (w & 0x1) { + for (x = 0; x < tile_w; ++x) + *p_out++ = *p_in++ + MEM2MEM_COLOR_STEP; + } else { + for (x = 0; x < tile_w; ++x) + *p_out++ = *p_in++ - MEM2MEM_COLOR_STEP; } - p_in += bytes_left; - p_out -= bytes_left; - } - break; - - case MEM2MEM_HFLIP: - for (y = 0; y < height; ++y) { - p_out += MEM2MEM_NUM_TILES * tile_w; - for (t = 0; t < MEM2MEM_NUM_TILES; ++t) { - if (w & 0x01) { - for (x = 0; x < tile_w; ++x) - *--p_out = *p_in++ + - MEM2MEM_COLOR_STEP; - } else { - for (x = 0; x < tile_w; ++x) - *--p_out = *p_in++ - - MEM2MEM_COLOR_STEP; - } - ++w; - } - p_in += bytes_left; - p_out += bytesperline; - } - break; - - case MEM2MEM_VFLIP: - p_out += bytesperline * (height - 1); - for (y = 0; y < height; ++y) { - for (t = 0; t < MEM2MEM_NUM_TILES; ++t) { - if (w & 0x1) { - for (x = 0; x < tile_w; ++x) - *p_out++ = *p_in++ + - MEM2MEM_COLOR_STEP; - } else { - for (x = 0; x < tile_w; ++x) - *p_out++ = *p_in++ - - MEM2MEM_COLOR_STEP; - } - ++w; - } - p_in += bytes_left; - p_out += bytes_left - 2 * bytesperline; - } - break; - - default: - for (y = 0; y < height; ++y) { - for (t = 0; t < MEM2MEM_NUM_TILES; ++t) { - if (w & 0x1) { - for (x = 0; x < tile_w; ++x) - *p_out++ = *p_in++ + - MEM2MEM_COLOR_STEP; - } else { - for (x = 0; x < tile_w; ++x) - *p_out++ = *p_in++ - - MEM2MEM_COLOR_STEP; - } - ++w; - } - p_in += bytes_left; - p_out += bytes_left; + ++w; } + p_in += bytes_left; + p_out += bytes_left; } return 0; @@ -738,14 +648,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv, struct m2mtest_ctx *ctx = priv; switch (ctrl->id) { - case V4L2_CID_HFLIP: - ctrl->value = (ctx->mode & MEM2MEM_HFLIP) ? 1 : 0; - break; - - case V4L2_CID_VFLIP: - ctrl->value = (ctx->mode & MEM2MEM_VFLIP) ? 1 : 0; - break; - case V4L2_CID_TRANS_TIME_MSEC: ctrl->value = ctx->transtime; break; @@ -789,20 +691,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, return ret; switch (ctrl->id) { - case V4L2_CID_HFLIP: - if (ctrl->value) - ctx->mode |= MEM2MEM_HFLIP; - else - ctx->mode &= ~MEM2MEM_HFLIP; - break; - - case V4L2_CID_VFLIP: - if (ctrl->value) - ctx->mode |= MEM2MEM_VFLIP; - else - ctx->mode &= ~MEM2MEM_VFLIP; - break; - case V4L2_CID_TRANS_TIME_MSEC: ctx->transtime = ctrl->value; break; @@ -973,7 +861,6 @@ static int m2mtest_open(struct file *file) ctx->translen = MEM2MEM_DEF_TRANSLEN; ctx->transtime = MEM2MEM_DEF_TRANSTIME; ctx->num_processed = 0; - ctx->mode = 0; ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0]; ctx->q_data[V4L2_M2M_DST].fmt = &formats[0]; diff --git a/trunk/drivers/media/video/mt9m001.c b/trunk/drivers/media/video/mt9m001.c index 00583f5fd26b..7e648183f157 100644 --- a/trunk/drivers/media/video/mt9m001.c +++ b/trunk/drivers/media/video/mt9m001.c @@ -22,7 +22,7 @@ /* * mt9m001 i2c address 0x5d - * The platform has to define struct i2c_board_info objects and link to them + * The platform has to define ctruct i2c_board_info objects and link to them * from struct soc_camera_link */ diff --git a/trunk/drivers/media/video/mt9m032.c b/trunk/drivers/media/video/mt9m032.c index 445359c96113..3c1e626139b7 100644 --- a/trunk/drivers/media/video/mt9m032.c +++ b/trunk/drivers/media/video/mt9m032.c @@ -688,17 +688,11 @@ static const struct v4l2_subdev_ops mt9m032_ops = { static int mt9m032_probe(struct i2c_client *client, const struct i2c_device_id *devid) { - struct mt9m032_platform_data *pdata = client->dev.platform_data; struct i2c_adapter *adapter = client->adapter; struct mt9m032 *sensor; int chip_version; int ret; - if (pdata == NULL) { - dev_err(&client->dev, "No platform data\n"); - return -EINVAL; - } - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_warn(&client->dev, "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); @@ -714,7 +708,7 @@ static int mt9m032_probe(struct i2c_client *client, mutex_init(&sensor->lock); - sensor->pdata = pdata; + sensor->pdata = client->dev.platform_data; v4l2_i2c_subdev_init(&sensor->subdev, client, &mt9m032_ops); sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; @@ -744,7 +738,7 @@ static int mt9m032_probe(struct i2c_client *client, sensor->format.field = V4L2_FIELD_NONE; sensor->format.colorspace = V4L2_COLORSPACE_SRGB; - v4l2_ctrl_handler_init(&sensor->ctrls, 5); + v4l2_ctrl_handler_init(&sensor->ctrls, 4); v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops, V4L2_CID_GAIN, 0, 127, 1, 64); @@ -760,9 +754,6 @@ static int mt9m032_probe(struct i2c_client *client, V4L2_CID_EXPOSURE, MT9M032_SHUTTER_WIDTH_MIN, MT9M032_SHUTTER_WIDTH_MAX, 1, MT9M032_SHUTTER_WIDTH_DEF); - v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops, - V4L2_CID_PIXEL_RATE, pdata->pix_clock, - pdata->pix_clock, 1, pdata->pix_clock); if (sensor->ctrls.error) { ret = sensor->ctrls.error; diff --git a/trunk/drivers/media/video/mt9m111.c b/trunk/drivers/media/video/mt9m111.c index 863d722dda06..b0c529964329 100644 --- a/trunk/drivers/media/video/mt9m111.c +++ b/trunk/drivers/media/video/mt9m111.c @@ -214,6 +214,7 @@ struct mt9m111 { int power_count; const struct mt9m111_datafmt *fmt; int lastpage; /* PageMap cache value */ + unsigned char datawidth; }; /* Find a data format by a pixel code */ diff --git a/trunk/drivers/media/video/mt9p031.c b/trunk/drivers/media/video/mt9p031.c index 3be537ef22d2..8f061d9ac443 100644 --- a/trunk/drivers/media/video/mt9p031.c +++ b/trunk/drivers/media/video/mt9p031.c @@ -950,7 +950,7 @@ static int mt9p031_probe(struct i2c_client *client, mt9p031->model = did->driver_data; mt9p031->reset = -1; - v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 5); + v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 4); v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN, @@ -963,9 +963,6 @@ static int mt9p031_probe(struct i2c_client *client, V4L2_CID_HFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); - v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, - V4L2_CID_PIXEL_RATE, pdata->target_freq, - pdata->target_freq, 1, pdata->target_freq); for (i = 0; i < ARRAY_SIZE(mt9p031_ctrls); ++i) v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL); diff --git a/trunk/drivers/media/video/mt9t001.c b/trunk/drivers/media/video/mt9t001.c index 6d343adf891d..49ca3cbfc6f1 100644 --- a/trunk/drivers/media/video/mt9t001.c +++ b/trunk/drivers/media/video/mt9t001.c @@ -691,7 +691,7 @@ static int mt9t001_video_probe(struct i2c_client *client) return ret; /* Configure the pixel clock polarity */ - if (pdata->clk_pol) { + if (pdata && pdata->clk_pol) { ret = mt9t001_write(client, MT9T001_PIXEL_CLOCK, MT9T001_PIXEL_CLOCK_INVERT); if (ret < 0) @@ -715,16 +715,10 @@ static int mt9t001_video_probe(struct i2c_client *client) static int mt9t001_probe(struct i2c_client *client, const struct i2c_device_id *did) { - struct mt9t001_platform_data *pdata = client->dev.platform_data; struct mt9t001 *mt9t001; unsigned int i; int ret; - if (pdata == NULL) { - dev_err(&client->dev, "No platform data\n"); - return -EINVAL; - } - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_warn(&client->adapter->dev, @@ -741,7 +735,7 @@ static int mt9t001_probe(struct i2c_client *client, return -ENOMEM; v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) + - ARRAY_SIZE(mt9t001_gains) + 3); + ARRAY_SIZE(mt9t001_gains) + 2); v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops, V4L2_CID_EXPOSURE, MT9T001_SHUTTER_WIDTH_MIN, @@ -749,9 +743,6 @@ static int mt9t001_probe(struct i2c_client *client, MT9T001_SHUTTER_WIDTH_DEF); v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops, V4L2_CID_BLACK_LEVEL, 1, 1, 1, 1); - v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops, - V4L2_CID_PIXEL_RATE, pdata->ext_clk, pdata->ext_clk, - 1, pdata->ext_clk); for (i = 0; i < ARRAY_SIZE(mt9t001_ctrls); ++i) v4l2_ctrl_new_custom(&mt9t001->ctrls, &mt9t001_ctrls[i], NULL); diff --git a/trunk/drivers/media/video/mt9v022.c b/trunk/drivers/media/video/mt9v022.c index 72479247522a..bf63417adb8f 100644 --- a/trunk/drivers/media/video/mt9v022.c +++ b/trunk/drivers/media/video/mt9v022.c @@ -23,7 +23,7 @@ /* * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c - * The platform has to define struct i2c_board_info objects and link to them + * The platform has to define ctruct i2c_board_info objects and link to them * from struct soc_camera_link */ diff --git a/trunk/drivers/media/video/omap3isp/ispccdc.c b/trunk/drivers/media/video/omap3isp/ispccdc.c index f1220d3d4970..7e32331b60fb 100644 --- a/trunk/drivers/media/video/omap3isp/ispccdc.c +++ b/trunk/drivers/media/video/omap3isp/ispccdc.c @@ -2014,7 +2014,7 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, return -EINVAL; switch (sel->target) { - case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS: sel->r.left = 0; sel->r.top = 0; sel->r.width = INT_MAX; @@ -2024,7 +2024,7 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, ccdc_try_crop(ccdc, format, &sel->r); break; - case V4L2_SEL_TGT_CROP: + case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: sel->r = *__ccdc_get_crop(ccdc, fh, sel->which); break; @@ -2052,7 +2052,7 @@ static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - if (sel->target != V4L2_SEL_TGT_CROP || + if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL || sel->pad != CCDC_PAD_SOURCE_OF) return -EINVAL; @@ -2064,7 +2064,7 @@ static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, * pad. If the KEEP_CONFIG flag is set, just return the current crop * rectangle. */ - if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) { + if (sel->flags & V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG) { sel->r = *__ccdc_get_crop(ccdc, fh, sel->which); return 0; } diff --git a/trunk/drivers/media/video/omap3isp/isppreview.c b/trunk/drivers/media/video/omap3isp/isppreview.c index 53f5a703e31a..dd91da26f1b0 100644 --- a/trunk/drivers/media/video/omap3isp/isppreview.c +++ b/trunk/drivers/media/video/omap3isp/isppreview.c @@ -1949,7 +1949,7 @@ static int preview_get_selection(struct v4l2_subdev *sd, return -EINVAL; switch (sel->target) { - case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS: sel->r.left = 0; sel->r.top = 0; sel->r.width = INT_MAX; @@ -1960,7 +1960,7 @@ static int preview_get_selection(struct v4l2_subdev *sd, preview_try_crop(prev, format, &sel->r); break; - case V4L2_SEL_TGT_CROP: + case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: sel->r = *__preview_get_crop(prev, fh, sel->which); break; @@ -1988,7 +1988,7 @@ static int preview_set_selection(struct v4l2_subdev *sd, struct isp_prev_device *prev = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - if (sel->target != V4L2_SEL_TGT_CROP || + if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL || sel->pad != PREV_PAD_SINK) return -EINVAL; @@ -2000,7 +2000,7 @@ static int preview_set_selection(struct v4l2_subdev *sd, * pad. If the KEEP_CONFIG flag is set, just return the current crop * rectangle. */ - if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) { + if (sel->flags & V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG) { sel->r = *__preview_get_crop(prev, fh, sel->which); return 0; } diff --git a/trunk/drivers/media/video/omap3isp/ispresizer.c b/trunk/drivers/media/video/omap3isp/ispresizer.c index ae17d917f77b..14041c9c8643 100644 --- a/trunk/drivers/media/video/omap3isp/ispresizer.c +++ b/trunk/drivers/media/video/omap3isp/ispresizer.c @@ -1249,7 +1249,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd, sel->which); switch (sel->target) { - case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS: sel->r.left = 0; sel->r.top = 0; sel->r.width = INT_MAX; @@ -1259,7 +1259,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd, resizer_calc_ratios(res, &sel->r, format_source, &ratio); break; - case V4L2_SEL_TGT_CROP: + case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: sel->r = *__resizer_get_crop(res, fh, sel->which); resizer_calc_ratios(res, &sel->r, format_source, &ratio); break; @@ -1293,7 +1293,7 @@ static int resizer_set_selection(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *format_sink, *format_source; struct resizer_ratio ratio; - if (sel->target != V4L2_SEL_TGT_CROP || + if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL || sel->pad != RESZ_PAD_SINK) return -EINVAL; diff --git a/trunk/drivers/media/video/pvrusb2/Kconfig b/trunk/drivers/media/video/pvrusb2/Kconfig index 25e412ecad2c..f9b6001e1dd7 100644 --- a/trunk/drivers/media/video/pvrusb2/Kconfig +++ b/trunk/drivers/media/video/pvrusb2/Kconfig @@ -1,6 +1,7 @@ config VIDEO_PVRUSB2 tristate "Hauppauge WinTV-PVR USB2 support" depends on VIDEO_V4L2 && I2C + depends on VIDEO_MEDIA # Avoids pvrusb = Y / DVB = M select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_CX2341X diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index f344aed32a93..7bddfaeeafc3 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -226,11 +226,13 @@ static int pvr2_enum_input(struct file *file, void *priv, struct v4l2_input *vi) struct v4l2_input tmp; unsigned int cnt; int val; + int ret; cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT); memset(&tmp, 0, sizeof(tmp)); tmp.index = vi->index; + ret = 0; if (vi->index >= fh->input_cnt) return -EINVAL; val = fh->input_map[vi->index]; @@ -554,7 +556,9 @@ static int pvr2_queryctrl(struct file *file, void *priv, struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; struct pvr2_ctrl *cptr; int val; + int ret; + ret = 0; if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) { cptr = pvr2_hdw_get_ctrl_nextv4l( hdw, (vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL)); @@ -701,9 +705,11 @@ static int pvr2_try_ext_ctrls(struct file *file, void *priv, struct v4l2_ext_control *ctrl; struct pvr2_ctrl *pctl; unsigned int idx; + int ret; /* For the moment just validate that the requested control actually exists. */ + ret = 0; for (idx = 0; idx < ctls->count; idx++) { ctrl = ctls->controls + idx; pctl = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id); @@ -764,10 +770,12 @@ static int pvr2_s_crop(struct file *file, void *priv, struct v4l2_crop *crop) { struct pvr2_v4l2_fh *fh = file->private_data; struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; + struct v4l2_cropcap cap; int ret; if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; + cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = pvr2_ctrl_set_value( pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), crop->c.left); @@ -957,7 +965,7 @@ static long pvr2_v4l2_ioctl(struct file *file, long ret = -EINVAL; if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) - v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), cmd); + v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), cmd); if (!pvr2_hdw_dev_ok(hdw)) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, @@ -990,7 +998,7 @@ static long pvr2_v4l2_ioctl(struct file *file, pvr2_trace(PVR2_TRACE_V4LIOCTL, "pvr2_v4l2_do_ioctl failure, ret=%ld" " command was:", ret); - v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), + v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), cmd); } } diff --git a/trunk/drivers/media/video/pwc/pwc-if.c b/trunk/drivers/media/video/pwc/pwc-if.c index de7c7ba99ef4..ec4e2ef54e65 100644 --- a/trunk/drivers/media/video/pwc/pwc-if.c +++ b/trunk/drivers/media/video/pwc/pwc-if.c @@ -136,13 +136,19 @@ static int leds[2] = { 100, 0 }; /***/ +static int pwc_video_close(struct file *file); +static ssize_t pwc_video_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos); +static unsigned int pwc_video_poll(struct file *file, poll_table *wait); +static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); + static const struct v4l2_file_operations pwc_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, - .release = vb2_fop_release, - .read = vb2_fop_read, - .poll = vb2_fop_poll, - .mmap = vb2_fop_mmap, + .release = pwc_video_close, + .read = pwc_video_read, + .poll = pwc_video_poll, + .mmap = pwc_video_mmap, .unlocked_ioctl = video_ioctl2, }; static struct video_device pwc_template = { @@ -556,6 +562,17 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type) /***************************************************************************/ /* Video4Linux functions */ +int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file) +{ + if (pdev->capt_file != NULL && + pdev->capt_file != file) + return -EBUSY; + + pdev->capt_file = file; + + return 0; +} + static void pwc_video_release(struct v4l2_device *v) { struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); @@ -566,6 +583,113 @@ static void pwc_video_release(struct v4l2_device *v) kfree(pdev); } +static int pwc_video_close(struct file *file) +{ + struct pwc_device *pdev = video_drvdata(file); + + /* + * If we're still streaming vb2_queue_release will call stream_stop + * so we must take both the v4l2_lock and the vb_queue_lock. + */ + if (mutex_lock_interruptible(&pdev->v4l2_lock)) + return -ERESTARTSYS; + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) { + mutex_unlock(&pdev->v4l2_lock); + return -ERESTARTSYS; + } + + if (pdev->capt_file == file) { + vb2_queue_release(&pdev->vb_queue); + pdev->capt_file = NULL; + } + + mutex_unlock(&pdev->vb_queue_lock); + mutex_unlock(&pdev->v4l2_lock); + + return v4l2_fh_release(file); +} + +static ssize_t pwc_video_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct pwc_device *pdev = video_drvdata(file); + int lock_v4l2 = 0; + ssize_t ret; + + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return -ERESTARTSYS; + + ret = pwc_test_n_set_capt_file(pdev, file); + if (ret) + goto out; + + /* stream_start will get called so we must take the v4l2_lock */ + if (pdev->vb_queue.fileio == NULL) + lock_v4l2 = 1; + + /* Use try_lock, since we're taking the locks in the *wrong* order! */ + if (lock_v4l2 && !mutex_trylock(&pdev->v4l2_lock)) { + ret = -ERESTARTSYS; + goto out; + } + ret = vb2_read(&pdev->vb_queue, buf, count, ppos, + file->f_flags & O_NONBLOCK); + if (lock_v4l2) + mutex_unlock(&pdev->v4l2_lock); +out: + mutex_unlock(&pdev->vb_queue_lock); + return ret; +} + +static unsigned int pwc_video_poll(struct file *file, poll_table *wait) +{ + struct pwc_device *pdev = video_drvdata(file); + struct vb2_queue *q = &pdev->vb_queue; + unsigned long req_events = poll_requested_events(wait); + unsigned int ret = POLL_ERR; + int lock_v4l2 = 0; + + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return POLL_ERR; + + /* Will this start fileio and thus call start_stream? */ + if ((req_events & (POLLIN | POLLRDNORM)) && + q->num_buffers == 0 && !q->streaming && q->fileio == NULL) { + if (pwc_test_n_set_capt_file(pdev, file)) + goto out; + lock_v4l2 = 1; + } + + /* Use try_lock, since we're taking the locks in the *wrong* order! */ + if (lock_v4l2 && !mutex_trylock(&pdev->v4l2_lock)) + goto out; + ret = vb2_poll(&pdev->vb_queue, file, wait); + if (lock_v4l2) + mutex_unlock(&pdev->v4l2_lock); + +out: + if (!pdev->udev) + ret |= POLLHUP; + mutex_unlock(&pdev->vb_queue_lock); + return ret; +} + +static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct pwc_device *pdev = video_drvdata(file); + int ret; + + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return -ERESTARTSYS; + + ret = pwc_test_n_set_capt_file(pdev, file); + if (ret == 0) + ret = vb2_mmap(&pdev->vb_queue, vma); + + mutex_unlock(&pdev->vb_queue_lock); + return ret; +} + /***************************************************************************/ /* Videobuf2 operations */ @@ -658,8 +782,6 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) if (!pdev->udev) return -ENODEV; - if (mutex_lock_interruptible(&pdev->v4l2_lock)) - return -ERESTARTSYS; /* Turn on camera and set LEDS on */ pwc_camera_power(pdev, 1); pwc_set_leds(pdev, leds[0], leds[1]); @@ -672,7 +794,6 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* And cleanup any queued bufs!! */ pwc_cleanup_queued_bufs(pdev); } - mutex_unlock(&pdev->v4l2_lock); return r; } @@ -681,8 +802,6 @@ static int stop_streaming(struct vb2_queue *vq) { struct pwc_device *pdev = vb2_get_drv_priv(vq); - if (mutex_lock_interruptible(&pdev->v4l2_lock)) - return -ERESTARTSYS; if (pdev->udev) { pwc_set_leds(pdev, 0, 0); pwc_camera_power(pdev, 0); @@ -690,11 +809,22 @@ static int stop_streaming(struct vb2_queue *vq) } pwc_cleanup_queued_bufs(pdev); - mutex_unlock(&pdev->v4l2_lock); return 0; } +static void wait_prepare(struct vb2_queue *vq) +{ + struct pwc_device *pdev = vb2_get_drv_priv(vq); + mutex_unlock(&pdev->vb_queue_lock); +} + +static void wait_finish(struct vb2_queue *vq) +{ + struct pwc_device *pdev = vb2_get_drv_priv(vq); + mutex_lock(&pdev->vb_queue_lock); +} + static struct vb2_ops pwc_vb_queue_ops = { .queue_setup = queue_setup, .buf_init = buffer_init, @@ -704,8 +834,8 @@ static struct vb2_ops pwc_vb_queue_ops = { .buf_queue = buffer_queue, .start_streaming = start_streaming, .stop_streaming = stop_streaming, - .wait_prepare = vb2_ops_wait_prepare, - .wait_finish = vb2_ops_wait_finish, + .wait_prepare = wait_prepare, + .wait_finish = wait_finish, }; /***************************************************************************/ @@ -1006,8 +1136,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id /* Init video_device structure */ memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template)); strcpy(pdev->vdev.name, name); - pdev->vdev.queue = &pdev->vb_queue; - pdev->vdev.queue->lock = &pdev->vb_queue_lock; set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags); video_set_drvdata(&pdev->vdev, pdev); @@ -1062,6 +1190,15 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id pdev->vdev.v4l2_dev = &pdev->v4l2_dev; pdev->vdev.lock = &pdev->v4l2_lock; + /* + * Don't take v4l2_lock for these ioctls. This improves latency if + * v4l2_lock is taken for a long time, e.g. when changing a control + * value, and a new frame is ready to be dequeued. + */ + v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_DQBUF); + v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_QBUF); + v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_QUERYBUF); + rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1); if (rc < 0) { PWC_ERROR("Failed to register as video device (%d).\n", rc); @@ -1116,18 +1253,20 @@ static void usb_pwc_disconnect(struct usb_interface *intf) struct v4l2_device *v = usb_get_intfdata(intf); struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); - mutex_lock(&pdev->vb_queue_lock); mutex_lock(&pdev->v4l2_lock); + + mutex_lock(&pdev->vb_queue_lock); /* No need to keep the urbs around after disconnection */ if (pdev->vb_queue.streaming) pwc_isoc_cleanup(pdev); pdev->udev = NULL; pwc_cleanup_queued_bufs(pdev); + mutex_unlock(&pdev->vb_queue_lock); v4l2_device_disconnect(&pdev->v4l2_dev); video_unregister_device(&pdev->vdev); + mutex_unlock(&pdev->v4l2_lock); - mutex_unlock(pdev->vb_queue.lock); #ifdef CONFIG_USB_PWC_INPUT_EVDEV if (pdev->button_dev) diff --git a/trunk/drivers/media/video/pwc/pwc-v4l.c b/trunk/drivers/media/video/pwc/pwc-v4l.c index 545e9bbdeede..c691e29cc36e 100644 --- a/trunk/drivers/media/video/pwc/pwc-v4l.c +++ b/trunk/drivers/media/video/pwc/pwc-v4l.c @@ -405,7 +405,6 @@ static void pwc_vidioc_fill_fmt(struct v4l2_format *f, f->fmt.pix.pixelformat = pixfmt; f->fmt.pix.bytesperline = f->fmt.pix.width; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.width * 3 / 2; - f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() " "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n", f->fmt.pix.width, @@ -469,8 +468,17 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) if (ret < 0) return ret; - if (vb2_is_busy(&pdev->vb_queue)) - return -EBUSY; + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return -ERESTARTSYS; + + ret = pwc_test_n_set_capt_file(pdev, file); + if (ret) + goto leave; + + if (pdev->vb_queue.streaming) { + ret = -EBUSY; + goto leave; + } pixelformat = f->fmt.pix.pixelformat; @@ -488,6 +496,8 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt); +leave: + mutex_unlock(&pdev->vb_queue_lock); return ret; } @@ -498,9 +508,10 @@ static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap strcpy(cap->driver, PWC_NAME); strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card)); usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info)); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + cap->capabilities = + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE; return 0; } @@ -509,8 +520,7 @@ static int pwc_enum_input(struct file *file, void *fh, struct v4l2_input *i) if (i->index) /* Only one INPUT is supported */ return -EINVAL; - strlcpy(i->name, "Camera", sizeof(i->name)); - i->type = V4L2_INPUT_TYPE_CAMERA; + strcpy(i->name, "usb"); return 0; } @@ -923,6 +933,104 @@ static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format * return pwc_vidioc_try_fmt(pdev, f); } +static int pwc_reqbufs(struct file *file, void *fh, + struct v4l2_requestbuffers *rb) +{ + struct pwc_device *pdev = video_drvdata(file); + int ret; + + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return -ERESTARTSYS; + + ret = pwc_test_n_set_capt_file(pdev, file); + if (ret == 0) + ret = vb2_reqbufs(&pdev->vb_queue, rb); + + mutex_unlock(&pdev->vb_queue_lock); + return ret; +} + +static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) +{ + struct pwc_device *pdev = video_drvdata(file); + int ret; + + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return -ERESTARTSYS; + + ret = pwc_test_n_set_capt_file(pdev, file); + if (ret == 0) + ret = vb2_querybuf(&pdev->vb_queue, buf); + + mutex_unlock(&pdev->vb_queue_lock); + return ret; +} + +static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) +{ + struct pwc_device *pdev = video_drvdata(file); + int ret; + + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return -ERESTARTSYS; + + ret = pwc_test_n_set_capt_file(pdev, file); + if (ret == 0) + ret = vb2_qbuf(&pdev->vb_queue, buf); + + mutex_unlock(&pdev->vb_queue_lock); + return ret; +} + +static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) +{ + struct pwc_device *pdev = video_drvdata(file); + int ret; + + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return -ERESTARTSYS; + + ret = pwc_test_n_set_capt_file(pdev, file); + if (ret == 0) + ret = vb2_dqbuf(&pdev->vb_queue, buf, + file->f_flags & O_NONBLOCK); + + mutex_unlock(&pdev->vb_queue_lock); + return ret; +} + +static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) +{ + struct pwc_device *pdev = video_drvdata(file); + int ret; + + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return -ERESTARTSYS; + + ret = pwc_test_n_set_capt_file(pdev, file); + if (ret == 0) + ret = vb2_streamon(&pdev->vb_queue, i); + + mutex_unlock(&pdev->vb_queue_lock); + return ret; +} + +static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) +{ + struct pwc_device *pdev = video_drvdata(file); + int ret; + + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return -ERESTARTSYS; + + ret = pwc_test_n_set_capt_file(pdev, file); + if (ret == 0) + ret = vb2_streamoff(&pdev->vb_queue, i); + + mutex_unlock(&pdev->vb_queue_lock); + return ret; +} + static int pwc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { @@ -1004,27 +1112,32 @@ static int pwc_s_parm(struct file *file, void *fh, int compression = 0; int ret, fps; - if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + parm->parm.capture.timeperframe.numerator == 0) return -EINVAL; - /* If timeperframe == 0, then reset the framerate to the nominal value. - We pick a high framerate here, and let pwc_set_video_mode() figure - out the best match. */ - if (parm->parm.capture.timeperframe.numerator == 0 || - parm->parm.capture.timeperframe.denominator == 0) - fps = 30; - else - fps = parm->parm.capture.timeperframe.denominator / - parm->parm.capture.timeperframe.numerator; + fps = parm->parm.capture.timeperframe.denominator / + parm->parm.capture.timeperframe.numerator; + + if (mutex_lock_interruptible(&pdev->vb_queue_lock)) + return -ERESTARTSYS; - if (vb2_is_busy(&pdev->vb_queue)) - return -EBUSY; + ret = pwc_test_n_set_capt_file(pdev, file); + if (ret) + goto leave; + + if (pdev->vb_queue.streaming) { + ret = -EBUSY; + goto leave; + } ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt, fps, &compression, 0); pwc_g_parm(file, fh, parm); +leave: + mutex_unlock(&pdev->vb_queue_lock); return ret; } @@ -1037,12 +1150,12 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = { .vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap, .vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap, - .vidioc_reqbufs = vb2_ioctl_reqbufs, - .vidioc_querybuf = vb2_ioctl_querybuf, - .vidioc_qbuf = vb2_ioctl_qbuf, - .vidioc_dqbuf = vb2_ioctl_dqbuf, - .vidioc_streamon = vb2_ioctl_streamon, - .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_reqbufs = pwc_reqbufs, + .vidioc_querybuf = pwc_querybuf, + .vidioc_qbuf = pwc_qbuf, + .vidioc_dqbuf = pwc_dqbuf, + .vidioc_streamon = pwc_streamon, + .vidioc_streamoff = pwc_streamoff, .vidioc_log_status = v4l2_ctrl_log_status, .vidioc_enum_framesizes = pwc_enum_framesizes, .vidioc_enum_frameintervals = pwc_enum_frameintervals, diff --git a/trunk/drivers/media/video/pwc/pwc.h b/trunk/drivers/media/video/pwc/pwc.h index 7a6a0d39c2c6..d6b5b216b9d6 100644 --- a/trunk/drivers/media/video/pwc/pwc.h +++ b/trunk/drivers/media/video/pwc/pwc.h @@ -239,6 +239,7 @@ struct pwc_device int features; /* feature bits */ /*** Video data ***/ + struct file *capt_file; /* file doing video capture */ int vendpoint; /* video isoc endpoint */ int vcinterface; /* video control interface */ int valternate; /* alternate interface needed */ @@ -354,6 +355,8 @@ struct pwc_device extern int pwc_trace; #endif +int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file); + /** Functions in pwc-misc.c */ /* sizes in pixels */ extern const int pwc_image_sizes[PSZ_MAX][2]; diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-capture.c b/trunk/drivers/media/video/s5p-fimc/fimc-capture.c index 6a34183564d2..725812aa0c30 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-capture.c @@ -658,7 +658,7 @@ static void fimc_capture_try_selection(struct fimc_ctx *ctx, r->left = r->top = 0; return; } - if (target == V4L2_SEL_TGT_COMPOSE) { + if (target == V4L2_SEL_TGT_COMPOSE_ACTIVE) { if (ctx->rotation != 90 && ctx->rotation != 270) align_h = 1; max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3)); @@ -685,7 +685,7 @@ static void fimc_capture_try_selection(struct fimc_ctx *ctx, rotate ? sink->f_height : sink->f_width); max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height); - if (target == V4L2_SEL_TGT_COMPOSE) { + if (target == V4L2_SEL_TGT_COMPOSE_ACTIVE) { min_w = min_t(u32, max_w, sink->f_width / max_sc_h); min_h = min_t(u32, max_h, sink->f_height / max_sc_v); if (rotate) { @@ -1146,9 +1146,9 @@ static int fimc_cap_g_selection(struct file *file, void *fh, s->r.height = f->o_height; return 0; - case V4L2_SEL_TGT_COMPOSE: + case V4L2_SEL_TGT_COMPOSE_ACTIVE: f = &ctx->d_frame; - case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_ACTIVE: s->r.left = f->offs_h; s->r.top = f->offs_v; s->r.width = f->width; @@ -1160,7 +1160,7 @@ static int fimc_cap_g_selection(struct file *file, void *fh, } /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */ -static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b) +int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b) { if (a->left < b->left || a->top < b->top) return 0; @@ -1184,9 +1184,9 @@ static int fimc_cap_s_selection(struct file *file, void *fh, if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) return -EINVAL; - if (s->target == V4L2_SEL_TGT_COMPOSE) + if (s->target == V4L2_SEL_TGT_COMPOSE_ACTIVE) f = &ctx->d_frame; - else if (s->target == V4L2_SEL_TGT_CROP) + else if (s->target == V4L2_SEL_TGT_CROP_ACTIVE) f = &ctx->s_frame; else return -EINVAL; @@ -1428,9 +1428,9 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd, mutex_lock(&fimc->lock); switch (sel->target) { - case V4L2_SEL_TGT_COMPOSE_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS: f = &ctx->d_frame; - case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS: r->width = f->o_width; r->height = f->o_height; r->left = 0; @@ -1438,10 +1438,10 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd, mutex_unlock(&fimc->lock); return 0; - case V4L2_SEL_TGT_CROP: + case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: try_sel = v4l2_subdev_get_try_crop(fh, sel->pad); break; - case V4L2_SEL_TGT_COMPOSE: + case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL: try_sel = v4l2_subdev_get_try_compose(fh, sel->pad); f = &ctx->d_frame; break; @@ -1482,12 +1482,12 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd, return -EINVAL; mutex_lock(&fimc->lock); - fimc_capture_try_selection(ctx, r, V4L2_SEL_TGT_CROP); + fimc_capture_try_selection(ctx, r, V4L2_SEL_TGT_CROP_ACTIVE); switch (sel->target) { - case V4L2_SEL_TGT_COMPOSE_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS: f = &ctx->d_frame; - case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS: r->width = f->o_width; r->height = f->o_height; r->left = 0; @@ -1495,10 +1495,10 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd, mutex_unlock(&fimc->lock); return 0; - case V4L2_SEL_TGT_CROP: + case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: try_sel = v4l2_subdev_get_try_crop(fh, sel->pad); break; - case V4L2_SEL_TGT_COMPOSE: + case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL: try_sel = v4l2_subdev_get_try_compose(fh, sel->pad); f = &ctx->d_frame; break; @@ -1514,7 +1514,7 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd, set_frame_crop(f, r->left, r->top, r->width, r->height); set_bit(ST_CAPT_APPLY_CFG, &fimc->state); spin_unlock_irqrestore(&fimc->slock, flags); - if (sel->target == V4L2_SEL_TGT_COMPOSE) + if (sel->target == V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL) ctx->state |= FIMC_COMPOSE; } diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-core.c b/trunk/drivers/media/video/s5p-fimc/fimc-core.c index 1a445404e73d..a4646ca1d56f 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-core.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-core.c @@ -463,7 +463,7 @@ void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v); } -static int fimc_set_color_effect(struct fimc_ctx *ctx, enum v4l2_colorfx colorfx) +int fimc_set_color_effect(struct fimc_ctx *ctx, enum v4l2_colorfx colorfx) { struct fimc_effect *effect = &ctx->effect; diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-lite-reg.c b/trunk/drivers/media/video/s5p-fimc/fimc-lite-reg.c index f996e94873f6..419adfb7cdf9 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-lite-reg.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-lite-reg.c @@ -215,7 +215,7 @@ void flite_hw_set_camera_bus(struct fimc_lite *dev, flite_hw_set_camera_port(dev, s_info->mux_id); } -static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f) +void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f) { static const u32 pixcode[4][2] = { { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR }, diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-lite.c b/trunk/drivers/media/video/s5p-fimc/fimc-lite.c index c5b57e805b68..74ff310db30c 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-lite.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-lite.c @@ -902,7 +902,7 @@ static int fimc_lite_g_selection(struct file *file, void *fh, sel->r.height = f->f_height; return 0; - case V4L2_SEL_TGT_COMPOSE: + case V4L2_SEL_TGT_COMPOSE_ACTIVE: sel->r = f->rect; return 0; } @@ -919,7 +919,7 @@ static int fimc_lite_s_selection(struct file *file, void *fh, unsigned long flags; if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || - sel->target != V4L2_SEL_TGT_COMPOSE) + sel->target != V4L2_SEL_TGT_COMPOSE_ACTIVE) return -EINVAL; fimc_lite_try_compose(fimc, &rect); @@ -1117,9 +1117,9 @@ static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd, struct fimc_lite *fimc = v4l2_get_subdevdata(sd); struct flite_frame *f = &fimc->inp_frame; - if ((sel->target != V4L2_SEL_TGT_CROP && - sel->target != V4L2_SEL_TGT_CROP_BOUNDS) || - sel->pad != FLITE_SD_PAD_SINK) + if ((sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL && + sel->target != V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS) || + sel->pad != FLITE_SD_PAD_SINK) return -EINVAL; if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { @@ -1128,7 +1128,7 @@ static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd, } mutex_lock(&fimc->lock); - if (sel->target == V4L2_SEL_TGT_CROP) { + if (sel->target == V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL) { sel->r = f->rect; } else { sel->r.left = 0; @@ -1153,7 +1153,8 @@ static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd, struct flite_frame *f = &fimc->inp_frame; int ret = 0; - if (sel->target != V4L2_SEL_TGT_CROP || sel->pad != FLITE_SD_PAD_SINK) + if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL || + sel->pad != FLITE_SD_PAD_SINK) return -EINVAL; mutex_lock(&fimc->lock); diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c b/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c index e65bb283fd8a..52cef4865423 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -180,7 +180,7 @@ EXPORT_SYMBOL_GPL(fimc_pipeline_initialize); * sensor clock. * Called with the graph mutex held. */ -static int __fimc_pipeline_shutdown(struct fimc_pipeline *p) +int __fimc_pipeline_shutdown(struct fimc_pipeline *p) { int ret = 0; @@ -1010,7 +1010,7 @@ static struct platform_driver fimc_md_driver = { } }; -static int __init fimc_md_init(void) +int __init fimc_md_init(void) { int ret; @@ -1021,8 +1021,7 @@ static int __init fimc_md_init(void) return platform_driver_register(&fimc_md_driver); } - -static void __exit fimc_md_exit(void) +void __exit fimc_md_exit(void) { platform_driver_unregister(&fimc_md_driver); fimc_unregister_driver(); diff --git a/trunk/drivers/media/video/s5p-jpeg/jpeg-core.c b/trunk/drivers/media/video/s5p-jpeg/jpeg-core.c index 95f23024b17d..28b5225d94f5 100644 --- a/trunk/drivers/media/video/s5p-jpeg/jpeg-core.c +++ b/trunk/drivers/media/video/s5p-jpeg/jpeg-core.c @@ -824,10 +824,10 @@ static int s5p_jpeg_g_selection(struct file *file, void *priv, /* For JPEG blob active == default == bounds */ switch (s->target) { - case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_ACTIVE: case V4L2_SEL_TGT_CROP_BOUNDS: case V4L2_SEL_TGT_CROP_DEFAULT: - case V4L2_SEL_TGT_COMPOSE: + case V4L2_SEL_TGT_COMPOSE_ACTIVE: case V4L2_SEL_TGT_COMPOSE_DEFAULT: s->r.width = ctx->out_q.w; s->r.height = ctx->out_q.h; @@ -1503,7 +1503,29 @@ static struct platform_driver s5p_jpeg_driver = { }, }; -module_platform_driver(s5p_jpeg_driver); +static int __init +s5p_jpeg_register(void) +{ + int ret; + + pr_info("S5P JPEG V4L2 Driver, (c) 2011 Samsung Electronics\n"); + + ret = platform_driver_register(&s5p_jpeg_driver); + + if (ret) + pr_err("%s: failed to register jpeg driver\n", __func__); + + return ret; +} + +static void __exit +s5p_jpeg_unregister(void) +{ + platform_driver_unregister(&s5p_jpeg_driver); +} + +module_init(s5p_jpeg_register); +module_exit(s5p_jpeg_unregister); MODULE_AUTHOR("Andrzej Pietrasiewicz "); MODULE_DESCRIPTION("Samsung JPEG codec driver"); diff --git a/trunk/drivers/media/video/s5p-tv/mixer_video.c b/trunk/drivers/media/video/s5p-tv/mixer_video.c index 6c74b05d1f95..33fde2a763ec 100644 --- a/trunk/drivers/media/video/s5p-tv/mixer_video.c +++ b/trunk/drivers/media/video/s5p-tv/mixer_video.c @@ -367,7 +367,7 @@ static int mxr_g_selection(struct file *file, void *fh, return -EINVAL; switch (s->target) { - case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_ACTIVE: s->r.left = geo->src.x_offset; s->r.top = geo->src.y_offset; s->r.width = geo->src.width; @@ -380,7 +380,7 @@ static int mxr_g_selection(struct file *file, void *fh, s->r.width = geo->src.full_width; s->r.height = geo->src.full_height; break; - case V4L2_SEL_TGT_COMPOSE: + case V4L2_SEL_TGT_COMPOSE_ACTIVE: case V4L2_SEL_TGT_COMPOSE_PADDED: s->r.left = geo->dst.x_offset; s->r.top = geo->dst.y_offset; @@ -449,11 +449,11 @@ static int mxr_s_selection(struct file *file, void *fh, res.height = geo->dst.full_height; break; - case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_ACTIVE: target = &geo->src; stage = MXR_GEOMETRY_CROP; break; - case V4L2_SEL_TGT_COMPOSE: + case V4L2_SEL_TGT_COMPOSE_ACTIVE: case V4L2_SEL_TGT_COMPOSE_PADDED: target = &geo->dst; stage = MXR_GEOMETRY_COMPOSE; diff --git a/trunk/drivers/media/video/s5p-tv/sii9234_drv.c b/trunk/drivers/media/video/s5p-tv/sii9234_drv.c index 6d348f90237a..0f31eccd7b80 100644 --- a/trunk/drivers/media/video/s5p-tv/sii9234_drv.c +++ b/trunk/drivers/media/video/s5p-tv/sii9234_drv.c @@ -419,4 +419,14 @@ static struct i2c_driver sii9234_driver = { .id_table = sii9234_id, }; -module_i2c_driver(sii9234_driver); +static int __init sii9234_init(void) +{ + return i2c_add_driver(&sii9234_driver); +} +module_init(sii9234_init); + +static void __exit sii9234_exit(void) +{ + i2c_del_driver(&sii9234_driver); +} +module_exit(sii9234_exit); diff --git a/trunk/drivers/media/video/saa7121.h b/trunk/drivers/media/video/saa7121.h new file mode 100644 index 000000000000..66967ae37494 --- /dev/null +++ b/trunk/drivers/media/video/saa7121.h @@ -0,0 +1,132 @@ +/* saa7121.h - saa7121 initializations + Copyright (C) 1999 Nathan Laredo (laredo@gnu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ +#ifndef __SAA7121_H__ +#define __SAA7121_H__ + +#define NTSC_BURST_START 0x19 /* 28 */ +#define NTSC_BURST_END 0x1d /* 29 */ +#define NTSC_CHROMA_PHASE 0x67 /* 5a */ +#define NTSC_GAINU 0x76 /* 5b */ +#define NTSC_GAINV 0xa5 /* 5c */ +#define NTSC_BLACK_LEVEL 0x2a /* 5d */ +#define NTSC_BLANKING_LEVEL 0x2e /* 5e */ +#define NTSC_VBI_BLANKING 0x2e /* 5f */ +#define NTSC_DAC_CONTROL 0x11 /* 61 */ +#define NTSC_BURST_AMP 0x3f /* 62 */ +#define NTSC_SUBC3 0x1f /* 63 */ +#define NTSC_SUBC2 0x7c /* 64 */ +#define NTSC_SUBC1 0xf0 /* 65 */ +#define NTSC_SUBC0 0x21 /* 66 */ +#define NTSC_HTRIG 0x72 /* 6c */ +#define NTSC_VTRIG 0x00 /* 6c */ +#define NTSC_MULTI 0x30 /* 6e */ +#define NTSC_CCTTX 0x11 /* 6f */ +#define NTSC_FIRST_ACTIVE 0x12 /* 7a */ +#define NTSC_LAST_ACTIVE 0x02 /* 7b */ +#define NTSC_MSB_VERTICAL 0x40 /* 7c */ + +#define PAL_BURST_START 0x21 /* 28 */ +#define PAL_BURST_END 0x1d /* 29 */ +#define PAL_CHROMA_PHASE 0x3f /* 5a */ +#define PAL_GAINU 0x7d /* 5b */ +#define PAL_GAINV 0xaf /* 5c */ +#define PAL_BLACK_LEVEL 0x23 /* 5d */ +#define PAL_BLANKING_LEVEL 0x35 /* 5e */ +#define PAL_VBI_BLANKING 0x35 /* 5f */ +#define PAL_DAC_CONTROL 0x02 /* 61 */ +#define PAL_BURST_AMP 0x2f /* 62 */ +#define PAL_SUBC3 0xcb /* 63 */ +#define PAL_SUBC2 0x8a /* 64 */ +#define PAL_SUBC1 0x09 /* 65 */ +#define PAL_SUBC0 0x2a /* 66 */ +#define PAL_HTRIG 0x86 /* 6c */ +#define PAL_VTRIG 0x04 /* 6d */ +#define PAL_MULTI 0x20 /* 6e */ +#define PAL_CCTTX 0x15 /* 6f */ +#define PAL_FIRST_ACTIVE 0x16 /* 7a */ +#define PAL_LAST_ACTIVE 0x36 /* 7b */ +#define PAL_MSB_VERTICAL 0x40 /* 7c */ + +/* Initialization Sequence */ + +static __u8 init7121ntsc[] = { + 0x26, 0x0, 0x27, 0x0, + 0x28, NTSC_BURST_START, 0x29, NTSC_BURST_END, + 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0, + 0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0, + 0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0, + 0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0, + 0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0, + 0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0, + 0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0, + 0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0, + 0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0, + 0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0, + 0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0, + 0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0, + 0x5a, NTSC_CHROMA_PHASE, 0x5b, NTSC_GAINU, + 0x5c, NTSC_GAINV, 0x5d, NTSC_BLACK_LEVEL, + 0x5e, NTSC_BLANKING_LEVEL, 0x5f, NTSC_VBI_BLANKING, + 0x60, 0x0, 0x61, NTSC_DAC_CONTROL, + 0x62, NTSC_BURST_AMP, 0x63, NTSC_SUBC3, + 0x64, NTSC_SUBC2, 0x65, NTSC_SUBC1, + 0x66, NTSC_SUBC0, 0x67, 0x80, 0x68, 0x80, + 0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29, + 0x6c, NTSC_HTRIG, 0x6d, NTSC_VTRIG, + 0x6e, NTSC_MULTI, 0x6f, NTSC_CCTTX, + 0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0, + 0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0, + 0x78, 0x0, 0x79, 0x0, 0x7a, NTSC_FIRST_ACTIVE, + 0x7b, NTSC_LAST_ACTIVE, 0x7c, NTSC_MSB_VERTICAL, + 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0 +}; +#define INIT7121LEN (sizeof(init7121ntsc)/2) + +static __u8 init7121pal[] = { + 0x26, 0x0, 0x27, 0x0, + 0x28, PAL_BURST_START, 0x29, PAL_BURST_END, + 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0, + 0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0, + 0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0, + 0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0, + 0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0, + 0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0, + 0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0, + 0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0, + 0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0, + 0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0, + 0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0, + 0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0, + 0x5a, PAL_CHROMA_PHASE, 0x5b, PAL_GAINU, + 0x5c, PAL_GAINV, 0x5d, PAL_BLACK_LEVEL, + 0x5e, PAL_BLANKING_LEVEL, 0x5f, PAL_VBI_BLANKING, + 0x60, 0x0, 0x61, PAL_DAC_CONTROL, + 0x62, PAL_BURST_AMP, 0x63, PAL_SUBC3, + 0x64, PAL_SUBC2, 0x65, PAL_SUBC1, + 0x66, PAL_SUBC0, 0x67, 0x80, 0x68, 0x80, + 0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29, + 0x6c, PAL_HTRIG, 0x6d, PAL_VTRIG, + 0x6e, PAL_MULTI, 0x6f, PAL_CCTTX, + 0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0, + 0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0, + 0x78, 0x0, 0x79, 0x0, 0x7a, PAL_FIRST_ACTIVE, + 0x7b, PAL_LAST_ACTIVE, 0x7c, PAL_MSB_VERTICAL, + 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0 +}; +#endif diff --git a/trunk/drivers/media/video/saa7134/saa7134-dvb.c b/trunk/drivers/media/video/saa7134/saa7134-dvb.c index cc7f3d6ee966..5dfd826d734e 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-dvb.c +++ b/trunk/drivers/media/video/saa7134/saa7134-dvb.c @@ -1282,7 +1282,7 @@ static int dvb_init(struct saa7134_dev *dev) case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: if (configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_PHILIPS_EUROPA: case SAA7134_BOARD_VIDEOMATE_DVBT_300: @@ -1322,7 +1322,7 @@ static int dvb_init(struct saa7134_dev *dev) case SAA7134_BOARD_KWORLD_DVBT_210: if (configure_tda827x_fe(dev, &kworld_dvb_t_210_config, &tda827x_cfg_2) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_HAUPPAUGE_HVR1120: fe0->dvb.frontend = dvb_attach(tda10048_attach, @@ -1340,17 +1340,17 @@ static int dvb_init(struct saa7134_dev *dev) case SAA7134_BOARD_PHILIPS_TIGER: if (configure_tda827x_fe(dev, &philips_tiger_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_PINNACLE_PCTV_310i: if (configure_tda827x_fe(dev, &pinnacle_pctv_310i_config, &tda827x_cfg_1) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_HAUPPAUGE_HVR1110: if (configure_tda827x_fe(dev, &hauppauge_hvr_1110_config, &tda827x_cfg_1) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_HAUPPAUGE_HVR1150: fe0->dvb.frontend = dvb_attach(lgdt3305_attach, @@ -1368,30 +1368,30 @@ static int dvb_init(struct saa7134_dev *dev) case SAA7134_BOARD_ASUSTeK_P7131_DUAL: if (configure_tda827x_fe(dev, &asus_p7131_dual_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_FLYDVBT_LR301: if (configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_FLYDVB_TRIO: if (!use_frontend) { /* terrestrial */ if (configure_tda827x_fe(dev, &lifeview_trio_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; } else { /* satellite */ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); if (fe0->dvb.frontend) { if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63, &dev->i2c_adap, 0) == NULL) { wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__); - goto detach_frontend; + goto dettach_frontend; } if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0) == NULL) { wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__); - goto detach_frontend; + goto dettach_frontend; } } } @@ -1407,7 +1407,7 @@ static int dvb_init(struct saa7134_dev *dev) &ads_duo_cfg) == NULL) { wprintk("no tda827x tuner found at addr: %02x\n", ads_tech_duo_config.tuner_address); - goto detach_frontend; + goto dettach_frontend; } } else wprintk("failed to attach tda10046\n"); @@ -1415,13 +1415,13 @@ static int dvb_init(struct saa7134_dev *dev) case SAA7134_BOARD_TEVION_DVBT_220RF: if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_MEDION_MD8800_QUADRO: if (!use_frontend) { /* terrestrial */ if (configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; } else { /* satellite */ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); @@ -1435,7 +1435,7 @@ static int dvb_init(struct saa7134_dev *dev) 0x60, &dev->i2c_adap, 0) == NULL) { wprintk("%s: Medion Quadro, no tda826x " "found !\n", __func__); - goto detach_frontend; + goto dettach_frontend; } if (dev_id != 0x08) { /* we need to open the i2c gate (we know it exists) */ @@ -1444,7 +1444,7 @@ static int dvb_init(struct saa7134_dev *dev) &dev->i2c_adap, 0x08, 0, 0) == NULL) { wprintk("%s: Medion Quadro, no ISL6405 " "found !\n", __func__); - goto detach_frontend; + goto dettach_frontend; } if (dev_id == 0x07) { /* fire up the 2nd section of the LNB supply since @@ -1503,12 +1503,12 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { wprintk("%s: No tda826x found!\n", __func__); - goto detach_frontend; + goto dettach_frontend; } if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0) == NULL) { wprintk("%s: No ISL6421 found!\n", __func__); - goto detach_frontend; + goto dettach_frontend; } } break; @@ -1537,37 +1537,37 @@ static int dvb_init(struct saa7134_dev *dev) case SAA7134_BOARD_CINERGY_HT_PCMCIA: if (configure_tda827x_fe(dev, &cinergy_ht_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_CINERGY_HT_PCI: if (configure_tda827x_fe(dev, &cinergy_ht_pci_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_PHILIPS_TIGER_S: if (configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_ASUS_P7131_4871: if (configure_tda827x_fe(dev, &asus_p7131_4871_config, &tda827x_cfg_2) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: if (configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config, &tda827x_cfg_2) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_AVERMEDIA_SUPER_007: if (configure_tda827x_fe(dev, &avermedia_super_007_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: if (configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config, &tda827x_cfg_2_sw42) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_PHILIPS_SNAKE: fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, @@ -1576,24 +1576,24 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { wprintk("%s: No tda826x found!\n", __func__); - goto detach_frontend; + goto dettach_frontend; } if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, &dev->i2c_adap, 0, 0) == NULL) { wprintk("%s: No lnbp21 found!\n", __func__); - goto detach_frontend; + goto dettach_frontend; } } break; case SAA7134_BOARD_CREATIX_CTX953: if (configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_MSI_TVANYWHERE_AD11: if (configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: dprintk("AverMedia E506R dvb setup\n"); @@ -1614,7 +1614,7 @@ static int dvb_init(struct saa7134_dev *dev) &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) { wprintk("%s: MD7134 DVB-S, no SD1878 " "found !\n", __func__); - goto detach_frontend; + goto dettach_frontend; } /* we need to open the i2c gate (we know it exists) */ fe = fe0->dvb.frontend; @@ -1623,7 +1623,7 @@ static int dvb_init(struct saa7134_dev *dev) &dev->i2c_adap, 0x08, 0, 0) == NULL) { wprintk("%s: MD7134 DVB-S, no ISL6405 " "found !\n", __func__); - goto detach_frontend; + goto dettach_frontend; } fe->ops.i2c_gate_ctrl(fe, 0); dev->original_set_voltage = fe->ops.set_voltage; @@ -1645,7 +1645,7 @@ static int dvb_init(struct saa7134_dev *dev) if (!use_frontend) { /* terrestrial */ if (configure_tda827x_fe(dev, &asus_tiger_3in1_config, &tda827x_cfg_2) < 0) - goto detach_frontend; + goto dettach_frontend; } else { /* satellite */ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); @@ -1655,13 +1655,13 @@ static int dvb_init(struct saa7134_dev *dev) &dev->i2c_adap, 0) == NULL) { wprintk("%s: Asus Tiger 3in1, no " "tda826x found!\n", __func__); - goto detach_frontend; + goto dettach_frontend; } if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, &dev->i2c_adap, 0, 0) == NULL) { wprintk("%s: Asus Tiger 3in1, no lnbp21" " found!\n", __func__); - goto detach_frontend; + goto dettach_frontend; } } } @@ -1670,7 +1670,7 @@ static int dvb_init(struct saa7134_dev *dev) if (!use_frontend) { /* terrestrial */ if (configure_tda827x_fe(dev, &asus_ps3_100_config, &tda827x_cfg_2) < 0) - goto detach_frontend; + goto dettach_frontend; } else { /* satellite */ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); @@ -1680,13 +1680,13 @@ static int dvb_init(struct saa7134_dev *dev) &dev->i2c_adap, 0) == NULL) { wprintk("%s: Asus My Cinema PS3-100, no " "tda826x found!\n", __func__); - goto detach_frontend; + goto dettach_frontend; } if (dvb_attach(lnbp21_attach, fe0->dvb.frontend, &dev->i2c_adap, 0, 0) == NULL) { wprintk("%s: Asus My Cinema PS3-100, no lnbp21" " found!\n", __func__); - goto detach_frontend; + goto dettach_frontend; } } } @@ -1694,7 +1694,7 @@ static int dvb_init(struct saa7134_dev *dev) case SAA7134_BOARD_ASUSTeK_TIGER: if (configure_tda827x_fe(dev, &philips_tiger_config, &tda827x_cfg_0) < 0) - goto detach_frontend; + goto dettach_frontend; break; case SAA7134_BOARD_BEHOLD_H6: fe0->dvb.frontend = dvb_attach(zl10353_attach, @@ -1830,19 +1830,19 @@ static int dvb_init(struct saa7134_dev *dev) }; if (!fe0->dvb.frontend) - goto detach_frontend; + goto dettach_frontend; fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); if (!fe) { printk(KERN_ERR "%s/2: xc3028 attach failed\n", dev->name); - goto detach_frontend; + goto dettach_frontend; } } if (NULL == fe0->dvb.frontend) { printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); - goto detach_frontend; + goto dettach_frontend; } /* define general-purpose callback pointer */ fe0->dvb.frontend->callback = saa7134_tuner_callback; @@ -1864,7 +1864,7 @@ static int dvb_init(struct saa7134_dev *dev) } return ret; -detach_frontend: +dettach_frontend: videobuf_dvb_dealloc_frontends(&dev->frontends); return -EINVAL; } diff --git a/trunk/drivers/media/video/saa7146.h b/trunk/drivers/media/video/saa7146.h new file mode 100644 index 000000000000..9fadb331a40b --- /dev/null +++ b/trunk/drivers/media/video/saa7146.h @@ -0,0 +1,112 @@ +/* + saa7146.h - definitions philips saa7146 based cards + Copyright (C) 1999 Nathan Laredo (laredo@gnu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __SAA7146__ +#define __SAA7146__ + +#define SAA7146_VERSION_CODE 0x000101 + +#include +#include + +#ifndef O_NONCAP +#define O_NONCAP O_TRUNC +#endif + +#define MAX_GBUFFERS 2 +#define FBUF_SIZE 0x190000 + +#ifdef __KERNEL__ + +struct saa7146_window +{ + int x, y; + ushort width, height; + ushort bpp, bpl; + ushort swidth, sheight; + short cropx, cropy; + ushort cropwidth, cropheight; + unsigned long vidadr; + int color_fmt; + ushort depth; +}; + +/* Per-open data for handling multiple opens on one device */ +struct device_open +{ + int isopen; + int noncapturing; + struct saa7146 *dev; +}; +#define MAX_OPENS 3 + +struct saa7146 +{ + struct video_device video_dev; + struct video_picture picture; + struct video_audio audio_dev; + struct video_info vidinfo; + int user; + int cap; + int capuser; + int irqstate; /* irq routine is state driven */ + int writemode; + int playmode; + unsigned int nr; + unsigned long irq; /* IRQ used by SAA7146 card */ + unsigned short id; + unsigned char revision; + unsigned char boardcfg[64]; /* 64 bytes of config from eeprom */ + unsigned long saa7146_adr; /* bus address of IO mem from PCI BIOS */ + struct saa7146_window win; + unsigned char __iomem *saa7146_mem; /* pointer to mapped IO memory */ + struct device_open open_data[MAX_OPENS]; +#define MAX_MARKS 16 + /* for a/v sync */ + int endmark[MAX_MARKS], endmarkhead, endmarktail; + u32 *dmaRPS1, *pageRPS1, *dmaRPS2, *pageRPS2, *dmavid1, *dmavid2, + *dmavid3, *dmaa1in, *dmaa1out, *dmaa2in, *dmaa2out, + *pagedebi, *pagevid1, *pagevid2, *pagevid3, *pagea1in, + *pagea1out, *pagea2in, *pagea2out; + wait_queue_head_t i2cq, debiq, audq, vidq; + u8 *vidbuf, *audbuf, *osdbuf, *dmadebi; + int audhead, vidhead, osdhead, audtail, vidtail, osdtail; + spinlock_t lock; /* the device lock */ +}; +#endif + +#ifdef _ALPHA_SAA7146 +#define saawrite(dat,adr) writel((dat), saa->saa7146_adr+(adr)) +#define saaread(adr) readl(saa->saa7146_adr+(adr)) +#else +#define saawrite(dat,adr) writel((dat), saa->saa7146_mem+(adr)) +#define saaread(adr) readl(saa->saa7146_mem+(adr)) +#endif + +#define saaand(dat,adr) saawrite((dat) & saaread(adr), adr) +#define saaor(dat,adr) saawrite((dat) | saaread(adr), adr) +#define saaaor(dat,mask,adr) saawrite((dat) | ((mask) & saaread(adr)), adr) + +/* bitmask of attached hardware found */ +#define SAA7146_UNKNOWN 0x00000000 +#define SAA7146_SAA7111 0x00000001 +#define SAA7146_SAA7121 0x00000002 +#define SAA7146_IBMMPEG 0x00000004 + +#endif diff --git a/trunk/drivers/media/video/saa7146reg.h b/trunk/drivers/media/video/saa7146reg.h new file mode 100644 index 000000000000..80ec2c146b4c --- /dev/null +++ b/trunk/drivers/media/video/saa7146reg.h @@ -0,0 +1,283 @@ +/* + saa7146.h - definitions philips saa7146 based cards + Copyright (C) 1999 Nathan Laredo (laredo@gnu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __SAA7146_REG__ +#define __SAA7146_REG__ +#define SAA7146_BASE_ODD1 0x00 +#define SAA7146_BASE_EVEN1 0x04 +#define SAA7146_PROT_ADDR1 0x08 +#define SAA7146_PITCH1 0x0c +#define SAA7146_PAGE1 0x10 +#define SAA7146_NUM_LINE_BYTE1 0x14 +#define SAA7146_BASE_ODD2 0x18 +#define SAA7146_BASE_EVEN2 0x1c +#define SAA7146_PROT_ADDR2 0x20 +#define SAA7146_PITCH2 0x24 +#define SAA7146_PAGE2 0x28 +#define SAA7146_NUM_LINE_BYTE2 0x2c +#define SAA7146_BASE_ODD3 0x30 +#define SAA7146_BASE_EVEN3 0x34 +#define SAA7146_PROT_ADDR3 0x38 +#define SAA7146_PITCH3 0x3c +#define SAA7146_PAGE3 0x40 +#define SAA7146_NUM_LINE_BYTE3 0x44 +#define SAA7146_PCI_BT_V1 0x48 +#define SAA7146_PCI_BT_V2 0x49 +#define SAA7146_PCI_BT_V3 0x4a +#define SAA7146_PCI_BT_DEBI 0x4b +#define SAA7146_PCI_BT_A 0x4c +#define SAA7146_DD1_INIT 0x50 +#define SAA7146_DD1_STREAM_B 0x54 +#define SAA7146_DD1_STREAM_A 0x56 +#define SAA7146_BRS_CTRL 0x58 +#define SAA7146_HPS_CTRL 0x5c +#define SAA7146_HPS_V_SCALE 0x60 +#define SAA7146_HPS_V_GAIN 0x64 +#define SAA7146_HPS_H_PRESCALE 0x68 +#define SAA7146_HPS_H_SCALE 0x6c +#define SAA7146_BCS_CTRL 0x70 +#define SAA7146_CHROMA_KEY_RANGE 0x74 +#define SAA7146_CLIP_FORMAT_CTRL 0x78 +#define SAA7146_DEBI_CONFIG 0x7c +#define SAA7146_DEBI_COMMAND 0x80 +#define SAA7146_DEBI_PAGE 0x84 +#define SAA7146_DEBI_AD 0x88 +#define SAA7146_I2C_TRANSFER 0x8c +#define SAA7146_I2C_STATUS 0x90 +#define SAA7146_BASE_A1_IN 0x94 +#define SAA7146_PROT_A1_IN 0x98 +#define SAA7146_PAGE_A1_IN 0x9C +#define SAA7146_BASE_A1_OUT 0xa0 +#define SAA7146_PROT_A1_OUT 0xa4 +#define SAA7146_PAGE_A1_OUT 0xa8 +#define SAA7146_BASE_A2_IN 0xac +#define SAA7146_PROT_A2_IN 0xb0 +#define SAA7146_PAGE_A2_IN 0xb4 +#define SAA7146_BASE_A2_OUT 0xb8 +#define SAA7146_PROT_A2_OUT 0xbc +#define SAA7146_PAGE_A2_OUT 0xc0 +#define SAA7146_RPS_PAGE0 0xc4 +#define SAA7146_RPS_PAGE1 0xc8 +#define SAA7146_RPS_THRESH0 0xcc +#define SAA7146_RPS_THRESH1 0xd0 +#define SAA7146_RPS_TOV0 0xd4 +#define SAA7146_RPS_TOV1 0xd8 +#define SAA7146_IER 0xdc +#define SAA7146_GPIO_CTRL 0xe0 +#define SAA7146_EC1SSR 0xe4 +#define SAA7146_EC2SSR 0xe8 +#define SAA7146_ECT1R 0xec +#define SAA7146_ECT2R 0xf0 +#define SAA7146_ACON1 0xf4 +#define SAA7146_ACON2 0xf8 +#define SAA7146_MC1 0xfc +#define SAA7146_MC2 0x100 +#define SAA7146_RPS_ADDR0 0x104 +#define SAA7146_RPS_ADDR1 0x108 +#define SAA7146_ISR 0x10c +#define SAA7146_PSR 0x110 +#define SAA7146_SSR 0x114 +#define SAA7146_EC1R 0x118 +#define SAA7146_EC2R 0x11c +#define SAA7146_VDP1 0x120 +#define SAA7146_VDP2 0x124 +#define SAA7146_VDP3 0x128 +#define SAA7146_ADP1 0x12c +#define SAA7146_ADP2 0x130 +#define SAA7146_ADP3 0x134 +#define SAA7146_ADP4 0x138 +#define SAA7146_DDP 0x13c +#define SAA7146_LEVEL_REP 0x140 +#define SAA7146_FB_BUFFER1 0x144 +#define SAA7146_FB_BUFFER2 0x148 +#define SAA7146_A_TIME_SLOT1 0x180 +#define SAA7146_A_TIME_SLOT2 0x1C0 + +/* bitfield defines */ +#define MASK_31 0x80000000 +#define MASK_30 0x40000000 +#define MASK_29 0x20000000 +#define MASK_28 0x10000000 +#define MASK_27 0x08000000 +#define MASK_26 0x04000000 +#define MASK_25 0x02000000 +#define MASK_24 0x01000000 +#define MASK_23 0x00800000 +#define MASK_22 0x00400000 +#define MASK_21 0x00200000 +#define MASK_20 0x00100000 +#define MASK_19 0x00080000 +#define MASK_18 0x00040000 +#define MASK_17 0x00020000 +#define MASK_16 0x00010000 +#define MASK_15 0x00008000 +#define MASK_14 0x00004000 +#define MASK_13 0x00002000 +#define MASK_12 0x00001000 +#define MASK_11 0x00000800 +#define MASK_10 0x00000400 +#define MASK_09 0x00000200 +#define MASK_08 0x00000100 +#define MASK_07 0x00000080 +#define MASK_06 0x00000040 +#define MASK_05 0x00000020 +#define MASK_04 0x00000010 +#define MASK_03 0x00000008 +#define MASK_02 0x00000004 +#define MASK_01 0x00000002 +#define MASK_00 0x00000001 +#define MASK_B0 0x000000ff +#define MASK_B1 0x0000ff00 +#define MASK_B2 0x00ff0000 +#define MASK_B3 0xff000000 +#define MASK_W0 0x0000ffff +#define MASK_W1 0xffff0000 +#define MASK_PA 0xfffffffc +#define MASK_PR 0xfffffffe +#define MASK_ER 0xffffffff +#define MASK_NONE 0x00000000 + +#define SAA7146_PAGE_MAP_EN MASK_11 +/* main control register 1 */ +#define SAA7146_MC1_MRST_N MASK_15 +#define SAA7146_MC1_ERPS1 MASK_13 +#define SAA7146_MC1_ERPS0 MASK_12 +#define SAA7146_MC1_EDP MASK_11 +#define SAA7146_MC1_EVP MASK_10 +#define SAA7146_MC1_EAP MASK_09 +#define SAA7146_MC1_EI2C MASK_08 +#define SAA7146_MC1_TR_E_DEBI MASK_07 +#define SAA7146_MC1_TR_E_1 MASK_06 +#define SAA7146_MC1_TR_E_2 MASK_05 +#define SAA7146_MC1_TR_E_3 MASK_04 +#define SAA7146_MC1_TR_E_A2_OUT MASK_03 +#define SAA7146_MC1_TR_E_A2_IN MASK_02 +#define SAA7146_MC1_TR_E_A1_OUT MASK_01 +#define SAA7146_MC1_TR_E_A1_IN MASK_00 +/* main control register 2 */ +#define SAA7146_MC2_RPS_SIG4 MASK_15 +#define SAA7146_MC2_RPS_SIG3 MASK_14 +#define SAA7146_MC2_RPS_SIG2 MASK_13 +#define SAA7146_MC2_RPS_SIG1 MASK_12 +#define SAA7146_MC2_RPS_SIG0 MASK_11 +#define SAA7146_MC2_UPLD_D1_B MASK_10 +#define SAA7146_MC2_UPLD_D1_A MASK_09 +#define SAA7146_MC2_UPLD_BRS MASK_08 +#define SAA7146_MC2_UPLD_HPS_H MASK_06 +#define SAA7146_MC2_UPLD_HPS_V MASK_05 +#define SAA7146_MC2_UPLD_DMA3 MASK_04 +#define SAA7146_MC2_UPLD_DMA2 MASK_03 +#define SAA7146_MC2_UPLD_DMA1 MASK_02 +#define SAA7146_MC2_UPLD_DEBI MASK_01 +#define SAA7146_MC2_UPLD_I2C MASK_00 +/* Primary Status Register and Interrupt Enable/Status Registers */ +#define SAA7146_PSR_PPEF MASK_31 +#define SAA7146_PSR_PABO MASK_30 +#define SAA7146_PSR_PPED MASK_29 +#define SAA7146_PSR_RPS_I1 MASK_28 +#define SAA7146_PSR_RPS_I0 MASK_27 +#define SAA7146_PSR_RPS_LATE1 MASK_26 +#define SAA7146_PSR_RPS_LATE0 MASK_25 +#define SAA7146_PSR_RPS_E1 MASK_24 +#define SAA7146_PSR_RPS_E0 MASK_23 +#define SAA7146_PSR_RPS_TO1 MASK_22 +#define SAA7146_PSR_RPS_TO0 MASK_21 +#define SAA7146_PSR_UPLD MASK_20 +#define SAA7146_PSR_DEBI_S MASK_19 +#define SAA7146_PSR_DEBI_E MASK_18 +#define SAA7146_PSR_I2C_S MASK_17 +#define SAA7146_PSR_I2C_E MASK_16 +#define SAA7146_PSR_A2_IN MASK_15 +#define SAA7146_PSR_A2_OUT MASK_14 +#define SAA7146_PSR_A1_IN MASK_13 +#define SAA7146_PSR_A1_OUT MASK_12 +#define SAA7146_PSR_AFOU MASK_11 +#define SAA7146_PSR_V_PE MASK_10 +#define SAA7146_PSR_VFOU MASK_09 +#define SAA7146_PSR_FIDA MASK_08 +#define SAA7146_PSR_FIDB MASK_07 +#define SAA7146_PSR_PIN3 MASK_06 +#define SAA7146_PSR_PIN2 MASK_05 +#define SAA7146_PSR_PIN1 MASK_04 +#define SAA7146_PSR_PIN0 MASK_03 +#define SAA7146_PSR_ECS MASK_02 +#define SAA7146_PSR_EC3S MASK_01 +#define SAA7146_PSR_EC0S MASK_00 +/* Secondary Status Register */ +#define SAA7146_SSR_PRQ MASK_31 +#define SAA7146_SSR_PMA MASK_30 +#define SAA7146_SSR_RPS_RE1 MASK_29 +#define SAA7146_SSR_RPS_PE1 MASK_28 +#define SAA7146_SSR_RPS_A1 MASK_27 +#define SAA7146_SSR_RPS_RE0 MASK_26 +#define SAA7146_SSR_RPS_PE0 MASK_25 +#define SAA7146_SSR_RPS_A0 MASK_24 +#define SAA7146_SSR_DEBI_TO MASK_23 +#define SAA7146_SSR_DEBI_EF MASK_22 +#define SAA7146_SSR_I2C_EA MASK_21 +#define SAA7146_SSR_I2C_EW MASK_20 +#define SAA7146_SSR_I2C_ER MASK_19 +#define SAA7146_SSR_I2C_EL MASK_18 +#define SAA7146_SSR_I2C_EF MASK_17 +#define SAA7146_SSR_V3P MASK_16 +#define SAA7146_SSR_V2P MASK_15 +#define SAA7146_SSR_V1P MASK_14 +#define SAA7146_SSR_VF3 MASK_13 +#define SAA7146_SSR_VF2 MASK_12 +#define SAA7146_SSR_VF1 MASK_11 +#define SAA7146_SSR_AF2_IN MASK_10 +#define SAA7146_SSR_AF2_OUT MASK_09 +#define SAA7146_SSR_AF1_IN MASK_08 +#define SAA7146_SSR_AF1_OUT MASK_07 +#define SAA7146_SSR_VGT MASK_05 +#define SAA7146_SSR_LNQG MASK_04 +#define SAA7146_SSR_EC5S MASK_03 +#define SAA7146_SSR_EC4S MASK_02 +#define SAA7146_SSR_EC2S MASK_01 +#define SAA7146_SSR_EC1S MASK_00 +/* I2C status register */ +#define SAA7146_I2C_ABORT MASK_07 +#define SAA7146_I2C_SPERR MASK_06 +#define SAA7146_I2C_APERR MASK_05 +#define SAA7146_I2C_DTERR MASK_04 +#define SAA7146_I2C_DRERR MASK_03 +#define SAA7146_I2C_AL MASK_02 +#define SAA7146_I2C_ERR MASK_01 +#define SAA7146_I2C_BUSY MASK_00 +/* output formats */ +#define SAA7146_YUV422 0 +#define SAA7146_RGB16 0 +#define SAA7146_YUV444 1 +#define SAA7146_RGB24 1 +#define SAA7146_ARGB32 2 +#define SAA7146_YUV411 3 +#define SAA7146_ARGB15 3 +#define SAA7146_YUV2 4 +#define SAA7146_RGAB15 4 +#define SAA7146_Y8 6 +#define SAA7146_YUV8 7 +#define SAA7146_RGB8 7 +#define SAA7146_YUV444p 8 +#define SAA7146_YUV422p 9 +#define SAA7146_YUV420p 10 +#define SAA7146_YUV1620 11 +#define SAA7146_Y1 13 +#define SAA7146_Y2 14 +#define SAA7146_YUV1 15 +#endif diff --git a/trunk/drivers/media/video/saa7164/saa7164-api.c b/trunk/drivers/media/video/saa7164/saa7164-api.c index c8799fdaae67..8a98ab68239e 100644 --- a/trunk/drivers/media/video/saa7164/saa7164-api.c +++ b/trunk/drivers/media/video/saa7164/saa7164-api.c @@ -1367,6 +1367,7 @@ int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg, struct saa7164_dev *dev = bus->dev; u16 len = 0; int unitid; + u32 regval; u8 buf[256]; int ret; @@ -1375,6 +1376,19 @@ int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg, if (reglen > 4) return -EIO; + if (reglen == 1) + regval = *(reg); + else + if (reglen == 2) + regval = ((*(reg) << 8) || *(reg+1)); + else + if (reglen == 3) + regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2)); + else + if (reglen == 4) + regval = ((*(reg) << 24) | (*(reg+1) << 16) | + (*(reg+2) << 8) | *(reg+3)); + /* Prepare the send buffer */ /* Bytes 00-03 source register length * 04-07 source bytes to read diff --git a/trunk/drivers/media/video/smiapp/Kconfig b/trunk/drivers/media/video/smiapp/Kconfig index 3149cda1d0db..fb99ff18be07 100644 --- a/trunk/drivers/media/video/smiapp/Kconfig +++ b/trunk/drivers/media/video/smiapp/Kconfig @@ -1,7 +1,6 @@ config VIDEO_SMIAPP tristate "SMIA++/SMIA sensor support" depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK - depends on MEDIA_CAMERA_SUPPORT select VIDEO_SMIAPP_PLL ---help--- This is a generic driver for SMIA++/SMIA camera modules. diff --git a/trunk/drivers/media/video/smiapp/smiapp-core.c b/trunk/drivers/media/video/smiapp/smiapp-core.c index f466a7edcb2a..9cf5bda35fbe 100644 --- a/trunk/drivers/media/video/smiapp/smiapp-core.c +++ b/trunk/drivers/media/video/smiapp/smiapp-core.c @@ -39,9 +39,9 @@ #include "smiapp.h" -#define SMIAPP_ALIGN_DIM(dim, flags) \ - ((flags) & V4L2_SEL_FLAG_GE \ - ? ALIGN((dim), 2) \ +#define SMIAPP_ALIGN_DIM(dim, flags) \ + ((flags) & V4L2_SUBDEV_SEL_FLAG_SIZE_GE \ + ? ALIGN((dim), 2) \ : (dim) & ~1) /* @@ -1631,7 +1631,7 @@ static void smiapp_propagate(struct v4l2_subdev *subdev, smiapp_get_crop_compose(subdev, fh, crops, &comp, which); switch (target) { - case V4L2_SEL_TGT_CROP: + case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: comp->width = crops[SMIAPP_PAD_SINK]->width; comp->height = crops[SMIAPP_PAD_SINK]->height; if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { @@ -1647,7 +1647,7 @@ static void smiapp_propagate(struct v4l2_subdev *subdev, } } /* Fall through */ - case V4L2_SEL_TGT_COMPOSE: + case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL: *crops[SMIAPP_PAD_SRC] = *comp; break; default: @@ -1723,7 +1723,7 @@ static int smiapp_set_format(struct v4l2_subdev *subdev, if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) ssd->sink_fmt = *crops[ssd->sink_pad]; smiapp_propagate(subdev, fh, fmt->which, - V4L2_SEL_TGT_CROP); + V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL); mutex_unlock(&sensor->mutex); @@ -1748,14 +1748,14 @@ static int scaling_goodness(struct v4l2_subdev *subdev, int w, int ask_w, h &= ~1; ask_h &= ~1; - if (flags & V4L2_SEL_FLAG_GE) { + if (flags & V4L2_SUBDEV_SEL_FLAG_SIZE_GE) { if (w < ask_w) val -= SCALING_GOODNESS; if (h < ask_h) val -= SCALING_GOODNESS; } - if (flags & V4L2_SEL_FLAG_LE) { + if (flags & V4L2_SUBDEV_SEL_FLAG_SIZE_LE) { if (w > ask_w) val -= SCALING_GOODNESS; if (h > ask_h) @@ -1958,7 +1958,7 @@ static int smiapp_set_compose(struct v4l2_subdev *subdev, *comp = sel->r; smiapp_propagate(subdev, fh, sel->which, - V4L2_SEL_TGT_COMPOSE); + V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL); if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) return smiapp_update_mode(sensor); @@ -1974,8 +1974,8 @@ static int __smiapp_sel_supported(struct v4l2_subdev *subdev, /* We only implement crop in three places. */ switch (sel->target) { - case V4L2_SEL_TGT_CROP: - case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: + case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS: if (ssd == sensor->pixel_array && sel->pad == SMIAPP_PA_PAD_SRC) return 0; @@ -1988,8 +1988,8 @@ static int __smiapp_sel_supported(struct v4l2_subdev *subdev, == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) return 0; return -EINVAL; - case V4L2_SEL_TGT_COMPOSE: - case V4L2_SEL_TGT_COMPOSE_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL: + case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS: if (sel->pad == ssd->source_pad) return -EINVAL; if (ssd == sensor->binner) @@ -2051,7 +2051,7 @@ static int smiapp_set_crop(struct v4l2_subdev *subdev, if (ssd != sensor->pixel_array && sel->pad == SMIAPP_PAD_SINK) smiapp_propagate(subdev, fh, sel->which, - V4L2_SEL_TGT_CROP); + V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL); return 0; } @@ -2085,7 +2085,7 @@ static int __smiapp_get_selection(struct v4l2_subdev *subdev, } switch (sel->target) { - case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS: if (ssd == sensor->pixel_array) { sel->r.width = sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; @@ -2097,11 +2097,11 @@ static int __smiapp_get_selection(struct v4l2_subdev *subdev, sel->r = *comp; } break; - case V4L2_SEL_TGT_CROP: - case V4L2_SEL_TGT_COMPOSE_BOUNDS: + case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: + case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS: sel->r = *crops[sel->pad]; break; - case V4L2_SEL_TGT_COMPOSE: + case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL: sel->r = *comp; break; } @@ -2148,10 +2148,10 @@ static int smiapp_set_selection(struct v4l2_subdev *subdev, sel->r.height); switch (sel->target) { - case V4L2_SEL_TGT_CROP: + case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: ret = smiapp_set_crop(subdev, fh, sel); break; - case V4L2_SEL_TGT_COMPOSE: + case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL: ret = smiapp_set_compose(subdev, fh, sel); break; default: diff --git a/trunk/drivers/media/video/sn9c102/sn9c102.h b/trunk/drivers/media/video/sn9c102/sn9c102.h index 2bc153e869be..22ea211ab54f 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102.h +++ b/trunk/drivers/media/video/sn9c102/sn9c102.h @@ -182,7 +182,7 @@ do { \ # define V4LDBG(level, name, cmd) \ do { \ if (debug >= (level)) \ - v4l_printk_ioctl(name, cmd); \ + v4l_print_ioctl(name, cmd); \ } while (0) # define KDBG(level, fmt, args...) \ do { \ diff --git a/trunk/drivers/media/video/tuner-core.c b/trunk/drivers/media/video/tuner-core.c index b5a819af2b8c..1ad5ab6ce5cf 100644 --- a/trunk/drivers/media/video/tuner-core.c +++ b/trunk/drivers/media/video/tuner-core.c @@ -228,16 +228,6 @@ static int fe_has_signal(struct dvb_frontend *fe) return strength; } -static int fe_get_afc(struct dvb_frontend *fe) -{ - s32 afc = 0; - - if (fe->ops.tuner_ops.get_afc) - fe->ops.tuner_ops.get_afc(fe, &afc); - - return 0; -} - static int fe_set_config(struct dvb_frontend *fe, void *priv_cfg) { struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops; @@ -257,7 +247,6 @@ static struct analog_demod_ops tuner_analog_ops = { .set_params = fe_set_params, .standby = fe_standby, .has_signal = fe_has_signal, - .get_afc = fe_get_afc, .set_config = fe_set_config, .tuner_status = tuner_status }; @@ -1189,8 +1178,6 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; if (vt->type == t->mode && analog_ops->get_afc) vt->afc = analog_ops->get_afc(&t->fe); - if (analog_ops->has_signal) - vt->signal = analog_ops->has_signal(&t->fe); if (vt->type != V4L2_TUNER_RADIO) { vt->capability |= V4L2_TUNER_CAP_NORM; vt->rangelow = tv_range[0] * 16; @@ -1210,6 +1197,8 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; } + if (analog_ops->has_signal) + vt->signal = analog_ops->has_signal(&t->fe); vt->audmode = t->audmode; } vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; diff --git a/trunk/drivers/media/video/tvaudio.c b/trunk/drivers/media/video/tvaudio.c index 321b3153df87..c5b1a7365e4f 100644 --- a/trunk/drivers/media/video/tvaudio.c +++ b/trunk/drivers/media/video/tvaudio.c @@ -59,8 +59,8 @@ struct CHIPSTATE; typedef int (*getvalue)(int); typedef int (*checkit)(struct CHIPSTATE*); typedef int (*initialize)(struct CHIPSTATE*); -typedef int (*getrxsubchans)(struct CHIPSTATE *); -typedef void (*setaudmode)(struct CHIPSTATE*, int mode); +typedef int (*getmode)(struct CHIPSTATE*); +typedef void (*setmode)(struct CHIPSTATE*, int mode); /* i2c command */ typedef struct AUDIOCMD { @@ -96,8 +96,8 @@ struct CHIPDESC { getvalue volfunc,treblefunc,bassfunc; /* get/set mode */ - getrxsubchans getrxsubchans; - setaudmode setaudmode; + getmode getmode; + setmode setmode; /* input switch register + values for v4l inputs */ int inputreg; @@ -118,7 +118,7 @@ struct CHIPSTATE { audiocmd shadow; /* current settings */ - __u16 left, right, treble, bass, muted; + __u16 left,right,treble,bass,muted,mode; int prevmode; int radio; int input; @@ -126,6 +126,7 @@ struct CHIPSTATE { /* thread */ struct task_struct *thread; struct timer_list wt; + int watch_stereo; int audmode; }; @@ -287,7 +288,7 @@ static int chip_thread(void *data) struct CHIPSTATE *chip = data; struct CHIPDESC *desc = chip->desc; struct v4l2_subdev *sd = &chip->sd; - int mode, selected; + int mode; v4l2_dbg(1, debug, sd, "thread started\n"); set_freezable(); @@ -301,12 +302,12 @@ static int chip_thread(void *data) break; v4l2_dbg(1, debug, sd, "thread wakeup\n"); - /* don't do anything for radio */ - if (chip->radio) + /* don't do anything for radio or if mode != auto */ + if (chip->radio || chip->mode != 0) continue; /* have a look what's going on */ - mode = desc->getrxsubchans(chip); + mode = desc->getmode(chip); if (mode == chip->prevmode) continue; @@ -315,32 +316,16 @@ static int chip_thread(void *data) chip->prevmode = mode; - selected = V4L2_TUNER_MODE_MONO; - switch (chip->audmode) { - case V4L2_TUNER_MODE_MONO: - if (mode & V4L2_TUNER_SUB_LANG1) - selected = V4L2_TUNER_MODE_LANG1; - break; - case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1: - if (mode & V4L2_TUNER_SUB_LANG1) - selected = V4L2_TUNER_MODE_LANG1; - else if (mode & V4L2_TUNER_SUB_STEREO) - selected = V4L2_TUNER_MODE_STEREO; - break; - case V4L2_TUNER_MODE_LANG2: - if (mode & V4L2_TUNER_SUB_LANG2) - selected = V4L2_TUNER_MODE_LANG2; - else if (mode & V4L2_TUNER_SUB_STEREO) - selected = V4L2_TUNER_MODE_STEREO; - break; - case V4L2_TUNER_MODE_LANG1_LANG2: - if (mode & V4L2_TUNER_SUB_LANG2) - selected = V4L2_TUNER_MODE_LANG1_LANG2; - else if (mode & V4L2_TUNER_SUB_STEREO) - selected = V4L2_TUNER_MODE_STEREO; - } - desc->setaudmode(chip, selected); + if (mode & V4L2_TUNER_MODE_STEREO) + desc->setmode(chip, V4L2_TUNER_MODE_STEREO); + if (mode & V4L2_TUNER_MODE_LANG1_LANG2) + desc->setmode(chip, V4L2_TUNER_MODE_STEREO); + else if (mode & V4L2_TUNER_MODE_LANG1) + desc->setmode(chip, V4L2_TUNER_MODE_LANG1); + else if (mode & V4L2_TUNER_MODE_LANG2) + desc->setmode(chip, V4L2_TUNER_MODE_LANG2); + else + desc->setmode(chip, V4L2_TUNER_MODE_MONO); /* schedule next check */ mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); @@ -373,25 +358,24 @@ static int chip_thread(void *data) #define TDA9840_TEST_INT1SN 0x1 /* Integration time 0.5s when set */ #define TDA9840_TEST_INTFU 0x02 /* Disables integrator function */ -static int tda9840_getrxsubchans(struct CHIPSTATE *chip) +static int tda9840_getmode(struct CHIPSTATE *chip) { struct v4l2_subdev *sd = &chip->sd; int val, mode; val = chip_read(chip); - mode = V4L2_TUNER_SUB_MONO; + mode = V4L2_TUNER_MODE_MONO; if (val & TDA9840_DS_DUAL) - mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + mode |= V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; if (val & TDA9840_ST_STEREO) - mode = V4L2_TUNER_SUB_STEREO; + mode |= V4L2_TUNER_MODE_STEREO; - v4l2_dbg(1, debug, sd, - "tda9840_getrxsubchans(): raw chip read: %d, return: %d\n", + v4l2_dbg(1, debug, sd, "tda9840_getmode(): raw chip read: %d, return: %d\n", val, mode); return mode; } -static void tda9840_setaudmode(struct CHIPSTATE *chip, int mode) +static void tda9840_setmode(struct CHIPSTATE *chip, int mode) { int update = 1; int t = chip->shadow.bytes[TDA9840_SW + 1] & ~0x7e; @@ -409,9 +393,6 @@ static void tda9840_setaudmode(struct CHIPSTATE *chip, int mode) case V4L2_TUNER_MODE_LANG2: t |= TDA9840_DUALB; break; - case V4L2_TUNER_MODE_LANG1_LANG2: - t |= TDA9840_DUALAB; - break; default: update = 0; } @@ -496,7 +477,6 @@ static int tda9840_checkit(struct CHIPSTATE *chip) /* 0x06 - C6 - Control 2 in TDA9855, Control 3 in TDA9850 */ /* Common to TDA9855 and TDA9850: */ #define TDA985x_SAP 3<<6 /* Selects SAP output, mute if not received */ -#define TDA985x_MONOSAP 2<<6 /* Selects Mono on left, SAP on right */ #define TDA985x_STEREO 1<<6 /* Selects Stereo ouput, mono if not received */ #define TDA985x_MONO 0 /* Forces Mono output */ #define TDA985x_LMU 1<<3 /* Mute (LOR/LOL for 9855, OUTL/OUTR for 9850) */ @@ -533,22 +513,18 @@ static int tda9855_volume(int val) { return val/0x2e8+0x27; } static int tda9855_bass(int val) { return val/0xccc+0x06; } static int tda9855_treble(int val) { return (val/0x1c71+0x3)<<1; } -static int tda985x_getrxsubchans(struct CHIPSTATE *chip) +static int tda985x_getmode(struct CHIPSTATE *chip) { - int mode, val; + int mode; + mode = ((TDA985x_STP | TDA985x_SAPP) & + chip_read(chip)) >> 4; /* Add mono mode regardless of SAP and stereo */ /* Allows forced mono */ - mode = V4L2_TUNER_SUB_MONO; - val = chip_read(chip); - if (val & TDA985x_STP) - mode = V4L2_TUNER_SUB_STEREO; - if (val & TDA985x_SAPP) - mode |= V4L2_TUNER_SUB_SAP; - return mode; + return mode | V4L2_TUNER_MODE_MONO; } -static void tda985x_setaudmode(struct CHIPSTATE *chip, int mode) +static void tda985x_setmode(struct CHIPSTATE *chip, int mode) { int update = 1; int c6 = chip->shadow.bytes[TDA985x_C6+1] & 0x3f; @@ -558,15 +534,11 @@ static void tda985x_setaudmode(struct CHIPSTATE *chip, int mode) c6 |= TDA985x_MONO; break; case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1: c6 |= TDA985x_STEREO; break; - case V4L2_TUNER_MODE_SAP: + case V4L2_TUNER_MODE_LANG1: c6 |= TDA985x_SAP; break; - case V4L2_TUNER_MODE_LANG1_LANG2: - c6 |= TDA985x_MONOSAP; - break; default: update = 0; } @@ -611,10 +583,9 @@ static void tda985x_setaudmode(struct CHIPSTATE *chip, int mode) #define TDA9873_TR_MASK (7 << 2) #define TDA9873_TR_MONO 4 #define TDA9873_TR_STEREO 1 << 4 -#define TDA9873_TR_REVERSE ((1 << 3) | (1 << 2)) +#define TDA9873_TR_REVERSE (1 << 3) & (1 << 2) #define TDA9873_TR_DUALA 1 << 2 #define TDA9873_TR_DUALB 1 << 3 -#define TDA9873_TR_DUALAB 0 /* output level controls * B5: output level switch (0 = reduced gain, 1 = normal gain) @@ -682,51 +653,46 @@ static void tda985x_setaudmode(struct CHIPSTATE *chip, int mode) #define TDA9873_MOUT_DUALA 0 #define TDA9873_MOUT_DUALB 1 << 3 #define TDA9873_MOUT_ST 1 << 4 -#define TDA9873_MOUT_EXTM ((1 << 4) | (1 << 3)) +#define TDA9873_MOUT_EXTM (1 << 4 ) & (1 << 3) #define TDA9873_MOUT_EXTL 1 << 5 -#define TDA9873_MOUT_EXTR ((1 << 5) | (1 << 3)) -#define TDA9873_MOUT_EXTLR ((1 << 5) | (1 << 4)) -#define TDA9873_MOUT_MUTE ((1 << 5) | (1 << 4) | (1 << 3)) +#define TDA9873_MOUT_EXTR (1 << 5 ) & (1 << 3) +#define TDA9873_MOUT_EXTLR (1 << 5 ) & (1 << 4) +#define TDA9873_MOUT_MUTE (1 << 5 ) & (1 << 4) & (1 << 3) /* Status bits: (chip read) */ #define TDA9873_PONR 0 /* Power-on reset detected if = 1 */ #define TDA9873_STEREO 2 /* Stereo sound is identified */ #define TDA9873_DUAL 4 /* Dual sound is identified */ -static int tda9873_getrxsubchans(struct CHIPSTATE *chip) +static int tda9873_getmode(struct CHIPSTATE *chip) { struct v4l2_subdev *sd = &chip->sd; int val,mode; val = chip_read(chip); - mode = V4L2_TUNER_SUB_MONO; + mode = V4L2_TUNER_MODE_MONO; if (val & TDA9873_STEREO) - mode = V4L2_TUNER_SUB_STEREO; + mode |= V4L2_TUNER_MODE_STEREO; if (val & TDA9873_DUAL) - mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - v4l2_dbg(1, debug, sd, - "tda9873_getrxsubchans(): raw chip read: %d, return: %d\n", + mode |= V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + v4l2_dbg(1, debug, sd, "tda9873_getmode(): raw chip read: %d, return: %d\n", val, mode); return mode; } -static void tda9873_setaudmode(struct CHIPSTATE *chip, int mode) +static void tda9873_setmode(struct CHIPSTATE *chip, int mode) { struct v4l2_subdev *sd = &chip->sd; int sw_data = chip->shadow.bytes[TDA9873_SW+1] & ~ TDA9873_TR_MASK; /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */ if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) { - v4l2_dbg(1, debug, sd, - "tda9873_setaudmode(): external input\n"); + v4l2_dbg(1, debug, sd, "tda9873_setmode(): external input\n"); return; } - v4l2_dbg(1, debug, sd, - "tda9873_setaudmode(): chip->shadow.bytes[%d] = %d\n", - TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]); - v4l2_dbg(1, debug, sd, "tda9873_setaudmode(): sw_data = %d\n", - sw_data); + v4l2_dbg(1, debug, sd, "tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]); + v4l2_dbg(1, debug, sd, "tda9873_setmode(): sw_data = %d\n", sw_data); switch (mode) { case V4L2_TUNER_MODE_MONO: @@ -741,16 +707,13 @@ static void tda9873_setaudmode(struct CHIPSTATE *chip, int mode) case V4L2_TUNER_MODE_LANG2: sw_data |= TDA9873_TR_DUALB; break; - case V4L2_TUNER_MODE_LANG1_LANG2: - sw_data |= TDA9873_TR_DUALAB; - break; default: + chip->mode = 0; return; } chip_write(chip, TDA9873_SW, sw_data); - v4l2_dbg(1, debug, sd, - "tda9873_setaudmode(): req. mode %d; chip_write: %d\n", + v4l2_dbg(1, debug, sd, "tda9873_setmode(): req. mode %d; chip_write: %d\n", mode, sw_data); } @@ -896,13 +859,13 @@ static int tda9874a_setup(struct CHIPSTATE *chip) return 1; } -static int tda9874a_getrxsubchans(struct CHIPSTATE *chip) +static int tda9874a_getmode(struct CHIPSTATE *chip) { struct v4l2_subdev *sd = &chip->sd; int dsr,nsr,mode; int necr; /* just for debugging */ - mode = V4L2_TUNER_SUB_MONO; + mode = V4L2_TUNER_MODE_MONO; if(-1 == (dsr = chip_read2(chip,TDA9874A_DSR))) return mode; @@ -925,23 +888,22 @@ static int tda9874a_getrxsubchans(struct CHIPSTATE *chip) * external 4052 multiplexer in audio_hook(). */ if(nsr & 0x02) /* NSR.S/MB=1 */ - mode = V4L2_TUNER_SUB_STEREO; + mode |= V4L2_TUNER_MODE_STEREO; if(nsr & 0x01) /* NSR.D/SB=1 */ - mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + mode |= V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; } else { if(dsr & 0x02) /* DSR.IDSTE=1 */ - mode = V4L2_TUNER_SUB_STEREO; + mode |= V4L2_TUNER_MODE_STEREO; if(dsr & 0x04) /* DSR.IDDUA=1 */ - mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + mode |= V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; } - v4l2_dbg(1, debug, sd, - "tda9874a_getrxsubchans(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n", + v4l2_dbg(1, debug, sd, "tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n", dsr, nsr, necr, mode); return mode; } -static void tda9874a_setaudmode(struct CHIPSTATE *chip, int mode) +static void tda9874a_setmode(struct CHIPSTATE *chip, int mode) { struct v4l2_subdev *sd = &chip->sd; @@ -977,18 +939,14 @@ static void tda9874a_setaudmode(struct CHIPSTATE *chip, int mode) aosr = 0xa0; /* auto-select, dual B/B */ mdacosr = (tda9874a_mode) ? 0x83:0x81; break; - case V4L2_TUNER_MODE_LANG1_LANG2: - aosr = 0x00; /* always route L to L and R to R */ - mdacosr = (tda9874a_mode) ? 0x82:0x80; - break; default: + chip->mode = 0; return; } chip_write(chip, TDA9874A_AOSR, aosr); chip_write(chip, TDA9874A_MDACOSR, mdacosr); - v4l2_dbg(1, debug, sd, - "tda9874a_setaudmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n", + v4l2_dbg(1, debug, sd, "tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n", mode, aosr, mdacosr); } else { /* dic == 0x07 */ @@ -1016,18 +974,14 @@ static void tda9874a_setaudmode(struct CHIPSTATE *chip, int mode) fmmr = 0x02; /* dual */ aosr = 0x20; /* dual B/B */ break; - case V4L2_TUNER_MODE_LANG1_LANG2: - fmmr = 0x02; /* dual */ - aosr = 0x00; /* dual A/B */ - break; default: + chip->mode = 0; return; } chip_write(chip, TDA9874A_FMMR, fmmr); chip_write(chip, TDA9874A_AOSR, aosr); - v4l2_dbg(1, debug, sd, - "tda9874a_setaudmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n", + v4l2_dbg(1, debug, sd, "tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n", mode, fmmr, aosr); } } @@ -1272,33 +1226,25 @@ static int tea6320_initialize(struct CHIPSTATE * chip) static int tda8425_shift10(int val) { return (val >> 10) | 0xc0; } static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; } -static void tda8425_setaudmode(struct CHIPSTATE *chip, int mode) +static void tda8425_setmode(struct CHIPSTATE *chip, int mode) { int s1 = chip->shadow.bytes[TDA8425_S1+1] & 0xe1; - switch (mode) { - case V4L2_TUNER_MODE_LANG1: + if (mode & V4L2_TUNER_MODE_LANG1) { s1 |= TDA8425_S1_ML_SOUND_A; s1 |= TDA8425_S1_STEREO_PSEUDO; - break; - case V4L2_TUNER_MODE_LANG2: + + } else if (mode & V4L2_TUNER_MODE_LANG2) { s1 |= TDA8425_S1_ML_SOUND_B; s1 |= TDA8425_S1_STEREO_PSEUDO; - break; - case V4L2_TUNER_MODE_LANG1_LANG2: - s1 |= TDA8425_S1_ML_STEREO; - s1 |= TDA8425_S1_STEREO_LINEAR; - break; - case V4L2_TUNER_MODE_MONO: - s1 |= TDA8425_S1_ML_STEREO; - s1 |= TDA8425_S1_STEREO_MONO; - break; - case V4L2_TUNER_MODE_STEREO: + + } else { s1 |= TDA8425_S1_ML_STEREO; - s1 |= TDA8425_S1_STEREO_SPATIAL; - break; - default: - return; + + if (mode & V4L2_TUNER_MODE_MONO) + s1 |= TDA8425_S1_STEREO_MONO; + if (mode & V4L2_TUNER_MODE_STEREO) + s1 |= TDA8425_S1_STEREO_SPATIAL; } chip_write(chip,TDA8425_S1,s1); } @@ -1351,20 +1297,18 @@ static void tda8425_setaudmode(struct CHIPSTATE *chip, int mode) * stereo L L * BIL H L */ -static int ta8874z_getrxsubchans(struct CHIPSTATE *chip) +static int ta8874z_getmode(struct CHIPSTATE *chip) { int val, mode; val = chip_read(chip); - mode = V4L2_TUNER_SUB_MONO; + mode = V4L2_TUNER_MODE_MONO; if (val & TA8874Z_B1){ - mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + mode |= V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; }else if (!(val & TA8874Z_B0)){ - mode = V4L2_TUNER_SUB_STEREO; + mode |= V4L2_TUNER_MODE_STEREO; } - /* v4l2_dbg(1, debug, &chip->sd, - "ta8874z_getrxsubchans(): raw chip read: 0x%02x, return: 0x%02x\n", - val, mode); */ + /* v4l_dbg(1, debug, chip->c, "ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */ return mode; } @@ -1372,15 +1316,14 @@ static audiocmd ta8874z_stereo = { 2, {0, TA8874Z_SEPARATION_DEFAULT}}; static audiocmd ta8874z_mono = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}; static audiocmd ta8874z_main = {2, { 0, TA8874Z_SEPARATION_DEFAULT}}; static audiocmd ta8874z_sub = {2, { TA8874Z_MODE_SUB, TA8874Z_SEPARATION_DEFAULT}}; -static audiocmd ta8874z_both = {2, { TA8874Z_MODE_MAIN | TA8874Z_MODE_SUB, TA8874Z_SEPARATION_DEFAULT}}; -static void ta8874z_setaudmode(struct CHIPSTATE *chip, int mode) +static void ta8874z_setmode(struct CHIPSTATE *chip, int mode) { struct v4l2_subdev *sd = &chip->sd; int update = 1; audiocmd *t = NULL; - v4l2_dbg(1, debug, sd, "ta8874z_setaudmode(): mode: 0x%02x\n", mode); + v4l2_dbg(1, debug, sd, "ta8874z_setmode(): mode: 0x%02x\n", mode); switch(mode){ case V4L2_TUNER_MODE_MONO: @@ -1395,9 +1338,6 @@ static void ta8874z_setaudmode(struct CHIPSTATE *chip, int mode) case V4L2_TUNER_MODE_LANG2: t = &ta8874z_sub; break; - case V4L2_TUNER_MODE_LANG1_LANG2: - t = &ta8874z_both; - break; default: update = 0; } @@ -1454,8 +1394,8 @@ static struct CHIPDESC chiplist[] = { /* callbacks */ .checkit = tda9840_checkit, - .getrxsubchans = tda9840_getrxsubchans, - .setaudmode = tda9840_setaudmode, + .getmode = tda9840_getmode, + .setmode = tda9840_setmode, .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN /* ,TDA9840_SW, TDA9840_MONO */} } @@ -1470,8 +1410,8 @@ static struct CHIPDESC chiplist[] = { /* callbacks */ .checkit = tda9873_checkit, - .getrxsubchans = tda9873_getrxsubchans, - .setaudmode = tda9873_setaudmode, + .getmode = tda9873_getmode, + .setmode = tda9873_setmode, .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } }, .inputreg = TDA9873_SW, @@ -1490,8 +1430,8 @@ static struct CHIPDESC chiplist[] = { /* callbacks */ .initialize = tda9874a_initialize, .checkit = tda9874a_checkit, - .getrxsubchans = tda9874a_getrxsubchans, - .setaudmode = tda9874a_setaudmode, + .getmode = tda9874a_getmode, + .setmode = tda9874a_setmode, }, { .name = "tda9875", @@ -1520,8 +1460,8 @@ static struct CHIPDESC chiplist[] = { .addr_hi = I2C_ADDR_TDA985x_H >> 1, .registers = 11, - .getrxsubchans = tda985x_getrxsubchans, - .setaudmode = tda985x_setaudmode, + .getmode = tda985x_getmode, + .setmode = tda985x_setmode, .init = { 8, { TDA9850_C4, 0x08, 0x08, TDA985x_STEREO, 0x07, 0x10, 0x10, 0x03 } } }, @@ -1542,8 +1482,8 @@ static struct CHIPDESC chiplist[] = { .volfunc = tda9855_volume, .bassfunc = tda9855_bass, .treblefunc = tda9855_treble, - .getrxsubchans = tda985x_getrxsubchans, - .setaudmode = tda985x_setaudmode, + .getmode = tda985x_getmode, + .setmode = tda985x_setmode, .init = { 12, { 0, 0x6f, 0x6f, 0x0e, 0x07<<1, 0x8<<2, TDA9855_MUTE | TDA9855_AVL | TDA9855_LOUD | TDA9855_INT, @@ -1624,7 +1564,7 @@ static struct CHIPDESC chiplist[] = { .volfunc = tda8425_shift10, .bassfunc = tda8425_shift12, .treblefunc = tda8425_shift12, - .setaudmode = tda8425_setaudmode, + .setmode = tda8425_setmode, .inputreg = TDA8425_S1, .inputmap = { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 }, @@ -1653,10 +1593,11 @@ static struct CHIPDESC chiplist[] = { .addr_lo = I2C_ADDR_TDA9840 >> 1, .addr_hi = I2C_ADDR_TDA9840 >> 1, .registers = 2, + .flags = CHIP_NEED_CHECKMODE, /* callbacks */ - .getrxsubchans = ta8874z_getrxsubchans, - .setaudmode = ta8874z_setaudmode, + .getmode = ta8874z_getmode, + .setmode = ta8874z_setmode, .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, }, @@ -1795,6 +1736,7 @@ static int tvaudio_s_radio(struct v4l2_subdev *sd) struct CHIPSTATE *chip = to_state(sd); chip->radio = 1; + chip->watch_stereo = 0; /* del_timer(&chip->wt); */ return 0; } @@ -1851,8 +1793,9 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) { struct CHIPSTATE *chip = to_state(sd); struct CHIPDESC *desc = chip->desc; + int mode = 0; - if (!desc->setaudmode) + if (!desc->setmode) return 0; if (chip->radio) return 0; @@ -1862,18 +1805,22 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_LANG1: case V4L2_TUNER_MODE_LANG2: + mode = vt->audmode; + break; case V4L2_TUNER_MODE_LANG1_LANG2: + mode = V4L2_TUNER_MODE_STEREO; break; default: return -EINVAL; } chip->audmode = vt->audmode; - if (chip->thread) - wake_up_process(chip->thread); - else - desc->setaudmode(chip, vt->audmode); - + if (mode) { + chip->watch_stereo = 0; + /* del_timer(&chip->wt); */ + chip->mode = mode; + desc->setmode(chip, mode); + } return 0; } @@ -1881,17 +1828,30 @@ static int tvaudio_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) { struct CHIPSTATE *chip = to_state(sd); struct CHIPDESC *desc = chip->desc; + int mode = V4L2_TUNER_MODE_MONO; - if (!desc->getrxsubchans) + if (!desc->getmode) return 0; if (chip->radio) return 0; vt->audmode = chip->audmode; - vt->rxsubchans = desc->getrxsubchans(chip); + vt->rxsubchans = 0; vt->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; + mode = desc->getmode(chip); + + if (mode & V4L2_TUNER_MODE_MONO) + vt->rxsubchans |= V4L2_TUNER_SUB_MONO; + if (mode & V4L2_TUNER_MODE_STEREO) + vt->rxsubchans |= V4L2_TUNER_SUB_STEREO; + /* Note: for SAP it should be mono/lang2 or stereo/lang2. + When this module is converted fully to v4l2, then this + should change for those chips that can detect SAP. */ + if (mode & V4L2_TUNER_MODE_LANG1) + vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | + V4L2_TUNER_SUB_LANG2; return 0; } @@ -1908,7 +1868,9 @@ static int tvaudio_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fr struct CHIPSTATE *chip = to_state(sd); struct CHIPDESC *desc = chip->desc; - /* For chips that provide getrxsubchans and setaudmode, and doesn't + chip->mode = 0; /* automatic */ + + /* For chips that provide getmode and setmode, and doesn't automatically follows the stereo carrier, a kthread is created to set the audio standard. In this case, when then the video channel is changed, tvaudio starts on MONO mode. @@ -1917,8 +1879,9 @@ static int tvaudio_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fr audio carrier. */ if (chip->thread) { - desc->setaudmode(chip, V4L2_TUNER_MODE_MONO); - chip->prevmode = -1; /* reset previous mode */ + desc->setmode(chip, V4L2_TUNER_MODE_MONO); + if (chip->prevmode != V4L2_TUNER_MODE_MONO) + chip->prevmode = -1; /* reset previous mode */ mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); } return 0; @@ -2060,7 +2023,7 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * chip->thread = NULL; init_timer(&chip->wt); if (desc->flags & CHIP_NEED_CHECKMODE) { - if (!desc->getrxsubchans || !desc->setaudmode) { + if (!desc->getmode || !desc->setmode) { /* This shouldn't be happen. Warn user, but keep working without kthread */ diff --git a/trunk/drivers/media/video/tvp5150.c b/trunk/drivers/media/video/tvp5150.c index 0d897cb1774a..b7867427e5c4 100644 --- a/trunk/drivers/media/video/tvp5150.c +++ b/trunk/drivers/media/video/tvp5150.c @@ -61,20 +61,13 @@ static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr) int rc; buffer[0] = addr; - - rc = i2c_master_send(c, buffer, 1); - if (rc < 0) { - v4l2_err(sd, "i2c i/o error: rc == %d (should be 1)\n", rc); - return rc; - } + if (1 != (rc = i2c_master_send(c, buffer, 1))) + v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 1)\n", rc); msleep(10); - rc = i2c_master_recv(c, buffer, 1); - if (rc < 0) { - v4l2_err(sd, "i2c i/o error: rc == %d (should be 1)\n", rc); - return rc; - } + if (1 != (rc = i2c_master_recv(c, buffer, 1))) + v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 1)\n", rc); v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]); @@ -286,11 +279,6 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd) * For Composite and TV, it should be the reverse */ val = tvp5150_read(sd, TVP5150_MISC_CTL); - if (val < 0) { - v4l2_err(sd, "%s: failed with error = %d\n", __func__, val); - return; - } - if (decoder->input == TVP5150_SVIDEO) val = (val & ~0x40) | 0x10; else @@ -688,7 +676,6 @@ static int tvp5150_get_vbi(struct v4l2_subdev *sd, v4l2_std_id std = decoder->norm; u8 reg; int pos, type = 0; - int i, ret = 0; if (std == V4L2_STD_ALL) { v4l2_err(sd, "VBI can't be configured without knowing number of lines\n"); @@ -703,17 +690,13 @@ static int tvp5150_get_vbi(struct v4l2_subdev *sd, reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI; - for (i = 0; i <= 1; i++) { - ret = tvp5150_read(sd, reg + i); - if (ret < 0) { - v4l2_err(sd, "%s: failed with error = %d\n", - __func__, ret); - return 0; - } - pos = ret & 0x0f; - if (pos < 0x0f) - type |= regs[pos].type.vbi_type; - } + pos = tvp5150_read(sd, reg) & 0x0f; + if (pos < 0x0f) + type = regs[pos].type.vbi_type; + + pos = tvp5150_read(sd, reg + 1) & 0x0f; + if (pos < 0x0f) + type |= regs[pos].type.vbi_type; return type; } @@ -1048,21 +1031,13 @@ static int tvp5150_g_chip_ident(struct v4l2_subdev *sd, #ifdef CONFIG_VIDEO_ADV_DEBUG static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { - int res; - struct i2c_client *client = v4l2_get_subdevdata(sd); if (!v4l2_chip_match_i2c_client(client, ®->match)) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - res = tvp5150_read(sd, reg->reg & 0xff); - if (res < 0) { - v4l2_err(sd, "%s: failed with error = %d\n", __func__, res); - return res; - } - - reg->val = res; + reg->val = tvp5150_read(sd, reg->reg & 0xff); reg->size = 1; return 0; } @@ -1151,8 +1126,7 @@ static int tvp5150_probe(struct i2c_client *c, { struct tvp5150 *core; struct v4l2_subdev *sd; - int tvp5150_id[4]; - int i, res; + u8 msb_id, lsb_id, msb_rom, lsb_rom; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(c->adapter, @@ -1165,37 +1139,26 @@ static int tvp5150_probe(struct i2c_client *c, } sd = &core->sd; v4l2_i2c_subdev_init(sd, c, &tvp5150_ops); - - /* - * Read consequent registers - TVP5150_MSB_DEV_ID, TVP5150_LSB_DEV_ID, - * TVP5150_ROM_MAJOR_VER, TVP5150_ROM_MINOR_VER - */ - for (i = 0; i < 4; i++) { - res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i); - if (res < 0) - goto free_core; - tvp5150_id[i] = res; - } - v4l_info(c, "chip found @ 0x%02x (%s)\n", c->addr << 1, c->adapter->name); - if (tvp5150_id[2] == 4 && tvp5150_id[3] == 0) { /* Is TVP5150AM1 */ - v4l2_info(sd, "tvp%02x%02xam1 detected.\n", - tvp5150_id[0], tvp5150_id[1]); + msb_id = tvp5150_read(sd, TVP5150_MSB_DEV_ID); + lsb_id = tvp5150_read(sd, TVP5150_LSB_DEV_ID); + msb_rom = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER); + lsb_rom = tvp5150_read(sd, TVP5150_ROM_MINOR_VER); + + if (msb_rom == 4 && lsb_rom == 0) { /* Is TVP5150AM1 */ + v4l2_info(sd, "tvp%02x%02xam1 detected.\n", msb_id, lsb_id); /* ITU-T BT.656.4 timing */ tvp5150_write(sd, TVP5150_REV_SELECT, 0); } else { - /* Is TVP5150A */ - if (tvp5150_id[2] == 3 || tvp5150_id[3] == 0x21) { - v4l2_info(sd, "tvp%02x%02xa detected.\n", - tvp5150_id[2], tvp5150_id[3]); + if (msb_rom == 3 || lsb_rom == 0x21) { /* Is TVP5150A */ + v4l2_info(sd, "tvp%02x%02xa detected.\n", msb_id, lsb_id); } else { v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n", - tvp5150_id[2], tvp5150_id[3]); - v4l2_info(sd, "*** Rom ver is %d.%d\n", - tvp5150_id[2], tvp5150_id[3]); + msb_id, lsb_id); + v4l2_info(sd, "*** Rom ver is %d.%d\n", msb_rom, lsb_rom); } } @@ -1214,9 +1177,11 @@ static int tvp5150_probe(struct i2c_client *c, V4L2_CID_HUE, -128, 127, 1, 0); sd->ctrl_handler = &core->hdl; if (core->hdl.error) { - res = core->hdl.error; + int err = core->hdl.error; + v4l2_ctrl_handler_free(&core->hdl); - goto free_core; + kfree(core); + return err; } v4l2_ctrl_handler_setup(&core->hdl); @@ -1232,10 +1197,6 @@ static int tvp5150_probe(struct i2c_client *c, if (debug > 1) tvp5150_log_status(sd); return 0; - -free_core: - kfree(core); - return res; } static int tvp5150_remove(struct i2c_client *c) diff --git a/trunk/drivers/media/video/uvc/Kconfig b/trunk/drivers/media/video/uvc/Kconfig index 541c9f1e4c6a..6c197da531b2 100644 --- a/trunk/drivers/media/video/uvc/Kconfig +++ b/trunk/drivers/media/video/uvc/Kconfig @@ -10,7 +10,6 @@ config USB_VIDEO_CLASS config USB_VIDEO_CLASS_INPUT_EVDEV bool "UVC input events device support" default y - depends on USB_VIDEO_CLASS depends on USB_VIDEO_CLASS=INPUT || INPUT=y ---help--- This option makes USB Video Class devices register an input device diff --git a/trunk/drivers/media/video/uvc/uvc_ctrl.c b/trunk/drivers/media/video/uvc/uvc_ctrl.c index f7061a5ef1d2..af26bbe6f76e 100644 --- a/trunk/drivers/media/video/uvc/uvc_ctrl.c +++ b/trunk/drivers/media/video/uvc/uvc_ctrl.c @@ -2083,7 +2083,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev) /* Walk the entities list and instantiate controls */ list_for_each_entry(entity, &dev->entities, list) { struct uvc_control *ctrl; - unsigned int bControlSize = 0, ncontrols; + unsigned int bControlSize = 0, ncontrols = 0; __u8 *bmControls = NULL; if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) { @@ -2101,7 +2101,8 @@ int uvc_ctrl_init_device(struct uvc_device *dev) uvc_ctrl_prune_entity(dev, entity); /* Count supported controls and allocate the controls array */ - ncontrols = memweight(bmControls, bControlSize); + for (i = 0; i < bControlSize; ++i) + ncontrols += hweight8(bmControls[i]); if (ncontrols == 0) continue; diff --git a/trunk/drivers/media/video/uvc/uvc_v4l2.c b/trunk/drivers/media/video/uvc/uvc_v4l2.c index f00db3060e0e..759bef8897e9 100644 --- a/trunk/drivers/media/video/uvc/uvc_v4l2.c +++ b/trunk/drivers/media/video/uvc/uvc_v4l2.c @@ -1051,7 +1051,7 @@ static long uvc_v4l2_ioctl(struct file *file, { if (uvc_trace_param & UVC_TRACE_IOCTL) { uvc_printk(KERN_DEBUG, "uvc_v4l2_ioctl("); - v4l_printk_ioctl(NULL, cmd); + v4l_printk_ioctl(cmd); printk(")\n"); } diff --git a/trunk/drivers/media/video/uvc/uvc_video.c b/trunk/drivers/media/video/uvc/uvc_video.c index 7ac4347ca09e..b76b0ac0958f 100644 --- a/trunk/drivers/media/video/uvc/uvc_video.c +++ b/trunk/drivers/media/video/uvc/uvc_video.c @@ -1188,11 +1188,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream, u8 *mem; int len, ret; - /* - * Ignore ZLPs if they're not part of a frame, otherwise process them - * to trigger the end of payload detection. - */ - if (urb->actual_length == 0 && stream->bulk.header_size == 0) + if (urb->actual_length == 0) return; mem = urb->transfer_buffer; @@ -1598,7 +1594,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) psize = le16_to_cpu(ep->desc.wMaxPacketSize); psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); if (psize >= bandwidth && psize <= best_psize) { - altsetting = alts->desc.bAlternateSetting; + altsetting = i; best_psize = psize; best_ep = ep; } diff --git a/trunk/drivers/media/video/v4l2-compat-ioctl32.c b/trunk/drivers/media/video/v4l2-compat-ioctl32.c index ac365cfb3706..5327ad3a6390 100644 --- a/trunk/drivers/media/video/v4l2-compat-ioctl32.c +++ b/trunk/drivers/media/video/v4l2-compat-ioctl32.c @@ -327,7 +327,7 @@ struct v4l2_buffer32 { compat_caddr_t planes; } m; __u32 length; - __u32 reserved2; + __u32 input; __u32 reserved; }; @@ -387,7 +387,8 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user get_user(kp->index, &up->index) || get_user(kp->type, &up->type) || get_user(kp->flags, &up->flags) || - get_user(kp->memory, &up->memory)) + get_user(kp->memory, &up->memory) || + get_user(kp->input, &up->input)) return -EFAULT; if (V4L2_TYPE_IS_OUTPUT(kp->type)) @@ -471,7 +472,8 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user put_user(kp->index, &up->index) || put_user(kp->type, &up->type) || put_user(kp->flags, &up->flags) || - put_user(kp->memory, &up->memory)) + put_user(kp->memory, &up->memory) || + put_user(kp->input, &up->input)) return -EFAULT; if (put_user(kp->bytesused, &up->bytesused) || @@ -480,7 +482,6 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) || copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) || put_user(kp->sequence, &up->sequence) || - put_user(kp->reserved2, &up->reserved2) || put_user(kp->reserved, &up->reserved)) return -EFAULT; diff --git a/trunk/drivers/media/video/v4l2-dev.c b/trunk/drivers/media/video/v4l2-dev.c index af70f931727c..0cbada18f6f5 100644 --- a/trunk/drivers/media/video/v4l2-dev.c +++ b/trunk/drivers/media/video/v4l2-dev.c @@ -46,29 +46,6 @@ static ssize_t show_index(struct device *cd, return sprintf(buf, "%i\n", vdev->index); } -static ssize_t show_debug(struct device *cd, - struct device_attribute *attr, char *buf) -{ - struct video_device *vdev = to_video_device(cd); - - return sprintf(buf, "%i\n", vdev->debug); -} - -static ssize_t set_debug(struct device *cd, struct device_attribute *attr, - const char *buf, size_t len) -{ - struct video_device *vdev = to_video_device(cd); - int res = 0; - u16 value; - - res = kstrtou16(buf, 0, &value); - if (res) - return res; - - vdev->debug = value; - return len; -} - static ssize_t show_name(struct device *cd, struct device_attribute *attr, char *buf) { @@ -79,7 +56,6 @@ static ssize_t show_name(struct device *cd, static struct device_attribute video_device_attrs[] = { __ATTR(name, S_IRUGO, show_name, NULL), - __ATTR(debug, 0644, show_debug, set_debug), __ATTR(index, S_IRUGO, show_index, NULL), __ATTR_NULL }; @@ -305,9 +281,6 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, ret = vdev->fops->read(filp, buf, sz, off); if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) mutex_unlock(vdev->lock); - if (vdev->debug) - printk(KERN_DEBUG "%s: read: %zd (%d)\n", - video_device_node_name(vdev), sz, ret); return ret; } @@ -326,9 +299,6 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, ret = vdev->fops->write(filp, buf, sz, off); if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) mutex_unlock(vdev->lock); - if (vdev->debug) - printk(KERN_DEBUG "%s: write: %zd (%d)\n", - video_device_node_name(vdev), sz, ret); return ret; } @@ -345,9 +315,6 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) ret = vdev->fops->poll(filp, poll); if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) mutex_unlock(vdev->lock); - if (vdev->debug) - printk(KERN_DEBUG "%s: poll: %08x\n", - video_device_node_name(vdev), ret); return ret; } @@ -357,14 +324,20 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) int ret = -ENODEV; if (vdev->fops->unlocked_ioctl) { - struct mutex *lock = v4l2_ioctl_get_lock(vdev, cmd); + bool locked = false; - if (lock && mutex_lock_interruptible(lock)) - return -ERESTARTSYS; + if (vdev->lock) { + /* always lock unless the cmd is marked as "don't use lock" */ + locked = !v4l2_is_known_ioctl(cmd) || + !test_bit(_IOC_NR(cmd), vdev->disable_locking); + + if (locked && mutex_lock_interruptible(vdev->lock)) + return -ERESTARTSYS; + } if (video_is_registered(vdev)) ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); - if (lock) - mutex_unlock(lock); + if (locked) + mutex_unlock(vdev->lock); } else if (vdev->fops->ioctl) { /* This code path is a replacement for the BKL. It is a major * hack but it will have to do for those drivers that are not @@ -412,17 +385,12 @@ static unsigned long v4l2_get_unmapped_area(struct file *filp, unsigned long flags) { struct video_device *vdev = video_devdata(filp); - int ret; if (!vdev->fops->get_unmapped_area) return -ENOSYS; if (!video_is_registered(vdev)) return -ENODEV; - ret = vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags); - if (vdev->debug) - printk(KERN_DEBUG "%s: get_unmapped_area (%d)\n", - video_device_node_name(vdev), ret); - return ret; + return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags); } #endif @@ -440,9 +408,6 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) ret = vdev->fops->mmap(filp, vm); if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) mutex_unlock(vdev->lock); - if (vdev->debug) - printk(KERN_DEBUG "%s: mmap (%d)\n", - video_device_node_name(vdev), ret); return ret; } @@ -481,9 +446,6 @@ static int v4l2_open(struct inode *inode, struct file *filp) /* decrease the refcount in case of an error */ if (ret) video_put(vdev); - if (vdev->debug) - printk(KERN_DEBUG "%s: open (%d)\n", - video_device_node_name(vdev), ret); return ret; } @@ -503,9 +465,6 @@ static int v4l2_release(struct inode *inode, struct file *filp) /* decrease the refcount unconditionally since the release() return value is ignored. */ video_put(vdev); - if (vdev->debug) - printk(KERN_DEBUG "%s: release\n", - video_device_node_name(vdev)); return ret; } diff --git a/trunk/drivers/media/video/v4l2-ioctl.c b/trunk/drivers/media/video/v4l2-ioctl.c index 70e0efb127a6..d7fa8962d8b3 100644 --- a/trunk/drivers/media/video/v4l2-ioctl.c +++ b/trunk/drivers/media/video/v4l2-ioctl.c @@ -27,7 +27,27 @@ #include #include #include -#include + +#define dbgarg(cmd, fmt, arg...) \ + do { \ + if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ + printk(KERN_DEBUG "%s: ", vfd->name); \ + v4l_printk_ioctl(cmd); \ + printk(" " fmt, ## arg); \ + } \ + } while (0) + +#define dbgarg2(fmt, arg...) \ + do { \ + if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ + printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\ + } while (0) + +#define dbgarg3(fmt, arg...) \ + do { \ + if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ + printk(KERN_CONT "%s: " fmt, vfd->name, ## arg);\ + } while (0) /* Zero out the end of the struct pointed to by p. Everything after, but * not including, the specified field is cleared. */ @@ -163,507 +183,207 @@ static const char *v4l2_memory_names[] = { /* ------------------------------------------------------------------ */ /* debug help functions */ -static void v4l_print_querycap(const void *arg, bool write_only) -{ - const struct v4l2_capability *p = arg; - - pr_cont("driver=%s, card=%s, bus=%s, version=0x%08x, " - "capabilities=0x%08x, device_caps=0x%08x\n", - p->driver, p->card, p->bus_info, - p->version, p->capabilities, p->device_caps); -} - -static void v4l_print_enuminput(const void *arg, bool write_only) -{ - const struct v4l2_input *p = arg; - - pr_cont("index=%u, name=%s, type=%u, audioset=0x%x, tuner=%u, " - "std=0x%08Lx, status=0x%x, capabilities=0x%x\n", - p->index, p->name, p->type, p->audioset, p->tuner, - (unsigned long long)p->std, p->status, p->capabilities); -} +struct v4l2_ioctl_info { + unsigned int ioctl; + u16 flags; + const char * const name; +}; -static void v4l_print_enumoutput(const void *arg, bool write_only) -{ - const struct v4l2_output *p = arg; +/* This control needs a priority check */ +#define INFO_FL_PRIO (1 << 0) +/* This control can be valid if the filehandle passes a control handler. */ +#define INFO_FL_CTRL (1 << 1) - pr_cont("index=%u, name=%s, type=%u, audioset=0x%x, " - "modulator=%u, std=0x%08Lx, capabilities=0x%x\n", - p->index, p->name, p->type, p->audioset, p->modulator, - (unsigned long long)p->std, p->capabilities); +#define IOCTL_INFO(_ioctl, _flags) [_IOC_NR(_ioctl)] = { \ + .ioctl = _ioctl, \ + .flags = _flags, \ + .name = #_ioctl, \ } -static void v4l_print_audio(const void *arg, bool write_only) -{ - const struct v4l2_audio *p = arg; - - if (write_only) - pr_cont("index=%u, mode=0x%x\n", p->index, p->mode); - else - pr_cont("index=%u, name=%s, capability=0x%x, mode=0x%x\n", - p->index, p->name, p->capability, p->mode); -} +static struct v4l2_ioctl_info v4l2_ioctls[] = { + IOCTL_INFO(VIDIOC_QUERYCAP, 0), + IOCTL_INFO(VIDIOC_ENUM_FMT, 0), + IOCTL_INFO(VIDIOC_G_FMT, 0), + IOCTL_INFO(VIDIOC_S_FMT, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_REQBUFS, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_QUERYBUF, 0), + IOCTL_INFO(VIDIOC_G_FBUF, 0), + IOCTL_INFO(VIDIOC_S_FBUF, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_OVERLAY, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_QBUF, 0), + IOCTL_INFO(VIDIOC_DQBUF, 0), + IOCTL_INFO(VIDIOC_STREAMON, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_STREAMOFF, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_PARM, 0), + IOCTL_INFO(VIDIOC_S_PARM, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_STD, 0), + IOCTL_INFO(VIDIOC_S_STD, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_ENUMSTD, 0), + IOCTL_INFO(VIDIOC_ENUMINPUT, 0), + IOCTL_INFO(VIDIOC_G_CTRL, INFO_FL_CTRL), + IOCTL_INFO(VIDIOC_S_CTRL, INFO_FL_PRIO | INFO_FL_CTRL), + IOCTL_INFO(VIDIOC_G_TUNER, 0), + IOCTL_INFO(VIDIOC_S_TUNER, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_AUDIO, 0), + IOCTL_INFO(VIDIOC_S_AUDIO, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_QUERYCTRL, INFO_FL_CTRL), + IOCTL_INFO(VIDIOC_QUERYMENU, INFO_FL_CTRL), + IOCTL_INFO(VIDIOC_G_INPUT, 0), + IOCTL_INFO(VIDIOC_S_INPUT, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_OUTPUT, 0), + IOCTL_INFO(VIDIOC_S_OUTPUT, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_ENUMOUTPUT, 0), + IOCTL_INFO(VIDIOC_G_AUDOUT, 0), + IOCTL_INFO(VIDIOC_S_AUDOUT, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_MODULATOR, 0), + IOCTL_INFO(VIDIOC_S_MODULATOR, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_FREQUENCY, 0), + IOCTL_INFO(VIDIOC_S_FREQUENCY, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_CROPCAP, 0), + IOCTL_INFO(VIDIOC_G_CROP, 0), + IOCTL_INFO(VIDIOC_S_CROP, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_SELECTION, 0), + IOCTL_INFO(VIDIOC_S_SELECTION, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_JPEGCOMP, 0), + IOCTL_INFO(VIDIOC_S_JPEGCOMP, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_QUERYSTD, 0), + IOCTL_INFO(VIDIOC_TRY_FMT, 0), + IOCTL_INFO(VIDIOC_ENUMAUDIO, 0), + IOCTL_INFO(VIDIOC_ENUMAUDOUT, 0), + IOCTL_INFO(VIDIOC_G_PRIORITY, 0), + IOCTL_INFO(VIDIOC_S_PRIORITY, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_SLICED_VBI_CAP, 0), + IOCTL_INFO(VIDIOC_LOG_STATUS, 0), + IOCTL_INFO(VIDIOC_G_EXT_CTRLS, INFO_FL_CTRL), + IOCTL_INFO(VIDIOC_S_EXT_CTRLS, INFO_FL_PRIO | INFO_FL_CTRL), + IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, 0), + IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, 0), + IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, 0), + IOCTL_INFO(VIDIOC_G_ENC_INDEX, 0), + IOCTL_INFO(VIDIOC_ENCODER_CMD, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, 0), + IOCTL_INFO(VIDIOC_DECODER_CMD, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, 0), +#ifdef CONFIG_VIDEO_ADV_DEBUG + IOCTL_INFO(VIDIOC_DBG_S_REGISTER, 0), + IOCTL_INFO(VIDIOC_DBG_G_REGISTER, 0), +#endif + IOCTL_INFO(VIDIOC_DBG_G_CHIP_IDENT, 0), + IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_ENUM_DV_PRESETS, 0), + IOCTL_INFO(VIDIOC_S_DV_PRESET, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_DV_PRESET, 0), + IOCTL_INFO(VIDIOC_QUERY_DV_PRESET, 0), + IOCTL_INFO(VIDIOC_S_DV_TIMINGS, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_G_DV_TIMINGS, 0), + IOCTL_INFO(VIDIOC_DQEVENT, 0), + IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, 0), + IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, 0), + IOCTL_INFO(VIDIOC_CREATE_BUFS, INFO_FL_PRIO), + IOCTL_INFO(VIDIOC_PREPARE_BUF, 0), + IOCTL_INFO(VIDIOC_ENUM_DV_TIMINGS, 0), + IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, 0), + IOCTL_INFO(VIDIOC_DV_TIMINGS_CAP, 0), +}; +#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) -static void v4l_print_audioout(const void *arg, bool write_only) +bool v4l2_is_known_ioctl(unsigned int cmd) { - const struct v4l2_audioout *p = arg; - - if (write_only) - pr_cont("index=%u\n", p->index); - else - pr_cont("index=%u, name=%s, capability=0x%x, mode=0x%x\n", - p->index, p->name, p->capability, p->mode); + if (_IOC_NR(cmd) >= V4L2_IOCTLS) + return false; + return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd; } -static void v4l_print_fmtdesc(const void *arg, bool write_only) +/* Common ioctl debug function. This function can be used by + external ioctl messages as well as internal V4L ioctl */ +void v4l_printk_ioctl(unsigned int cmd) { - const struct v4l2_fmtdesc *p = arg; - - pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, description='%s'\n", - p->index, prt_names(p->type, v4l2_type_names), - p->flags, (p->pixelformat & 0xff), - (p->pixelformat >> 8) & 0xff, - (p->pixelformat >> 16) & 0xff, - (p->pixelformat >> 24) & 0xff, - p->description); -} + char *dir, *type; -static void v4l_print_format(const void *arg, bool write_only) -{ - const struct v4l2_format *p = arg; - const struct v4l2_pix_format *pix; - const struct v4l2_pix_format_mplane *mp; - const struct v4l2_vbi_format *vbi; - const struct v4l2_sliced_vbi_format *sliced; - const struct v4l2_window *win; - const struct v4l2_clip *clip; - unsigned i; - - pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); - switch (p->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - pix = &p->fmt.pix; - pr_cont(", width=%u, height=%u, " - "pixelformat=%c%c%c%c, field=%s, " - "bytesperline=%u sizeimage=%u, colorspace=%d\n", - pix->width, pix->height, - (pix->pixelformat & 0xff), - (pix->pixelformat >> 8) & 0xff, - (pix->pixelformat >> 16) & 0xff, - (pix->pixelformat >> 24) & 0xff, - prt_names(pix->field, v4l2_field_names), - pix->bytesperline, pix->sizeimage, - pix->colorspace); - break; - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - mp = &p->fmt.pix_mp; - pr_cont(", width=%u, height=%u, " - "format=%c%c%c%c, field=%s, " - "colorspace=%d, num_planes=%u\n", - mp->width, mp->height, - (mp->pixelformat & 0xff), - (mp->pixelformat >> 8) & 0xff, - (mp->pixelformat >> 16) & 0xff, - (mp->pixelformat >> 24) & 0xff, - prt_names(mp->field, v4l2_field_names), - mp->colorspace, mp->num_planes); - for (i = 0; i < mp->num_planes; i++) - printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i, - mp->plane_fmt[i].bytesperline, - mp->plane_fmt[i].sizeimage); + switch (_IOC_TYPE(cmd)) { + case 'd': + type = "v4l2_int"; break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - win = &p->fmt.win; - pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, " - "chromakey=0x%08x, bitmap=%p, " - "global_alpha=0x%02x\n", - win->w.width, win->w.height, - win->w.left, win->w.top, - prt_names(win->field, v4l2_field_names), - win->chromakey, win->bitmap, win->global_alpha); - clip = win->clips; - for (i = 0; i < win->clipcount; i++) { - printk(KERN_DEBUG "clip %u: wxh=%dx%d, x,y=%d,%d\n", - i, clip->c.width, clip->c.height, - clip->c.left, clip->c.top); - clip = clip->next; + case 'V': + if (_IOC_NR(cmd) >= V4L2_IOCTLS) { + type = "v4l2"; + break; } - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - case V4L2_BUF_TYPE_VBI_OUTPUT: - vbi = &p->fmt.vbi; - pr_cont(", sampling_rate=%u, offset=%u, samples_per_line=%u, " - "sample_format=%c%c%c%c, start=%u,%u, count=%u,%u\n", - vbi->sampling_rate, vbi->offset, - vbi->samples_per_line, - (vbi->sample_format & 0xff), - (vbi->sample_format >> 8) & 0xff, - (vbi->sample_format >> 16) & 0xff, - (vbi->sample_format >> 24) & 0xff, - vbi->start[0], vbi->start[1], - vbi->count[0], vbi->count[1]); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - sliced = &p->fmt.sliced; - pr_cont(", service_set=0x%08x, io_size=%d\n", - sliced->service_set, sliced->io_size); - for (i = 0; i < 24; i++) - printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i, - sliced->service_lines[0][i], - sliced->service_lines[1][i]); - break; - case V4L2_BUF_TYPE_PRIVATE: - pr_cont("\n"); - break; + printk("%s", v4l2_ioctls[_IOC_NR(cmd)].name); + return; + default: + type = "unknown"; } -} - -static void v4l_print_framebuffer(const void *arg, bool write_only) -{ - const struct v4l2_framebuffer *p = arg; - - pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, " - "height=%u, pixelformat=%c%c%c%c, " - "bytesperline=%u sizeimage=%u, colorspace=%d\n", - p->capability, p->flags, p->base, - p->fmt.width, p->fmt.height, - (p->fmt.pixelformat & 0xff), - (p->fmt.pixelformat >> 8) & 0xff, - (p->fmt.pixelformat >> 16) & 0xff, - (p->fmt.pixelformat >> 24) & 0xff, - p->fmt.bytesperline, p->fmt.sizeimage, - p->fmt.colorspace); -} - -static void v4l_print_buftype(const void *arg, bool write_only) -{ - pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names)); -} - -static void v4l_print_modulator(const void *arg, bool write_only) -{ - const struct v4l2_modulator *p = arg; - - if (write_only) - pr_cont("index=%u, txsubchans=0x%x", p->index, p->txsubchans); - else - pr_cont("index=%u, name=%s, capability=0x%x, " - "rangelow=%u, rangehigh=%u, txsubchans=0x%x\n", - p->index, p->name, p->capability, - p->rangelow, p->rangehigh, p->txsubchans); -} - -static void v4l_print_tuner(const void *arg, bool write_only) -{ - const struct v4l2_tuner *p = arg; - - if (write_only) - pr_cont("index=%u, audmode=%u\n", p->index, p->audmode); - else - pr_cont("index=%u, name=%s, type=%u, capability=0x%x, " - "rangelow=%u, rangehigh=%u, signal=%u, afc=%d, " - "rxsubchans=0x%x, audmode=%u\n", - p->index, p->name, p->type, - p->capability, p->rangelow, - p->rangehigh, p->signal, p->afc, - p->rxsubchans, p->audmode); -} - -static void v4l_print_frequency(const void *arg, bool write_only) -{ - const struct v4l2_frequency *p = arg; - - pr_cont("tuner=%u, type=%u, frequency=%u\n", - p->tuner, p->type, p->frequency); -} - -static void v4l_print_standard(const void *arg, bool write_only) -{ - const struct v4l2_standard *p = arg; - - pr_cont("index=%u, id=0x%Lx, name=%s, fps=%u/%u, " - "framelines=%u\n", p->index, - (unsigned long long)p->id, p->name, - p->frameperiod.numerator, - p->frameperiod.denominator, - p->framelines); -} - -static void v4l_print_std(const void *arg, bool write_only) -{ - pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg); -} - -static void v4l_print_hw_freq_seek(const void *arg, bool write_only) -{ - const struct v4l2_hw_freq_seek *p = arg; - - pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n", - p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing); -} - -static void v4l_print_requestbuffers(const void *arg, bool write_only) -{ - const struct v4l2_requestbuffers *p = arg; - pr_cont("count=%d, type=%s, memory=%s\n", - p->count, - prt_names(p->type, v4l2_type_names), - prt_names(p->memory, v4l2_memory_names)); + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: dir = "--"; break; + case _IOC_READ: dir = "r-"; break; + case _IOC_WRITE: dir = "-w"; break; + case _IOC_READ | _IOC_WRITE: dir = "rw"; break; + default: dir = "*ERR*"; break; + } + printk("%s ioctl '%c', dir=%s, #%d (0x%08x)", + type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); } +EXPORT_SYMBOL(v4l_printk_ioctl); -static void v4l_print_buffer(const void *arg, bool write_only) +static void dbgbuf(unsigned int cmd, struct video_device *vfd, + struct v4l2_buffer *p) { - const struct v4l2_buffer *p = arg; - const struct v4l2_timecode *tc = &p->timecode; - const struct v4l2_plane *plane; + struct v4l2_timecode *tc = &p->timecode; + struct v4l2_plane *plane; int i; - pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, " - "flags=0x%08x, field=%s, sequence=%d, memory=%s", + dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, " + "flags=0x%08d, field=%0d, sequence=%d, memory=%s\n", p->timestamp.tv_sec / 3600, (int)(p->timestamp.tv_sec / 60) % 60, (int)(p->timestamp.tv_sec % 60), (long)p->timestamp.tv_usec, p->index, prt_names(p->type, v4l2_type_names), - p->flags, prt_names(p->field, v4l2_field_names), - p->sequence, prt_names(p->memory, v4l2_memory_names)); + p->flags, p->field, p->sequence, + prt_names(p->memory, v4l2_memory_names)); if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) { - pr_cont("\n"); for (i = 0; i < p->length; ++i) { plane = &p->m.planes[i]; - printk(KERN_DEBUG - "plane %d: bytesused=%d, data_offset=0x%08x " - "offset/userptr=0x%lx, length=%d\n", + dbgarg2("plane %d: bytesused=%d, data_offset=0x%08x " + "offset/userptr=0x%08lx, length=%d\n", i, plane->bytesused, plane->data_offset, plane->m.userptr, plane->length); } } else { - pr_cont("bytesused=%d, offset/userptr=0x%lx, length=%d\n", + dbgarg2("bytesused=%d, offset/userptr=0x%08lx, length=%d\n", p->bytesused, p->m.userptr, p->length); } - printk(KERN_DEBUG "timecode=%02d:%02d:%02d type=%d, " - "flags=0x%08x, frames=%d, userbits=0x%08x\n", + dbgarg2("timecode=%02d:%02d:%02d type=%d, " + "flags=0x%08d, frames=%d, userbits=0x%08x\n", tc->hours, tc->minutes, tc->seconds, tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits); } -static void v4l_print_create_buffers(const void *arg, bool write_only) -{ - const struct v4l2_create_buffers *p = arg; - - pr_cont("index=%d, count=%d, memory=%s, ", - p->index, p->count, - prt_names(p->memory, v4l2_memory_names)); - v4l_print_format(&p->format, write_only); -} - -static void v4l_print_streamparm(const void *arg, bool write_only) -{ - const struct v4l2_streamparm *p = arg; - - pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); - - if (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || - p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - const struct v4l2_captureparm *c = &p->parm.capture; - - pr_cont(", capability=0x%x, capturemode=0x%x, timeperframe=%d/%d, " - "extendedmode=%d, readbuffers=%d\n", - c->capability, c->capturemode, - c->timeperframe.numerator, c->timeperframe.denominator, - c->extendedmode, c->readbuffers); - } else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || - p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - const struct v4l2_outputparm *c = &p->parm.output; - - pr_cont(", capability=0x%x, outputmode=0x%x, timeperframe=%d/%d, " - "extendedmode=%d, writebuffers=%d\n", - c->capability, c->outputmode, - c->timeperframe.numerator, c->timeperframe.denominator, - c->extendedmode, c->writebuffers); - } -} - -static void v4l_print_queryctrl(const void *arg, bool write_only) -{ - const struct v4l2_queryctrl *p = arg; - - pr_cont("id=0x%x, type=%d, name=%s, min/max=%d/%d, " - "step=%d, default=%d, flags=0x%08x\n", - p->id, p->type, p->name, - p->minimum, p->maximum, - p->step, p->default_value, p->flags); -} - -static void v4l_print_querymenu(const void *arg, bool write_only) -{ - const struct v4l2_querymenu *p = arg; - - pr_cont("id=0x%x, index=%d\n", p->id, p->index); -} - -static void v4l_print_control(const void *arg, bool write_only) -{ - const struct v4l2_control *p = arg; - - pr_cont("id=0x%x, value=%d\n", p->id, p->value); -} - -static void v4l_print_ext_controls(const void *arg, bool write_only) -{ - const struct v4l2_ext_controls *p = arg; - int i; - - pr_cont("class=0x%x, count=%d, error_idx=%d", - p->ctrl_class, p->count, p->error_idx); - for (i = 0; i < p->count; i++) { - if (p->controls[i].size) - pr_cont(", id/val=0x%x/0x%x", - p->controls[i].id, p->controls[i].value); - else - pr_cont(", id/size=0x%x/%u", - p->controls[i].id, p->controls[i].size); - } - pr_cont("\n"); -} - -static void v4l_print_cropcap(const void *arg, bool write_only) -{ - const struct v4l2_cropcap *p = arg; - - pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, " - "defrect wxh=%dx%d, x,y=%d,%d\n, " - "pixelaspect %d/%d\n", - prt_names(p->type, v4l2_type_names), - p->bounds.width, p->bounds.height, - p->bounds.left, p->bounds.top, - p->defrect.width, p->defrect.height, - p->defrect.left, p->defrect.top, - p->pixelaspect.numerator, p->pixelaspect.denominator); -} - -static void v4l_print_crop(const void *arg, bool write_only) -{ - const struct v4l2_crop *p = arg; - - pr_cont("type=%s, wxh=%dx%d, x,y=%d,%d\n", - prt_names(p->type, v4l2_type_names), - p->c.width, p->c.height, - p->c.left, p->c.top); -} - -static void v4l_print_selection(const void *arg, bool write_only) -{ - const struct v4l2_selection *p = arg; - - pr_cont("type=%s, target=%d, flags=0x%x, wxh=%dx%d, x,y=%d,%d\n", - prt_names(p->type, v4l2_type_names), - p->target, p->flags, - p->r.width, p->r.height, p->r.left, p->r.top); -} - -static void v4l_print_jpegcompression(const void *arg, bool write_only) -{ - const struct v4l2_jpegcompression *p = arg; - - pr_cont("quality=%d, APPn=%d, APP_len=%d, " - "COM_len=%d, jpeg_markers=0x%x\n", - p->quality, p->APPn, p->APP_len, - p->COM_len, p->jpeg_markers); -} - -static void v4l_print_enc_idx(const void *arg, bool write_only) -{ - const struct v4l2_enc_idx *p = arg; - - pr_cont("entries=%d, entries_cap=%d\n", - p->entries, p->entries_cap); -} - -static void v4l_print_encoder_cmd(const void *arg, bool write_only) -{ - const struct v4l2_encoder_cmd *p = arg; - - pr_cont("cmd=%d, flags=0x%x\n", - p->cmd, p->flags); -} - -static void v4l_print_decoder_cmd(const void *arg, bool write_only) -{ - const struct v4l2_decoder_cmd *p = arg; - - pr_cont("cmd=%d, flags=0x%x\n", p->cmd, p->flags); - - if (p->cmd == V4L2_DEC_CMD_START) - pr_info("speed=%d, format=%u\n", - p->start.speed, p->start.format); - else if (p->cmd == V4L2_DEC_CMD_STOP) - pr_info("pts=%llu\n", p->stop.pts); -} - -static void v4l_print_dbg_chip_ident(const void *arg, bool write_only) -{ - const struct v4l2_dbg_chip_ident *p = arg; - - pr_cont("type=%u, ", p->match.type); - if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER) - pr_cont("name=%s, ", p->match.name); - else - pr_cont("addr=%u, ", p->match.addr); - pr_cont("chip_ident=%u, revision=0x%x\n", - p->ident, p->revision); -} - -static void v4l_print_dbg_register(const void *arg, bool write_only) -{ - const struct v4l2_dbg_register *p = arg; - - pr_cont("type=%u, ", p->match.type); - if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER) - pr_cont("name=%s, ", p->match.name); - else - pr_cont("addr=%u, ", p->match.addr); - pr_cont("reg=0x%llx, val=0x%llx\n", - p->reg, p->val); -} - -static void v4l_print_dv_enum_presets(const void *arg, bool write_only) -{ - const struct v4l2_dv_enum_preset *p = arg; - - pr_cont("index=%u, preset=%u, name=%s, width=%u, height=%u\n", - p->index, p->preset, p->name, p->width, p->height); -} - -static void v4l_print_dv_preset(const void *arg, bool write_only) +static inline void dbgrect(struct video_device *vfd, char *s, + struct v4l2_rect *r) { - const struct v4l2_dv_preset *p = arg; - - pr_cont("preset=%u\n", p->preset); -} + dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top, + r->width, r->height); +}; -static void v4l_print_dv_timings(const void *arg, bool write_only) +static void dbgtimings(struct video_device *vfd, + const struct v4l2_dv_timings *p) { - const struct v4l2_dv_timings *p = arg; - switch (p->type) { case V4L2_DV_BT_656_1120: - pr_cont("type=bt-656/1120, interlaced=%u, " - "pixelclock=%llu, " - "width=%u, height=%u, polarities=0x%x, " - "hfrontporch=%u, hsync=%u, " - "hbackporch=%u, vfrontporch=%u, " - "vsync=%u, vbackporch=%u, " - "il_vfrontporch=%u, il_vsync=%u, " - "il_vbackporch=%u, standards=0x%x, flags=0x%x\n", + dbgarg2("bt-656/1120:interlaced=%d," + " pixelclock=%lld," + " width=%d, height=%d, polarities=%x," + " hfrontporch=%d, hsync=%d," + " hbackporch=%d, vfrontporch=%d," + " vsync=%d, vbackporch=%d," + " il_vfrontporch=%d, il_vsync=%d," + " il_vbackporch=%d, standards=%x, flags=%x\n", p->bt.interlaced, p->bt.pixelclock, p->bt.width, p->bt.height, p->bt.polarities, p->bt.hfrontporch, @@ -674,173 +394,67 @@ static void v4l_print_dv_timings(const void *arg, bool write_only) p->bt.standards, p->bt.flags); break; default: - pr_cont("type=%d\n", p->type); + dbgarg2("Unknown type %d!\n", p->type); break; } } -static void v4l_print_enum_dv_timings(const void *arg, bool write_only) -{ - const struct v4l2_enum_dv_timings *p = arg; - - pr_cont("index=%u, ", p->index); - v4l_print_dv_timings(&p->timings, write_only); -} - -static void v4l_print_dv_timings_cap(const void *arg, bool write_only) +static inline void v4l_print_pix_fmt(struct video_device *vfd, + struct v4l2_pix_format *fmt) { - const struct v4l2_dv_timings_cap *p = arg; - - switch (p->type) { - case V4L2_DV_BT_656_1120: - pr_cont("type=bt-656/1120, width=%u-%u, height=%u-%u, " - "pixelclock=%llu-%llu, standards=0x%x, capabilities=0x%x\n", - p->bt.min_width, p->bt.max_width, - p->bt.min_height, p->bt.max_height, - p->bt.min_pixelclock, p->bt.max_pixelclock, - p->bt.standards, p->bt.capabilities); - break; - default: - pr_cont("type=%u\n", p->type); - break; - } -} + dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, " + "bytesperline=%d sizeimage=%d, colorspace=%d\n", + fmt->width, fmt->height, + (fmt->pixelformat & 0xff), + (fmt->pixelformat >> 8) & 0xff, + (fmt->pixelformat >> 16) & 0xff, + (fmt->pixelformat >> 24) & 0xff, + prt_names(fmt->field, v4l2_field_names), + fmt->bytesperline, fmt->sizeimage, fmt->colorspace); +}; -static void v4l_print_frmsizeenum(const void *arg, bool write_only) +static inline void v4l_print_pix_fmt_mplane(struct video_device *vfd, + struct v4l2_pix_format_mplane *fmt) { - const struct v4l2_frmsizeenum *p = arg; - - pr_cont("index=%u, pixelformat=%c%c%c%c, type=%u", - p->index, - (p->pixel_format & 0xff), - (p->pixel_format >> 8) & 0xff, - (p->pixel_format >> 16) & 0xff, - (p->pixel_format >> 24) & 0xff, - p->type); - switch (p->type) { - case V4L2_FRMSIZE_TYPE_DISCRETE: - pr_cont(" wxh=%ux%u\n", - p->discrete.width, p->discrete.height); - break; - case V4L2_FRMSIZE_TYPE_STEPWISE: - pr_cont(" min=%ux%u, max=%ux%u, step=%ux%u\n", - p->stepwise.min_width, p->stepwise.min_height, - p->stepwise.step_width, p->stepwise.step_height, - p->stepwise.max_width, p->stepwise.max_height); - break; - case V4L2_FRMSIZE_TYPE_CONTINUOUS: - /* fall through */ - default: - pr_cont("\n"); - break; - } -} + int i; -static void v4l_print_frmivalenum(const void *arg, bool write_only) -{ - const struct v4l2_frmivalenum *p = arg; + dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, " + "colorspace=%d, num_planes=%d\n", + fmt->width, fmt->height, + (fmt->pixelformat & 0xff), + (fmt->pixelformat >> 8) & 0xff, + (fmt->pixelformat >> 16) & 0xff, + (fmt->pixelformat >> 24) & 0xff, + prt_names(fmt->field, v4l2_field_names), + fmt->colorspace, fmt->num_planes); - pr_cont("index=%u, pixelformat=%c%c%c%c, wxh=%ux%u, type=%u", - p->index, - (p->pixel_format & 0xff), - (p->pixel_format >> 8) & 0xff, - (p->pixel_format >> 16) & 0xff, - (p->pixel_format >> 24) & 0xff, - p->width, p->height, p->type); - switch (p->type) { - case V4L2_FRMIVAL_TYPE_DISCRETE: - pr_cont(" fps=%d/%d\n", - p->discrete.numerator, - p->discrete.denominator); - break; - case V4L2_FRMIVAL_TYPE_STEPWISE: - pr_cont(" min=%d/%d, max=%d/%d, step=%d/%d\n", - p->stepwise.min.numerator, - p->stepwise.min.denominator, - p->stepwise.max.numerator, - p->stepwise.max.denominator, - p->stepwise.step.numerator, - p->stepwise.step.denominator); - break; - case V4L2_FRMIVAL_TYPE_CONTINUOUS: - /* fall through */ - default: - pr_cont("\n"); - break; - } + for (i = 0; i < fmt->num_planes; ++i) + dbgarg2("plane %d: bytesperline=%d sizeimage=%d\n", i, + fmt->plane_fmt[i].bytesperline, + fmt->plane_fmt[i].sizeimage); } -static void v4l_print_event(const void *arg, bool write_only) +static inline void v4l_print_ext_ctrls(unsigned int cmd, + struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals) { - const struct v4l2_event *p = arg; - const struct v4l2_event_ctrl *c; + __u32 i; - pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, " - "timestamp=%lu.%9.9lu\n", - p->type, p->pending, p->sequence, p->id, - p->timestamp.tv_sec, p->timestamp.tv_nsec); - switch (p->type) { - case V4L2_EVENT_VSYNC: - printk(KERN_DEBUG "field=%s\n", - prt_names(p->u.vsync.field, v4l2_field_names)); - break; - case V4L2_EVENT_CTRL: - c = &p->u.ctrl; - printk(KERN_DEBUG "changes=0x%x, type=%u, ", - c->changes, c->type); - if (c->type == V4L2_CTRL_TYPE_INTEGER64) - pr_cont("value64=%lld, ", c->value64); + if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) + return; + dbgarg(cmd, ""); + printk(KERN_CONT "class=0x%x", c->ctrl_class); + for (i = 0; i < c->count; i++) { + if (show_vals && !c->controls[i].size) + printk(KERN_CONT " id/val=0x%x/0x%x", + c->controls[i].id, c->controls[i].value); else - pr_cont("value=%d, ", c->value); - pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d," - " default_value=%d\n", - c->flags, c->minimum, c->maximum, - c->step, c->default_value); - break; - case V4L2_EVENT_FRAME_SYNC: - pr_cont("frame_sequence=%u\n", - p->u.frame_sync.frame_sequence); - break; + printk(KERN_CONT " id=0x%x,size=%u", + c->controls[i].id, c->controls[i].size); } -} - -static void v4l_print_event_subscription(const void *arg, bool write_only) -{ - const struct v4l2_event_subscription *p = arg; - - pr_cont("type=0x%x, id=0x%x, flags=0x%x\n", - p->type, p->id, p->flags); -} - -static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only) -{ - const struct v4l2_sliced_vbi_cap *p = arg; - int i; - - pr_cont("type=%s, service_set=0x%08x\n", - prt_names(p->type, v4l2_type_names), p->service_set); - for (i = 0; i < 24; i++) - printk(KERN_DEBUG "line[%02u]=0x%04x, 0x%04x\n", i, - p->service_lines[0][i], - p->service_lines[1][i]); -} - -static void v4l_print_u32(const void *arg, bool write_only) -{ - pr_cont("value=%u\n", *(const u32 *)arg); -} - -static void v4l_print_newline(const void *arg, bool write_only) -{ - pr_cont("\n"); -} - -static void v4l_print_default(const void *arg, bool write_only) -{ - pr_cont("driver-specific ioctl\n"); -} + printk(KERN_CONT "\n"); +}; -static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) +static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) { __u32 i; @@ -922,1159 +536,1615 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) return -EINVAL; } -static int v4l_querycap(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) +static long __video_do_ioctl(struct file *file, + unsigned int cmd, void *arg) { - struct v4l2_capability *cap = (struct v4l2_capability *)arg; - - cap->version = LINUX_VERSION_CODE; - return ops->vidioc_querycap(file, fh, cap); -} + struct video_device *vfd = video_devdata(file); + const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; + void *fh = file->private_data; + struct v4l2_fh *vfh = NULL; + int use_fh_prio = 0; + long ret = -ENOTTY; -static int v4l_s_input(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - return ops->vidioc_s_input(file, fh, *(unsigned int *)arg); -} + if (ops == NULL) { + printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n", + vfd->name); + return ret; + } -static int v4l_s_output(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - return ops->vidioc_s_output(file, fh, *(unsigned int *)arg); -} + if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { + vfh = file->private_data; + use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); + } -static int v4l_g_priority(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd; - u32 *p = arg; + if (v4l2_is_known_ioctl(cmd)) { + struct v4l2_ioctl_info *info = &v4l2_ioctls[_IOC_NR(cmd)]; - if (ops->vidioc_g_priority) - return ops->vidioc_g_priority(file, fh, arg); - vfd = video_devdata(file); - *p = v4l2_prio_max(&vfd->v4l2_dev->prio); - return 0; -} + if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) && + !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler)) + return -ENOTTY; -static int v4l_s_priority(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd; - struct v4l2_fh *vfh; - u32 *p = arg; - - if (ops->vidioc_s_priority) - return ops->vidioc_s_priority(file, fh, *p); - vfd = video_devdata(file); - vfh = file->private_data; - return v4l2_prio_change(&vfd->v4l2_dev->prio, &vfh->prio, *p); -} + if (use_fh_prio && (info->flags & INFO_FL_PRIO)) { + ret = v4l2_prio_check(vfd->prio, vfh->prio); + if (ret) + return ret; + } + } -static int v4l_enuminput(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_input *p = arg; + if ((vfd->debug & V4L2_DEBUG_IOCTL) && + !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { + v4l_print_ioctl(vfd->name, cmd); + printk(KERN_CONT "\n"); + } - /* - * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & - * CAP_STD here based on ioctl handler provided by the - * driver. If the driver doesn't support these - * for a specific input, it must override these flags. - */ - if (ops->vidioc_s_std) - p->capabilities |= V4L2_IN_CAP_STD; - if (ops->vidioc_s_dv_preset) - p->capabilities |= V4L2_IN_CAP_PRESETS; - if (ops->vidioc_s_dv_timings) - p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS; - - return ops->vidioc_enum_input(file, fh, p); -} + switch (cmd) { -static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_output *p = arg; + /* --- capabilities ------------------------------------------ */ + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *cap = (struct v4l2_capability *)arg; + + cap->version = LINUX_VERSION_CODE; + ret = ops->vidioc_querycap(file, fh, cap); + if (!ret) + dbgarg(cmd, "driver=%s, card=%s, bus=%s, " + "version=0x%08x, " + "capabilities=0x%08x, " + "device_caps=0x%08x\n", + cap->driver, cap->card, cap->bus_info, + cap->version, + cap->capabilities, + cap->device_caps); + break; + } - /* - * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & - * CAP_STD here based on ioctl handler provided by the - * driver. If the driver doesn't support these - * for a specific output, it must override these flags. - */ - if (ops->vidioc_s_std) - p->capabilities |= V4L2_OUT_CAP_STD; - if (ops->vidioc_s_dv_preset) - p->capabilities |= V4L2_OUT_CAP_PRESETS; - if (ops->vidioc_s_dv_timings) - p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS; - - return ops->vidioc_enum_output(file, fh, p); -} + /* --- priority ------------------------------------------ */ + case VIDIOC_G_PRIORITY: + { + enum v4l2_priority *p = arg; -static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_fmtdesc *p = arg; + if (ops->vidioc_g_priority) { + ret = ops->vidioc_g_priority(file, fh, p); + } else if (use_fh_prio) { + *p = v4l2_prio_max(&vfd->v4l2_dev->prio); + ret = 0; + } + if (!ret) + dbgarg(cmd, "priority is %d\n", *p); + break; + } + case VIDIOC_S_PRIORITY: + { + enum v4l2_priority *p = arg; - switch (p->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (unlikely(!ops->vidioc_enum_fmt_vid_cap)) + dbgarg(cmd, "setting priority to %d\n", *p); + if (ops->vidioc_s_priority) + ret = ops->vidioc_s_priority(file, fh, *p); + else + ret = v4l2_prio_change(&vfd->v4l2_dev->prio, + &vfh->prio, *p); + break; + } + + /* --- capture ioctls ---------------------------------------- */ + case VIDIOC_ENUM_FMT: + { + struct v4l2_fmtdesc *f = arg; + + ret = -EINVAL; + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (likely(ops->vidioc_enum_fmt_vid_cap)) + ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); break; - return ops->vidioc_enum_fmt_vid_cap(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - if (unlikely(!ops->vidioc_enum_fmt_vid_cap_mplane)) + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + if (likely(ops->vidioc_enum_fmt_vid_cap_mplane)) + ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, + fh, f); break; - return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (unlikely(!ops->vidioc_enum_fmt_vid_overlay)) + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (likely(ops->vidioc_enum_fmt_vid_overlay)) + ret = ops->vidioc_enum_fmt_vid_overlay(file, + fh, f); break; - return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (unlikely(!ops->vidioc_enum_fmt_vid_out)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (likely(ops->vidioc_enum_fmt_vid_out)) + ret = ops->vidioc_enum_fmt_vid_out(file, fh, f); break; - return ops->vidioc_enum_fmt_vid_out(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - if (unlikely(!ops->vidioc_enum_fmt_vid_out_mplane)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + if (likely(ops->vidioc_enum_fmt_vid_out_mplane)) + ret = ops->vidioc_enum_fmt_vid_out_mplane(file, + fh, f); break; - return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); - case V4L2_BUF_TYPE_PRIVATE: - if (unlikely(!ops->vidioc_enum_fmt_type_private)) + case V4L2_BUF_TYPE_PRIVATE: + if (likely(ops->vidioc_enum_fmt_type_private)) + ret = ops->vidioc_enum_fmt_type_private(file, + fh, f); + break; + default: break; - return ops->vidioc_enum_fmt_type_private(file, fh, arg); + } + if (likely(!ret)) + dbgarg(cmd, "index=%d, type=%d, flags=%d, " + "pixelformat=%c%c%c%c, description='%s'\n", + f->index, f->type, f->flags, + (f->pixelformat & 0xff), + (f->pixelformat >> 8) & 0xff, + (f->pixelformat >> 16) & 0xff, + (f->pixelformat >> 24) & 0xff, + f->description); + break; } - return -EINVAL; -} - -static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_format *p = arg; - - switch (p->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (unlikely(!ops->vidioc_g_fmt_vid_cap)) + case VIDIOC_G_FMT: + { + struct v4l2_format *f = (struct v4l2_format *)arg; + + /* FIXME: Should be one dump per type */ + dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); + + ret = -EINVAL; + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (ops->vidioc_g_fmt_vid_cap) + ret = ops->vidioc_g_fmt_vid_cap(file, fh, f); + if (!ret) + v4l_print_pix_fmt(vfd, &f->fmt.pix); break; - return ops->vidioc_g_fmt_vid_cap(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - if (unlikely(!ops->vidioc_g_fmt_vid_cap_mplane)) + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + if (ops->vidioc_g_fmt_vid_cap_mplane) + ret = ops->vidioc_g_fmt_vid_cap_mplane(file, + fh, f); + if (!ret) + v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); break; - return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (unlikely(!ops->vidioc_g_fmt_vid_overlay)) + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (likely(ops->vidioc_g_fmt_vid_overlay)) + ret = ops->vidioc_g_fmt_vid_overlay(file, + fh, f); break; - return ops->vidioc_g_fmt_vid_overlay(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (unlikely(!ops->vidioc_g_fmt_vid_out)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (ops->vidioc_g_fmt_vid_out) + ret = ops->vidioc_g_fmt_vid_out(file, fh, f); + if (!ret) + v4l_print_pix_fmt(vfd, &f->fmt.pix); break; - return ops->vidioc_g_fmt_vid_out(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - if (unlikely(!ops->vidioc_g_fmt_vid_out_mplane)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + if (ops->vidioc_g_fmt_vid_out_mplane) + ret = ops->vidioc_g_fmt_vid_out_mplane(file, + fh, f); + if (!ret) + v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); break; - return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (unlikely(!ops->vidioc_g_fmt_vid_out_overlay)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + if (likely(ops->vidioc_g_fmt_vid_out_overlay)) + ret = ops->vidioc_g_fmt_vid_out_overlay(file, + fh, f); break; - return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg); - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (unlikely(!ops->vidioc_g_fmt_vbi_cap)) + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (likely(ops->vidioc_g_fmt_vbi_cap)) + ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f); break; - return ops->vidioc_g_fmt_vbi_cap(file, fh, arg); - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (unlikely(!ops->vidioc_g_fmt_vbi_out)) + case V4L2_BUF_TYPE_VBI_OUTPUT: + if (likely(ops->vidioc_g_fmt_vbi_out)) + ret = ops->vidioc_g_fmt_vbi_out(file, fh, f); break; - return ops->vidioc_g_fmt_vbi_out(file, fh, arg); - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (unlikely(!ops->vidioc_g_fmt_sliced_vbi_cap)) + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + if (likely(ops->vidioc_g_fmt_sliced_vbi_cap)) + ret = ops->vidioc_g_fmt_sliced_vbi_cap(file, + fh, f); break; - return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg); - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (unlikely(!ops->vidioc_g_fmt_sliced_vbi_out)) + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + if (likely(ops->vidioc_g_fmt_sliced_vbi_out)) + ret = ops->vidioc_g_fmt_sliced_vbi_out(file, + fh, f); break; - return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg); - case V4L2_BUF_TYPE_PRIVATE: - if (unlikely(!ops->vidioc_g_fmt_type_private)) + case V4L2_BUF_TYPE_PRIVATE: + if (likely(ops->vidioc_g_fmt_type_private)) + ret = ops->vidioc_g_fmt_type_private(file, + fh, f); break; - return ops->vidioc_g_fmt_type_private(file, fh, arg); + } + break; } - return -EINVAL; -} + case VIDIOC_S_FMT: + { + struct v4l2_format *f = (struct v4l2_format *)arg; -static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_format *p = arg; + ret = -EINVAL; - switch (p->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (unlikely(!ops->vidioc_s_fmt_vid_cap)) + /* FIXME: Should be one dump per type */ + dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.pix); + v4l_print_pix_fmt(vfd, &f->fmt.pix); + if (ops->vidioc_s_fmt_vid_cap) + ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.pix); - return ops->vidioc_s_fmt_vid_cap(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane)) + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + CLEAR_AFTER_FIELD(f, fmt.pix_mp); + v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); + if (ops->vidioc_s_fmt_vid_cap_mplane) + ret = ops->vidioc_s_fmt_vid_cap_mplane(file, + fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.pix_mp); - return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (unlikely(!ops->vidioc_s_fmt_vid_overlay)) + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + CLEAR_AFTER_FIELD(f, fmt.win); + if (ops->vidioc_s_fmt_vid_overlay) + ret = ops->vidioc_s_fmt_vid_overlay(file, + fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.win); - return ops->vidioc_s_fmt_vid_overlay(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (unlikely(!ops->vidioc_s_fmt_vid_out)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.pix); + v4l_print_pix_fmt(vfd, &f->fmt.pix); + if (ops->vidioc_s_fmt_vid_out) + ret = ops->vidioc_s_fmt_vid_out(file, fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.pix); - return ops->vidioc_s_fmt_vid_out(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + CLEAR_AFTER_FIELD(f, fmt.pix_mp); + v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); + if (ops->vidioc_s_fmt_vid_out_mplane) + ret = ops->vidioc_s_fmt_vid_out_mplane(file, + fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.pix_mp); - return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + CLEAR_AFTER_FIELD(f, fmt.win); + if (ops->vidioc_s_fmt_vid_out_overlay) + ret = ops->vidioc_s_fmt_vid_out_overlay(file, + fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.win); - return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg); - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (unlikely(!ops->vidioc_s_fmt_vbi_cap)) + case V4L2_BUF_TYPE_VBI_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.vbi); + if (likely(ops->vidioc_s_fmt_vbi_cap)) + ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.vbi); - return ops->vidioc_s_fmt_vbi_cap(file, fh, arg); - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (unlikely(!ops->vidioc_s_fmt_vbi_out)) + case V4L2_BUF_TYPE_VBI_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.vbi); + if (likely(ops->vidioc_s_fmt_vbi_out)) + ret = ops->vidioc_s_fmt_vbi_out(file, fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.vbi); - return ops->vidioc_s_fmt_vbi_out(file, fh, arg); - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap)) + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.sliced); + if (likely(ops->vidioc_s_fmt_sliced_vbi_cap)) + ret = ops->vidioc_s_fmt_sliced_vbi_cap(file, + fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.sliced); - return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg); - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out)) + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.sliced); + if (likely(ops->vidioc_s_fmt_sliced_vbi_out)) + ret = ops->vidioc_s_fmt_sliced_vbi_out(file, + fh, f); + break; - CLEAR_AFTER_FIELD(p, fmt.sliced); - return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg); - case V4L2_BUF_TYPE_PRIVATE: - if (unlikely(!ops->vidioc_s_fmt_type_private)) + case V4L2_BUF_TYPE_PRIVATE: + /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ + if (likely(ops->vidioc_s_fmt_type_private)) + ret = ops->vidioc_s_fmt_type_private(file, + fh, f); break; - return ops->vidioc_s_fmt_type_private(file, fh, arg); + } + break; } - return -EINVAL; -} - -static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_format *p = arg; - - switch (p->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (unlikely(!ops->vidioc_try_fmt_vid_cap)) + case VIDIOC_TRY_FMT: + { + struct v4l2_format *f = (struct v4l2_format *)arg; + + /* FIXME: Should be one dump per type */ + dbgarg(cmd, "type=%s\n", prt_names(f->type, + v4l2_type_names)); + ret = -EINVAL; + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.pix); + if (ops->vidioc_try_fmt_vid_cap) + ret = ops->vidioc_try_fmt_vid_cap(file, fh, f); + if (!ret) + v4l_print_pix_fmt(vfd, &f->fmt.pix); break; - CLEAR_AFTER_FIELD(p, fmt.pix); - return ops->vidioc_try_fmt_vid_cap(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane)) + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + CLEAR_AFTER_FIELD(f, fmt.pix_mp); + if (ops->vidioc_try_fmt_vid_cap_mplane) + ret = ops->vidioc_try_fmt_vid_cap_mplane(file, + fh, f); + if (!ret) + v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); break; - CLEAR_AFTER_FIELD(p, fmt.pix_mp); - return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (unlikely(!ops->vidioc_try_fmt_vid_overlay)) + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + CLEAR_AFTER_FIELD(f, fmt.win); + if (likely(ops->vidioc_try_fmt_vid_overlay)) + ret = ops->vidioc_try_fmt_vid_overlay(file, + fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.win); - return ops->vidioc_try_fmt_vid_overlay(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (unlikely(!ops->vidioc_try_fmt_vid_out)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.pix); + if (ops->vidioc_try_fmt_vid_out) + ret = ops->vidioc_try_fmt_vid_out(file, fh, f); + if (!ret) + v4l_print_pix_fmt(vfd, &f->fmt.pix); break; - CLEAR_AFTER_FIELD(p, fmt.pix); - return ops->vidioc_try_fmt_vid_out(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + CLEAR_AFTER_FIELD(f, fmt.pix_mp); + if (ops->vidioc_try_fmt_vid_out_mplane) + ret = ops->vidioc_try_fmt_vid_out_mplane(file, + fh, f); + if (!ret) + v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); break; - CLEAR_AFTER_FIELD(p, fmt.pix_mp); - return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg); - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay)) + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + CLEAR_AFTER_FIELD(f, fmt.win); + if (likely(ops->vidioc_try_fmt_vid_out_overlay)) + ret = ops->vidioc_try_fmt_vid_out_overlay(file, + fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.win); - return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg); - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (unlikely(!ops->vidioc_try_fmt_vbi_cap)) + case V4L2_BUF_TYPE_VBI_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.vbi); + if (likely(ops->vidioc_try_fmt_vbi_cap)) + ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.vbi); - return ops->vidioc_try_fmt_vbi_cap(file, fh, arg); - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (unlikely(!ops->vidioc_try_fmt_vbi_out)) + case V4L2_BUF_TYPE_VBI_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.vbi); + if (likely(ops->vidioc_try_fmt_vbi_out)) + ret = ops->vidioc_try_fmt_vbi_out(file, fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.vbi); - return ops->vidioc_try_fmt_vbi_out(file, fh, arg); - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap)) + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.sliced); + if (likely(ops->vidioc_try_fmt_sliced_vbi_cap)) + ret = ops->vidioc_try_fmt_sliced_vbi_cap(file, + fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.sliced); - return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg); - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out)) + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.sliced); + if (likely(ops->vidioc_try_fmt_sliced_vbi_out)) + ret = ops->vidioc_try_fmt_sliced_vbi_out(file, + fh, f); break; - CLEAR_AFTER_FIELD(p, fmt.sliced); - return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg); - case V4L2_BUF_TYPE_PRIVATE: - if (unlikely(!ops->vidioc_try_fmt_type_private)) + case V4L2_BUF_TYPE_PRIVATE: + /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ + if (likely(ops->vidioc_try_fmt_type_private)) + ret = ops->vidioc_try_fmt_type_private(file, + fh, f); break; - return ops->vidioc_try_fmt_type_private(file, fh, arg); + } + break; } - return -EINVAL; -} + /* FIXME: Those buf reqs could be handled here, + with some changes on videobuf to allow its header to be included at + videodev2.h or being merged at videodev2. + */ + case VIDIOC_REQBUFS: + { + struct v4l2_requestbuffers *p = arg; -static int v4l_streamon(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - return ops->vidioc_streamon(file, fh, *(unsigned int *)arg); -} + ret = check_fmt(ops, p->type); + if (ret) + break; -static int v4l_streamoff(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg); -} + if (p->type < V4L2_BUF_TYPE_PRIVATE) + CLEAR_AFTER_FIELD(p, memory); -static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_tuner *p = arg; + ret = ops->vidioc_reqbufs(file, fh, p); + dbgarg(cmd, "count=%d, type=%s, memory=%s\n", + p->count, + prt_names(p->type, v4l2_type_names), + prt_names(p->memory, v4l2_memory_names)); + break; + } + case VIDIOC_QUERYBUF: + { + struct v4l2_buffer *p = arg; - p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? - V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - return ops->vidioc_g_tuner(file, fh, p); -} + ret = check_fmt(ops, p->type); + if (ret) + break; -static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_tuner *p = arg; + ret = ops->vidioc_querybuf(file, fh, p); + if (!ret) + dbgbuf(cmd, vfd, p); + break; + } + case VIDIOC_QBUF: + { + struct v4l2_buffer *p = arg; - p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? - V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - return ops->vidioc_s_tuner(file, fh, p); -} + ret = check_fmt(ops, p->type); + if (ret) + break; -static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_frequency *p = arg; + ret = ops->vidioc_qbuf(file, fh, p); + if (!ret) + dbgbuf(cmd, vfd, p); + break; + } + case VIDIOC_DQBUF: + { + struct v4l2_buffer *p = arg; - p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? - V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - return ops->vidioc_g_frequency(file, fh, p); -} + ret = check_fmt(ops, p->type); + if (ret) + break; -static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_frequency *p = arg; - enum v4l2_tuner_type type; + ret = ops->vidioc_dqbuf(file, fh, p); + if (!ret) + dbgbuf(cmd, vfd, p); + break; + } + case VIDIOC_OVERLAY: + { + int *i = arg; - type = (vfd->vfl_type == VFL_TYPE_RADIO) ? - V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - if (p->type != type) - return -EINVAL; - return ops->vidioc_s_frequency(file, fh, p); -} + dbgarg(cmd, "value=%d\n", *i); + ret = ops->vidioc_overlay(file, fh, *i); + break; + } + case VIDIOC_G_FBUF: + { + struct v4l2_framebuffer *p = arg; + + ret = ops->vidioc_g_fbuf(file, fh, arg); + if (!ret) { + dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", + p->capability, p->flags, + (unsigned long)p->base); + v4l_print_pix_fmt(vfd, &p->fmt); + } + break; + } + case VIDIOC_S_FBUF: + { + struct v4l2_framebuffer *p = arg; + + dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", + p->capability, p->flags, (unsigned long)p->base); + v4l_print_pix_fmt(vfd, &p->fmt); + ret = ops->vidioc_s_fbuf(file, fh, arg); + break; + } + case VIDIOC_STREAMON: + { + enum v4l2_buf_type i = *(int *)arg; -static int v4l_enumstd(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_standard *p = arg; - v4l2_std_id id = vfd->tvnorms, curr_id = 0; - unsigned int index = p->index, i, j = 0; - const char *descr = ""; - - /* Return norm array in a canonical way */ - for (i = 0; i <= index && id; i++) { - /* last std value in the standards array is 0, so this - while always ends there since (id & 0) == 0. */ - while ((id & standards[j].std) != standards[j].std) + dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); + ret = ops->vidioc_streamon(file, fh, i); + break; + } + case VIDIOC_STREAMOFF: + { + enum v4l2_buf_type i = *(int *)arg; + + dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); + ret = ops->vidioc_streamoff(file, fh, i); + break; + } + /* ---------- tv norms ---------- */ + case VIDIOC_ENUMSTD: + { + struct v4l2_standard *p = arg; + v4l2_std_id id = vfd->tvnorms, curr_id = 0; + unsigned int index = p->index, i, j = 0; + const char *descr = ""; + + if (id == 0) + break; + ret = -EINVAL; + + /* Return norm array in a canonical way */ + for (i = 0; i <= index && id; i++) { + /* last std value in the standards array is 0, so this + while always ends there since (id & 0) == 0. */ + while ((id & standards[j].std) != standards[j].std) + j++; + curr_id = standards[j].std; + descr = standards[j].descr; j++; - curr_id = standards[j].std; - descr = standards[j].descr; - j++; - if (curr_id == 0) + if (curr_id == 0) + break; + if (curr_id != V4L2_STD_PAL && + curr_id != V4L2_STD_SECAM && + curr_id != V4L2_STD_NTSC) + id &= ~curr_id; + } + if (i <= index) break; - if (curr_id != V4L2_STD_PAL && - curr_id != V4L2_STD_SECAM && - curr_id != V4L2_STD_NTSC) - id &= ~curr_id; + + v4l2_video_std_construct(p, curr_id, descr); + + dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, " + "framelines=%d\n", p->index, + (unsigned long long)p->id, p->name, + p->frameperiod.numerator, + p->frameperiod.denominator, + p->framelines); + + ret = 0; + break; } - if (i <= index) - return -EINVAL; + case VIDIOC_G_STD: + { + v4l2_std_id *id = arg; + + /* Calls the specific handler */ + if (ops->vidioc_g_std) + ret = ops->vidioc_g_std(file, fh, id); + else if (vfd->current_norm) { + ret = 0; + *id = vfd->current_norm; + } - v4l2_video_std_construct(p, curr_id, descr); - return 0; -} + if (likely(!ret)) + dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id); + break; + } + case VIDIOC_S_STD: + { + v4l2_std_id *id = arg, norm; -static int v4l_g_std(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - v4l2_std_id *id = arg; + dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id); - /* Calls the specific handler */ - if (ops->vidioc_g_std) - return ops->vidioc_g_std(file, fh, arg); - if (vfd->current_norm) { - *id = vfd->current_norm; - return 0; + ret = -EINVAL; + norm = (*id) & vfd->tvnorms; + if (vfd->tvnorms && !norm) /* Check if std is supported */ + break; + + /* Calls the specific handler */ + ret = ops->vidioc_s_std(file, fh, &norm); + + /* Updates standard information */ + if (ret >= 0) + vfd->current_norm = norm; + break; } - return -ENOTTY; -} + case VIDIOC_QUERYSTD: + { + v4l2_std_id *p = arg; -static int v4l_s_std(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - v4l2_std_id *id = arg, norm; - int ret; + /* + * If nothing detected, it should return all supported + * Drivers just need to mask the std argument, in order + * to remove the standards that don't apply from the mask. + * This means that tuners, audio and video decoders can join + * their efforts to improve the standards detection + */ + *p = vfd->tvnorms; + ret = ops->vidioc_querystd(file, fh, arg); + if (!ret) + dbgarg(cmd, "detected std=%08Lx\n", + (unsigned long long)*p); + break; + } + /* ------ input switching ---------- */ + /* FIXME: Inputs can be handled inside videodev2 */ + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *p = arg; - norm = (*id) & vfd->tvnorms; - if (vfd->tvnorms && !norm) /* Check if std is supported */ - return -EINVAL; + /* + * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & + * CAP_STD here based on ioctl handler provided by the + * driver. If the driver doesn't support these + * for a specific input, it must override these flags. + */ + if (ops->vidioc_s_std) + p->capabilities |= V4L2_IN_CAP_STD; + if (ops->vidioc_s_dv_preset) + p->capabilities |= V4L2_IN_CAP_PRESETS; + if (ops->vidioc_s_dv_timings) + p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS; + + ret = ops->vidioc_enum_input(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "audioset=%d, " + "tuner=%d, std=%08Lx, status=%d\n", + p->index, p->name, p->type, p->audioset, + p->tuner, + (unsigned long long)p->std, + p->status); + break; + } + case VIDIOC_G_INPUT: + { + unsigned int *i = arg; - /* Calls the specific handler */ - ret = ops->vidioc_s_std(file, fh, &norm); + ret = ops->vidioc_g_input(file, fh, i); + if (!ret) + dbgarg(cmd, "value=%d\n", *i); + break; + } + case VIDIOC_S_INPUT: + { + unsigned int *i = arg; - /* Updates standard information */ - if (ret >= 0) - vfd->current_norm = norm; - return ret; -} + dbgarg(cmd, "value=%d\n", *i); + ret = ops->vidioc_s_input(file, fh, *i); + break; + } -static int v4l_querystd(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - v4l2_std_id *p = arg; - - /* - * If nothing detected, it should return all supported - * standard. - * Drivers just need to mask the std argument, in order - * to remove the standards that don't apply from the mask. - * This means that tuners, audio and video decoders can join - * their efforts to improve the standards detection. - */ - *p = vfd->tvnorms; - return ops->vidioc_querystd(file, fh, arg); -} + /* ------ output switching ---------- */ + case VIDIOC_ENUMOUTPUT: + { + struct v4l2_output *p = arg; -static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_hw_freq_seek *p = arg; - enum v4l2_tuner_type type; + /* + * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & + * CAP_STD here based on ioctl handler provided by the + * driver. If the driver doesn't support these + * for a specific output, it must override these flags. + */ + if (ops->vidioc_s_std) + p->capabilities |= V4L2_OUT_CAP_STD; + if (ops->vidioc_s_dv_preset) + p->capabilities |= V4L2_OUT_CAP_PRESETS; + if (ops->vidioc_s_dv_timings) + p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS; + + ret = ops->vidioc_enum_output(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "audioset=0x%x, " + "modulator=%d, std=0x%08Lx\n", + p->index, p->name, p->type, p->audioset, + p->modulator, (unsigned long long)p->std); + break; + } + case VIDIOC_G_OUTPUT: + { + unsigned int *i = arg; - type = (vfd->vfl_type == VFL_TYPE_RADIO) ? - V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - if (p->type != type) - return -EINVAL; - return ops->vidioc_s_hw_freq_seek(file, fh, p); -} + ret = ops->vidioc_g_output(file, fh, i); + if (!ret) + dbgarg(cmd, "value=%d\n", *i); + break; + } + case VIDIOC_S_OUTPUT: + { + unsigned int *i = arg; -static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_requestbuffers *p = arg; - int ret = check_fmt(ops, p->type); + dbgarg(cmd, "value=%d\n", *i); + ret = ops->vidioc_s_output(file, fh, *i); + break; + } - if (ret) - return ret; + /* --- controls ---------------------------------------------- */ + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *p = arg; + + if (vfh && vfh->ctrl_handler) + ret = v4l2_queryctrl(vfh->ctrl_handler, p); + else if (vfd->ctrl_handler) + ret = v4l2_queryctrl(vfd->ctrl_handler, p); + else if (ops->vidioc_queryctrl) + ret = ops->vidioc_queryctrl(file, fh, p); + else + break; + if (!ret) + dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, " + "step=%d, default=%d, flags=0x%08x\n", + p->id, p->type, p->name, + p->minimum, p->maximum, + p->step, p->default_value, p->flags); + else + dbgarg(cmd, "id=0x%x\n", p->id); + break; + } + case VIDIOC_G_CTRL: + { + struct v4l2_control *p = arg; + + if (vfh && vfh->ctrl_handler) + ret = v4l2_g_ctrl(vfh->ctrl_handler, p); + else if (vfd->ctrl_handler) + ret = v4l2_g_ctrl(vfd->ctrl_handler, p); + else if (ops->vidioc_g_ctrl) + ret = ops->vidioc_g_ctrl(file, fh, p); + else if (ops->vidioc_g_ext_ctrls) { + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); + ctrls.count = 1; + ctrls.controls = &ctrl; + ctrl.id = p->id; + ctrl.value = p->value; + if (check_ext_ctrls(&ctrls, 1)) { + ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls); + if (ret == 0) + p->value = ctrl.value; + } + } else + break; + if (!ret) + dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); + else + dbgarg(cmd, "id=0x%x\n", p->id); + break; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *p = arg; + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + + if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler && + !ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls) + break; - if (p->type < V4L2_BUF_TYPE_PRIVATE) - CLEAR_AFTER_FIELD(p, memory); + dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); - return ops->vidioc_reqbufs(file, fh, p); -} + if (vfh && vfh->ctrl_handler) { + ret = v4l2_s_ctrl(vfh, vfh->ctrl_handler, p); + break; + } + if (vfd->ctrl_handler) { + ret = v4l2_s_ctrl(NULL, vfd->ctrl_handler, p); + break; + } + if (ops->vidioc_s_ctrl) { + ret = ops->vidioc_s_ctrl(file, fh, p); + break; + } + if (!ops->vidioc_s_ext_ctrls) + break; -static int v4l_querybuf(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_buffer *p = arg; - int ret = check_fmt(ops, p->type); + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); + ctrls.count = 1; + ctrls.controls = &ctrl; + ctrl.id = p->id; + ctrl.value = p->value; + if (check_ext_ctrls(&ctrls, 1)) + ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls); + else + ret = -EINVAL; + break; + } + case VIDIOC_G_EXT_CTRLS: + { + struct v4l2_ext_controls *p = arg; + + p->error_idx = p->count; + if (vfh && vfh->ctrl_handler) + ret = v4l2_g_ext_ctrls(vfh->ctrl_handler, p); + else if (vfd->ctrl_handler) + ret = v4l2_g_ext_ctrls(vfd->ctrl_handler, p); + else if (ops->vidioc_g_ext_ctrls) + ret = check_ext_ctrls(p, 0) ? + ops->vidioc_g_ext_ctrls(file, fh, p) : + -EINVAL; + else + break; + v4l_print_ext_ctrls(cmd, vfd, p, !ret); + break; + } + case VIDIOC_S_EXT_CTRLS: + { + struct v4l2_ext_controls *p = arg; - return ret ? ret : ops->vidioc_querybuf(file, fh, p); -} + p->error_idx = p->count; + if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler && + !ops->vidioc_s_ext_ctrls) + break; + v4l_print_ext_ctrls(cmd, vfd, p, 1); + if (vfh && vfh->ctrl_handler) + ret = v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p); + else if (vfd->ctrl_handler) + ret = v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p); + else if (check_ext_ctrls(p, 0)) + ret = ops->vidioc_s_ext_ctrls(file, fh, p); + else + ret = -EINVAL; + break; + } + case VIDIOC_TRY_EXT_CTRLS: + { + struct v4l2_ext_controls *p = arg; -static int v4l_qbuf(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_buffer *p = arg; - int ret = check_fmt(ops, p->type); + p->error_idx = p->count; + if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler && + !ops->vidioc_try_ext_ctrls) + break; + v4l_print_ext_ctrls(cmd, vfd, p, 1); + if (vfh && vfh->ctrl_handler) + ret = v4l2_try_ext_ctrls(vfh->ctrl_handler, p); + else if (vfd->ctrl_handler) + ret = v4l2_try_ext_ctrls(vfd->ctrl_handler, p); + else if (check_ext_ctrls(p, 0)) + ret = ops->vidioc_try_ext_ctrls(file, fh, p); + else + ret = -EINVAL; + break; + } + case VIDIOC_QUERYMENU: + { + struct v4l2_querymenu *p = arg; + + if (vfh && vfh->ctrl_handler) + ret = v4l2_querymenu(vfh->ctrl_handler, p); + else if (vfd->ctrl_handler) + ret = v4l2_querymenu(vfd->ctrl_handler, p); + else if (ops->vidioc_querymenu) + ret = ops->vidioc_querymenu(file, fh, p); + else + break; + if (!ret) + dbgarg(cmd, "id=0x%x, index=%d, name=%s\n", + p->id, p->index, p->name); + else + dbgarg(cmd, "id=0x%x, index=%d\n", + p->id, p->index); + break; + } + /* --- audio ---------------------------------------------- */ + case VIDIOC_ENUMAUDIO: + { + struct v4l2_audio *p = arg; + + ret = ops->vidioc_enumaudio(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " + "mode=0x%x\n", p->index, p->name, + p->capability, p->mode); + else + dbgarg(cmd, "index=%d\n", p->index); + break; + } + case VIDIOC_G_AUDIO: + { + struct v4l2_audio *p = arg; + + ret = ops->vidioc_g_audio(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " + "mode=0x%x\n", p->index, + p->name, p->capability, p->mode); + else + dbgarg(cmd, "index=%d\n", p->index); + break; + } + case VIDIOC_S_AUDIO: + { + struct v4l2_audio *p = arg; + + dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " + "mode=0x%x\n", p->index, p->name, + p->capability, p->mode); + ret = ops->vidioc_s_audio(file, fh, p); + break; + } + case VIDIOC_ENUMAUDOUT: + { + struct v4l2_audioout *p = arg; + + dbgarg(cmd, "Enum for index=%d\n", p->index); + ret = ops->vidioc_enumaudout(file, fh, p); + if (!ret) + dbgarg2("index=%d, name=%s, capability=%d, " + "mode=%d\n", p->index, p->name, + p->capability, p->mode); + break; + } + case VIDIOC_G_AUDOUT: + { + struct v4l2_audioout *p = arg; + + ret = ops->vidioc_g_audout(file, fh, p); + if (!ret) + dbgarg2("index=%d, name=%s, capability=%d, " + "mode=%d\n", p->index, p->name, + p->capability, p->mode); + break; + } + case VIDIOC_S_AUDOUT: + { + struct v4l2_audioout *p = arg; - return ret ? ret : ops->vidioc_qbuf(file, fh, p); -} + dbgarg(cmd, "index=%d, name=%s, capability=%d, " + "mode=%d\n", p->index, p->name, + p->capability, p->mode); -static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_buffer *p = arg; - int ret = check_fmt(ops, p->type); + ret = ops->vidioc_s_audout(file, fh, p); + break; + } + case VIDIOC_G_MODULATOR: + { + struct v4l2_modulator *p = arg; + + ret = ops->vidioc_g_modulator(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, " + "capability=%d, rangelow=%d," + " rangehigh=%d, txsubchans=%d\n", + p->index, p->name, p->capability, + p->rangelow, p->rangehigh, + p->txsubchans); + break; + } + case VIDIOC_S_MODULATOR: + { + struct v4l2_modulator *p = arg; + + dbgarg(cmd, "index=%d, name=%s, capability=%d, " + "rangelow=%d, rangehigh=%d, txsubchans=%d\n", + p->index, p->name, p->capability, p->rangelow, + p->rangehigh, p->txsubchans); + ret = ops->vidioc_s_modulator(file, fh, p); + break; + } + case VIDIOC_G_CROP: + { + struct v4l2_crop *p = arg; - return ret ? ret : ops->vidioc_dqbuf(file, fh, p); -} + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); -static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_create_buffers *create = arg; - int ret = check_fmt(ops, create->format.type); + if (ops->vidioc_g_crop) { + ret = ops->vidioc_g_crop(file, fh, p); + } else { + /* simulate capture crop using selection api */ + struct v4l2_selection s = { + .type = p->type, + }; + + /* crop means compose for output devices */ + if (V4L2_TYPE_IS_OUTPUT(p->type)) + s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE; + else + s.target = V4L2_SEL_TGT_CROP_ACTIVE; + + ret = ops->vidioc_g_selection(file, fh, &s); + + /* copying results to old structure on success */ + if (!ret) + p->c = s.r; + } - return ret ? ret : ops->vidioc_create_bufs(file, fh, create); -} + if (!ret) + dbgrect(vfd, "", &p->c); + break; + } + case VIDIOC_S_CROP: + { + struct v4l2_crop *p = arg; -static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_buffer *b = arg; - int ret = check_fmt(ops, b->type); + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); + dbgrect(vfd, "", &p->c); - return ret ? ret : ops->vidioc_prepare_buf(file, fh, b); -} + if (ops->vidioc_s_crop) { + ret = ops->vidioc_s_crop(file, fh, p); + } else { + /* simulate capture crop using selection api */ + struct v4l2_selection s = { + .type = p->type, + .r = p->c, + }; + + /* crop means compose for output devices */ + if (V4L2_TYPE_IS_OUTPUT(p->type)) + s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE; + else + s.target = V4L2_SEL_TGT_CROP_ACTIVE; + + ret = ops->vidioc_s_selection(file, fh, &s); + } + break; + } + case VIDIOC_G_SELECTION: + { + struct v4l2_selection *p = arg; -static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_streamparm *p = arg; - v4l2_std_id std; - int ret = check_fmt(ops, p->type); + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - if (ret) - return ret; - if (ops->vidioc_g_parm) - return ops->vidioc_g_parm(file, fh, p); - std = vfd->current_norm; - if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return -EINVAL; - p->parm.capture.readbuffers = 2; - if (ops->vidioc_g_std) - ret = ops->vidioc_g_std(file, fh, &std); - if (ret == 0) - v4l2_video_std_frame_period(std, - &p->parm.capture.timeperframe); - return ret; -} + ret = ops->vidioc_g_selection(file, fh, p); + if (!ret) + dbgrect(vfd, "", &p->r); + break; + } + case VIDIOC_S_SELECTION: + { + struct v4l2_selection *p = arg; -static int v4l_s_parm(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_streamparm *p = arg; - int ret = check_fmt(ops, p->type); - return ret ? ret : ops->vidioc_s_parm(file, fh, p); -} + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); + dbgrect(vfd, "", &p->r); -static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_queryctrl *p = arg; - struct v4l2_fh *vfh = fh; - - if (vfh && vfh->ctrl_handler) - return v4l2_queryctrl(vfh->ctrl_handler, p); - if (vfd->ctrl_handler) - return v4l2_queryctrl(vfd->ctrl_handler, p); - if (ops->vidioc_queryctrl) - return ops->vidioc_queryctrl(file, fh, p); - return -ENOTTY; -} + ret = ops->vidioc_s_selection(file, fh, p); + break; + } + case VIDIOC_CROPCAP: + { + struct v4l2_cropcap *p = arg; + + /*FIXME: Should also show v4l2_fract pixelaspect */ + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); + if (ops->vidioc_cropcap) { + ret = ops->vidioc_cropcap(file, fh, p); + } else { + struct v4l2_selection s = { .type = p->type }; + + /* obtaining bounds */ + if (V4L2_TYPE_IS_OUTPUT(p->type)) + s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; + else + s.target = V4L2_SEL_TGT_CROP_BOUNDS; + + ret = ops->vidioc_g_selection(file, fh, &s); + if (ret) + break; + p->bounds = s.r; + + /* obtaining defrect */ + if (V4L2_TYPE_IS_OUTPUT(p->type)) + s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; + else + s.target = V4L2_SEL_TGT_CROP_DEFAULT; + + ret = ops->vidioc_g_selection(file, fh, &s); + if (ret) + break; + p->defrect = s.r; + + /* setting trivial pixelaspect */ + p->pixelaspect.numerator = 1; + p->pixelaspect.denominator = 1; + } -static int v4l_querymenu(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_querymenu *p = arg; - struct v4l2_fh *vfh = fh; - - if (vfh && vfh->ctrl_handler) - return v4l2_querymenu(vfh->ctrl_handler, p); - if (vfd->ctrl_handler) - return v4l2_querymenu(vfd->ctrl_handler, p); - if (ops->vidioc_querymenu) - return ops->vidioc_querymenu(file, fh, p); - return -ENOTTY; -} + if (!ret) { + dbgrect(vfd, "bounds ", &p->bounds); + dbgrect(vfd, "defrect ", &p->defrect); + } + break; + } + case VIDIOC_G_JPEGCOMP: + { + struct v4l2_jpegcompression *p = arg; + + ret = ops->vidioc_g_jpegcomp(file, fh, p); + if (!ret) + dbgarg(cmd, "quality=%d, APPn=%d, " + "APP_len=%d, COM_len=%d, " + "jpeg_markers=%d\n", + p->quality, p->APPn, p->APP_len, + p->COM_len, p->jpeg_markers); + break; + } + case VIDIOC_S_JPEGCOMP: + { + struct v4l2_jpegcompression *p = arg; + + dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, " + "COM_len=%d, jpeg_markers=%d\n", + p->quality, p->APPn, p->APP_len, + p->COM_len, p->jpeg_markers); + ret = ops->vidioc_s_jpegcomp(file, fh, p); + break; + } + case VIDIOC_G_ENC_INDEX: + { + struct v4l2_enc_idx *p = arg; + + ret = ops->vidioc_g_enc_index(file, fh, p); + if (!ret) + dbgarg(cmd, "entries=%d, entries_cap=%d\n", + p->entries, p->entries_cap); + break; + } + case VIDIOC_ENCODER_CMD: + { + struct v4l2_encoder_cmd *p = arg; -static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_control *p = arg; - struct v4l2_fh *vfh = fh; - struct v4l2_ext_controls ctrls; - struct v4l2_ext_control ctrl; - - if (vfh && vfh->ctrl_handler) - return v4l2_g_ctrl(vfh->ctrl_handler, p); - if (vfd->ctrl_handler) - return v4l2_g_ctrl(vfd->ctrl_handler, p); - if (ops->vidioc_g_ctrl) - return ops->vidioc_g_ctrl(file, fh, p); - if (ops->vidioc_g_ext_ctrls == NULL) - return -ENOTTY; - - ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); - ctrls.count = 1; - ctrls.controls = &ctrl; - ctrl.id = p->id; - ctrl.value = p->value; - if (check_ext_ctrls(&ctrls, 1)) { - int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls); - - if (ret == 0) - p->value = ctrl.value; - return ret; + ret = ops->vidioc_encoder_cmd(file, fh, p); + if (!ret) + dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); + break; } - return -EINVAL; -} + case VIDIOC_TRY_ENCODER_CMD: + { + struct v4l2_encoder_cmd *p = arg; -static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_control *p = arg; - struct v4l2_fh *vfh = fh; - struct v4l2_ext_controls ctrls; - struct v4l2_ext_control ctrl; - - if (vfh && vfh->ctrl_handler) - return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p); - if (vfd->ctrl_handler) - return v4l2_s_ctrl(NULL, vfd->ctrl_handler, p); - if (ops->vidioc_s_ctrl) - return ops->vidioc_s_ctrl(file, fh, p); - if (ops->vidioc_s_ext_ctrls == NULL) - return -ENOTTY; - - ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); - ctrls.count = 1; - ctrls.controls = &ctrl; - ctrl.id = p->id; - ctrl.value = p->value; - if (check_ext_ctrls(&ctrls, 1)) - return ops->vidioc_s_ext_ctrls(file, fh, &ctrls); - return -EINVAL; -} + ret = ops->vidioc_try_encoder_cmd(file, fh, p); + if (!ret) + dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); + break; + } + case VIDIOC_DECODER_CMD: + { + struct v4l2_decoder_cmd *p = arg; -static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_ext_controls *p = arg; - struct v4l2_fh *vfh = fh; - - p->error_idx = p->count; - if (vfh && vfh->ctrl_handler) - return v4l2_g_ext_ctrls(vfh->ctrl_handler, p); - if (vfd->ctrl_handler) - return v4l2_g_ext_ctrls(vfd->ctrl_handler, p); - if (ops->vidioc_g_ext_ctrls == NULL) - return -ENOTTY; - return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) : - -EINVAL; -} + ret = ops->vidioc_decoder_cmd(file, fh, p); + if (!ret) + dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); + break; + } + case VIDIOC_TRY_DECODER_CMD: + { + struct v4l2_decoder_cmd *p = arg; -static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_ext_controls *p = arg; - struct v4l2_fh *vfh = fh; - - p->error_idx = p->count; - if (vfh && vfh->ctrl_handler) - return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p); - if (vfd->ctrl_handler) - return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p); - if (ops->vidioc_s_ext_ctrls == NULL) - return -ENOTTY; - return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) : - -EINVAL; -} + ret = ops->vidioc_try_decoder_cmd(file, fh, p); + if (!ret) + dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); + break; + } + case VIDIOC_G_PARM: + { + struct v4l2_streamparm *p = arg; -static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_ext_controls *p = arg; - struct v4l2_fh *vfh = fh; - - p->error_idx = p->count; - if (vfh && vfh->ctrl_handler) - return v4l2_try_ext_ctrls(vfh->ctrl_handler, p); - if (vfd->ctrl_handler) - return v4l2_try_ext_ctrls(vfd->ctrl_handler, p); - if (ops->vidioc_try_ext_ctrls == NULL) - return -ENOTTY; - return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) : - -EINVAL; -} + if (ops->vidioc_g_parm) { + ret = check_fmt(ops, p->type); + if (ret) + break; + ret = ops->vidioc_g_parm(file, fh, p); + } else { + v4l2_std_id std = vfd->current_norm; -static int v4l_g_crop(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_crop *p = arg; - struct v4l2_selection s = { - .type = p->type, - }; - int ret; - - if (ops->vidioc_g_crop) - return ops->vidioc_g_crop(file, fh, p); - /* simulate capture crop using selection api */ - - /* crop means compose for output devices */ - if (V4L2_TYPE_IS_OUTPUT(p->type)) - s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE; - else - s.target = V4L2_SEL_TGT_CROP_ACTIVE; - - ret = ops->vidioc_g_selection(file, fh, &s); - - /* copying results to old structure on success */ - if (!ret) - p->c = s.r; - return ret; -} + ret = -EINVAL; + if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + break; -static int v4l_s_crop(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_crop *p = arg; - struct v4l2_selection s = { - .type = p->type, - .r = p->c, - }; - - if (ops->vidioc_s_crop) - return ops->vidioc_s_crop(file, fh, p); - /* simulate capture crop using selection api */ - - /* crop means compose for output devices */ - if (V4L2_TYPE_IS_OUTPUT(p->type)) - s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE; - else - s.target = V4L2_SEL_TGT_CROP_ACTIVE; - - return ops->vidioc_s_selection(file, fh, &s); -} + ret = 0; + p->parm.capture.readbuffers = 2; + if (ops->vidioc_g_std) + ret = ops->vidioc_g_std(file, fh, &std); + if (ret == 0) + v4l2_video_std_frame_period(std, + &p->parm.capture.timeperframe); + } -static int v4l_cropcap(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_cropcap *p = arg; - struct v4l2_selection s = { .type = p->type }; - int ret; + dbgarg(cmd, "type=%d\n", p->type); + break; + } + case VIDIOC_S_PARM: + { + struct v4l2_streamparm *p = arg; - if (ops->vidioc_cropcap) - return ops->vidioc_cropcap(file, fh, p); + ret = check_fmt(ops, p->type); + if (ret) + break; - /* obtaining bounds */ - if (V4L2_TYPE_IS_OUTPUT(p->type)) - s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; - else - s.target = V4L2_SEL_TGT_CROP_BOUNDS; + dbgarg(cmd, "type=%d\n", p->type); + ret = ops->vidioc_s_parm(file, fh, p); + break; + } + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *p = arg; - ret = ops->vidioc_g_selection(file, fh, &s); - if (ret) - return ret; - p->bounds = s.r; + p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + ret = ops->vidioc_g_tuner(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "capability=0x%x, rangelow=%d, " + "rangehigh=%d, signal=%d, afc=%d, " + "rxsubchans=0x%x, audmode=%d\n", + p->index, p->name, p->type, + p->capability, p->rangelow, + p->rangehigh, p->signal, p->afc, + p->rxsubchans, p->audmode); + break; + } + case VIDIOC_S_TUNER: + { + struct v4l2_tuner *p = arg; - /* obtaining defrect */ - if (V4L2_TYPE_IS_OUTPUT(p->type)) - s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; - else - s.target = V4L2_SEL_TGT_CROP_DEFAULT; + p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "capability=0x%x, rangelow=%d, " + "rangehigh=%d, signal=%d, afc=%d, " + "rxsubchans=0x%x, audmode=%d\n", + p->index, p->name, p->type, + p->capability, p->rangelow, + p->rangehigh, p->signal, p->afc, + p->rxsubchans, p->audmode); + ret = ops->vidioc_s_tuner(file, fh, p); + break; + } + case VIDIOC_G_FREQUENCY: + { + struct v4l2_frequency *p = arg; - ret = ops->vidioc_g_selection(file, fh, &s); - if (ret) - return ret; - p->defrect = s.r; + p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + ret = ops->vidioc_g_frequency(file, fh, p); + if (!ret) + dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", + p->tuner, p->type, p->frequency); + break; + } + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *p = arg; + enum v4l2_tuner_type type; - /* setting trivial pixelaspect */ - p->pixelaspect.numerator = 1; - p->pixelaspect.denominator = 1; - return 0; -} + type = (vfd->vfl_type == VFL_TYPE_RADIO) ? + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", + p->tuner, p->type, p->frequency); + if (p->type != type) + ret = -EINVAL; + else + ret = ops->vidioc_s_frequency(file, fh, p); + break; + } + case VIDIOC_G_SLICED_VBI_CAP: + { + struct v4l2_sliced_vbi_cap *p = arg; -static int v4l_log_status(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct video_device *vfd = video_devdata(file); - int ret; - - if (vfd->v4l2_dev) - pr_info("%s: ================= START STATUS =================\n", - vfd->v4l2_dev->name); - ret = ops->vidioc_log_status(file, fh); - if (vfd->v4l2_dev) - pr_info("%s: ================== END STATUS ==================\n", - vfd->v4l2_dev->name); - return ret; -} + /* Clear up to type, everything after type is zerod already */ + memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); -static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); + ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p); + if (!ret) + dbgarg2("service_set=%d\n", p->service_set); + break; + } + case VIDIOC_LOG_STATUS: + { + if (vfd->v4l2_dev) + pr_info("%s: ================= START STATUS =================\n", + vfd->v4l2_dev->name); + ret = ops->vidioc_log_status(file, fh); + if (vfd->v4l2_dev) + pr_info("%s: ================== END STATUS ==================\n", + vfd->v4l2_dev->name); + break; + } + case VIDIOC_DBG_G_REGISTER: + { #ifdef CONFIG_VIDEO_ADV_DEBUG - struct v4l2_dbg_register *p = arg; + struct v4l2_dbg_register *p = arg; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - return ops->vidioc_g_register(file, fh, p); -#else - return -ENOTTY; + if (!capable(CAP_SYS_ADMIN)) + ret = -EPERM; + else + ret = ops->vidioc_g_register(file, fh, p); #endif -} - -static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ + break; + } + case VIDIOC_DBG_S_REGISTER: + { #ifdef CONFIG_VIDEO_ADV_DEBUG - struct v4l2_dbg_register *p = arg; + struct v4l2_dbg_register *p = arg; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - return ops->vidioc_s_register(file, fh, p); -#else - return -ENOTTY; + if (!capable(CAP_SYS_ADMIN)) + ret = -EPERM; + else + ret = ops->vidioc_s_register(file, fh, p); #endif -} - -static int v4l_dbg_g_chip_ident(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_dbg_chip_ident *p = arg; + break; + } + case VIDIOC_DBG_G_CHIP_IDENT: + { + struct v4l2_dbg_chip_ident *p = arg; + + p->ident = V4L2_IDENT_NONE; + p->revision = 0; + ret = ops->vidioc_g_chip_ident(file, fh, p); + if (!ret) + dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); + break; + } + case VIDIOC_S_HW_FREQ_SEEK: + { + struct v4l2_hw_freq_seek *p = arg; + enum v4l2_tuner_type type; - p->ident = V4L2_IDENT_NONE; - p->revision = 0; - return ops->vidioc_g_chip_ident(file, fh, p); -} + type = (vfd->vfl_type == VFL_TYPE_RADIO) ? + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + dbgarg(cmd, + "tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n", + p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing); + if (p->type != type) + ret = -EINVAL; + else + ret = ops->vidioc_s_hw_freq_seek(file, fh, p); + break; + } + case VIDIOC_ENUM_FRAMESIZES: + { + struct v4l2_frmsizeenum *p = arg; -static int v4l_dqevent(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK); -} + ret = ops->vidioc_enum_framesizes(file, fh, p); + dbgarg(cmd, + "index=%d, pixelformat=%c%c%c%c, type=%d ", + p->index, + (p->pixel_format & 0xff), + (p->pixel_format >> 8) & 0xff, + (p->pixel_format >> 16) & 0xff, + (p->pixel_format >> 24) & 0xff, + p->type); + switch (p->type) { + case V4L2_FRMSIZE_TYPE_DISCRETE: + dbgarg3("width = %d, height=%d\n", + p->discrete.width, p->discrete.height); + break; + case V4L2_FRMSIZE_TYPE_STEPWISE: + dbgarg3("min %dx%d, max %dx%d, step %dx%d\n", + p->stepwise.min_width, p->stepwise.min_height, + p->stepwise.step_width, p->stepwise.step_height, + p->stepwise.max_width, p->stepwise.max_height); + break; + case V4L2_FRMSIZE_TYPE_CONTINUOUS: + dbgarg3("continuous\n"); + break; + default: + dbgarg3("- Unknown type!\n"); + } -static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - return ops->vidioc_subscribe_event(fh, arg); -} + break; + } + case VIDIOC_ENUM_FRAMEINTERVALS: + { + struct v4l2_frmivalenum *p = arg; + + ret = ops->vidioc_enum_frameintervals(file, fh, p); + dbgarg(cmd, + "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ", + p->index, p->pixel_format, + p->width, p->height, p->type); + switch (p->type) { + case V4L2_FRMIVAL_TYPE_DISCRETE: + dbgarg2("fps=%d/%d\n", + p->discrete.numerator, + p->discrete.denominator); + break; + case V4L2_FRMIVAL_TYPE_STEPWISE: + dbgarg2("min=%d/%d, max=%d/%d, step=%d/%d\n", + p->stepwise.min.numerator, + p->stepwise.min.denominator, + p->stepwise.max.numerator, + p->stepwise.max.denominator, + p->stepwise.step.numerator, + p->stepwise.step.denominator); + break; + case V4L2_FRMIVAL_TYPE_CONTINUOUS: + dbgarg2("continuous\n"); + break; + default: + dbgarg2("- Unknown type!\n"); + } + break; + } + case VIDIOC_ENUM_DV_PRESETS: + { + struct v4l2_dv_enum_preset *p = arg; + + ret = ops->vidioc_enum_dv_presets(file, fh, p); + if (!ret) + dbgarg(cmd, + "index=%d, preset=%d, name=%s, width=%d," + " height=%d ", + p->index, p->preset, p->name, p->width, + p->height); + break; + } + case VIDIOC_S_DV_PRESET: + { + struct v4l2_dv_preset *p = arg; -static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - return ops->vidioc_unsubscribe_event(fh, arg); -} + dbgarg(cmd, "preset=%d\n", p->preset); + ret = ops->vidioc_s_dv_preset(file, fh, p); + break; + } + case VIDIOC_G_DV_PRESET: + { + struct v4l2_dv_preset *p = arg; -static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *arg) -{ - struct v4l2_sliced_vbi_cap *p = arg; + ret = ops->vidioc_g_dv_preset(file, fh, p); + if (!ret) + dbgarg(cmd, "preset=%d\n", p->preset); + break; + } + case VIDIOC_QUERY_DV_PRESET: + { + struct v4l2_dv_preset *p = arg; - /* Clear up to type, everything after type is zeroed already */ - memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); + ret = ops->vidioc_query_dv_preset(file, fh, p); + if (!ret) + dbgarg(cmd, "preset=%d\n", p->preset); + break; + } + case VIDIOC_S_DV_TIMINGS: + { + struct v4l2_dv_timings *p = arg; + + dbgtimings(vfd, p); + switch (p->type) { + case V4L2_DV_BT_656_1120: + ret = ops->vidioc_s_dv_timings(file, fh, p); + break; + default: + ret = -EINVAL; + break; + } + break; + } + case VIDIOC_G_DV_TIMINGS: + { + struct v4l2_dv_timings *p = arg; - return ops->vidioc_g_sliced_vbi_cap(file, fh, p); -} + ret = ops->vidioc_g_dv_timings(file, fh, p); + if (!ret) + dbgtimings(vfd, p); + break; + } + case VIDIOC_ENUM_DV_TIMINGS: + { + struct v4l2_enum_dv_timings *p = arg; -struct v4l2_ioctl_info { - unsigned int ioctl; - u32 flags; - const char * const name; - union { - u32 offset; - int (*func)(const struct v4l2_ioctl_ops *ops, - struct file *file, void *fh, void *p); - }; - void (*debug)(const void *arg, bool write_only); -}; + if (!ops->vidioc_enum_dv_timings) + break; -/* This control needs a priority check */ -#define INFO_FL_PRIO (1 << 0) -/* This control can be valid if the filehandle passes a control handler. */ -#define INFO_FL_CTRL (1 << 1) -/* This is a standard ioctl, no need for special code */ -#define INFO_FL_STD (1 << 2) -/* This is ioctl has its own function */ -#define INFO_FL_FUNC (1 << 3) -/* Queuing ioctl */ -#define INFO_FL_QUEUE (1 << 4) -/* Zero struct from after the field to the end */ -#define INFO_FL_CLEAR(v4l2_struct, field) \ - ((offsetof(struct v4l2_struct, field) + \ - sizeof(((struct v4l2_struct *)0)->field)) << 16) -#define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16) - -#define IOCTL_INFO_STD(_ioctl, _vidioc, _debug, _flags) \ - [_IOC_NR(_ioctl)] = { \ - .ioctl = _ioctl, \ - .flags = _flags | INFO_FL_STD, \ - .name = #_ioctl, \ - .offset = offsetof(struct v4l2_ioctl_ops, _vidioc), \ - .debug = _debug, \ - } - -#define IOCTL_INFO_FNC(_ioctl, _func, _debug, _flags) \ - [_IOC_NR(_ioctl)] = { \ - .ioctl = _ioctl, \ - .flags = _flags | INFO_FL_FUNC, \ - .name = #_ioctl, \ - .func = _func, \ - .debug = _debug, \ + ret = ops->vidioc_enum_dv_timings(file, fh, p); + if (!ret) { + dbgarg(cmd, "index=%d: ", p->index); + dbgtimings(vfd, &p->timings); + } + break; } + case VIDIOC_QUERY_DV_TIMINGS: + { + struct v4l2_dv_timings *p = arg; -static struct v4l2_ioctl_info v4l2_ioctls[] = { - IOCTL_INFO_FNC(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0), - IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)), - IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, INFO_FL_CLEAR(v4l2_format, type)), - IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO), - IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE), - IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)), - IOCTL_INFO_STD(VIDIOC_G_FBUF, vidioc_g_fbuf, v4l_print_framebuffer, 0), - IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_OVERLAY, vidioc_overlay, v4l_print_u32, INFO_FL_PRIO), - IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE), - IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE), - IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), - IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), - IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)), - IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO), - IOCTL_INFO_FNC(VIDIOC_G_STD, v4l_g_std, v4l_print_std, 0), - IOCTL_INFO_FNC(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO), - IOCTL_INFO_FNC(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)), - IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)), - IOCTL_INFO_FNC(VIDIOC_G_CTRL, v4l_g_ctrl, v4l_print_control, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_control, id)), - IOCTL_INFO_FNC(VIDIOC_S_CTRL, v4l_s_ctrl, v4l_print_control, INFO_FL_PRIO | INFO_FL_CTRL), - IOCTL_INFO_FNC(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)), - IOCTL_INFO_FNC(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_G_AUDIO, vidioc_g_audio, v4l_print_audio, 0), - IOCTL_INFO_STD(VIDIOC_S_AUDIO, vidioc_s_audio, v4l_print_audio, INFO_FL_PRIO), - IOCTL_INFO_FNC(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)), - IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)), - IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0), - IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0), - IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO), - IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), - IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0), - IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_G_MODULATOR, vidioc_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)), - IOCTL_INFO_STD(VIDIOC_S_MODULATOR, vidioc_s_modulator, v4l_print_modulator, INFO_FL_PRIO), - IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)), - IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO), - IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)), - IOCTL_INFO_FNC(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)), - IOCTL_INFO_FNC(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_G_SELECTION, vidioc_g_selection, v4l_print_selection, 0), - IOCTL_INFO_STD(VIDIOC_S_SELECTION, vidioc_s_selection, v4l_print_selection, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp, v4l_print_jpegcompression, 0), - IOCTL_INFO_STD(VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO), - IOCTL_INFO_FNC(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0), - IOCTL_INFO_FNC(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0), - IOCTL_INFO_STD(VIDIOC_ENUMAUDIO, vidioc_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)), - IOCTL_INFO_STD(VIDIOC_ENUMAUDOUT, vidioc_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)), - IOCTL_INFO_FNC(VIDIOC_G_PRIORITY, v4l_g_priority, v4l_print_u32, 0), - IOCTL_INFO_FNC(VIDIOC_S_PRIORITY, v4l_s_priority, v4l_print_u32, INFO_FL_PRIO), - IOCTL_INFO_FNC(VIDIOC_G_SLICED_VBI_CAP, v4l_g_sliced_vbi_cap, v4l_print_sliced_vbi_cap, INFO_FL_CLEAR(v4l2_sliced_vbi_cap, type)), - IOCTL_INFO_FNC(VIDIOC_LOG_STATUS, v4l_log_status, v4l_print_newline, 0), - IOCTL_INFO_FNC(VIDIOC_G_EXT_CTRLS, v4l_g_ext_ctrls, v4l_print_ext_controls, INFO_FL_CTRL), - IOCTL_INFO_FNC(VIDIOC_S_EXT_CTRLS, v4l_s_ext_ctrls, v4l_print_ext_controls, INFO_FL_PRIO | INFO_FL_CTRL), - IOCTL_INFO_FNC(VIDIOC_TRY_EXT_CTRLS, v4l_try_ext_ctrls, v4l_print_ext_controls, 0), - IOCTL_INFO_STD(VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes, v4l_print_frmsizeenum, INFO_FL_CLEAR(v4l2_frmsizeenum, pixel_format)), - IOCTL_INFO_STD(VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals, v4l_print_frmivalenum, INFO_FL_CLEAR(v4l2_frmivalenum, height)), - IOCTL_INFO_STD(VIDIOC_G_ENC_INDEX, vidioc_g_enc_index, v4l_print_enc_idx, 0), - IOCTL_INFO_STD(VIDIOC_ENCODER_CMD, vidioc_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_encoder_cmd, flags)), - IOCTL_INFO_STD(VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd, v4l_print_encoder_cmd, INFO_FL_CLEAR(v4l2_encoder_cmd, flags)), - IOCTL_INFO_STD(VIDIOC_DECODER_CMD, vidioc_decoder_cmd, v4l_print_decoder_cmd, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd, v4l_print_decoder_cmd, 0), - IOCTL_INFO_FNC(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0), - IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0), - IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_IDENT, v4l_dbg_g_chip_ident, v4l_print_dbg_chip_ident, 0), - IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_ENUM_DV_PRESETS, vidioc_enum_dv_presets, v4l_print_dv_enum_presets, 0), - IOCTL_INFO_STD(VIDIOC_S_DV_PRESET, vidioc_s_dv_preset, v4l_print_dv_preset, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_G_DV_PRESET, vidioc_g_dv_preset, v4l_print_dv_preset, 0), - IOCTL_INFO_STD(VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset, v4l_print_dv_preset, 0), - IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0), - IOCTL_INFO_FNC(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0), - IOCTL_INFO_FNC(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0), - IOCTL_INFO_FNC(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0), - IOCTL_INFO_FNC(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE), - IOCTL_INFO_FNC(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE), - IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, 0), - IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, 0), - IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, 0), -}; -#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) - -bool v4l2_is_known_ioctl(unsigned int cmd) -{ - if (_IOC_NR(cmd) >= V4L2_IOCTLS) - return false; - return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd; -} + if (!ops->vidioc_query_dv_timings) + break; -struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd) -{ - if (_IOC_NR(cmd) >= V4L2_IOCTLS) - return vdev->lock; - if (test_bit(_IOC_NR(cmd), vdev->disable_locking)) - return NULL; - if (vdev->queue && vdev->queue->lock && - (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) - return vdev->queue->lock; - return vdev->lock; -} + ret = ops->vidioc_query_dv_timings(file, fh, p); + if (!ret) + dbgtimings(vfd, p); + break; + } + case VIDIOC_DV_TIMINGS_CAP: + { + struct v4l2_dv_timings_cap *p = arg; -/* Common ioctl debug function. This function can be used by - external ioctl messages as well as internal V4L ioctl */ -void v4l_printk_ioctl(const char *prefix, unsigned int cmd) -{ - const char *dir, *type; + if (!ops->vidioc_dv_timings_cap) + break; - if (prefix) - printk(KERN_DEBUG "%s: ", prefix); + ret = ops->vidioc_dv_timings_cap(file, fh, p); + if (ret) + break; + switch (p->type) { + case V4L2_DV_BT_656_1120: + dbgarg(cmd, + "type=%d, width=%u-%u, height=%u-%u, " + "pixelclock=%llu-%llu, standards=%x, capabilities=%x ", + p->type, + p->bt.min_width, p->bt.max_width, + p->bt.min_height, p->bt.max_height, + p->bt.min_pixelclock, p->bt.max_pixelclock, + p->bt.standards, p->bt.capabilities); + break; + default: + dbgarg(cmd, "unknown type "); + break; + } + break; + } + case VIDIOC_DQEVENT: + { + struct v4l2_event *ev = arg; - switch (_IOC_TYPE(cmd)) { - case 'd': - type = "v4l2_int"; + ret = v4l2_event_dequeue(fh, ev, file->f_flags & O_NONBLOCK); + if (ret < 0) { + dbgarg(cmd, "no pending events?"); + break; + } + dbgarg(cmd, + "pending=%d, type=0x%8.8x, sequence=%d, " + "timestamp=%lu.%9.9lu ", + ev->pending, ev->type, ev->sequence, + ev->timestamp.tv_sec, ev->timestamp.tv_nsec); break; - case 'V': - if (_IOC_NR(cmd) >= V4L2_IOCTLS) { - type = "v4l2"; + } + case VIDIOC_SUBSCRIBE_EVENT: + { + struct v4l2_event_subscription *sub = arg; + + ret = ops->vidioc_subscribe_event(fh, sub); + if (ret < 0) { + dbgarg(cmd, "failed, ret=%ld", ret); break; } - pr_cont("%s", v4l2_ioctls[_IOC_NR(cmd)].name); - return; - default: - type = "unknown"; + dbgarg(cmd, "type=0x%8.8x", sub->type); break; } + case VIDIOC_UNSUBSCRIBE_EVENT: + { + struct v4l2_event_subscription *sub = arg; - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: dir = "--"; break; - case _IOC_READ: dir = "r-"; break; - case _IOC_WRITE: dir = "-w"; break; - case _IOC_READ | _IOC_WRITE: dir = "rw"; break; - default: dir = "*ERR*"; break; + ret = ops->vidioc_unsubscribe_event(fh, sub); + if (ret < 0) { + dbgarg(cmd, "failed, ret=%ld", ret); + break; + } + dbgarg(cmd, "type=0x%8.8x", sub->type); + break; } - pr_cont("%s ioctl '%c', dir=%s, #%d (0x%08x)", - type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); -} -EXPORT_SYMBOL(v4l_printk_ioctl); + case VIDIOC_CREATE_BUFS: + { + struct v4l2_create_buffers *create = arg; -static long __video_do_ioctl(struct file *file, - unsigned int cmd, void *arg) -{ - struct video_device *vfd = video_devdata(file); - const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; - bool write_only = false; - struct v4l2_ioctl_info default_info; - const struct v4l2_ioctl_info *info; - void *fh = file->private_data; - struct v4l2_fh *vfh = NULL; - int use_fh_prio = 0; - int debug = vfd->debug; - long ret = -ENOTTY; + ret = check_fmt(ops, create->format.type); + if (ret) + break; - if (ops == NULL) { - pr_warn("%s: has no ioctl_ops.\n", - video_device_node_name(vfd)); - return ret; - } + ret = ops->vidioc_create_bufs(file, fh, create); - if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { - vfh = file->private_data; - use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); + dbgarg(cmd, "count=%d @ %d\n", create->count, create->index); + break; } + case VIDIOC_PREPARE_BUF: + { + struct v4l2_buffer *b = arg; - if (v4l2_is_known_ioctl(cmd)) { - info = &v4l2_ioctls[_IOC_NR(cmd)]; + ret = check_fmt(ops, b->type); + if (ret) + break; - if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) && - !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler)) - goto done; + ret = ops->vidioc_prepare_buf(file, fh, b); - if (use_fh_prio && (info->flags & INFO_FL_PRIO)) { - ret = v4l2_prio_check(vfd->prio, vfh->prio); - if (ret) - goto done; - } - } else { - default_info.ioctl = cmd; - default_info.flags = 0; - default_info.debug = v4l_print_default; - info = &default_info; - } - - write_only = _IOC_DIR(cmd) == _IOC_WRITE; - if (write_only && debug > V4L2_DEBUG_IOCTL) { - v4l_printk_ioctl(video_device_node_name(vfd), cmd); - pr_cont(": "); - info->debug(arg, write_only); - } - if (info->flags & INFO_FL_STD) { - typedef int (*vidioc_op)(struct file *file, void *fh, void *p); - const void *p = vfd->ioctl_ops; - const vidioc_op *vidioc = p + info->offset; - - ret = (*vidioc)(file, fh, arg); - } else if (info->flags & INFO_FL_FUNC) { - ret = info->func(ops, file, fh, arg); - } else if (!ops->vidioc_default) { - ret = -ENOTTY; - } else { - ret = ops->vidioc_default(file, fh, - use_fh_prio ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0, - cmd, arg); - } - -done: - if (debug) { - if (write_only && debug > V4L2_DEBUG_IOCTL) { - if (ret < 0) - printk(KERN_DEBUG "%s: error %ld\n", - video_device_node_name(vfd), ret); - return ret; - } - v4l_printk_ioctl(video_device_node_name(vfd), cmd); - if (ret < 0) - pr_cont(": error %ld\n", ret); - else if (debug == V4L2_DEBUG_IOCTL) - pr_cont("\n"); - else if (_IOC_DIR(cmd) == _IOC_NONE) - info->debug(arg, write_only); - else { - pr_cont(": "); - info->debug(arg, write_only); + dbgarg(cmd, "index=%d", b->index); + break; + } + default: + if (!ops->vidioc_default) + break; + ret = ops->vidioc_default(file, fh, use_fh_prio ? + v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0, + cmd, arg); + break; + } /* switch */ + + if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { + if (ret < 0) { + v4l_print_ioctl(vfd->name, cmd); + printk(KERN_CONT " error %ld\n", ret); } } return ret; } +/* In some cases, only a few fields are used as input, i.e. when the app sets + * "index" and then the driver fills in the rest of the structure for the thing + * with that index. We only need to copy up the first non-input field. */ +static unsigned long cmd_input_size(unsigned int cmd) +{ + /* Size of structure up to and including 'field' */ +#define CMDINSIZE(cmd, type, field) \ + case VIDIOC_##cmd: \ + return offsetof(struct v4l2_##type, field) + \ + sizeof(((struct v4l2_##type *)0)->field); + + switch (cmd) { + CMDINSIZE(ENUM_FMT, fmtdesc, type); + CMDINSIZE(G_FMT, format, type); + CMDINSIZE(QUERYBUF, buffer, length); + CMDINSIZE(G_PARM, streamparm, type); + CMDINSIZE(ENUMSTD, standard, index); + CMDINSIZE(ENUMINPUT, input, index); + CMDINSIZE(G_CTRL, control, id); + CMDINSIZE(G_TUNER, tuner, index); + CMDINSIZE(QUERYCTRL, queryctrl, id); + CMDINSIZE(QUERYMENU, querymenu, index); + CMDINSIZE(ENUMOUTPUT, output, index); + CMDINSIZE(G_MODULATOR, modulator, index); + CMDINSIZE(G_FREQUENCY, frequency, tuner); + CMDINSIZE(CROPCAP, cropcap, type); + CMDINSIZE(G_CROP, crop, type); + CMDINSIZE(ENUMAUDIO, audio, index); + CMDINSIZE(ENUMAUDOUT, audioout, index); + CMDINSIZE(ENCODER_CMD, encoder_cmd, flags); + CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags); + CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type); + CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format); + CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height); + default: + return _IOC_SIZE(cmd); + } +} + static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, void * __user *user_ptr, void ***kernel_ptr) { @@ -2149,20 +2219,7 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, err = -EFAULT; if (_IOC_DIR(cmd) & _IOC_WRITE) { - unsigned int n = _IOC_SIZE(cmd); - - /* - * In some cases, only a few fields are used as input, - * i.e. when the app sets "index" and then the driver - * fills in the rest of the structure for the thing - * with that index. We only need to copy up the first - * non-input field. - */ - if (v4l2_is_known_ioctl(cmd)) { - u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags; - if (flags & INFO_FL_CLEAR_MASK) - n = (flags & INFO_FL_CLEAR_MASK) >> 16; - } + unsigned long n = cmd_input_size(cmd); if (copy_from_user(parg, (void __user *)arg, n)) goto out; diff --git a/trunk/drivers/media/video/v4l2-subdev.c b/trunk/drivers/media/video/v4l2-subdev.c index 9182f81deb5b..db6e859b93d4 100644 --- a/trunk/drivers/media/video/v4l2-subdev.c +++ b/trunk/drivers/media/video/v4l2-subdev.c @@ -245,7 +245,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(&sel, 0, sizeof(sel)); sel.which = crop->which; sel.pad = crop->pad; - sel.target = V4L2_SEL_TGT_CROP; + sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL; rval = v4l2_subdev_call( sd, pad, get_selection, subdev_fh, &sel); @@ -274,7 +274,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(&sel, 0, sizeof(sel)); sel.which = crop->which; sel.pad = crop->pad; - sel.target = V4L2_SEL_TGT_CROP; + sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL; sel.r = crop->rect; rval = v4l2_subdev_call( diff --git a/trunk/drivers/media/video/videobuf-core.c b/trunk/drivers/media/video/videobuf-core.c index bf7a326b1cdc..ffdf59cfe405 100644 --- a/trunk/drivers/media/video/videobuf-core.c +++ b/trunk/drivers/media/video/videobuf-core.c @@ -359,6 +359,11 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, break; } + if (vb->input != UNSET) { + b->flags |= V4L2_BUF_FLAG_INPUT; + b->input = vb->input; + } + b->field = vb->field; b->timestamp = vb->ts; b->bytesused = vb->size; @@ -397,6 +402,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q, break; q->bufs[i]->i = i; + q->bufs[i]->input = UNSET; q->bufs[i]->memory = memory; q->bufs[i]->bsize = bsize; switch (memory) { @@ -560,6 +566,16 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b) goto done; } + if (b->flags & V4L2_BUF_FLAG_INPUT) { + if (b->input >= q->inputs) { + dprintk(1, "qbuf: wrong input.\n"); + goto done; + } + buf->input = b->input; + } else { + buf->input = UNSET; + } + switch (b->memory) { case V4L2_MEMORY_MMAP: if (0 == buf->baddr) { diff --git a/trunk/drivers/media/video/videobuf-dma-contig.c b/trunk/drivers/media/video/videobuf-dma-contig.c index 9b9a06fdd0f0..b6b5cc1a43cb 100644 --- a/trunk/drivers/media/video/videobuf-dma-contig.c +++ b/trunk/drivers/media/video/videobuf-dma-contig.c @@ -40,7 +40,7 @@ struct videobuf_dma_contig_memory { static int __videobuf_dc_alloc(struct device *dev, struct videobuf_dma_contig_memory *mem, - unsigned long size, gfp_t flags) + unsigned long size, unsigned long flags) { mem->size = size; if (mem->cached) { diff --git a/trunk/drivers/media/video/videobuf2-core.c b/trunk/drivers/media/video/videobuf2-core.c index 4e0290ab5071..9d4e9edbd2e7 100644 --- a/trunk/drivers/media/video/videobuf2-core.c +++ b/trunk/drivers/media/video/videobuf2-core.c @@ -336,9 +336,9 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) struct vb2_queue *q = vb->vb2_queue; int ret; - /* Copy back data such as timestamp, flags, etc. */ + /* Copy back data such as timestamp, flags, input, etc. */ memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); - b->reserved2 = vb->v4l2_buf.reserved2; + b->input = vb->v4l2_buf.input; b->reserved = vb->v4l2_buf.reserved; if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) { @@ -454,50 +454,7 @@ static int __verify_mmap_ops(struct vb2_queue *q) } /** - * __verify_memory_type() - Check whether the memory type and buffer type - * passed to a buffer operation are compatible with the queue. - */ -static int __verify_memory_type(struct vb2_queue *q, - enum v4l2_memory memory, enum v4l2_buf_type type) -{ - if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR) { - dprintk(1, "reqbufs: unsupported memory type\n"); - return -EINVAL; - } - - if (type != q->type) { - dprintk(1, "reqbufs: requested type is incorrect\n"); - return -EINVAL; - } - - /* - * Make sure all the required memory ops for given memory type - * are available. - */ - if (memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) { - dprintk(1, "reqbufs: MMAP for current setup unsupported\n"); - return -EINVAL; - } - - if (memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) { - dprintk(1, "reqbufs: USERPTR for current setup unsupported\n"); - return -EINVAL; - } - - /* - * Place the busy tests at the end: -EBUSY can be ignored when - * create_bufs is called with count == 0, but count == 0 should still - * do the memory and type validation. - */ - if (q->fileio) { - dprintk(1, "reqbufs: file io in progress\n"); - return -EBUSY; - } - return 0; -} - -/** - * __reqbufs() - Initiate streaming + * vb2_reqbufs() - Initiate streaming * @q: videobuf2 queue * @req: struct passed from userspace to vidioc_reqbufs handler in driver * @@ -519,16 +476,46 @@ static int __verify_memory_type(struct vb2_queue *q, * The return values from this function are intended to be directly returned * from vidioc_reqbufs handler in driver. */ -static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) +int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) { unsigned int num_buffers, allocated_buffers, num_planes = 0; - int ret; + int ret = 0; + + if (q->fileio) { + dprintk(1, "reqbufs: file io in progress\n"); + return -EBUSY; + } + + if (req->memory != V4L2_MEMORY_MMAP + && req->memory != V4L2_MEMORY_USERPTR) { + dprintk(1, "reqbufs: unsupported memory type\n"); + return -EINVAL; + } + + if (req->type != q->type) { + dprintk(1, "reqbufs: requested type is incorrect\n"); + return -EINVAL; + } if (q->streaming) { dprintk(1, "reqbufs: streaming active\n"); return -EBUSY; } + /* + * Make sure all the required memory ops for given memory type + * are available. + */ + if (req->memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) { + dprintk(1, "reqbufs: MMAP for current setup unsupported\n"); + return -EINVAL; + } + + if (req->memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) { + dprintk(1, "reqbufs: USERPTR for current setup unsupported\n"); + return -EINVAL; + } + if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) { /* * We already have buffers allocated, so first check if they @@ -608,23 +595,10 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) return 0; } - -/** - * vb2_reqbufs() - Wrapper for __reqbufs() that also verifies the memory and - * type values. - * @q: videobuf2 queue - * @req: struct passed from userspace to vidioc_reqbufs handler in driver - */ -int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) -{ - int ret = __verify_memory_type(q, req->memory, req->type); - - return ret ? ret : __reqbufs(q, req); -} EXPORT_SYMBOL_GPL(vb2_reqbufs); /** - * __create_bufs() - Allocate buffers and any required auxiliary structs + * vb2_create_bufs() - Allocate buffers and any required auxiliary structs * @q: videobuf2 queue * @create: creation parameters, passed from userspace to vidioc_create_bufs * handler in driver @@ -638,10 +612,40 @@ EXPORT_SYMBOL_GPL(vb2_reqbufs); * The return values from this function are intended to be directly returned * from vidioc_create_bufs handler in driver. */ -static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) +int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) { unsigned int num_planes = 0, num_buffers, allocated_buffers; - int ret; + int ret = 0; + + if (q->fileio) { + dprintk(1, "%s(): file io in progress\n", __func__); + return -EBUSY; + } + + if (create->memory != V4L2_MEMORY_MMAP + && create->memory != V4L2_MEMORY_USERPTR) { + dprintk(1, "%s(): unsupported memory type\n", __func__); + return -EINVAL; + } + + if (create->format.type != q->type) { + dprintk(1, "%s(): requested type is incorrect\n", __func__); + return -EINVAL; + } + + /* + * Make sure all the required memory ops for given memory type + * are available. + */ + if (create->memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) { + dprintk(1, "%s(): MMAP for current setup unsupported\n", __func__); + return -EINVAL; + } + + if (create->memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) { + dprintk(1, "%s(): USERPTR for current setup unsupported\n", __func__); + return -EINVAL; + } if (q->num_buffers == VIDEO_MAX_FRAME) { dprintk(1, "%s(): maximum number of buffers already allocated\n", @@ -649,6 +653,8 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create return -ENOBUFS; } + create->index = q->num_buffers; + if (!q->num_buffers) { memset(q->plane_sizes, 0, sizeof(q->plane_sizes)); memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); @@ -669,9 +675,9 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create /* Finally, allocate buffers and video memory */ ret = __vb2_queue_alloc(q, create->memory, num_buffers, num_planes); - if (ret == 0) { - dprintk(1, "Memory allocation failed\n"); - return -ENOMEM; + if (ret < 0) { + dprintk(1, "Memory allocation failed with error: %d\n", ret); + return ret; } allocated_buffers = ret; @@ -702,7 +708,7 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create if (ret < 0) { __vb2_queue_free(q, allocated_buffers); - return -ENOMEM; + return ret; } /* @@ -713,23 +719,6 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create return 0; } - -/** - * vb2_reqbufs() - Wrapper for __reqbufs() that also verifies the memory and - * type values. - * @q: videobuf2 queue - * @create: creation parameters, passed from userspace to vidioc_create_bufs - * handler in driver - */ -int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) -{ - int ret = __verify_memory_type(q, create->memory, create->format.type); - - create->index = q->num_buffers; - if (create->count == 0) - return ret != -EBUSY ? ret : 0; - return ret ? ret : __create_bufs(q, create); -} EXPORT_SYMBOL_GPL(vb2_create_bufs); /** @@ -871,6 +860,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b, vb->v4l2_buf.field = b->field; vb->v4l2_buf.timestamp = b->timestamp; + vb->v4l2_buf.input = b->input; vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_STATE_FLAGS; return 0; @@ -2125,263 +2115,6 @@ size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count, } EXPORT_SYMBOL_GPL(vb2_write); - -/* - * The following functions are not part of the vb2 core API, but are helper - * functions that plug into struct v4l2_ioctl_ops, struct v4l2_file_operations - * and struct vb2_ops. - * They contain boilerplate code that most if not all drivers have to do - * and so they simplify the driver code. - */ - -/* The queue is busy if there is a owner and you are not that owner. */ -static inline bool vb2_queue_is_busy(struct video_device *vdev, struct file *file) -{ - return vdev->queue->owner && vdev->queue->owner != file->private_data; -} - -/* vb2 ioctl helpers */ - -int vb2_ioctl_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *p) -{ - struct video_device *vdev = video_devdata(file); - int res = __verify_memory_type(vdev->queue, p->memory, p->type); - - if (res) - return res; - if (vb2_queue_is_busy(vdev, file)) - return -EBUSY; - res = __reqbufs(vdev->queue, p); - /* If count == 0, then the owner has released all buffers and he - is no longer owner of the queue. Otherwise we have a new owner. */ - if (res == 0) - vdev->queue->owner = p->count ? file->private_data : NULL; - return res; -} -EXPORT_SYMBOL_GPL(vb2_ioctl_reqbufs); - -int vb2_ioctl_create_bufs(struct file *file, void *priv, - struct v4l2_create_buffers *p) -{ - struct video_device *vdev = video_devdata(file); - int res = __verify_memory_type(vdev->queue, p->memory, p->format.type); - - p->index = vdev->queue->num_buffers; - /* If count == 0, then just check if memory and type are valid. - Any -EBUSY result from __verify_memory_type can be mapped to 0. */ - if (p->count == 0) - return res != -EBUSY ? res : 0; - if (res) - return res; - if (vb2_queue_is_busy(vdev, file)) - return -EBUSY; - res = __create_bufs(vdev->queue, p); - if (res == 0) - vdev->queue->owner = file->private_data; - return res; -} -EXPORT_SYMBOL_GPL(vb2_ioctl_create_bufs); - -int vb2_ioctl_prepare_buf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct video_device *vdev = video_devdata(file); - - if (vb2_queue_is_busy(vdev, file)) - return -EBUSY; - return vb2_prepare_buf(vdev->queue, p); -} -EXPORT_SYMBOL_GPL(vb2_ioctl_prepare_buf); - -int vb2_ioctl_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) -{ - struct video_device *vdev = video_devdata(file); - - /* No need to call vb2_queue_is_busy(), anyone can query buffers. */ - return vb2_querybuf(vdev->queue, p); -} -EXPORT_SYMBOL_GPL(vb2_ioctl_querybuf); - -int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) -{ - struct video_device *vdev = video_devdata(file); - - if (vb2_queue_is_busy(vdev, file)) - return -EBUSY; - return vb2_qbuf(vdev->queue, p); -} -EXPORT_SYMBOL_GPL(vb2_ioctl_qbuf); - -int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) -{ - struct video_device *vdev = video_devdata(file); - - if (vb2_queue_is_busy(vdev, file)) - return -EBUSY; - return vb2_dqbuf(vdev->queue, p, file->f_flags & O_NONBLOCK); -} -EXPORT_SYMBOL_GPL(vb2_ioctl_dqbuf); - -int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct video_device *vdev = video_devdata(file); - - if (vb2_queue_is_busy(vdev, file)) - return -EBUSY; - return vb2_streamon(vdev->queue, i); -} -EXPORT_SYMBOL_GPL(vb2_ioctl_streamon); - -int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct video_device *vdev = video_devdata(file); - - if (vb2_queue_is_busy(vdev, file)) - return -EBUSY; - return vb2_streamoff(vdev->queue, i); -} -EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff); - -/* v4l2_file_operations helpers */ - -int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct video_device *vdev = video_devdata(file); - - return vb2_mmap(vdev->queue, vma); -} -EXPORT_SYMBOL_GPL(vb2_fop_mmap); - -int vb2_fop_release(struct file *file) -{ - struct video_device *vdev = video_devdata(file); - - if (file->private_data == vdev->queue->owner) { - vb2_queue_release(vdev->queue); - vdev->queue->owner = NULL; - } - return v4l2_fh_release(file); -} -EXPORT_SYMBOL_GPL(vb2_fop_release); - -ssize_t vb2_fop_write(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - struct video_device *vdev = video_devdata(file); - struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; - bool must_lock = !test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && lock; - int err = -EBUSY; - - if (must_lock && mutex_lock_interruptible(lock)) - return -ERESTARTSYS; - if (vb2_queue_is_busy(vdev, file)) - goto exit; - err = vb2_write(vdev->queue, buf, count, ppos, - file->f_flags & O_NONBLOCK); - if (err >= 0) - vdev->queue->owner = file->private_data; -exit: - if (must_lock) - mutex_unlock(lock); - return err; -} -EXPORT_SYMBOL_GPL(vb2_fop_write); - -ssize_t vb2_fop_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - struct video_device *vdev = video_devdata(file); - struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; - bool must_lock = !test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && vdev->lock; - int err = -EBUSY; - - if (must_lock && mutex_lock_interruptible(lock)) - return -ERESTARTSYS; - if (vb2_queue_is_busy(vdev, file)) - goto exit; - err = vb2_read(vdev->queue, buf, count, ppos, - file->f_flags & O_NONBLOCK); - if (err >= 0) - vdev->queue->owner = file->private_data; -exit: - if (must_lock) - mutex_unlock(lock); - return err; -} -EXPORT_SYMBOL_GPL(vb2_fop_read); - -unsigned int vb2_fop_poll(struct file *file, poll_table *wait) -{ - struct video_device *vdev = video_devdata(file); - struct vb2_queue *q = vdev->queue; - struct mutex *lock = q->lock ? q->lock : vdev->lock; - unsigned long req_events = poll_requested_events(wait); - unsigned res; - void *fileio; - /* Yuck. We really need to get rid of this flag asap. If it is - set, then the core took the serialization lock before calling - poll(). This is being phased out, but for now we have to handle - this case. */ - bool locked = test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags); - bool must_lock = false; - - /* Try to be smart: only lock if polling might start fileio, - otherwise locking will only introduce unwanted delays. */ - if (q->num_buffers == 0 && q->fileio == NULL) { - if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) && - (req_events & (POLLIN | POLLRDNORM))) - must_lock = true; - else if (V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_WRITE) && - (req_events & (POLLOUT | POLLWRNORM))) - must_lock = true; - } - - /* If locking is needed, but this helper doesn't know how, then you - shouldn't be using this helper but you should write your own. */ - WARN_ON(must_lock && !locked && !lock); - - if (must_lock && !locked && lock && mutex_lock_interruptible(lock)) - return POLLERR; - - fileio = q->fileio; - - res = vb2_poll(vdev->queue, file, wait); - - /* If fileio was started, then we have a new queue owner. */ - if (must_lock && !fileio && q->fileio) - q->owner = file->private_data; - if (must_lock && !locked && lock) - mutex_unlock(lock); - return res; -} -EXPORT_SYMBOL_GPL(vb2_fop_poll); - -#ifndef CONFIG_MMU -unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) -{ - struct video_device *vdev = video_devdata(file); - - return vb2_get_unmapped_area(vdev->queue, addr, len, pgoff, flags); -} -EXPORT_SYMBOL_GPL(vb2_fop_get_unmapped_area); -#endif - -/* vb2_ops helpers. Only use if vq->lock is non-NULL. */ - -void vb2_ops_wait_prepare(struct vb2_queue *vq) -{ - mutex_unlock(vq->lock); -} -EXPORT_SYMBOL_GPL(vb2_ops_wait_prepare); - -void vb2_ops_wait_finish(struct vb2_queue *vq) -{ - mutex_lock(vq->lock); -} -EXPORT_SYMBOL_GPL(vb2_ops_wait_finish); - MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2"); MODULE_AUTHOR("Pawel Osciak , Marek Szyprowski"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index 1e8c4f3ab602..08c10240e70f 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -188,7 +188,6 @@ struct vivi_dev { struct list_head vivi_devlist; struct v4l2_device v4l2_dev; struct v4l2_ctrl_handler ctrl_handler; - struct video_device vdev; /* controls */ struct v4l2_ctrl *brightness; @@ -214,6 +213,9 @@ struct vivi_dev { spinlock_t slock; struct mutex mutex; + /* various device info */ + struct video_device *vfd; + struct vivi_dmaqueue vidq; /* Several counters */ @@ -767,13 +769,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, struct vivi_dev *dev = vb2_get_drv_priv(vq); unsigned long size; - if (fmt) - size = fmt->fmt.pix.sizeimage; - else - size = dev->width * dev->height * dev->pixelsize; - - if (size == 0) - return -EINVAL; + size = dev->width * dev->height * dev->pixelsize; if (0 == *nbuffers) *nbuffers = 32; @@ -796,6 +792,27 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, return 0; } +static int buffer_init(struct vb2_buffer *vb) +{ + struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + + BUG_ON(NULL == dev->fmt); + + /* + * This callback is called once per buffer, after its allocation. + * + * Vivi does not allow changing format during streaming, but it is + * possible to do so when streaming is paused (i.e. in streamoff state). + * Buffers however are not freed when going into streamoff and so + * buffer size verification has to be done in buffer_prepare, on each + * qbuf. + * It would be best to move verification code here to buf_init and + * s_fmt though. + */ + + return 0; +} + static int buffer_prepare(struct vb2_buffer *vb) { struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue); @@ -833,6 +850,20 @@ static int buffer_prepare(struct vb2_buffer *vb) return 0; } +static int buffer_finish(struct vb2_buffer *vb) +{ + struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + dprintk(dev, 1, "%s\n", __func__); + return 0; +} + +static void buffer_cleanup(struct vb2_buffer *vb) +{ + struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + dprintk(dev, 1, "%s\n", __func__); + +} + static void buffer_queue(struct vb2_buffer *vb) { struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue); @@ -878,7 +909,10 @@ static void vivi_unlock(struct vb2_queue *vq) static struct vb2_ops vivi_video_qops = { .queue_setup = queue_setup, + .buf_init = buffer_init, .buf_prepare = buffer_prepare, + .buf_finish = buffer_finish, + .buf_cleanup = buffer_cleanup, .buf_queue = buffer_queue, .start_streaming = start_streaming, .stop_streaming = stop_streaming, @@ -987,7 +1021,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, if (ret < 0) return ret; - if (vb2_is_busy(q)) { + if (vb2_is_streaming(q)) { dprintk(dev, 1, "%s device busy\n", __func__); return -EBUSY; } @@ -1001,6 +1035,48 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return 0; } +static int vidioc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + struct vivi_dev *dev = video_drvdata(file); + return vb2_reqbufs(&dev->vb_vidq, p); +} + +static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + struct vivi_dev *dev = video_drvdata(file); + return vb2_querybuf(&dev->vb_vidq, p); +} + +static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + struct vivi_dev *dev = video_drvdata(file); + return vb2_qbuf(&dev->vb_vidq, p); +} + +static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + struct vivi_dev *dev = video_drvdata(file); + return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK); +} + +static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct vivi_dev *dev = video_drvdata(file); + return vb2_streamon(&dev->vb_vidq, i); +} + +static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct vivi_dev *dev = video_drvdata(file); + return vb2_streamoff(&dev->vb_vidq, i); +} + +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) +{ + return 0; +} + /* only one input in this sample driver */ static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *inp) @@ -1009,6 +1085,7 @@ static int vidioc_enum_input(struct file *file, void *priv, return -EINVAL; inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = V4L2_STD_525_60; sprintf(inp->name, "Camera %u", inp->index); return 0; } @@ -1068,6 +1145,58 @@ static int vivi_s_ctrl(struct v4l2_ctrl *ctrl) File operations for the device ------------------------------------------------------------------*/ +static ssize_t +vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) +{ + struct vivi_dev *dev = video_drvdata(file); + int err; + + dprintk(dev, 1, "read called\n"); + mutex_lock(&dev->mutex); + err = vb2_read(&dev->vb_vidq, data, count, ppos, + file->f_flags & O_NONBLOCK); + mutex_unlock(&dev->mutex); + return err; +} + +static unsigned int +vivi_poll(struct file *file, struct poll_table_struct *wait) +{ + struct vivi_dev *dev = video_drvdata(file); + struct vb2_queue *q = &dev->vb_vidq; + + dprintk(dev, 1, "%s\n", __func__); + return vb2_poll(q, file, wait); +} + +static int vivi_close(struct file *file) +{ + struct video_device *vdev = video_devdata(file); + struct vivi_dev *dev = video_drvdata(file); + + dprintk(dev, 1, "close called (dev=%s), file %p\n", + video_device_node_name(vdev), file); + + if (v4l2_fh_is_singular_file(file)) + vb2_queue_release(&dev->vb_vidq); + return v4l2_fh_release(file); +} + +static int vivi_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct vivi_dev *dev = video_drvdata(file); + int ret; + + dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); + + ret = vb2_mmap(&dev->vb_vidq, vma); + dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", + (unsigned long)vma->vm_start, + (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, + ret); + return ret; +} + static const struct v4l2_ctrl_ops vivi_ctrl_ops = { .g_volatile_ctrl = vivi_g_volatile_ctrl, .s_ctrl = vivi_s_ctrl, @@ -1172,11 +1301,11 @@ static const struct v4l2_ctrl_config vivi_ctrl_int_menu = { static const struct v4l2_file_operations vivi_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, - .release = vb2_fop_release, - .read = vb2_fop_read, - .poll = vb2_fop_poll, + .release = vivi_close, + .read = vivi_read, + .poll = vivi_poll, .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ - .mmap = vb2_fop_mmap, + .mmap = vivi_mmap, }; static const struct v4l2_ioctl_ops vivi_ioctl_ops = { @@ -1185,17 +1314,16 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = { .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_reqbufs = vb2_ioctl_reqbufs, - .vidioc_create_bufs = vb2_ioctl_create_bufs, - .vidioc_prepare_buf = vb2_ioctl_prepare_buf, - .vidioc_querybuf = vb2_ioctl_querybuf, - .vidioc_qbuf = vb2_ioctl_qbuf, - .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_reqbufs = vidioc_reqbufs, + .vidioc_querybuf = vidioc_querybuf, + .vidioc_qbuf = vidioc_qbuf, + .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_s_std = vidioc_s_std, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, - .vidioc_streamon = vb2_ioctl_streamon, - .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_streamon = vidioc_streamon, + .vidioc_streamoff = vidioc_streamoff, .vidioc_log_status = v4l2_ctrl_log_status, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, @@ -1205,7 +1333,10 @@ static struct video_device vivi_template = { .name = "vivi", .fops = &vivi_fops, .ioctl_ops = &vivi_ioctl_ops, - .release = video_device_release_empty, + .release = video_device_release, + + .tvnorms = V4L2_STD_525_60, + .current_norm = V4L2_STD_NTSC_M, }; /* ----------------------------------------------------------------- @@ -1223,8 +1354,8 @@ static int vivi_release(void) dev = list_entry(list, struct vivi_dev, vivi_devlist); v4l2_info(&dev->v4l2_dev, "unregistering %s\n", - video_device_node_name(&dev->vdev)); - video_unregister_device(&dev->vdev); + video_device_node_name(dev->vfd)); + video_unregister_device(dev->vfd); v4l2_device_unregister(&dev->v4l2_dev); v4l2_ctrl_handler_free(&dev->ctrl_handler); kfree(dev); @@ -1309,11 +1440,14 @@ static int __init vivi_create_instance(int inst) INIT_LIST_HEAD(&dev->vidq.active); init_waitqueue_head(&dev->vidq.wq); - vfd = &dev->vdev; + ret = -ENOMEM; + vfd = video_device_alloc(); + if (!vfd) + goto unreg_dev; + *vfd = vivi_template; vfd->debug = debug; vfd->v4l2_dev = &dev->v4l2_dev; - vfd->queue = q; set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); /* @@ -1321,11 +1455,12 @@ static int __init vivi_create_instance(int inst) * all fops and v4l2 ioctls. */ vfd->lock = &dev->mutex; - video_set_drvdata(vfd, dev); ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); if (ret < 0) - goto unreg_dev; + goto rel_vdev; + + video_set_drvdata(vfd, dev); /* Now that everything is fine, let's add it to device list */ list_add_tail(&dev->vivi_devlist, &vivi_devlist); @@ -1333,10 +1468,13 @@ static int __init vivi_create_instance(int inst) if (video_nr != -1) video_nr++; + dev->vfd = vfd; v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n", video_device_node_name(vfd)); return 0; +rel_vdev: + video_device_release(vfd); unreg_dev: v4l2_ctrl_handler_free(hdl); v4l2_device_unregister(&dev->v4l2_dev); diff --git a/trunk/drivers/media/video/zr364xx.c b/trunk/drivers/media/video/zr364xx.c index 9afab35878b4..e44cb330bbc8 100644 --- a/trunk/drivers/media/video/zr364xx.c +++ b/trunk/drivers/media/video/zr364xx.c @@ -37,10 +37,6 @@ #include #include #include -#include -#include -#include -#include #include @@ -124,6 +120,11 @@ static struct usb_device_id device_table[] = { MODULE_DEVICE_TABLE(usb, device_table); +struct zr364xx_mode { + u32 color; /* output video color format */ + u32 brightness; /* brightness */ +}; + /* frame structure */ struct zr364xx_framei { unsigned long ulState; /* ulState:ZR364XX_READ_IDLE, @@ -172,10 +173,7 @@ static const struct zr364xx_fmt formats[] = { struct zr364xx_camera { struct usb_device *udev; /* save off the usb device pointer */ struct usb_interface *interface;/* the interface for this device */ - struct v4l2_device v4l2_dev; - struct v4l2_ctrl_handler ctrl_handler; - struct video_device vdev; /* v4l video device */ - struct v4l2_fh *owner; /* owns the streaming */ + struct video_device *vdev; /* v4l video device */ int nb; struct zr364xx_bufferi buffer; int skip; @@ -183,9 +181,12 @@ struct zr364xx_camera { int height; int method; struct mutex lock; + struct mutex open_lock; + int users; spinlock_t slock; struct zr364xx_dmaqueue vidq; + int resources; int last_frame; int cur_frame; unsigned long frame_count; @@ -196,7 +197,8 @@ struct zr364xx_camera { const struct zr364xx_fmt *fmt; struct videobuf_queue vb_vidq; - bool was_streaming; + enum v4l2_buf_type type; + struct zr364xx_mode mode; }; /* buffer for one video frame */ @@ -228,6 +230,11 @@ static int send_control_msg(struct usb_device *udev, u8 request, u16 value, transfer_buffer, size, CTRL_TIMEOUT); kfree(transfer_buffer); + + if (status < 0) + dev_err(&udev->dev, + "Failed sending control message, error %d.\n", status); + return status; } @@ -461,7 +468,6 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) { struct zr364xx_camera *cam = video_drvdata(file); - int err = 0; _DBG("%s\n", __func__); @@ -471,21 +477,17 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count, if (!count) return -EINVAL; - if (mutex_lock_interruptible(&cam->lock)) - return -ERESTARTSYS; - - err = zr364xx_vidioc_streamon(file, file->private_data, - V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (err == 0) { - DBG("%s: reading %d bytes at pos %d.\n", __func__, - (int) count, (int) *ppos); + if (cam->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && + zr364xx_vidioc_streamon(file, cam, cam->type) == 0) { + DBG("%s: reading %d bytes at pos %d.\n", __func__, (int) count, + (int) *ppos); /* NoMan Sux ! */ - err = videobuf_read_one(&cam->vb_vidq, buf, count, ppos, + return videobuf_read_one(&cam->vb_vidq, buf, count, ppos, file->f_flags & O_NONBLOCK); } - mutex_unlock(&cam->lock); - return err; + + return 0; } /* video buffer vmalloc implementation based partly on VIVI driver which is @@ -700,6 +702,35 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam, return 0; } +static int res_get(struct zr364xx_camera *cam) +{ + /* is it free? */ + mutex_lock(&cam->lock); + if (cam->resources) { + /* no, someone else uses it */ + mutex_unlock(&cam->lock); + return 0; + } + /* it's free, grab it */ + cam->resources = 1; + _DBG("res: get\n"); + mutex_unlock(&cam->lock); + return 1; +} + +static inline int res_check(struct zr364xx_camera *cam) +{ + return cam->resources; +} + +static void res_free(struct zr364xx_camera *cam) +{ + mutex_lock(&cam->lock); + cam->resources = 0; + mutex_unlock(&cam->lock); + _DBG("res: put\n"); +} + static int zr364xx_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -709,10 +740,9 @@ static int zr364xx_vidioc_querycap(struct file *file, void *priv, strlcpy(cap->card, cam->udev->product, sizeof(cap->card)); strlcpy(cap->bus_info, dev_name(&cam->udev->dev), sizeof(cap->bus_info)); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } @@ -742,18 +772,50 @@ static int zr364xx_vidioc_s_input(struct file *file, void *priv, return 0; } -static int zr364xx_s_ctrl(struct v4l2_ctrl *ctrl) +static int zr364xx_vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *c) { - struct zr364xx_camera *cam = - container_of(ctrl->handler, struct zr364xx_camera, ctrl_handler); + struct zr364xx_camera *cam; + + if (file == NULL) + return -ENODEV; + cam = video_drvdata(file); + + switch (c->id) { + case V4L2_CID_BRIGHTNESS: + c->type = V4L2_CTRL_TYPE_INTEGER; + strcpy(c->name, "Brightness"); + c->minimum = 0; + c->maximum = 127; + c->step = 1; + c->default_value = cam->mode.brightness; + c->flags = 0; + break; + default: + return -EINVAL; + } + return 0; +} + +static int zr364xx_vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *c) +{ + struct zr364xx_camera *cam; int temp; - switch (ctrl->id) { + if (file == NULL) + return -ENODEV; + cam = video_drvdata(file); + + switch (c->id) { case V4L2_CID_BRIGHTNESS: + cam->mode.brightness = c->value; /* hardware brightness */ + mutex_lock(&cam->lock); send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0); - temp = (0x60 << 8) + 127 - ctrl->val; + temp = (0x60 << 8) + 127 - cam->mode.brightness; send_control_msg(cam->udev, 1, temp, 0, NULL, 0); + mutex_unlock(&cam->lock); break; default: return -EINVAL; @@ -762,6 +824,25 @@ static int zr364xx_s_ctrl(struct v4l2_ctrl *ctrl) return 0; } +static int zr364xx_vidioc_g_ctrl(struct file *file, void *priv, + struct v4l2_control *c) +{ + struct zr364xx_camera *cam; + + if (file == NULL) + return -ENODEV; + cam = video_drvdata(file); + + switch (c->id) { + case V4L2_CID_BRIGHTNESS: + c->value = cam->mode.brightness; + break; + default: + return -EINVAL; + } + return 0; +} + static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { @@ -807,7 +888,7 @@ static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.field = V4L2_FIELD_NONE; f->fmt.pix.bytesperline = f->fmt.pix.width * 2; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; - f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; + f->fmt.pix.colorspace = 0; f->fmt.pix.priv = 0; DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__, decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name), @@ -830,7 +911,7 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.height = cam->height; f->fmt.pix.bytesperline = f->fmt.pix.width * 2; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; - f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; + f->fmt.pix.colorspace = 0; f->fmt.pix.priv = 0; return 0; } @@ -855,7 +936,7 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv, goto out; } - if (cam->owner) { + if (res_check(cam)) { DBG("%s can't change format after started\n", __func__); ret = -EBUSY; goto out; @@ -863,13 +944,14 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv, cam->width = f->fmt.pix.width; cam->height = f->fmt.pix.height; - DBG("%s: %dx%d mode selected\n", __func__, + dev_info(&cam->udev->dev, "%s: %dx%d mode selected\n", __func__, cam->width, cam->height); f->fmt.pix.bytesperline = f->fmt.pix.width * 2; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; - f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; + f->fmt.pix.colorspace = 0; f->fmt.pix.priv = 0; cam->vb_vidq.field = f->fmt.pix.field; + cam->mode.color = V4L2_PIX_FMT_JPEG; if (f->fmt.pix.width == 160 && f->fmt.pix.height == 120) mode = 1; @@ -933,11 +1015,10 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv, static int zr364xx_vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { + int rc; struct zr364xx_camera *cam = video_drvdata(file); - - if (cam->owner && cam->owner != priv) - return -EBUSY; - return videobuf_reqbufs(&cam->vb_vidq, p); + rc = videobuf_reqbufs(&cam->vb_vidq, p); + return rc; } static int zr364xx_vidioc_querybuf(struct file *file, @@ -957,8 +1038,6 @@ static int zr364xx_vidioc_qbuf(struct file *file, int rc; struct zr364xx_camera *cam = video_drvdata(file); _DBG("%s\n", __func__); - if (cam->owner && cam->owner != priv) - return -EBUSY; rc = videobuf_qbuf(&cam->vb_vidq, p); return rc; } @@ -970,8 +1049,6 @@ static int zr364xx_vidioc_dqbuf(struct file *file, int rc; struct zr364xx_camera *cam = video_drvdata(file); _DBG("%s\n", __func__); - if (cam->owner && cam->owner != priv) - return -EBUSY; rc = videobuf_dqbuf(&cam->vb_vidq, p, file->f_flags & O_NONBLOCK); return rc; } @@ -1120,55 +1197,41 @@ static inline int zr364xx_stop_acquire(struct zr364xx_camera *cam) return 0; } -static int zr364xx_prepare(struct zr364xx_camera *cam) -{ - int res; - int i, j; - - for (i = 0; init[cam->method][i].size != -1; i++) { - res = send_control_msg(cam->udev, 1, init[cam->method][i].value, - 0, init[cam->method][i].bytes, - init[cam->method][i].size); - if (res < 0) { - dev_err(&cam->udev->dev, - "error during open sequence: %d\n", i); - return res; - } - } - - cam->skip = 2; - cam->last_frame = -1; - cam->cur_frame = 0; - cam->frame_count = 0; - for (j = 0; j < FRAMES; j++) { - cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE; - cam->buffer.frame[j].cur_size = 0; - } - v4l2_ctrl_handler_setup(&cam->ctrl_handler); - return 0; -} - static int zr364xx_vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type type) { struct zr364xx_camera *cam = video_drvdata(file); + int j; int res; DBG("%s\n", __func__); - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (cam->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dev_err(&cam->udev->dev, "invalid fh type0\n"); + return -EINVAL; + } + if (cam->type != type) { + dev_err(&cam->udev->dev, "invalid fh type1\n"); return -EINVAL; + } - if (cam->owner && cam->owner != priv) + if (!res_get(cam)) { + dev_err(&cam->udev->dev, "stream busy\n"); return -EBUSY; + } - res = zr364xx_prepare(cam); - if (res) - return res; + cam->last_frame = -1; + cam->cur_frame = 0; + cam->frame_count = 0; + for (j = 0; j < FRAMES; j++) { + cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE; + cam->buffer.frame[j].cur_size = 0; + } res = videobuf_streamon(&cam->vb_vidq); if (res == 0) { zr364xx_start_acquire(cam); - cam->owner = file->private_data; + } else { + res_free(cam); } return res; } @@ -1176,32 +1239,67 @@ static int zr364xx_vidioc_streamon(struct file *file, void *priv, static int zr364xx_vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { + int res; struct zr364xx_camera *cam = video_drvdata(file); DBG("%s\n", __func__); - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (cam->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dev_err(&cam->udev->dev, "invalid fh type0\n"); return -EINVAL; - if (cam->owner && cam->owner != priv) - return -EBUSY; + } + if (cam->type != type) { + dev_err(&cam->udev->dev, "invalid fh type1\n"); + return -EINVAL; + } zr364xx_stop_acquire(cam); - return videobuf_streamoff(&cam->vb_vidq); + res = videobuf_streamoff(&cam->vb_vidq); + if (res < 0) + return res; + res_free(cam); + return 0; } /* open the camera */ static int zr364xx_open(struct file *file) { + struct video_device *vdev = video_devdata(file); struct zr364xx_camera *cam = video_drvdata(file); - int err; + struct usb_device *udev = cam->udev; + int i, err; DBG("%s\n", __func__); - if (mutex_lock_interruptible(&cam->lock)) - return -ERESTARTSYS; + mutex_lock(&cam->open_lock); - err = v4l2_fh_open(file); - if (err) + if (cam->users) { + err = -EBUSY; goto out; + } + + for (i = 0; init[cam->method][i].size != -1; i++) { + err = + send_control_msg(udev, 1, init[cam->method][i].value, + 0, init[cam->method][i].bytes, + init[cam->method][i].size); + if (err < 0) { + dev_err(&cam->udev->dev, + "error during open sequence: %d\n", i); + goto out; + } + } + + cam->skip = 2; + cam->users++; + file->private_data = vdev; + cam->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cam->fmt = formats; + + videobuf_queue_vmalloc_init(&cam->vb_vidq, &zr364xx_video_qops, + NULL, &cam->slock, + cam->type, + V4L2_FIELD_NONE, + sizeof(struct zr364xx_buffer), cam, NULL); /* Added some delay here, since opening/closing the camera quickly, * like Ekiga does during its startup, can crash the webcam @@ -1210,20 +1308,29 @@ static int zr364xx_open(struct file *file) err = 0; out: - mutex_unlock(&cam->lock); + mutex_unlock(&cam->open_lock); DBG("%s: %d\n", __func__, err); return err; } -static void zr364xx_release(struct v4l2_device *v4l2_dev) +static void zr364xx_destroy(struct zr364xx_camera *cam) { - struct zr364xx_camera *cam = - container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev); unsigned long i; - v4l2_device_unregister(&cam->v4l2_dev); + if (!cam) { + printk(KERN_ERR KBUILD_MODNAME ", %s: no device\n", __func__); + return; + } + mutex_lock(&cam->open_lock); + if (cam->vdev) + video_unregister_device(cam->vdev); + cam->vdev = NULL; - videobuf_mmap_free(&cam->vb_vidq); + /* stops the read pipe if it is running */ + if (cam->b_acquire) + zr364xx_stop_acquire(cam); + + zr364xx_stop_readpipe(cam); /* release sys buffers */ for (i = 0; i < FRAMES; i++) { @@ -1234,45 +1341,62 @@ static void zr364xx_release(struct v4l2_device *v4l2_dev) cam->buffer.frame[i].lpvbits = NULL; } - v4l2_ctrl_handler_free(&cam->ctrl_handler); /* release transfer buffer */ kfree(cam->pipe->transfer_buffer); + cam->pipe->transfer_buffer = NULL; + mutex_unlock(&cam->open_lock); kfree(cam); + cam = NULL; } /* release the camera */ -static int zr364xx_close(struct file *file) +static int zr364xx_release(struct file *file) { struct zr364xx_camera *cam; struct usb_device *udev; - int i; + int i, err; DBG("%s\n", __func__); cam = video_drvdata(file); - mutex_lock(&cam->lock); + if (!cam) + return -ENODEV; + + mutex_lock(&cam->open_lock); udev = cam->udev; - if (file->private_data == cam->owner) { - /* turn off stream */ + /* turn off stream */ + if (res_check(cam)) { if (cam->b_acquire) zr364xx_stop_acquire(cam); videobuf_streamoff(&cam->vb_vidq); + res_free(cam); + } + + cam->users--; + file->private_data = NULL; - for (i = 0; i < 2; i++) { - send_control_msg(udev, 1, init[cam->method][i].value, - 0, init[cam->method][i].bytes, - init[cam->method][i].size); + for (i = 0; i < 2; i++) { + err = + send_control_msg(udev, 1, init[cam->method][i].value, + 0, init[cam->method][i].bytes, + init[cam->method][i].size); + if (err < 0) { + dev_err(&udev->dev, "error during release sequence\n"); + goto out; } - cam->owner = NULL; } /* Added some delay here, since opening/closing the camera quickly, * like Ekiga does during its startup, can crash the webcam */ mdelay(100); - mutex_unlock(&cam->lock); - return v4l2_fh_release(file); + err = 0; + +out: + mutex_unlock(&cam->open_lock); + + return err; } @@ -1300,24 +1424,21 @@ static unsigned int zr364xx_poll(struct file *file, { struct zr364xx_camera *cam = video_drvdata(file); struct videobuf_queue *q = &cam->vb_vidq; - unsigned res = v4l2_ctrl_poll(file, wait); - _DBG("%s\n", __func__); - return res | videobuf_poll_stream(file, q, wait); -} + if (cam->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return POLLERR; -static const struct v4l2_ctrl_ops zr364xx_ctrl_ops = { - .s_ctrl = zr364xx_s_ctrl, -}; + return videobuf_poll_stream(file, q, wait); +} static const struct v4l2_file_operations zr364xx_fops = { .owner = THIS_MODULE, .open = zr364xx_open, - .release = zr364xx_close, + .release = zr364xx_release, .read = zr364xx_read, .mmap = zr364xx_mmap, - .unlocked_ioctl = video_ioctl2, + .ioctl = video_ioctl2, .poll = zr364xx_poll, }; @@ -1332,20 +1453,20 @@ static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { .vidioc_s_input = zr364xx_vidioc_s_input, .vidioc_streamon = zr364xx_vidioc_streamon, .vidioc_streamoff = zr364xx_vidioc_streamoff, + .vidioc_queryctrl = zr364xx_vidioc_queryctrl, + .vidioc_g_ctrl = zr364xx_vidioc_g_ctrl, + .vidioc_s_ctrl = zr364xx_vidioc_s_ctrl, .vidioc_reqbufs = zr364xx_vidioc_reqbufs, .vidioc_querybuf = zr364xx_vidioc_querybuf, .vidioc_qbuf = zr364xx_vidioc_qbuf, .vidioc_dqbuf = zr364xx_vidioc_dqbuf, - .vidioc_log_status = v4l2_ctrl_log_status, - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device zr364xx_template = { .name = DRIVER_DESC, .fops = &zr364xx_fops, .ioctl_ops = &zr364xx_ioctl_ops, - .release = video_device_release_empty, + .release = video_device_release, }; @@ -1419,7 +1540,6 @@ static int zr364xx_probe(struct usb_interface *intf, struct zr364xx_camera *cam = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; - struct v4l2_ctrl_handler *hdl; int err; int i; @@ -1435,34 +1555,21 @@ static int zr364xx_probe(struct usb_interface *intf, dev_err(&udev->dev, "cam: out of memory !\n"); return -ENOMEM; } + /* save the init method used by this camera */ + cam->method = id->driver_info; - cam->v4l2_dev.release = zr364xx_release; - err = v4l2_device_register(&intf->dev, &cam->v4l2_dev); - if (err < 0) { - dev_err(&udev->dev, "couldn't register v4l2_device\n"); + cam->vdev = video_device_alloc(); + if (cam->vdev == NULL) { + dev_err(&udev->dev, "cam->vdev: out of memory !\n"); kfree(cam); - return err; - } - hdl = &cam->ctrl_handler; - v4l2_ctrl_handler_init(hdl, 1); - v4l2_ctrl_new_std(hdl, &zr364xx_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 127, 1, 64); - if (hdl->error) { - err = hdl->error; - dev_err(&udev->dev, "couldn't register control\n"); - goto fail; + cam = NULL; + return -ENOMEM; } - /* save the init method used by this camera */ - cam->method = id->driver_info; - mutex_init(&cam->lock); - cam->vdev = zr364xx_template; - cam->vdev.lock = &cam->lock; - cam->vdev.v4l2_dev = &cam->v4l2_dev; - cam->vdev.ctrl_handler = &cam->ctrl_handler; - set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags); - video_set_drvdata(&cam->vdev, cam); + memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template)); + cam->vdev->parent = &intf->dev; + video_set_drvdata(cam->vdev, cam); if (debug) - cam->vdev.debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; + cam->vdev->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; cam->udev = udev; @@ -1508,7 +1615,11 @@ static int zr364xx_probe(struct usb_interface *intf, header2[439] = cam->width / 256; header2[440] = cam->width % 256; + cam->users = 0; cam->nb = 0; + cam->mode.brightness = 64; + mutex_init(&cam->lock); + mutex_init(&cam->open_lock); DBG("dev: %p, udev %p interface %p\n", cam, cam->udev, intf); @@ -1524,100 +1635,52 @@ static int zr364xx_probe(struct usb_interface *intf, } if (!cam->read_endpoint) { - err = -ENOMEM; dev_err(&intf->dev, "Could not find bulk-in endpoint\n"); - goto fail; + video_device_release(cam->vdev); + kfree(cam); + cam = NULL; + return -ENOMEM; } /* v4l */ INIT_LIST_HEAD(&cam->vidq.active); cam->vidq.cam = cam; + err = video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1); + if (err) { + dev_err(&udev->dev, "video_register_device failed\n"); + video_device_release(cam->vdev); + kfree(cam); + cam = NULL; + return err; + } usb_set_intfdata(intf, cam); /* load zr364xx board specific */ err = zr364xx_board_init(cam); - if (!err) - err = v4l2_ctrl_handler_setup(hdl); - if (err) - goto fail; - - spin_lock_init(&cam->slock); - - cam->fmt = formats; - - videobuf_queue_vmalloc_init(&cam->vb_vidq, &zr364xx_video_qops, - NULL, &cam->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_NONE, - sizeof(struct zr364xx_buffer), cam, &cam->lock); - - err = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); if (err) { - dev_err(&udev->dev, "video_register_device failed\n"); - goto fail; + spin_lock_init(&cam->slock); + return err; } + spin_lock_init(&cam->slock); + dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n", - video_device_node_name(&cam->vdev)); + video_device_node_name(cam->vdev)); return 0; - -fail: - v4l2_ctrl_handler_free(hdl); - v4l2_device_unregister(&cam->v4l2_dev); - kfree(cam); - return err; } static void zr364xx_disconnect(struct usb_interface *intf) { struct zr364xx_camera *cam = usb_get_intfdata(intf); - - mutex_lock(&cam->lock); + videobuf_mmap_free(&cam->vb_vidq); usb_set_intfdata(intf, NULL); dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n"); - video_unregister_device(&cam->vdev); - v4l2_device_disconnect(&cam->v4l2_dev); - - /* stops the read pipe if it is running */ - if (cam->b_acquire) - zr364xx_stop_acquire(cam); - - zr364xx_stop_readpipe(cam); - mutex_unlock(&cam->lock); - v4l2_device_put(&cam->v4l2_dev); + zr364xx_destroy(cam); } -#ifdef CONFIG_PM -static int zr364xx_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct zr364xx_camera *cam = usb_get_intfdata(intf); - - cam->was_streaming = cam->b_acquire; - if (!cam->was_streaming) - return 0; - zr364xx_stop_acquire(cam); - zr364xx_stop_readpipe(cam); - return 0; -} - -static int zr364xx_resume(struct usb_interface *intf) -{ - struct zr364xx_camera *cam = usb_get_intfdata(intf); - int res; - - if (!cam->was_streaming) - return 0; - - zr364xx_start_readpipe(cam); - res = zr364xx_prepare(cam); - if (!res) - zr364xx_start_acquire(cam); - return res; -} -#endif /**********************/ /* Module integration */ @@ -1627,11 +1690,6 @@ static struct usb_driver zr364xx_driver = { .name = "zr364xx", .probe = zr364xx_probe, .disconnect = zr364xx_disconnect, -#ifdef CONFIG_PM - .suspend = zr364xx_suspend, - .resume = zr364xx_resume, - .reset_resume = zr364xx_resume, -#endif .id_table = device_table }; diff --git a/trunk/drivers/message/i2o/i2o_config.c b/trunk/drivers/message/i2o/i2o_config.c index 9a49c243a6ac..098de2b35784 100644 --- a/trunk/drivers/message/i2o/i2o_config.c +++ b/trunk/drivers/message/i2o/i2o_config.c @@ -188,13 +188,6 @@ static int i2o_cfg_parms(unsigned long arg, unsigned int type) if (!dev) return -ENXIO; - /* - * Stop users being able to try and allocate arbitary amounts - * of DMA space. 64K is way more than sufficient for this. - */ - if (kcmd.oplen > 65536) - return -EMSGSIZE; - ops = memdup_user(kcmd.opbuf, kcmd.oplen); if (IS_ERR(ops)) return PTR_ERR(ops); diff --git a/trunk/drivers/message/i2o/i2o_proc.c b/trunk/drivers/message/i2o/i2o_proc.c index 8001aa6bfb48..506c36f6e1db 100644 --- a/trunk/drivers/message/i2o/i2o_proc.c +++ b/trunk/drivers/message/i2o/i2o_proc.c @@ -255,8 +255,9 @@ static char *scsi_devices[] = { "Array Controller Device" }; -static char *chtostr(char *tmp, u8 *chars, int n) +static char *chtostr(u8 * chars, int n) { + char tmp[256]; tmp[0] = 0; return strncat(tmp, (char *)chars, n); } @@ -790,7 +791,6 @@ static int i2o_seq_show_ddm_table(struct seq_file *seq, void *v) } *result; i2o_exec_execute_ddm_table ddm_table; - char tmp[28 + 1]; result = kmalloc(sizeof(*result), GFP_KERNEL); if (!result) @@ -826,7 +826,7 @@ static int i2o_seq_show_ddm_table(struct seq_file *seq, void *v) seq_printf(seq, "%-#7x", ddm_table.i2o_vendor_id); seq_printf(seq, "%-#8x", ddm_table.module_id); seq_printf(seq, "%-29s", - chtostr(tmp, ddm_table.module_name_version, 28)); + chtostr(ddm_table.module_name_version, 28)); seq_printf(seq, "%9d ", ddm_table.data_size); seq_printf(seq, "%8d", ddm_table.code_size); @@ -893,7 +893,6 @@ static int i2o_seq_show_drivers_stored(struct seq_file *seq, void *v) i2o_driver_result_table *result; i2o_driver_store_table *dst; - char tmp[28 + 1]; result = kmalloc(sizeof(i2o_driver_result_table), GFP_KERNEL); if (result == NULL) @@ -928,9 +927,8 @@ static int i2o_seq_show_drivers_stored(struct seq_file *seq, void *v) seq_printf(seq, "%-#7x", dst->i2o_vendor_id); seq_printf(seq, "%-#8x", dst->module_id); - seq_printf(seq, "%-29s", - chtostr(tmp, dst->module_name_version, 28)); - seq_printf(seq, "%-9s", chtostr(tmp, dst->date, 8)); + seq_printf(seq, "%-29s", chtostr(dst->module_name_version, 28)); + seq_printf(seq, "%-9s", chtostr(dst->date, 8)); seq_printf(seq, "%8d ", dst->module_size); seq_printf(seq, "%8d ", dst->mpb_size); seq_printf(seq, "0x%04x", dst->module_flags); @@ -1250,7 +1248,6 @@ static int i2o_seq_show_dev_identity(struct seq_file *seq, void *v) // == (allow) 512d bytes (max) static u16 *work16 = (u16 *) work32; int token; - char tmp[16 + 1]; token = i2o_parm_field_get(d, 0xF100, -1, &work32, sizeof(work32)); @@ -1263,13 +1260,13 @@ static int i2o_seq_show_dev_identity(struct seq_file *seq, void *v) seq_printf(seq, "Owner TID : %0#5x\n", work16[2]); seq_printf(seq, "Parent TID : %0#5x\n", work16[3]); seq_printf(seq, "Vendor info : %s\n", - chtostr(tmp, (u8 *) (work32 + 2), 16)); + chtostr((u8 *) (work32 + 2), 16)); seq_printf(seq, "Product info : %s\n", - chtostr(tmp, (u8 *) (work32 + 6), 16)); + chtostr((u8 *) (work32 + 6), 16)); seq_printf(seq, "Description : %s\n", - chtostr(tmp, (u8 *) (work32 + 10), 16)); + chtostr((u8 *) (work32 + 10), 16)); seq_printf(seq, "Product rev. : %s\n", - chtostr(tmp, (u8 *) (work32 + 14), 8)); + chtostr((u8 *) (work32 + 14), 8)); seq_printf(seq, "Serial number : "); print_serial_number(seq, (u8 *) (work32 + 16), @@ -1306,8 +1303,6 @@ static int i2o_seq_show_ddm_identity(struct seq_file *seq, void *v) u8 pad[256]; // allow up to 256 byte (max) serial number } result; - char tmp[24 + 1]; - token = i2o_parm_field_get(d, 0xF101, -1, &result, sizeof(result)); if (token < 0) { @@ -1317,9 +1312,9 @@ static int i2o_seq_show_ddm_identity(struct seq_file *seq, void *v) seq_printf(seq, "Registering DDM TID : 0x%03x\n", result.ddm_tid); seq_printf(seq, "Module name : %s\n", - chtostr(tmp, result.module_name, 24)); + chtostr(result.module_name, 24)); seq_printf(seq, "Module revision : %s\n", - chtostr(tmp, result.module_rev, 8)); + chtostr(result.module_rev, 8)); seq_printf(seq, "Serial number : "); print_serial_number(seq, result.serial_number, sizeof(result) - 36); @@ -1343,8 +1338,6 @@ static int i2o_seq_show_uinfo(struct seq_file *seq, void *v) u8 instance_number[4]; } result; - char tmp[64 + 1]; - token = i2o_parm_field_get(d, 0xF102, -1, &result, sizeof(result)); if (token < 0) { @@ -1353,13 +1346,13 @@ static int i2o_seq_show_uinfo(struct seq_file *seq, void *v) } seq_printf(seq, "Device name : %s\n", - chtostr(tmp, result.device_name, 64)); + chtostr(result.device_name, 64)); seq_printf(seq, "Service name : %s\n", - chtostr(tmp, result.service_name, 64)); + chtostr(result.service_name, 64)); seq_printf(seq, "Physical name : %s\n", - chtostr(tmp, result.physical_location, 64)); + chtostr(result.physical_location, 64)); seq_printf(seq, "Instance number : %s\n", - chtostr(tmp, result.instance_number, 4)); + chtostr(result.instance_number, 4)); return 0; } diff --git a/trunk/drivers/misc/lkdtm.c b/trunk/drivers/misc/lkdtm.c index 08aad69c8da4..28adefe70f96 100644 --- a/trunk/drivers/misc/lkdtm.c +++ b/trunk/drivers/misc/lkdtm.c @@ -477,8 +477,6 @@ static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf, int i, n, out; buf = (char *)__get_free_page(GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; n = snprintf(buf, PAGE_SIZE, "Available crash types:\n"); for (i = 0; i < ARRAY_SIZE(cp_type); i++) diff --git a/trunk/drivers/misc/ti-st/st_core.c b/trunk/drivers/misc/ti-st/st_core.c index acfaeeb9e01a..2b62232c2c6a 100644 --- a/trunk/drivers/misc/ti-st/st_core.c +++ b/trunk/drivers/misc/ti-st/st_core.c @@ -349,11 +349,6 @@ void st_int_recv(void *disc_data, st_gdata->rx_skb = alloc_skb( st_gdata->list[type]->max_frame_size, GFP_ATOMIC); - if (st_gdata->rx_skb == NULL) { - pr_err("out of memory: dropping\n"); - goto done; - } - skb_reserve(st_gdata->rx_skb, st_gdata->list[type]->reserve); /* next 2 required for BT only */ diff --git a/trunk/drivers/net/can/c_can/c_can_platform.c b/trunk/drivers/net/can/c_can/c_can_platform.c index 6ff7ad006c30..f0921d16f0a9 100644 --- a/trunk/drivers/net/can/c_can/c_can_platform.c +++ b/trunk/drivers/net/can/c_can/c_can_platform.c @@ -74,6 +74,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) const struct platform_device_id *id; struct resource *mem; int irq; +#ifdef CONFIG_HAVE_CLK struct clk *clk; /* get the appropriate clk */ @@ -83,6 +84,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) ret = -ENODEV; goto exit; } +#endif /* get the platform data */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -143,8 +145,10 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) dev->irq = irq; priv->base = addr; +#ifdef CONFIG_HAVE_CLK priv->can.clock.freq = clk_get_rate(clk); priv->priv = clk; +#endif platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); @@ -168,8 +172,10 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) exit_release_mem: release_mem_region(mem->start, resource_size(mem)); exit_free_clk: +#ifdef CONFIG_HAVE_CLK clk_put(clk); exit: +#endif dev_err(&pdev->dev, "probe failed\n"); return ret; @@ -190,7 +196,9 @@ static int __devexit c_can_plat_remove(struct platform_device *pdev) mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(mem->start, resource_size(mem)); +#ifdef CONFIG_HAVE_CLK clk_put(priv->priv); +#endif return 0; } diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h index f2d3665430ad..ab4c376cb276 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -82,7 +82,9 @@ struct stmmac_priv { struct stmmac_counters mmc; struct dma_features dma_cap; int hw_cap_support; +#ifdef CONFIG_HAVE_CLK struct clk *stmmac_clk; +#endif int clk_csr; int synopsys_id; struct timer_list eee_ctrl_timer; @@ -111,6 +113,46 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, void stmmac_disable_eee_mode(struct stmmac_priv *priv); bool stmmac_eee_init(struct stmmac_priv *priv); +#ifdef CONFIG_HAVE_CLK +static inline int stmmac_clk_enable(struct stmmac_priv *priv) +{ + if (!IS_ERR(priv->stmmac_clk)) + return clk_prepare_enable(priv->stmmac_clk); + + return 0; +} + +static inline void stmmac_clk_disable(struct stmmac_priv *priv) +{ + if (IS_ERR(priv->stmmac_clk)) + return; + + clk_disable_unprepare(priv->stmmac_clk); +} +static inline int stmmac_clk_get(struct stmmac_priv *priv) +{ + priv->stmmac_clk = clk_get(priv->device, NULL); + + if (IS_ERR(priv->stmmac_clk)) + return PTR_ERR(priv->stmmac_clk); + + return 0; +} +#else +static inline int stmmac_clk_enable(struct stmmac_priv *priv) +{ + return 0; +} +static inline void stmmac_clk_disable(struct stmmac_priv *priv) +{ +} +static inline int stmmac_clk_get(struct stmmac_priv *priv) +{ + return 0; +} +#endif /* CONFIG_HAVE_CLK */ + + #ifdef CONFIG_STMMAC_PLATFORM extern struct platform_driver stmmac_pltfr_driver; static inline int stmmac_register_platform(void) diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index fd8882f9602a..f6b04c1a3672 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -28,7 +28,6 @@ https://bugzilla.stlinux.com/ *******************************************************************************/ -#include #include #include #include @@ -174,8 +173,12 @@ static void stmmac_verify_args(void) static void stmmac_clk_csr_set(struct stmmac_priv *priv) { +#ifdef CONFIG_HAVE_CLK u32 clk_rate; + if (IS_ERR(priv->stmmac_clk)) + return; + clk_rate = clk_get_rate(priv->stmmac_clk); /* Platform provided default clk_csr would be assumed valid @@ -197,6 +200,7 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv) * we can not estimate the proper divider as it is not known * the frequency of clk_csr_i. So we do not change the default * divider. */ +#endif } #if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG) @@ -1066,7 +1070,7 @@ static int stmmac_open(struct net_device *dev) } else priv->tm->enable = 1; #endif - clk_enable(priv->stmmac_clk); + stmmac_clk_enable(priv); stmmac_check_ether_addr(priv); @@ -1188,7 +1192,7 @@ static int stmmac_open(struct net_device *dev) if (priv->phydev) phy_disconnect(priv->phydev); - clk_disable(priv->stmmac_clk); + stmmac_clk_disable(priv); return ret; } @@ -1246,7 +1250,7 @@ static int stmmac_release(struct net_device *dev) #ifdef CONFIG_STMMAC_DEBUG_FS stmmac_exit_fs(); #endif - clk_disable(priv->stmmac_clk); + stmmac_clk_disable(priv); return 0; } @@ -2074,14 +2078,11 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, ret = register_netdev(ndev); if (ret) { pr_err("%s: ERROR %i registering the device\n", __func__, ret); - goto error_netdev_register; + goto error; } - priv->stmmac_clk = clk_get(priv->device, NULL); - if (IS_ERR(priv->stmmac_clk)) { + if (stmmac_clk_get(priv)) pr_warning("%s: warning: cannot get CSR clock\n", __func__); - goto error_clk_get; - } /* If a specific clk_csr value is passed from the platform * this means that the CSR Clock Range selection cannot be @@ -2099,17 +2100,15 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, if (ret < 0) { pr_debug("%s: MDIO bus (id: %d) registration failed", __func__, priv->plat->bus_id); - goto error_mdio_register; + goto error; } return priv; -error_mdio_register: - clk_put(priv->stmmac_clk); -error_clk_get: - unregister_netdev(ndev); -error_netdev_register: +error: netif_napi_del(&priv->napi); + + unregister_netdev(ndev); free_netdev(ndev); return NULL; @@ -2178,7 +2177,7 @@ int stmmac_suspend(struct net_device *ndev) else { stmmac_set_mac(priv->ioaddr, false); /* Disable clock in case of PWM is off */ - clk_disable(priv->stmmac_clk); + stmmac_clk_disable(priv); } spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -2203,7 +2202,7 @@ int stmmac_resume(struct net_device *ndev) priv->hw->mac->pmt(priv->ioaddr, 0); else /* enable the clk prevously disabled */ - clk_enable(priv->stmmac_clk); + stmmac_clk_enable(priv); netif_device_attach(ndev); diff --git a/trunk/drivers/pps/pps.c b/trunk/drivers/pps/pps.c index e771487132f7..98fbe62694d4 100644 --- a/trunk/drivers/pps/pps.c +++ b/trunk/drivers/pps/pps.c @@ -327,10 +327,8 @@ int pps_register_cdev(struct pps_device *pps) } pps->dev = device_create(pps_class, pps->info.dev, devt, pps, "pps%d", pps->id); - if (IS_ERR(pps->dev)) { - err = PTR_ERR(pps->dev); + if (IS_ERR(pps->dev)) goto del_cdev; - } pps->dev->release = pps_device_destruct; diff --git a/trunk/drivers/regulator/s5m8767.c b/trunk/drivers/regulator/s5m8767.c index 5a0d18a7aa2a..abe64a32aedf 100644 --- a/trunk/drivers/regulator/s5m8767.c +++ b/trunk/drivers/regulator/s5m8767.c @@ -572,21 +572,21 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) pdata->buck2_init + buck_voltage_val2.step); - s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS2, buck_init); + sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS2, buck_init); buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, pdata->buck3_init, pdata->buck3_init + buck_voltage_val2.step); - s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS2, buck_init); + sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS2, buck_init); buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, pdata->buck4_init, pdata->buck4_init + buck_voltage_val2.step); - s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS2, buck_init); + sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS2, buck_init); for (i = 0; i < 8; i++) { if (s5m8767->buck2_gpiodvs) { diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index fabc99a75c65..f049c02413ce 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -704,7 +704,6 @@ config RTC_DRV_AB3100 config RTC_DRV_AB8500 tristate "ST-Ericsson AB8500 RTC" depends on AB8500_CORE - select RTC_INTF_DEV_UIE_EMUL help Select this to enable the ST-Ericsson AB8500 power management IC RTC support. This chip contains a battery- and capacitor-backed RTC. diff --git a/trunk/drivers/rtc/rtc-ab8500.c b/trunk/drivers/rtc/rtc-ab8500.c index bf3c2f669c3c..370889d0489b 100644 --- a/trunk/drivers/rtc/rtc-ab8500.c +++ b/trunk/drivers/rtc/rtc-ab8500.c @@ -89,17 +89,22 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) if (retval < 0) return retval; - /* Wait for some cycles after enabling the rtc read in ab8500 */ - while (time_before(jiffies, timeout)) { - retval = abx500_get_register_interruptible(dev, - AB8500_RTC, AB8500_RTC_READ_REQ_REG, &value); - if (retval < 0) - return retval; - - if (!(value & RTC_READ_REQUEST)) - break; - - usleep_range(1000, 5000); + /* Early AB8500 chips will not clear the rtc read request bit */ + if (abx500_get_chip_id(dev) == 0) { + usleep_range(1000, 1000); + } else { + /* Wait for some cycles after enabling the rtc read in ab8500 */ + while (time_before(jiffies, timeout)) { + retval = abx500_get_register_interruptible(dev, + AB8500_RTC, AB8500_RTC_READ_REQ_REG, &value); + if (retval < 0) + return retval; + + if (!(value & RTC_READ_REQUEST)) + break; + + usleep_range(1000, 5000); + } } /* Read the Watchtime registers */ @@ -220,8 +225,7 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { int retval, i; unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; - unsigned long mins, secs = 0, cursec = 0; - struct rtc_time curtm; + unsigned long mins, secs = 0; if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) { dev_dbg(dev, "year should be equal to or greater than %d\n", @@ -232,18 +236,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) /* Get the number of seconds since 1970 */ rtc_tm_to_time(&alarm->time, &secs); - /* - * Check whether alarm is set less than 1min. - * Since our RTC doesn't support alarm resolution less than 1min, - * return -EINVAL, so UIE EMUL can take it up, incase of UIE_ON - */ - ab8500_rtc_read_time(dev, &curtm); /* Read current time */ - rtc_tm_to_time(&curtm, &cursec); - if ((secs - cursec) < 59) { - dev_dbg(dev, "Alarm less than 1 minute not supported\r\n"); - return -EINVAL; - } - /* * Convert it to the number of seconds since 01-01-2000 00:00:00, since * we only have a small counter in the RTC. diff --git a/trunk/drivers/rtc/rtc-coh901331.c b/trunk/drivers/rtc/rtc-coh901331.c index 76b2156d3c62..a5b8a0c4ea84 100644 --- a/trunk/drivers/rtc/rtc-coh901331.c +++ b/trunk/drivers/rtc/rtc-coh901331.c @@ -155,10 +155,13 @@ static int __exit coh901331_remove(struct platform_device *pdev) struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); if (rtap) { + free_irq(rtap->irq, rtap); rtc_device_unregister(rtap->rtc); - clk_unprepare(rtap->clk); clk_put(rtap->clk); + iounmap(rtap->virtbase); + release_mem_region(rtap->phybase, rtap->physize); platform_set_drvdata(pdev, NULL); + kfree(rtap); } return 0; @@ -171,43 +174,49 @@ static int __init coh901331_probe(struct platform_device *pdev) struct coh901331_port *rtap; struct resource *res; - rtap = devm_kzalloc(&pdev->dev, - sizeof(struct coh901331_port), GFP_KERNEL); + rtap = kzalloc(sizeof(struct coh901331_port), GFP_KERNEL); if (!rtap) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENOENT; - + if (!res) { + ret = -ENOENT; + goto out_no_resource; + } rtap->phybase = res->start; rtap->physize = resource_size(res); - if (devm_request_mem_region(&pdev->dev, rtap->phybase, rtap->physize, - "rtc-coh901331") == NULL) - return -EBUSY; + if (request_mem_region(rtap->phybase, rtap->physize, + "rtc-coh901331") == NULL) { + ret = -EBUSY; + goto out_no_memregion; + } - rtap->virtbase = devm_ioremap(&pdev->dev, rtap->phybase, rtap->physize); - if (!rtap->virtbase) - return -ENOMEM; + rtap->virtbase = ioremap(rtap->phybase, rtap->physize); + if (!rtap->virtbase) { + ret = -ENOMEM; + goto out_no_remap; + } rtap->irq = platform_get_irq(pdev, 0); - if (devm_request_irq(&pdev->dev, rtap->irq, coh901331_interrupt, 0, - "RTC COH 901 331 Alarm", rtap)) - return -EIO; + if (request_irq(rtap->irq, coh901331_interrupt, 0, + "RTC COH 901 331 Alarm", rtap)) { + ret = -EIO; + goto out_no_irq; + } rtap->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(rtap->clk)) { ret = PTR_ERR(rtap->clk); dev_err(&pdev->dev, "could not get clock\n"); - return ret; + goto out_no_clk; } /* We enable/disable the clock only to assure it works */ - ret = clk_prepare_enable(rtap->clk); + ret = clk_enable(rtap->clk); if (ret) { dev_err(&pdev->dev, "could not enable clock\n"); - goto out_no_clk_prepenable; + goto out_no_clk_enable; } clk_disable(rtap->clk); @@ -223,9 +232,18 @@ static int __init coh901331_probe(struct platform_device *pdev) out_no_rtc: platform_set_drvdata(pdev, NULL); - clk_unprepare(rtap->clk); - out_no_clk_prepenable: + out_no_clk_enable: clk_put(rtap->clk); + out_no_clk: + free_irq(rtap->irq, rtap); + out_no_irq: + iounmap(rtap->virtbase); + out_no_remap: + platform_set_drvdata(pdev, NULL); + out_no_memregion: + release_mem_region(rtap->phybase, SZ_4K); + out_no_resource: + kfree(rtap); return ret; } @@ -247,7 +265,6 @@ static int coh901331_suspend(struct platform_device *pdev, pm_message_t state) writel(0, rtap->virtbase + COH901331_IRQ_MASK); clk_disable(rtap->clk); } - clk_unprepare(rtap->clk); return 0; } @@ -255,7 +272,6 @@ static int coh901331_resume(struct platform_device *pdev) { struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); - clk_prepare(rtap->clk); if (device_may_wakeup(&pdev->dev)) { disable_irq_wake(rtap->irq); } else { @@ -277,7 +293,6 @@ static void coh901331_shutdown(struct platform_device *pdev) clk_enable(rtap->clk); writel(0, rtap->virtbase + COH901331_IRQ_MASK); clk_disable(rtap->clk); - clk_unprepare(rtap->clk); } static struct platform_driver coh901331_driver = { diff --git a/trunk/drivers/rtc/rtc-da9052.c b/trunk/drivers/rtc/rtc-da9052.c index 78070255bd3f..da6ab5291a41 100644 --- a/trunk/drivers/rtc/rtc-da9052.c +++ b/trunk/drivers/rtc/rtc-da9052.c @@ -245,7 +245,7 @@ static int __devinit da9052_rtc_probe(struct platform_device *pdev) "ALM", rtc); if (ret != 0) { rtc_err(rtc->da9052, "irq registration failed: %d\n", ret); - return ret; + goto err_mem; } rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, @@ -259,6 +259,8 @@ static int __devinit da9052_rtc_probe(struct platform_device *pdev) err_free_irq: free_irq(rtc->irq, rtc); +err_mem: + devm_kfree(&pdev->dev, rtc); return ret; } @@ -269,6 +271,7 @@ static int __devexit da9052_rtc_remove(struct platform_device *pdev) rtc_device_unregister(rtc->rtc); free_irq(rtc->irq, rtc); platform_set_drvdata(pdev, NULL); + devm_kfree(&pdev->dev, rtc); return 0; } diff --git a/trunk/drivers/rtc/rtc-mc13xxx.c b/trunk/drivers/rtc/rtc-mc13xxx.c index 2643d8874925..546f6850bffb 100644 --- a/trunk/drivers/rtc/rtc-mc13xxx.c +++ b/trunk/drivers/rtc/rtc-mc13xxx.c @@ -404,12 +404,9 @@ static const struct platform_device_id mc13xxx_rtc_idtable[] = { .name = "mc13783-rtc", }, { .name = "mc13892-rtc", - }, { - .name = "mc34708-rtc", }, - { /* sentinel */ } + { } }; -MODULE_DEVICE_TABLE(platform, mc13xxx_rtc_idtable); static struct platform_driver mc13xxx_rtc_driver = { .id_table = mc13xxx_rtc_idtable, @@ -435,3 +432,4 @@ module_exit(mc13xxx_rtc_exit); MODULE_AUTHOR("Sascha Hauer "); MODULE_DESCRIPTION("RTC driver for Freescale MC13XXX PMIC"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/trunk/drivers/rtc/rtc-pcf8563.c b/trunk/drivers/rtc/rtc-pcf8563.c index c2fe426a6ef2..97a3284bb7c6 100644 --- a/trunk/drivers/rtc/rtc-pcf8563.c +++ b/trunk/drivers/rtc/rtc-pcf8563.c @@ -19,7 +19,6 @@ #include #include #include -#include #define DRV_VERSION "0.4.3" @@ -286,19 +285,9 @@ static const struct i2c_device_id pcf8563_id[] = { }; MODULE_DEVICE_TABLE(i2c, pcf8563_id); -#ifdef CONFIG_OF -static const struct of_device_id pcf8563_of_match[] __devinitconst = { - { .compatible = "nxp,pcf8563" }, - {} -}; -MODULE_DEVICE_TABLE(of, pcf8563_of_match); -#endif - static struct i2c_driver pcf8563_driver = { .driver = { .name = "rtc-pcf8563", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(pcf8563_of_match), }, .probe = pcf8563_probe, .remove = pcf8563_remove, diff --git a/trunk/drivers/rtc/rtc-pl031.c b/trunk/drivers/rtc/rtc-pl031.c index 08378e3cc21c..cc0533994f6e 100644 --- a/trunk/drivers/rtc/rtc-pl031.c +++ b/trunk/drivers/rtc/rtc-pl031.c @@ -68,26 +68,11 @@ #define RTC_TIMER_FREQ 32768 -/** - * struct pl031_vendor_data - per-vendor variations - * @ops: the vendor-specific operations used on this silicon version - * @clockwatch: if this is an ST Microelectronics silicon version with a - * clockwatch function - * @st_weekday: if this is an ST Microelectronics silicon version that need - * the weekday fix - * @irqflags: special IRQ flags per variant - */ -struct pl031_vendor_data { - struct rtc_class_ops ops; - bool clockwatch; - bool st_weekday; - unsigned long irqflags; -}; - struct pl031_local { - struct pl031_vendor_data *vendor; struct rtc_device *rtc; void __iomem *base; + u8 hw_designer; + u8 hw_revision:4; }; static int pl031_alarm_irq_enable(struct device *dev, @@ -318,8 +303,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) { int ret; struct pl031_local *ldata; - struct pl031_vendor_data *vendor = id->data; - struct rtc_class_ops *ops = &vendor->ops; + struct rtc_class_ops *ops = id->data; unsigned long time; ret = amba_request_regions(adev, NULL); @@ -331,7 +315,6 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) ret = -ENOMEM; goto out; } - ldata->vendor = vendor; ldata->base = ioremap(adev->res.start, resource_size(&adev->res)); @@ -342,11 +325,14 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) amba_set_drvdata(adev, ldata); - dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev)); - dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev)); + ldata->hw_designer = amba_manf(adev); + ldata->hw_revision = amba_rev(adev); + + dev_dbg(&adev->dev, "designer ID = 0x%02x\n", ldata->hw_designer); + dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision); /* Enable the clockwatch on ST Variants */ - if (vendor->clockwatch) + if (ldata->hw_designer == AMBA_VENDOR_ST) writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, ldata->base + RTC_CR); @@ -354,7 +340,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) * On ST PL031 variants, the RTC reset value does not provide correct * weekday for 2000-01-01. Correct the erroneous sunday to saturday. */ - if (vendor->st_weekday) { + if (ldata->hw_designer == AMBA_VENDOR_ST) { if (readl(ldata->base + RTC_YDR) == 0x2000) { time = readl(ldata->base + RTC_DR); if ((time & @@ -375,7 +361,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) } if (request_irq(adev->irq[0], pl031_interrupt, - vendor->irqflags, "rtc-pl031", ldata)) { + 0, "rtc-pl031", ldata)) { ret = -EIO; goto out_no_irq; } @@ -397,65 +383,48 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) } /* Operations for the original ARM version */ -static struct pl031_vendor_data arm_pl031 = { - .ops = { - .read_time = pl031_read_time, - .set_time = pl031_set_time, - .read_alarm = pl031_read_alarm, - .set_alarm = pl031_set_alarm, - .alarm_irq_enable = pl031_alarm_irq_enable, - }, - .irqflags = IRQF_NO_SUSPEND, +static struct rtc_class_ops arm_pl031_ops = { + .read_time = pl031_read_time, + .set_time = pl031_set_time, + .read_alarm = pl031_read_alarm, + .set_alarm = pl031_set_alarm, + .alarm_irq_enable = pl031_alarm_irq_enable, }; /* The First ST derivative */ -static struct pl031_vendor_data stv1_pl031 = { - .ops = { - .read_time = pl031_read_time, - .set_time = pl031_set_time, - .read_alarm = pl031_read_alarm, - .set_alarm = pl031_set_alarm, - .alarm_irq_enable = pl031_alarm_irq_enable, - }, - .clockwatch = true, - .st_weekday = true, - .irqflags = IRQF_NO_SUSPEND, +static struct rtc_class_ops stv1_pl031_ops = { + .read_time = pl031_read_time, + .set_time = pl031_set_time, + .read_alarm = pl031_read_alarm, + .set_alarm = pl031_set_alarm, + .alarm_irq_enable = pl031_alarm_irq_enable, }; /* And the second ST derivative */ -static struct pl031_vendor_data stv2_pl031 = { - .ops = { - .read_time = pl031_stv2_read_time, - .set_time = pl031_stv2_set_time, - .read_alarm = pl031_stv2_read_alarm, - .set_alarm = pl031_stv2_set_alarm, - .alarm_irq_enable = pl031_alarm_irq_enable, - }, - .clockwatch = true, - .st_weekday = true, - /* - * This variant shares the IRQ with another block and must not - * suspend that IRQ line. - */ - .irqflags = IRQF_SHARED | IRQF_NO_SUSPEND, +static struct rtc_class_ops stv2_pl031_ops = { + .read_time = pl031_stv2_read_time, + .set_time = pl031_stv2_set_time, + .read_alarm = pl031_stv2_read_alarm, + .set_alarm = pl031_stv2_set_alarm, + .alarm_irq_enable = pl031_alarm_irq_enable, }; static struct amba_id pl031_ids[] = { { .id = 0x00041031, .mask = 0x000fffff, - .data = &arm_pl031, + .data = &arm_pl031_ops, }, /* ST Micro variants */ { .id = 0x00180031, .mask = 0x00ffffff, - .data = &stv1_pl031, + .data = &stv1_pl031_ops, }, { .id = 0x00280031, .mask = 0x00ffffff, - .data = &stv2_pl031, + .data = &stv2_pl031_ops, }, {0, 0}, }; diff --git a/trunk/drivers/rtc/rtc-r9701.c b/trunk/drivers/rtc/rtc-r9701.c index 2c183ebff715..33b6ba0afa0d 100644 --- a/trunk/drivers/rtc/rtc-r9701.c +++ b/trunk/drivers/rtc/rtc-r9701.c @@ -138,7 +138,8 @@ static int __devinit r9701_probe(struct spi_device *spi) * contain invalid values. If so, try to write a default date: * 2000/1/1 00:00:00 */ - if (r9701_get_datetime(&spi->dev, &dt)) { + r9701_get_datetime(&spi->dev, &dt); + if (rtc_valid_tm(&dt)) { dev_info(&spi->dev, "trying to repair invalid date/time\n"); dt.tm_sec = 0; dt.tm_min = 0; @@ -147,8 +148,7 @@ static int __devinit r9701_probe(struct spi_device *spi) dt.tm_mon = 0; dt.tm_year = 100; - if (r9701_set_datetime(&spi->dev, &dt) || - r9701_get_datetime(&spi->dev, &dt)) { + if (r9701_set_datetime(&spi->dev, &dt)) { dev_err(&spi->dev, "cannot repair RTC register\n"); return -ENODEV; } diff --git a/trunk/drivers/rtc/rtc-s3c.c b/trunk/drivers/rtc/rtc-s3c.c index bfbd92c8d1c9..7e6af0b22f17 100644 --- a/trunk/drivers/rtc/rtc-s3c.c +++ b/trunk/drivers/rtc/rtc-s3c.c @@ -26,10 +26,10 @@ #include #include #include -#include -#include #include +#include +#include #include #include diff --git a/trunk/drivers/staging/media/lirc/lirc_sir.c b/trunk/drivers/staging/media/lirc/lirc_sir.c index 4afc3b419738..945d9623550b 100644 --- a/trunk/drivers/staging/media/lirc/lirc_sir.c +++ b/trunk/drivers/staging/media/lirc/lirc_sir.c @@ -52,7 +52,6 @@ #include #include #include -#include #ifdef LIRC_ON_SA1100 #include #ifdef CONFIG_SA1100_COLLIE @@ -488,11 +487,9 @@ static struct lirc_driver driver = { .owner = THIS_MODULE, }; -static struct platform_device *lirc_sir_dev; static int init_chrdev(void) { - driver.dev = &lirc_sir_dev->dev; driver.minor = lirc_register_driver(&driver); if (driver.minor < 0) { printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n"); @@ -1218,71 +1215,20 @@ static int init_lirc_sir(void) return 0; } -static int __devinit lirc_sir_probe(struct platform_device *dev) -{ - return 0; -} - -static int __devexit lirc_sir_remove(struct platform_device *dev) -{ - return 0; -} - -static struct platform_driver lirc_sir_driver = { - .probe = lirc_sir_probe, - .remove = __devexit_p(lirc_sir_remove), - .driver = { - .name = "lirc_sir", - .owner = THIS_MODULE, - }, -}; static int __init lirc_sir_init(void) { int retval; - retval = platform_driver_register(&lirc_sir_driver); - if (retval) { - printk(KERN_ERR LIRC_DRIVER_NAME ": Platform driver register " - "failed!\n"); - return -ENODEV; - } - - lirc_sir_dev = platform_device_alloc("lirc_dev", 0); - if (!lirc_sir_dev) { - printk(KERN_ERR LIRC_DRIVER_NAME ": Platform device alloc " - "failed!\n"); - retval = -ENOMEM; - goto pdev_alloc_fail; - } - - retval = platform_device_add(lirc_sir_dev); - if (retval) { - printk(KERN_ERR LIRC_DRIVER_NAME ": Platform device add " - "failed!\n"); - retval = -ENODEV; - goto pdev_add_fail; - } - retval = init_chrdev(); if (retval < 0) - goto fail; - + return retval; retval = init_lirc_sir(); if (retval) { drop_chrdev(); - goto fail; + return retval; } - return 0; - -fail: - platform_device_del(lirc_sir_dev); -pdev_add_fail: - platform_device_put(lirc_sir_dev); -pdev_alloc_fail: - platform_driver_unregister(&lirc_sir_driver); - return retval; } static void __exit lirc_sir_exit(void) @@ -1290,8 +1236,6 @@ static void __exit lirc_sir_exit(void) drop_hardware(); drop_chrdev(); drop_port(); - platform_device_unregister(lirc_sir_dev); - platform_driver_unregister(&lirc_sir_driver); printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); } diff --git a/trunk/drivers/staging/media/solo6x10/TODO b/trunk/drivers/staging/media/solo6x10/TODO index 539f739fe9e6..7e6c4fa130df 100644 --- a/trunk/drivers/staging/media/solo6x10/TODO +++ b/trunk/drivers/staging/media/solo6x10/TODO @@ -20,5 +20,5 @@ TODO (general): - implement loopback of external sound jack with incoming audio? - implement pause/resume -Plase send patches to Mauro Carvalho Chehab and Cc Ben Collins +Plase send patches to Greg Kroah-Hartman and Cc Ben Collins diff --git a/trunk/drivers/staging/media/solo6x10/i2c.c b/trunk/drivers/staging/media/solo6x10/i2c.c index 398070a3d293..ef95a500b4da 100644 --- a/trunk/drivers/staging/media/solo6x10/i2c.c +++ b/trunk/drivers/staging/media/solo6x10/i2c.c @@ -175,7 +175,7 @@ int solo_i2c_isr(struct solo_dev *solo_dev) solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_IIC); - if (status & (SOLO_IIC_STATE_TRNS | SOLO_IIC_STATE_SIG_ERR) || + if (status & (SOLO_IIC_STATE_TRNS & SOLO_IIC_STATE_SIG_ERR) || solo_dev->i2c_id < 0) { solo_i2c_stop(solo_dev); return -ENXIO; diff --git a/trunk/drivers/usb/gadget/m66592-udc.c b/trunk/drivers/usb/gadget/m66592-udc.c index cf6bd626f3fe..8981fbb5748c 100644 --- a/trunk/drivers/usb/gadget/m66592-udc.c +++ b/trunk/drivers/usb/gadget/m66592-udc.c @@ -1583,10 +1583,12 @@ static int __exit m66592_remove(struct platform_device *pdev) iounmap(m66592->reg); free_irq(platform_get_irq(pdev, 0), m66592); m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); +#ifdef CONFIG_HAVE_CLK if (m66592->pdata->on_chip) { clk_disable(m66592->clk); clk_put(m66592->clk); } +#endif kfree(m66592); return 0; } @@ -1600,7 +1602,9 @@ static int __init m66592_probe(struct platform_device *pdev) struct resource *res, *ires; void __iomem *reg = NULL; struct m66592 *m66592 = NULL; +#ifdef CONFIG_HAVE_CLK char clk_name[8]; +#endif int ret = 0; int i; @@ -1667,6 +1671,7 @@ static int __init m66592_probe(struct platform_device *pdev) goto clean_up; } +#ifdef CONFIG_HAVE_CLK if (m66592->pdata->on_chip) { snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id); m66592->clk = clk_get(&pdev->dev, clk_name); @@ -1678,7 +1683,7 @@ static int __init m66592_probe(struct platform_device *pdev) } clk_enable(m66592->clk); } - +#endif INIT_LIST_HEAD(&m66592->gadget.ep_list); m66592->gadget.ep0 = &m66592->ep[0].ep; INIT_LIST_HEAD(&m66592->gadget.ep0->ep_list); @@ -1726,11 +1731,13 @@ static int __init m66592_probe(struct platform_device *pdev) m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); clean_up3: +#ifdef CONFIG_HAVE_CLK if (m66592->pdata->on_chip) { clk_disable(m66592->clk); clk_put(m66592->clk); } clean_up2: +#endif free_irq(ires->start, m66592); clean_up: if (m66592) { diff --git a/trunk/drivers/usb/gadget/m66592-udc.h b/trunk/drivers/usb/gadget/m66592-udc.h index 16c7e14678b8..88c85b4116a2 100644 --- a/trunk/drivers/usb/gadget/m66592-udc.h +++ b/trunk/drivers/usb/gadget/m66592-udc.h @@ -13,7 +13,10 @@ #ifndef __M66592_UDC_H__ #define __M66592_UDC_H__ +#ifdef CONFIG_HAVE_CLK #include +#endif + #include #define M66592_SYSCFG 0x00 @@ -465,7 +468,9 @@ struct m66592_ep { struct m66592 { spinlock_t lock; void __iomem *reg; +#ifdef CONFIG_HAVE_CLK struct clk *clk; +#endif struct m66592_platdata *pdata; unsigned long irq_trigger; diff --git a/trunk/drivers/usb/gadget/r8a66597-udc.c b/trunk/drivers/usb/gadget/r8a66597-udc.c index 5a80751accb7..f3ac2a20c27c 100644 --- a/trunk/drivers/usb/gadget/r8a66597-udc.c +++ b/trunk/drivers/usb/gadget/r8a66597-udc.c @@ -1831,12 +1831,12 @@ static int __exit r8a66597_remove(struct platform_device *pdev) iounmap(r8a66597->sudmac_reg); free_irq(platform_get_irq(pdev, 0), r8a66597); r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); - +#ifdef CONFIG_HAVE_CLK if (r8a66597->pdata->on_chip) { clk_disable(r8a66597->clk); clk_put(r8a66597->clk); } - +#endif device_unregister(&r8a66597->gadget.dev); kfree(r8a66597); return 0; @@ -1868,7 +1868,9 @@ static int __init r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597, static int __init r8a66597_probe(struct platform_device *pdev) { +#ifdef CONFIG_HAVE_CLK char clk_name[8]; +#endif struct resource *res, *ires; int irq; void __iomem *reg = NULL; @@ -1932,6 +1934,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) r8a66597->timer.data = (unsigned long)r8a66597; r8a66597->reg = reg; +#ifdef CONFIG_HAVE_CLK if (r8a66597->pdata->on_chip) { snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id); r8a66597->clk = clk_get(&pdev->dev, clk_name); @@ -1943,7 +1946,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) } clk_enable(r8a66597->clk); } - +#endif if (r8a66597->pdata->sudmac) { ret = r8a66597_sudmac_ioremap(r8a66597, pdev); if (ret < 0) @@ -2003,11 +2006,13 @@ static int __init r8a66597_probe(struct platform_device *pdev) clean_up3: free_irq(irq, r8a66597); clean_up2: +#ifdef CONFIG_HAVE_CLK if (r8a66597->pdata->on_chip) { clk_disable(r8a66597->clk); clk_put(r8a66597->clk); } clean_up_dev: +#endif device_unregister(&r8a66597->gadget.dev); clean_up: if (r8a66597) { diff --git a/trunk/drivers/usb/gadget/r8a66597-udc.h b/trunk/drivers/usb/gadget/r8a66597-udc.h index 45c4b2df1785..99908c76ccd1 100644 --- a/trunk/drivers/usb/gadget/r8a66597-udc.h +++ b/trunk/drivers/usb/gadget/r8a66597-udc.h @@ -13,7 +13,10 @@ #ifndef __R8A66597_H__ #define __R8A66597_H__ +#ifdef CONFIG_HAVE_CLK #include +#endif + #include #define R8A66597_MAX_SAMPLING 10 @@ -89,7 +92,9 @@ struct r8a66597 { void __iomem *reg; void __iomem *sudmac_reg; +#ifdef CONFIG_HAVE_CLK struct clk *clk; +#endif struct r8a66597_platdata *pdata; struct usb_gadget gadget; diff --git a/trunk/drivers/usb/host/r8a66597-hcd.c b/trunk/drivers/usb/host/r8a66597-hcd.c index 4c634eb56358..c868be65e763 100644 --- a/trunk/drivers/usb/host/r8a66597-hcd.c +++ b/trunk/drivers/usb/host/r8a66597-hcd.c @@ -95,7 +95,9 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) int i = 0; if (r8a66597->pdata->on_chip) { +#ifdef CONFIG_HAVE_CLK clk_enable(r8a66597->clk); +#endif do { r8a66597_write(r8a66597, SCKE, SYSCFG0); tmp = r8a66597_read(r8a66597, SYSCFG0); @@ -139,7 +141,9 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597) udelay(1); if (r8a66597->pdata->on_chip) { +#ifdef CONFIG_HAVE_CLK clk_disable(r8a66597->clk); +#endif } else { r8a66597_bclr(r8a66597, PLLC, SYSCFG0); r8a66597_bclr(r8a66597, XCKE, SYSCFG0); @@ -2402,15 +2406,19 @@ static int __devexit r8a66597_remove(struct platform_device *pdev) del_timer_sync(&r8a66597->rh_timer); usb_remove_hcd(hcd); iounmap(r8a66597->reg); +#ifdef CONFIG_HAVE_CLK if (r8a66597->pdata->on_chip) clk_put(r8a66597->clk); +#endif usb_put_hcd(hcd); return 0; } static int __devinit r8a66597_probe(struct platform_device *pdev) { +#ifdef CONFIG_HAVE_CLK char clk_name[8]; +#endif struct resource *res = NULL, *ires; int irq = -1; void __iomem *reg = NULL; @@ -2474,6 +2482,7 @@ static int __devinit r8a66597_probe(struct platform_device *pdev) r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW; if (r8a66597->pdata->on_chip) { +#ifdef CONFIG_HAVE_CLK snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id); r8a66597->clk = clk_get(&pdev->dev, clk_name); if (IS_ERR(r8a66597->clk)) { @@ -2482,6 +2491,7 @@ static int __devinit r8a66597_probe(struct platform_device *pdev) ret = PTR_ERR(r8a66597->clk); goto clean_up2; } +#endif r8a66597->max_root_hub = 1; } else r8a66597->max_root_hub = 2; @@ -2521,9 +2531,11 @@ static int __devinit r8a66597_probe(struct platform_device *pdev) return 0; clean_up3: +#ifdef CONFIG_HAVE_CLK if (r8a66597->pdata->on_chip) clk_put(r8a66597->clk); clean_up2: +#endif usb_put_hcd(hcd); clean_up: diff --git a/trunk/drivers/usb/host/r8a66597.h b/trunk/drivers/usb/host/r8a66597.h index 672cea307abb..f28782d20eef 100644 --- a/trunk/drivers/usb/host/r8a66597.h +++ b/trunk/drivers/usb/host/r8a66597.h @@ -26,7 +26,10 @@ #ifndef __R8A66597_H__ #define __R8A66597_H__ +#ifdef CONFIG_HAVE_CLK #include +#endif + #include #define R8A66597_MAX_NUM_PIPE 10 @@ -110,7 +113,9 @@ struct r8a66597_root_hub { struct r8a66597 { spinlock_t lock; void __iomem *reg; +#ifdef CONFIG_HAVE_CLK struct clk *clk; +#endif struct r8a66597_platdata *pdata; struct r8a66597_device device0; struct r8a66597_root_hub root_hub[R8A66597_MAX_ROOT_HUB]; diff --git a/trunk/drivers/usb/musb/musb_core.h b/trunk/drivers/usb/musb/musb_core.h index 586105b55a7c..dbcdeea30f09 100644 --- a/trunk/drivers/usb/musb/musb_core.h +++ b/trunk/drivers/usb/musb/musb_core.h @@ -81,6 +81,14 @@ struct musb_ep; #define is_peripheral_active(m) (!(m)->is_host) #define is_host_active(m) ((m)->is_host) +#ifndef CONFIG_HAVE_CLK +/* Dummy stub for clk framework */ +#define clk_get(dev, id) NULL +#define clk_put(clock) do {} while (0) +#define clk_enable(clock) do {} while (0) +#define clk_disable(clock) do {} while (0) +#endif + #ifdef CONFIG_PROC_FS #include #define MUSB_CONFIG_PROC_FS diff --git a/trunk/drivers/video/backlight/atmel-pwm-bl.c b/trunk/drivers/video/backlight/atmel-pwm-bl.c index df1cbb7ef6ca..0443a4f71858 100644 --- a/trunk/drivers/video/backlight/atmel-pwm-bl.c +++ b/trunk/drivers/video/backlight/atmel-pwm-bl.c @@ -127,8 +127,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) struct atmel_pwm_bl *pwmbl; int retval; - pwmbl = devm_kzalloc(&pdev->dev, sizeof(struct atmel_pwm_bl), - GFP_KERNEL); + pwmbl = kzalloc(sizeof(struct atmel_pwm_bl), GFP_KERNEL); if (!pwmbl) return -ENOMEM; @@ -155,8 +154,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) goto err_free_mem; if (pwmbl->gpio_on != -1) { - retval = devm_gpio_request(&pdev->dev, pwmbl->gpio_on, - "gpio_atmel_pwm_bl"); + retval = gpio_request(pwmbl->gpio_on, "gpio_atmel_pwm_bl"); if (retval) { pwmbl->gpio_on = -1; goto err_free_pwm; @@ -166,7 +164,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) retval = gpio_direction_output(pwmbl->gpio_on, 0 ^ pdata->on_active_low); if (retval) - goto err_free_pwm; + goto err_free_gpio; } memset(&props, 0, sizeof(struct backlight_properties)); @@ -176,7 +174,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) &atmel_pwm_bl_ops, &props); if (IS_ERR(bldev)) { retval = PTR_ERR(bldev); - goto err_free_pwm; + goto err_free_gpio; } pwmbl->bldev = bldev; @@ -198,9 +196,13 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) err_free_bl_dev: platform_set_drvdata(pdev, NULL); backlight_device_unregister(bldev); +err_free_gpio: + if (pwmbl->gpio_on != -1) + gpio_free(pwmbl->gpio_on); err_free_pwm: pwm_channel_free(&pwmbl->pwmc); err_free_mem: + kfree(pwmbl); return retval; } @@ -208,12 +210,15 @@ static int __exit atmel_pwm_bl_remove(struct platform_device *pdev) { struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev); - if (pwmbl->gpio_on != -1) + if (pwmbl->gpio_on != -1) { gpio_set_value(pwmbl->gpio_on, 0); + gpio_free(pwmbl->gpio_on); + } pwm_channel_disable(&pwmbl->pwmc); pwm_channel_free(&pwmbl->pwmc); backlight_device_unregister(pwmbl->bldev); platform_set_drvdata(pdev, NULL); + kfree(pwmbl); return 0; } diff --git a/trunk/drivers/video/backlight/corgi_lcd.c b/trunk/drivers/video/backlight/corgi_lcd.c index c781768ba892..23d732677ba1 100644 --- a/trunk/drivers/video/backlight/corgi_lcd.c +++ b/trunk/drivers/video/backlight/corgi_lcd.c @@ -492,8 +492,7 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd, lcd->gpio_backlight_cont = -1; if (gpio_is_valid(pdata->gpio_backlight_on)) { - err = devm_gpio_request(&spi->dev, pdata->gpio_backlight_on, - "BL_ON"); + err = gpio_request(pdata->gpio_backlight_on, "BL_ON"); if (err) { dev_err(&spi->dev, "failed to request GPIO%d for " "backlight_on\n", pdata->gpio_backlight_on); @@ -505,12 +504,11 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd, } if (gpio_is_valid(pdata->gpio_backlight_cont)) { - err = devm_gpio_request(&spi->dev, pdata->gpio_backlight_cont, - "BL_CONT"); + err = gpio_request(pdata->gpio_backlight_cont, "BL_CONT"); if (err) { dev_err(&spi->dev, "failed to request GPIO%d for " "backlight_cont\n", pdata->gpio_backlight_cont); - return err; + goto err_free_backlight_on; } lcd->gpio_backlight_cont = pdata->gpio_backlight_cont; @@ -527,6 +525,11 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd, } } return 0; + +err_free_backlight_on: + if (gpio_is_valid(lcd->gpio_backlight_on)) + gpio_free(lcd->gpio_backlight_on); + return err; } static int __devinit corgi_lcd_probe(struct spi_device *spi) @@ -599,6 +602,12 @@ static int __devexit corgi_lcd_remove(struct spi_device *spi) backlight_update_status(lcd->bl_dev); backlight_device_unregister(lcd->bl_dev); + if (gpio_is_valid(lcd->gpio_backlight_on)) + gpio_free(lcd->gpio_backlight_on); + + if (gpio_is_valid(lcd->gpio_backlight_cont)) + gpio_free(lcd->gpio_backlight_cont); + corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); lcd_device_unregister(lcd->lcd_dev); diff --git a/trunk/drivers/video/backlight/l4f00242t03.c b/trunk/drivers/video/backlight/l4f00242t03.c index 2d90c0648aa0..40f606a86093 100644 --- a/trunk/drivers/video/backlight/l4f00242t03.c +++ b/trunk/drivers/video/backlight/l4f00242t03.c @@ -175,27 +175,28 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) priv->spi = spi; - ret = devm_gpio_request_one(&spi->dev, pdata->reset_gpio, - GPIOF_OUT_INIT_HIGH, "lcd l4f00242t03 reset"); + ret = gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, + "lcd l4f00242t03 reset"); if (ret) { dev_err(&spi->dev, "Unable to get the lcd l4f00242t03 reset gpio.\n"); return ret; } - ret = devm_gpio_request_one(&spi->dev, pdata->data_enable_gpio, - GPIOF_OUT_INIT_LOW, "lcd l4f00242t03 data enable"); + ret = gpio_request_one(pdata->data_enable_gpio, GPIOF_OUT_INIT_LOW, + "lcd l4f00242t03 data enable"); if (ret) { dev_err(&spi->dev, "Unable to get the lcd l4f00242t03 data en gpio.\n"); - return ret; + goto err; } priv->io_reg = regulator_get(&spi->dev, "vdd"); if (IS_ERR(priv->io_reg)) { + ret = PTR_ERR(priv->io_reg); dev_err(&spi->dev, "%s: Unable to get the IO regulator\n", __func__); - return PTR_ERR(priv->io_reg); + goto err2; } priv->core_reg = regulator_get(&spi->dev, "vcore"); @@ -203,14 +204,14 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) ret = PTR_ERR(priv->core_reg); dev_err(&spi->dev, "%s: Unable to get the core regulator\n", __func__); - goto err1; + goto err3; } priv->ld = lcd_device_register("l4f00242t03", &spi->dev, priv, &l4f_ops); if (IS_ERR(priv->ld)) { ret = PTR_ERR(priv->ld); - goto err2; + goto err4; } /* Init the LCD */ @@ -222,10 +223,14 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) return 0; -err2: +err4: regulator_put(priv->core_reg); -err1: +err3: regulator_put(priv->io_reg); +err2: + gpio_free(pdata->data_enable_gpio); +err: + gpio_free(pdata->reset_gpio); return ret; } @@ -233,12 +238,16 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) static int __devexit l4f00242t03_remove(struct spi_device *spi) { struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); + struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data; l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); lcd_device_unregister(priv->ld); dev_set_drvdata(&spi->dev, NULL); + gpio_free(pdata->data_enable_gpio); + gpio_free(pdata->reset_gpio); + regulator_put(priv->io_reg); regulator_put(priv->core_reg); diff --git a/trunk/drivers/video/backlight/lm3533_bl.c b/trunk/drivers/video/backlight/lm3533_bl.c index 18dca0c29c68..bebeb63607db 100644 --- a/trunk/drivers/video/backlight/lm3533_bl.c +++ b/trunk/drivers/video/backlight/lm3533_bl.c @@ -295,7 +295,7 @@ static int __devinit lm3533_bl_probe(struct platform_device *pdev) return -EINVAL; } - bl = devm_kzalloc(&pdev->dev, sizeof(*bl), GFP_KERNEL); + bl = kzalloc(sizeof(*bl), GFP_KERNEL); if (!bl) { dev_err(&pdev->dev, "failed to allocate memory for backlight\n"); @@ -317,7 +317,8 @@ static int __devinit lm3533_bl_probe(struct platform_device *pdev) &lm3533_bl_ops, &props); if (IS_ERR(bd)) { dev_err(&pdev->dev, "failed to register backlight device\n"); - return PTR_ERR(bd); + ret = PTR_ERR(bd); + goto err_free; } bl->bd = bd; @@ -347,6 +348,8 @@ static int __devinit lm3533_bl_probe(struct platform_device *pdev) sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group); err_unregister: backlight_device_unregister(bd); +err_free: + kfree(bl); return ret; } @@ -364,6 +367,7 @@ static int __devexit lm3533_bl_remove(struct platform_device *pdev) lm3533_ctrlbank_disable(&bl->cb); sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group); backlight_device_unregister(bd); + kfree(bl); return 0; } diff --git a/trunk/drivers/video/backlight/lms283gf05.c b/trunk/drivers/video/backlight/lms283gf05.c index ea43f2254196..a9f2c36966f1 100644 --- a/trunk/drivers/video/backlight/lms283gf05.c +++ b/trunk/drivers/video/backlight/lms283gf05.c @@ -158,27 +158,29 @@ static int __devinit lms283gf05_probe(struct spi_device *spi) int ret = 0; if (pdata != NULL) { - ret = devm_gpio_request(&spi->dev, pdata->reset_gpio, - "LMS285GF05 RESET"); + ret = gpio_request(pdata->reset_gpio, "LMS285GF05 RESET"); if (ret) return ret; ret = gpio_direction_output(pdata->reset_gpio, !pdata->reset_inverted); if (ret) - return ret; + goto err; } st = devm_kzalloc(&spi->dev, sizeof(struct lms283gf05_state), GFP_KERNEL); if (st == NULL) { dev_err(&spi->dev, "No memory for device state\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err; } ld = lcd_device_register("lms283gf05", &spi->dev, st, &lms_ops); - if (IS_ERR(ld)) - return PTR_ERR(ld); + if (IS_ERR(ld)) { + ret = PTR_ERR(ld); + goto err; + } st->spi = spi; st->ld = ld; @@ -191,14 +193,24 @@ static int __devinit lms283gf05_probe(struct spi_device *spi) lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq)); return 0; + +err: + if (pdata != NULL) + gpio_free(pdata->reset_gpio); + + return ret; } static int __devexit lms283gf05_remove(struct spi_device *spi) { struct lms283gf05_state *st = dev_get_drvdata(&spi->dev); + struct lms283gf05_pdata *pdata = st->spi->dev.platform_data; lcd_device_unregister(st->ld); + if (pdata != NULL) + gpio_free(pdata->reset_gpio); + return 0; } diff --git a/trunk/drivers/video/backlight/lp855x_bl.c b/trunk/drivers/video/backlight/lp855x_bl.c index aa6d4f71131f..72a0e0c917cf 100644 --- a/trunk/drivers/video/backlight/lp855x_bl.c +++ b/trunk/drivers/video/backlight/lp855x_bl.c @@ -14,15 +14,11 @@ #include #include #include -#include +#include /* Registers */ -#define BRIGHTNESS_CTRL 0x00 -#define DEVICE_CTRL 0x01 -#define EEPROM_START 0xA0 -#define EEPROM_END 0xA7 -#define EPROM_START 0xA0 -#define EPROM_END 0xAF +#define BRIGHTNESS_CTRL (0x00) +#define DEVICE_CTRL (0x01) #define BUF_SIZE 20 #define DEFAULT_BL_NAME "lcd-backlight" diff --git a/trunk/drivers/video/backlight/ot200_bl.c b/trunk/drivers/video/backlight/ot200_bl.c index 469cf0f109d2..f519d55a294c 100644 --- a/trunk/drivers/video/backlight/ot200_bl.c +++ b/trunk/drivers/video/backlight/ot200_bl.c @@ -84,8 +84,7 @@ static int ot200_backlight_probe(struct platform_device *pdev) int retval = 0; /* request gpio */ - if (devm_gpio_request(&pdev->dev, GPIO_DIMM, - "ot200 backlight dimmer") < 0) { + if (gpio_request(GPIO_DIMM, "ot200 backlight dimmer") < 0) { dev_err(&pdev->dev, "failed to request GPIO %d\n", GPIO_DIMM); return -ENODEV; } @@ -94,13 +93,14 @@ static int ot200_backlight_probe(struct platform_device *pdev) pwm_timer = cs5535_mfgpt_alloc_timer(7, MFGPT_DOMAIN_ANY); if (!pwm_timer) { dev_err(&pdev->dev, "MFGPT 7 not available\n"); - return -ENODEV; + retval = -ENODEV; + goto error_mfgpt_alloc; } - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { retval = -ENOMEM; - goto error_devm_kzalloc; + goto error_kzalloc; } /* setup gpio */ @@ -122,21 +122,26 @@ static int ot200_backlight_probe(struct platform_device *pdev) if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); retval = PTR_ERR(bl); - goto error_devm_kzalloc; + goto error_backlight_device_register; } platform_set_drvdata(pdev, bl); return 0; -error_devm_kzalloc: +error_backlight_device_register: + kfree(data); +error_kzalloc: cs5535_mfgpt_free_timer(pwm_timer); +error_mfgpt_alloc: + gpio_free(GPIO_DIMM); return retval; } static int ot200_backlight_remove(struct platform_device *pdev) { struct backlight_device *bl = platform_get_drvdata(pdev); + struct ot200_backlight_data *data = bl_get_data(bl); backlight_device_unregister(bl); @@ -147,7 +152,9 @@ static int ot200_backlight_remove(struct platform_device *pdev) MAX_COMP2 - dim_table[100]); cs5535_mfgpt_free_timer(pwm_timer); + gpio_free(GPIO_DIMM); + kfree(data); return 0; } diff --git a/trunk/drivers/video/backlight/tosa_bl.c b/trunk/drivers/video/backlight/tosa_bl.c index 49342e1d20be..0d54e607e82d 100644 --- a/trunk/drivers/video/backlight/tosa_bl.c +++ b/trunk/drivers/video/backlight/tosa_bl.c @@ -92,14 +92,14 @@ static int __devinit tosa_bl_probe(struct i2c_client *client, data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj; - ret = devm_gpio_request(&client->dev, TOSA_GPIO_BL_C20MA, "backlight"); + ret = gpio_request(TOSA_GPIO_BL_C20MA, "backlight"); if (ret) { dev_dbg(&data->bl->dev, "Unable to request gpio!\n"); return ret; } ret = gpio_direction_output(TOSA_GPIO_BL_C20MA, 0); if (ret) - return ret; + goto err_gpio_dir; i2c_set_clientdata(client, data); data->i2c = client; @@ -123,6 +123,8 @@ static int __devinit tosa_bl_probe(struct i2c_client *client, err_reg: data->bl = NULL; +err_gpio_dir: + gpio_free(TOSA_GPIO_BL_C20MA); return ret; } @@ -133,6 +135,8 @@ static int __devexit tosa_bl_remove(struct i2c_client *client) backlight_device_unregister(data->bl); data->bl = NULL; + gpio_free(TOSA_GPIO_BL_C20MA); + return 0; } diff --git a/trunk/drivers/video/backlight/tosa_lcd.c b/trunk/drivers/video/backlight/tosa_lcd.c index 33047a66cc24..47823b8efff0 100644 --- a/trunk/drivers/video/backlight/tosa_lcd.c +++ b/trunk/drivers/video/backlight/tosa_lcd.c @@ -193,7 +193,7 @@ static int __devinit tosa_lcd_probe(struct spi_device *spi) data->spi = spi; dev_set_drvdata(&spi->dev, data); - ret = devm_gpio_request(&spi->dev, TOSA_GPIO_TG_ON, "tg #pwr"); + ret = gpio_request(TOSA_GPIO_TG_ON, "tg #pwr"); if (ret < 0) goto err_gpio_tg; @@ -201,7 +201,7 @@ static int __devinit tosa_lcd_probe(struct spi_device *spi) ret = gpio_direction_output(TOSA_GPIO_TG_ON, 0); if (ret < 0) - goto err_gpio_tg; + goto err_gpio_dir; mdelay(60); tosa_lcd_tg_init(data); @@ -221,6 +221,8 @@ static int __devinit tosa_lcd_probe(struct spi_device *spi) err_register: tosa_lcd_tg_off(data); +err_gpio_dir: + gpio_free(TOSA_GPIO_TG_ON); err_gpio_tg: dev_set_drvdata(&spi->dev, NULL); return ret; @@ -237,6 +239,7 @@ static int __devexit tosa_lcd_remove(struct spi_device *spi) tosa_lcd_tg_off(data); + gpio_free(TOSA_GPIO_TG_ON); dev_set_drvdata(&spi->dev, NULL); return 0; diff --git a/trunk/fs/affs/bitmap.c b/trunk/fs/affs/bitmap.c index a32246b8359e..6e0be43ef6ef 100644 --- a/trunk/fs/affs/bitmap.c +++ b/trunk/fs/affs/bitmap.c @@ -10,6 +10,30 @@ #include #include "affs.h" +/* This is, of course, shamelessly stolen from fs/minix */ + +static const int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; + +static u32 +affs_count_free_bits(u32 blocksize, const void *data) +{ + const u32 *map; + u32 free; + u32 tmp; + + map = data; + free = 0; + for (blocksize /= 4; blocksize > 0; blocksize--) { + tmp = *map++; + while (tmp) { + free += nibblemap[tmp & 0xf]; + tmp >>= 4; + } + } + + return free; +} + u32 affs_count_free_blocks(struct super_block *sb) { @@ -293,7 +317,7 @@ int affs_init_bitmap(struct super_block *sb, int *flags) goto out; } pr_debug("AFFS: read bitmap block %d: %d\n", blk, bm->bm_key); - bm->bm_free = memweight(bh->b_data + 4, sb->s_blocksize - 4); + bm->bm_free = affs_count_free_bits(sb->s_blocksize - 4, bh->b_data + 4); /* Don't try read the extension if this is the last block, * but we also need the right bm pointer below @@ -343,7 +367,7 @@ int affs_init_bitmap(struct super_block *sb, int *flags) /* recalculate bitmap count for last block */ bm--; - bm->bm_free = memweight(bh->b_data + 4, sb->s_blocksize - 4); + bm->bm_free = affs_count_free_bits(sb->s_blocksize - 4, bh->b_data + 4); out: affs_brelse(bh); diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index 4bab807227ad..adb1cd7ceb9b 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -3342,22 +3342,10 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size); /* super.c */ int btrfs_parse_options(struct btrfs_root *root, char *options); int btrfs_sync_fs(struct super_block *sb, int wait); - -#ifdef CONFIG_PRINTK -__printf(2, 3) void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...); -#else -static inline __printf(2, 3) -void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...) -{ -} -#endif - -__printf(5, 6) void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, unsigned int line, int errno, const char *fmt, ...); - void __btrfs_abort_transaction(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *function, unsigned int line, int errno); @@ -3398,7 +3386,6 @@ do { \ (errno), fmt, ##args); \ } while (0) -__printf(5, 6) void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function, unsigned int line, int errno, const char *fmt, ...); diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index fadeba6a5db9..502b20c56e84 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -1114,7 +1114,7 @@ void clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, spin_unlock(&root->fs_info->delalloc_lock); btrfs_panic(root->fs_info, -EOVERFLOW, "Can't clear %lu bytes from " - " dirty_mdatadata_bytes (%llu)", + " dirty_mdatadata_bytes (%lu)", buf->len, root->fs_info->dirty_metadata_bytes); } diff --git a/trunk/fs/btrfs/relocation.c b/trunk/fs/btrfs/relocation.c index 4da08652004d..c5dbd9149679 100644 --- a/trunk/fs/btrfs/relocation.c +++ b/trunk/fs/btrfs/relocation.c @@ -1241,7 +1241,7 @@ static int __must_check __add_reloc_root(struct btrfs_root *root) if (rb_node) { btrfs_panic(root->fs_info, -EEXIST, "Duplicate root found " "for start=%llu while inserting into relocation " - "tree\n", node->bytenr); + "tree\n"); kfree(node); return -EEXIST; } diff --git a/trunk/fs/btrfs/super.c b/trunk/fs/btrfs/super.c index 8c6e61d6eed5..fa61ef59cd61 100644 --- a/trunk/fs/btrfs/super.c +++ b/trunk/fs/btrfs/super.c @@ -125,7 +125,6 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info) } } -#ifdef CONFIG_PRINTK /* * __btrfs_std_error decodes expected errors from the caller and * invokes the approciate error response. @@ -168,7 +167,7 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, va_end(args); } -static const char * const logtypes[] = { +const char *logtypes[] = { "emergency", "alert", "critical", @@ -186,50 +185,22 @@ void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...) struct va_format vaf; va_list args; const char *type = logtypes[4]; - int kern_level; va_start(args, fmt); - kern_level = printk_get_level(fmt); - if (kern_level) { - size_t size = printk_skip_level(fmt) - fmt; - memcpy(lvl, fmt, size); - lvl[size] = '\0'; - fmt += size; - type = logtypes[kern_level - '0']; + if (fmt[0] == '<' && isdigit(fmt[1]) && fmt[2] == '>') { + memcpy(lvl, fmt, 3); + lvl[3] = '\0'; + fmt += 3; + type = logtypes[fmt[1] - '0']; } else *lvl = '\0'; vaf.fmt = fmt; vaf.va = &args; - printk("%sBTRFS %s (device %s): %pV", lvl, type, sb->s_id, &vaf); - - va_end(args); } -#else - -void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, - unsigned int line, int errno, const char *fmt, ...) -{ - struct super_block *sb = fs_info->sb; - - /* - * Special case: if the error is EROFS, and we're already - * under MS_RDONLY, then it is safe here. - */ - if (errno == -EROFS && (sb->s_flags & MS_RDONLY)) - return; - - /* Don't go through full error handling during mount */ - if (sb->s_flags & MS_BORN) { - save_error_info(fs_info); - btrfs_handle_error(fs_info); - } -} -#endif - /* * We only mark the transaction aborted and then set the file system read-only. * This will prevent new transactions from starting or trying to join this diff --git a/trunk/fs/cachefiles/rdwr.c b/trunk/fs/cachefiles/rdwr.c index c994691d9445..c0353dfac51f 100644 --- a/trunk/fs/cachefiles/rdwr.c +++ b/trunk/fs/cachefiles/rdwr.c @@ -919,7 +919,7 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) * own time */ path.mnt = cache->mnt; path.dentry = object->backer; - file = dentry_open(&path, O_RDWR | O_LARGEFILE, cache->cache_cred); + file = dentry_open(&path, O_RDWR, cache->cache_cred); if (IS_ERR(file)) { ret = PTR_ERR(file); } else { diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 3684353ebd5f..e95aeeddd25c 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -2002,17 +2002,17 @@ static void coredump_finish(struct mm_struct *mm) void set_dumpable(struct mm_struct *mm, int value) { switch (value) { - case SUID_DUMPABLE_DISABLED: + case 0: clear_bit(MMF_DUMPABLE, &mm->flags); smp_wmb(); clear_bit(MMF_DUMP_SECURELY, &mm->flags); break; - case SUID_DUMPABLE_ENABLED: + case 1: set_bit(MMF_DUMPABLE, &mm->flags); smp_wmb(); clear_bit(MMF_DUMP_SECURELY, &mm->flags); break; - case SUID_DUMPABLE_SAFE: + case 2: set_bit(MMF_DUMP_SECURELY, &mm->flags); smp_wmb(); set_bit(MMF_DUMPABLE, &mm->flags); @@ -2025,7 +2025,7 @@ static int __get_dumpable(unsigned long mm_flags) int ret; ret = mm_flags & MMF_DUMPABLE_MASK; - return (ret > SUID_DUMPABLE_ENABLED) ? SUID_DUMPABLE_SAFE : ret; + return (ret >= 2) ? 2 : ret; } int get_dumpable(struct mm_struct *mm) @@ -2111,7 +2111,6 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) int retval = 0; int flag = 0; int ispipe; - bool need_nonrelative = false; static atomic_t core_dump_count = ATOMIC_INIT(0); struct coredump_params cprm = { .signr = signr, @@ -2137,16 +2136,14 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) if (!cred) goto fail; /* - * We cannot trust fsuid as being the "true" uid of the process - * nor do we know its entire history. We only know it was tainted - * so we dump it as root in mode 2, and only into a controlled - * environment (pipe handler or fully qualified path). + * We cannot trust fsuid as being the "true" uid of the + * process nor do we know its entire history. We only know it + * was tainted so we dump it as root in mode 2. */ - if (__get_dumpable(cprm.mm_flags) == SUID_DUMPABLE_SAFE) { + if (__get_dumpable(cprm.mm_flags) == 2) { /* Setuid core dump mode */ flag = O_EXCL; /* Stop rewrite attacks */ cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */ - need_nonrelative = true; } retval = coredump_wait(exit_code, &core_state); @@ -2174,16 +2171,15 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) } if (cprm.limit == 1) { - /* See umh_pipe_setup() which sets RLIMIT_CORE = 1. - * + /* * Normally core limits are irrelevant to pipes, since * we're not writing to the file system, but we use - * cprm.limit of 1 here as a speacial value, this is a - * consistent way to catch recursive crashes. - * We can still crash if the core_pattern binary sets - * RLIM_CORE = !1, but it runs as root, and can do - * lots of stupid things. - * + * cprm.limit of 1 here as a speacial value. Any + * non-1 limit gets set to RLIM_INFINITY below, but + * a limit of 0 skips the dump. This is a consistent + * way to catch recursive crashes. We can still crash + * if the core_pattern binary sets RLIM_CORE = !1 + * but it runs as root, and can do lots of stupid things * Note that we use task_tgid_vnr here to grab the pid * of the process group leader. That way we get the * right pid if a thread in a multi-threaded @@ -2227,14 +2223,6 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) if (cprm.limit < binfmt->min_coredump) goto fail_unlock; - if (need_nonrelative && cn.corename[0] != '/') { - printk(KERN_WARNING "Pid %d(%s) can only dump core "\ - "to fully qualified path!\n", - task_tgid_vnr(current), current->comm); - printk(KERN_WARNING "Skipping core dump\n"); - goto fail_unlock; - } - cprm.file = filp_open(cn.corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600); diff --git a/trunk/fs/ext2/balloc.c b/trunk/fs/ext2/balloc.c index 376aa77f3ca7..1c3613998862 100644 --- a/trunk/fs/ext2/balloc.c +++ b/trunk/fs/ext2/balloc.c @@ -1444,9 +1444,19 @@ ext2_fsblk_t ext2_new_block(struct inode *inode, unsigned long goal, int *errp) #ifdef EXT2FS_DEBUG -unsigned long ext2_count_free(struct buffer_head *map, unsigned int numchars) +static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; + +unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars) { - return numchars * BITS_PER_BYTE - memweight(map->b_data, numchars); + unsigned int i; + unsigned long sum = 0; + + if (!map) + return (0); + for (i = 0; i < numchars; i++) + sum += nibblemap[map->b_data[i] & 0xf] + + nibblemap[(map->b_data[i] >> 4) & 0xf]; + return (sum); } #endif /* EXT2FS_DEBUG */ diff --git a/trunk/fs/ext2/ialloc.c b/trunk/fs/ext2/ialloc.c index 8f370e012e61..c13eb7b91a11 100644 --- a/trunk/fs/ext2/ialloc.c +++ b/trunk/fs/ext2/ialloc.c @@ -644,7 +644,6 @@ unsigned long ext2_count_free_inodes (struct super_block * sb) } brelse(bitmap_bh); printk("ext2_count_free_inodes: stored = %lu, computed = %lu, %lu\n", - (unsigned long) percpu_counter_read(&EXT2_SB(sb)->s_freeinodes_counter), desc_count, bitmap_count); return desc_count; diff --git a/trunk/fs/ext3/balloc.c b/trunk/fs/ext3/balloc.c index 90d901f0486b..25cd60892116 100644 --- a/trunk/fs/ext3/balloc.c +++ b/trunk/fs/ext3/balloc.c @@ -1813,7 +1813,7 @@ ext3_fsblk_t ext3_count_free_blocks(struct super_block *sb) brelse(bitmap_bh); printk("ext3_count_free_blocks: stored = "E3FSBLK ", computed = "E3FSBLK", "E3FSBLK"\n", - (ext3_fsblk_t)le32_to_cpu(es->s_free_blocks_count), + le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count); return bitmap_count; #else diff --git a/trunk/fs/ext3/bitmap.c b/trunk/fs/ext3/bitmap.c index ef9c643e8e9d..909d13e26560 100644 --- a/trunk/fs/ext3/bitmap.c +++ b/trunk/fs/ext3/bitmap.c @@ -11,9 +11,19 @@ #ifdef EXT3FS_DEBUG +static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; + unsigned long ext3_count_free (struct buffer_head * map, unsigned int numchars) { - return numchars * BITS_PER_BYTE - memweight(map->b_data, numchars); + unsigned int i; + unsigned long sum = 0; + + if (!map) + return (0); + for (i = 0; i < numchars; i++) + sum += nibblemap[map->b_data[i] & 0xf] + + nibblemap[(map->b_data[i] >> 4) & 0xf]; + return (sum); } #endif /* EXT3FS_DEBUG */ diff --git a/trunk/fs/ext4/bitmap.c b/trunk/fs/ext4/bitmap.c index f8716eab9995..a94b9c63ee5c 100644 --- a/trunk/fs/ext4/bitmap.c +++ b/trunk/fs/ext4/bitmap.c @@ -11,9 +11,16 @@ #include #include "ext4.h" +static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; + unsigned int ext4_count_free(char *bitmap, unsigned int numchars) { - return numchars * BITS_PER_BYTE - memweight(bitmap, numchars); + unsigned int i, sum = 0; + + for (i = 0; i < numchars; i++) + sum += nibblemap[bitmap[i] & 0xf] + + nibblemap[(bitmap[i] >> 4) & 0xf]; + return sum; } int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, diff --git a/trunk/fs/fat/dir.c b/trunk/fs/fat/dir.c index dc49ed2cbffa..6eaa28c98ad1 100644 --- a/trunk/fs/fat/dir.c +++ b/trunk/fs/fat/dir.c @@ -35,11 +35,6 @@ #define FAT_MAX_UNI_CHARS ((MSDOS_SLOTS - 1) * 13 + 1) #define FAT_MAX_UNI_SIZE (FAT_MAX_UNI_CHARS * sizeof(wchar_t)) -static inline unsigned char fat_tolower(unsigned char c) -{ - return ((c >= 'A') && (c <= 'Z')) ? c+32 : c; -} - static inline loff_t fat_make_i_pos(struct super_block *sb, struct buffer_head *bh, struct msdos_dir_entry *de) @@ -338,124 +333,6 @@ static int fat_parse_long(struct inode *dir, loff_t *pos, return 0; } -/** - * fat_parse_short - Parse MS-DOS (short) directory entry. - * @sb: superblock - * @de: directory entry to parse - * @name: FAT_MAX_SHORT_SIZE array in which to place extracted name - * @dot_hidden: Nonzero == prepend '.' to names with ATTR_HIDDEN - * - * Returns the number of characters extracted into 'name'. - */ -static int fat_parse_short(struct super_block *sb, - const struct msdos_dir_entry *de, - unsigned char *name, int dot_hidden) -{ - const struct msdos_sb_info *sbi = MSDOS_SB(sb); - int isvfat = sbi->options.isvfat; - int nocase = sbi->options.nocase; - unsigned short opt_shortname = sbi->options.shortname; - struct nls_table *nls_disk = sbi->nls_disk; - wchar_t uni_name[14]; - unsigned char c, work[MSDOS_NAME]; - unsigned char *ptname = name; - int chi, chl, i, j, k; - int dotoffset = 0; - int name_len = 0, uni_len = 0; - - if (!isvfat && dot_hidden && (de->attr & ATTR_HIDDEN)) { - *ptname++ = '.'; - dotoffset = 1; - } - - memcpy(work, de->name, sizeof(work)); - /* see namei.c, msdos_format_name */ - if (work[0] == 0x05) - work[0] = 0xE5; - - /* Filename */ - for (i = 0, j = 0; i < 8;) { - c = work[i]; - if (!c) - break; - chl = fat_shortname2uni(nls_disk, &work[i], 8 - i, - &uni_name[j++], opt_shortname, - de->lcase & CASE_LOWER_BASE); - if (chl <= 1) { - if (!isvfat) - ptname[i] = nocase ? c : fat_tolower(c); - i++; - if (c != ' ') { - name_len = i; - uni_len = j; - } - } else { - uni_len = j; - if (isvfat) - i += min(chl, 8-i); - else { - for (chi = 0; chi < chl && i < 8; chi++, i++) - ptname[i] = work[i]; - } - if (chl) - name_len = i; - } - } - - i = name_len; - j = uni_len; - fat_short2uni(nls_disk, ".", 1, &uni_name[j++]); - if (!isvfat) - ptname[i] = '.'; - i++; - - /* Extension */ - for (k = 8; k < MSDOS_NAME;) { - c = work[k]; - if (!c) - break; - chl = fat_shortname2uni(nls_disk, &work[k], MSDOS_NAME - k, - &uni_name[j++], opt_shortname, - de->lcase & CASE_LOWER_EXT); - if (chl <= 1) { - k++; - if (!isvfat) - ptname[i] = nocase ? c : fat_tolower(c); - i++; - if (c != ' ') { - name_len = i; - uni_len = j; - } - } else { - uni_len = j; - if (isvfat) { - int offset = min(chl, MSDOS_NAME-k); - k += offset; - i += offset; - } else { - for (chi = 0; chi < chl && k < MSDOS_NAME; - chi++, i++, k++) { - ptname[i] = work[k]; - } - } - if (chl) - name_len = i; - } - } - - if (name_len > 0) { - name_len += dotoffset; - - if (sbi->options.isvfat) { - uni_name[uni_len] = 0x0000; - name_len = fat_uni_to_x8(sb, uni_name, name, - FAT_MAX_SHORT_SIZE); - } - } - - return name_len; -} - /* * Return values: negative -> error, 0 -> not found, positive -> found, * value is the total amount of slots, including the shortname entry. @@ -467,11 +344,15 @@ int fat_search_long(struct inode *inode, const unsigned char *name, struct msdos_sb_info *sbi = MSDOS_SB(sb); struct buffer_head *bh = NULL; struct msdos_dir_entry *de; + struct nls_table *nls_disk = sbi->nls_disk; unsigned char nr_slots; + wchar_t bufuname[14]; wchar_t *unicode = NULL; + unsigned char work[MSDOS_NAME]; unsigned char bufname[FAT_MAX_SHORT_SIZE]; + unsigned short opt_shortname = sbi->options.shortname; loff_t cpos = 0; - int err, len; + int chl, i, j, last_u, err, len; err = -ENOENT; while (1) { @@ -499,16 +380,47 @@ int fat_search_long(struct inode *inode, const unsigned char *name, goto end_of_dir; } - /* Never prepend '.' to hidden files here. - * That is done only for msdos mounts (and only when - * 'dotsOK=yes'); if we are executing here, it is in the - * context of a vfat mount. - */ - len = fat_parse_short(sb, de, bufname, 0); - if (len == 0) + memcpy(work, de->name, sizeof(de->name)); + /* see namei.c, msdos_format_name */ + if (work[0] == 0x05) + work[0] = 0xE5; + for (i = 0, j = 0, last_u = 0; i < 8;) { + if (!work[i]) + break; + chl = fat_shortname2uni(nls_disk, &work[i], 8 - i, + &bufuname[j++], opt_shortname, + de->lcase & CASE_LOWER_BASE); + if (chl <= 1) { + if (work[i] != ' ') + last_u = j; + } else { + last_u = j; + } + i += chl; + } + j = last_u; + fat_short2uni(nls_disk, ".", 1, &bufuname[j++]); + for (i = 8; i < MSDOS_NAME;) { + if (!work[i]) + break; + chl = fat_shortname2uni(nls_disk, &work[i], + MSDOS_NAME - i, + &bufuname[j++], opt_shortname, + de->lcase & CASE_LOWER_EXT); + if (chl <= 1) { + if (work[i] != ' ') + last_u = j; + } else { + last_u = j; + } + i += chl; + } + if (!last_u) continue; /* Compare shortname */ + bufuname[last_u] = 0x0000; + len = fat_uni_to_x8(sb, bufuname, bufname, sizeof(bufname)); if (fat_name_match(sbi, name, name_len, bufname, len)) goto found; @@ -557,15 +469,20 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent, struct msdos_sb_info *sbi = MSDOS_SB(sb); struct buffer_head *bh; struct msdos_dir_entry *de; + struct nls_table *nls_disk = sbi->nls_disk; unsigned char nr_slots; + wchar_t bufuname[14]; wchar_t *unicode = NULL; - unsigned char bufname[FAT_MAX_SHORT_SIZE]; + unsigned char c, work[MSDOS_NAME]; + unsigned char bufname[FAT_MAX_SHORT_SIZE], *ptname = bufname; + unsigned short opt_shortname = sbi->options.shortname; int isvfat = sbi->options.isvfat; + int nocase = sbi->options.nocase; const char *fill_name = NULL; unsigned long inum; unsigned long lpos, dummy, *furrfu = &lpos; loff_t cpos; - int short_len = 0, fill_len = 0; + int chi, chl, i, i2, j, last, last_u, dotoffset = 0, fill_len = 0; int ret = 0; lock_super(sb); @@ -639,10 +556,74 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent, } } - short_len = fat_parse_short(sb, de, bufname, sbi->options.dotsOK); - if (short_len == 0) + if (sbi->options.dotsOK) { + ptname = bufname; + dotoffset = 0; + if (de->attr & ATTR_HIDDEN) { + *ptname++ = '.'; + dotoffset = 1; + } + } + + memcpy(work, de->name, sizeof(de->name)); + /* see namei.c, msdos_format_name */ + if (work[0] == 0x05) + work[0] = 0xE5; + for (i = 0, j = 0, last = 0, last_u = 0; i < 8;) { + if (!(c = work[i])) + break; + chl = fat_shortname2uni(nls_disk, &work[i], 8 - i, + &bufuname[j++], opt_shortname, + de->lcase & CASE_LOWER_BASE); + if (chl <= 1) { + ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c; + if (c != ' ') { + last = i; + last_u = j; + } + } else { + last_u = j; + for (chi = 0; chi < chl && i < 8; chi++) { + ptname[i] = work[i]; + i++; last = i; + } + } + } + i = last; + j = last_u; + fat_short2uni(nls_disk, ".", 1, &bufuname[j++]); + ptname[i++] = '.'; + for (i2 = 8; i2 < MSDOS_NAME;) { + if (!(c = work[i2])) + break; + chl = fat_shortname2uni(nls_disk, &work[i2], MSDOS_NAME - i2, + &bufuname[j++], opt_shortname, + de->lcase & CASE_LOWER_EXT); + if (chl <= 1) { + i2++; + ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c; + if (c != ' ') { + last = i; + last_u = j; + } + } else { + last_u = j; + for (chi = 0; chi < chl && i2 < MSDOS_NAME; chi++) { + ptname[i++] = work[i2++]; + last = i; + } + } + } + if (!last) goto record_end; + i = last + dotoffset; + j = last_u; + + if (isvfat) { + bufuname[j] = 0x0000; + i = fat_uni_to_x8(sb, bufuname, bufname, sizeof(bufname)); + } if (nr_slots) { /* hack for fat_ioctl_filldir() */ struct fat_ioctl_filldir_callback *p = dirent; @@ -650,12 +631,12 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent, p->longname = fill_name; p->long_len = fill_len; p->shortname = bufname; - p->short_len = short_len; + p->short_len = i; fill_name = NULL; fill_len = 0; } else { fill_name = bufname; - fill_len = short_len; + fill_len = i; } start_filldir: diff --git a/trunk/fs/fat/fat.h b/trunk/fs/fat/fat.h index 2deeeb86f331..fc35c5c69136 100644 --- a/trunk/fs/fat/fat.h +++ b/trunk/fs/fat/fat.h @@ -217,21 +217,6 @@ static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len) #endif } -static inline int fat_get_start(const struct msdos_sb_info *sbi, - const struct msdos_dir_entry *de) -{ - int cluster = le16_to_cpu(de->start); - if (sbi->fat_bits == 32) - cluster |= (le16_to_cpu(de->starthi) << 16); - return cluster; -} - -static inline void fat_set_start(struct msdos_dir_entry *de, int cluster) -{ - de->start = cpu_to_le16(cluster); - de->starthi = cpu_to_le16(cluster >> 16); -} - static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len) { #ifdef __BIG_ENDIAN diff --git a/trunk/fs/fat/inode.c b/trunk/fs/fat/inode.c index 05e897fe9866..0038b32cb362 100644 --- a/trunk/fs/fat/inode.c +++ b/trunk/fs/fat/inode.c @@ -369,7 +369,10 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) inode->i_op = sbi->dir_ops; inode->i_fop = &fat_dir_operations; - MSDOS_I(inode)->i_start = fat_get_start(sbi, de); + MSDOS_I(inode)->i_start = le16_to_cpu(de->start); + if (sbi->fat_bits == 32) + MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16); + MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start; error = fat_calc_dir_size(inode); if (error < 0) @@ -382,7 +385,9 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) inode->i_mode = fat_make_mode(sbi, de->attr, ((sbi->options.showexec && !is_exec(de->name + 8)) ? S_IRUGO|S_IWUGO : S_IRWXUGO)); - MSDOS_I(inode)->i_start = fat_get_start(sbi, de); + MSDOS_I(inode)->i_start = le16_to_cpu(de->start); + if (sbi->fat_bits == 32) + MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16); MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start; inode->i_size = le32_to_cpu(de->size); @@ -608,7 +613,8 @@ static int __fat_write_inode(struct inode *inode, int wait) else raw_entry->size = cpu_to_le32(inode->i_size); raw_entry->attr = fat_make_attrs(inode); - fat_set_start(raw_entry, MSDOS_I(inode)->i_logstart); + raw_entry->start = cpu_to_le16(MSDOS_I(inode)->i_logstart); + raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16); fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time, &raw_entry->date, NULL); if (sbi->options.isvfat) { diff --git a/trunk/fs/fat/namei_msdos.c b/trunk/fs/fat/namei_msdos.c index b0e12bf9f4a1..70d993a93805 100644 --- a/trunk/fs/fat/namei_msdos.c +++ b/trunk/fs/fat/namei_msdos.c @@ -246,7 +246,8 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name, de.ctime_cs = 0; de.time = time; de.date = date; - fat_set_start(&de, cluster); + de.start = cpu_to_le16(cluster); + de.starthi = cpu_to_le16(cluster >> 16); de.size = 0; err = fat_add_entries(dir, &de, 1, sinfo); @@ -529,7 +530,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, mark_inode_dirty(old_inode); if (update_dotdot) { - fat_set_start(dotdot_de, MSDOS_I(new_dir)->i_logstart); + int start = MSDOS_I(new_dir)->i_logstart; + dotdot_de->start = cpu_to_le16(start); + dotdot_de->starthi = cpu_to_le16(start >> 16); mark_buffer_dirty_inode(dotdot_bh, old_inode); if (IS_DIRSYNC(new_dir)) { err = sync_dirty_buffer(dotdot_bh); @@ -569,7 +572,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, corrupt = 1; if (update_dotdot) { - fat_set_start(dotdot_de, MSDOS_I(old_dir)->i_logstart); + int start = MSDOS_I(old_dir)->i_logstart; + dotdot_de->start = cpu_to_le16(start); + dotdot_de->starthi = cpu_to_le16(start >> 16); mark_buffer_dirty_inode(dotdot_bh, old_inode); corrupt |= sync_dirty_buffer(dotdot_bh); } diff --git a/trunk/fs/fat/namei_vfat.c b/trunk/fs/fat/namei_vfat.c index 6a6d8c0715a1..6cc480652433 100644 --- a/trunk/fs/fat/namei_vfat.c +++ b/trunk/fs/fat/namei_vfat.c @@ -651,7 +651,8 @@ static int vfat_build_slots(struct inode *dir, const unsigned char *name, de->time = de->ctime = time; de->date = de->cdate = de->adate = date; de->ctime_cs = time_cs; - fat_set_start(de, cluster); + de->start = cpu_to_le16(cluster); + de->starthi = cpu_to_le16(cluster >> 16); de->size = 0; out_free: __putname(uname); @@ -964,7 +965,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, mark_inode_dirty(old_inode); if (update_dotdot) { - fat_set_start(dotdot_de, MSDOS_I(new_dir)->i_logstart); + int start = MSDOS_I(new_dir)->i_logstart; + dotdot_de->start = cpu_to_le16(start); + dotdot_de->starthi = cpu_to_le16(start >> 16); mark_buffer_dirty_inode(dotdot_bh, old_inode); if (IS_DIRSYNC(new_dir)) { err = sync_dirty_buffer(dotdot_bh); @@ -1006,7 +1009,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, corrupt = 1; if (update_dotdot) { - fat_set_start(dotdot_de, MSDOS_I(old_dir)->i_logstart); + int start = MSDOS_I(old_dir)->i_logstart; + dotdot_de->start = cpu_to_le16(start); + dotdot_de->starthi = cpu_to_le16(start >> 16); mark_buffer_dirty_inode(dotdot_bh, old_inode); corrupt |= sync_dirty_buffer(dotdot_bh); } diff --git a/trunk/fs/fcntl.c b/trunk/fs/fcntl.c index 887b5ba8c9b5..81b70e665bf0 100644 --- a/trunk/fs/fcntl.c +++ b/trunk/fs/fcntl.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -341,31 +340,6 @@ static int f_getown_ex(struct file *filp, unsigned long arg) return ret; } -#ifdef CONFIG_CHECKPOINT_RESTORE -static int f_getowner_uids(struct file *filp, unsigned long arg) -{ - struct user_namespace *user_ns = current_user_ns(); - uid_t * __user dst = (void * __user)arg; - uid_t src[2]; - int err; - - read_lock(&filp->f_owner.lock); - src[0] = from_kuid(user_ns, filp->f_owner.uid); - src[1] = from_kuid(user_ns, filp->f_owner.euid); - read_unlock(&filp->f_owner.lock); - - err = put_user(src[0], &dst[0]); - err |= put_user(src[1], &dst[1]); - - return err; -} -#else -static int f_getowner_uids(struct file *filp, unsigned long arg) -{ - return -EINVAL; -} -#endif - static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, struct file *filp) { @@ -422,9 +396,6 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, case F_SETOWN_EX: err = f_setown_ex(filp, arg); break; - case F_GETOWNER_UIDS: - err = f_getowner_uids(filp, arg); - break; case F_GETSIG: err = filp->f_owner.signum; break; diff --git a/trunk/fs/hfsplus/super.c b/trunk/fs/hfsplus/super.c index fdafb2d71654..473332098013 100644 --- a/trunk/fs/hfsplus/super.c +++ b/trunk/fs/hfsplus/super.c @@ -365,7 +365,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) u64 last_fs_block, last_fs_page; int err; - err = -ENOMEM; + err = -EINVAL; sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); if (!sbi) goto out; diff --git a/trunk/fs/minix/itree_v2.c b/trunk/fs/minix/itree_v2.c index 78e2d93e5c83..13487ad16894 100644 --- a/trunk/fs/minix/itree_v2.c +++ b/trunk/fs/minix/itree_v2.c @@ -32,8 +32,7 @@ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) if (block < 0) { printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n", block, bdevname(sb->s_bdev, b)); - } else if ((u64)block * (u64)sb->s_blocksize >= - minix_sb(sb)->s_max_size) { + } else if (block >= (minix_sb(inode->i_sb)->s_max_size/sb->s_blocksize)) { if (printk_ratelimit()) printk("MINIX-fs: block_to_path: " "block %ld too big on dev %s\n", diff --git a/trunk/fs/nilfs2/alloc.h b/trunk/fs/nilfs2/alloc.h index fb7238100548..f5fde36b9e28 100644 --- a/trunk/fs/nilfs2/alloc.h +++ b/trunk/fs/nilfs2/alloc.h @@ -76,23 +76,15 @@ int nilfs_palloc_freev(struct inode *, __u64 *, size_t); #define nilfs_clear_bit_atomic ext2_clear_bit_atomic #define nilfs_find_next_zero_bit find_next_zero_bit_le -/** - * struct nilfs_bh_assoc - block offset and buffer head association - * @blkoff: block offset - * @bh: buffer head +/* + * persistent object allocator cache */ + struct nilfs_bh_assoc { unsigned long blkoff; struct buffer_head *bh; }; -/** - * struct nilfs_palloc_cache - persistent object allocator cache - * @lock: cache protecting lock - * @prev_desc: blockgroup descriptors cache - * @prev_bitmap: blockgroup bitmap cache - * @prev_entry: translation entries cache - */ struct nilfs_palloc_cache { spinlock_t lock; struct nilfs_bh_assoc prev_desc; diff --git a/trunk/fs/nilfs2/bmap.h b/trunk/fs/nilfs2/bmap.h index b89e68076adc..40d9f453d31c 100644 --- a/trunk/fs/nilfs2/bmap.h +++ b/trunk/fs/nilfs2/bmap.h @@ -135,13 +135,6 @@ struct nilfs_bmap { /* state */ #define NILFS_BMAP_DIRTY 0x00000001 -/** - * struct nilfs_bmap_store - shadow copy of bmap state - * @data: cached raw block mapping of on-disk inode - * @last_allocated_key: cached value of last allocated key for data block - * @last_allocated_ptr: cached value of last allocated ptr for data block - * @state: cached value of state field of bmap structure - */ struct nilfs_bmap_store { __le64 data[NILFS_BMAP_SIZE / sizeof(__le64)]; __u64 last_allocated_key; diff --git a/trunk/fs/nilfs2/btnode.h b/trunk/fs/nilfs2/btnode.h index d876b565ce64..3a4dd2d8d3fc 100644 --- a/trunk/fs/nilfs2/btnode.h +++ b/trunk/fs/nilfs2/btnode.h @@ -29,13 +29,7 @@ #include #include -/** - * struct nilfs_btnode_chkey_ctxt - change key context - * @oldkey: old key of block's moving content - * @newkey: new key for block's content - * @bh: buffer head of old buffer - * @newbh: buffer head of new buffer - */ + struct nilfs_btnode_chkey_ctxt { __u64 oldkey; __u64 newkey; diff --git a/trunk/fs/nilfs2/cpfile.c b/trunk/fs/nilfs2/cpfile.c index deaa3d33a0aa..dab5c4c6dfaf 100644 --- a/trunk/fs/nilfs2/cpfile.c +++ b/trunk/fs/nilfs2/cpfile.c @@ -286,7 +286,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, __u64 cno; void *kaddr; unsigned long tnicps; - int ret, ncps, nicps, nss, count, i; + int ret, ncps, nicps, count, i; if (unlikely(start == 0 || start > end)) { printk(KERN_ERR "%s: invalid range of checkpoint numbers: " @@ -301,7 +301,6 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, if (ret < 0) goto out_sem; tnicps = 0; - nss = 0; for (cno = start; cno < end; cno += ncps) { ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, end); @@ -319,9 +318,8 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, cpfile, cno, cp_bh, kaddr); nicps = 0; for (i = 0; i < ncps; i++, cp = (void *)cp + cpsz) { - if (nilfs_checkpoint_snapshot(cp)) { - nss++; - } else if (!nilfs_checkpoint_invalid(cp)) { + WARN_ON(nilfs_checkpoint_snapshot(cp)); + if (!nilfs_checkpoint_invalid(cp)) { nilfs_checkpoint_set_invalid(cp); nicps++; } @@ -366,8 +364,6 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, } brelse(header_bh); - if (nss > 0) - ret = -EBUSY; out_sem: up_write(&NILFS_MDT(cpfile)->mi_sem); diff --git a/trunk/fs/nilfs2/dat.c b/trunk/fs/nilfs2/dat.c index fa0f80308c2d..b5c13f3576b9 100644 --- a/trunk/fs/nilfs2/dat.c +++ b/trunk/fs/nilfs2/dat.c @@ -33,12 +33,6 @@ #define NILFS_CNO_MIN ((__u64)1) #define NILFS_CNO_MAX (~(__u64)0) -/** - * struct nilfs_dat_info - on-memory private data of DAT file - * @mi: on-memory private data of metadata file - * @palloc_cache: persistent object allocator cache of DAT file - * @shadow: shadow map of DAT file - */ struct nilfs_dat_info { struct nilfs_mdt_info mi; struct nilfs_palloc_cache palloc_cache; diff --git a/trunk/fs/nilfs2/export.h b/trunk/fs/nilfs2/export.h index 19ccbf9522ab..a71cc412b651 100644 --- a/trunk/fs/nilfs2/export.h +++ b/trunk/fs/nilfs2/export.h @@ -5,14 +5,6 @@ extern const struct export_operations nilfs_export_ops; -/** - * struct nilfs_fid - NILFS file id type - * @cno: checkpoint number - * @ino: inode number - * @gen: file generation (version) for NFS - * @parent_gen: parent generation (version) for NFS - * @parent_ino: parent inode number - */ struct nilfs_fid { u64 cno; u64 ino; diff --git a/trunk/fs/nilfs2/ifile.c b/trunk/fs/nilfs2/ifile.c index d8e65bde083c..5a48df79d674 100644 --- a/trunk/fs/nilfs2/ifile.c +++ b/trunk/fs/nilfs2/ifile.c @@ -29,11 +29,7 @@ #include "alloc.h" #include "ifile.h" -/** - * struct nilfs_ifile_info - on-memory private data of ifile - * @mi: on-memory private data of metadata file - * @palloc_cache: persistent object allocator cache of ifile - */ + struct nilfs_ifile_info { struct nilfs_mdt_info mi; struct nilfs_palloc_cache palloc_cache; diff --git a/trunk/fs/nilfs2/inode.c b/trunk/fs/nilfs2/inode.c index 6e2c3db976b2..7cc64465ec26 100644 --- a/trunk/fs/nilfs2/inode.c +++ b/trunk/fs/nilfs2/inode.c @@ -34,13 +34,6 @@ #include "cpfile.h" #include "ifile.h" -/** - * struct nilfs_iget_args - arguments used during comparison between inodes - * @ino: inode number - * @cno: checkpoint number - * @root: pointer on NILFS root object (mounted checkpoint) - * @for_gc: inode for GC flag - */ struct nilfs_iget_args { u64 ino; __u64 cno; diff --git a/trunk/fs/nilfs2/ioctl.c b/trunk/fs/nilfs2/ioctl.c index 0b6387c67e6c..06658caa18bd 100644 --- a/trunk/fs/nilfs2/ioctl.c +++ b/trunk/fs/nilfs2/ioctl.c @@ -182,7 +182,7 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp, if (copy_from_user(&cpmode, argp, sizeof(cpmode))) goto out; - mutex_lock(&nilfs->ns_snapshot_mount_mutex); + down_read(&inode->i_sb->s_umount); nilfs_transaction_begin(inode->i_sb, &ti, 0); ret = nilfs_cpfile_change_cpmode( @@ -192,7 +192,7 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp, else nilfs_transaction_commit(inode->i_sb); /* never fails */ - mutex_unlock(&nilfs->ns_snapshot_mount_mutex); + up_read(&inode->i_sb->s_umount); out: mnt_drop_write_file(filp); return ret; diff --git a/trunk/fs/nilfs2/mdt.h b/trunk/fs/nilfs2/mdt.h index ab172e8549c5..ab20a4baa50f 100644 --- a/trunk/fs/nilfs2/mdt.h +++ b/trunk/fs/nilfs2/mdt.h @@ -28,13 +28,6 @@ #include "nilfs.h" #include "page.h" -/** - * struct nilfs_shadow_map - shadow mapping of meta data file - * @bmap_store: shadow copy of bmap state - * @frozen_data: shadowed dirty data pages - * @frozen_btnodes: shadowed dirty b-tree nodes' pages - * @frozen_buffers: list of frozen buffers - */ struct nilfs_shadow_map { struct nilfs_bmap_store bmap_store; struct address_space frozen_data; diff --git a/trunk/fs/nilfs2/nilfs.h b/trunk/fs/nilfs2/nilfs.h index 74cece80e9a3..250add84da76 100644 --- a/trunk/fs/nilfs2/nilfs.h +++ b/trunk/fs/nilfs2/nilfs.h @@ -32,21 +32,8 @@ #include "the_nilfs.h" #include "bmap.h" -/** - * struct nilfs_inode_info - nilfs inode data in memory - * @i_flags: inode flags - * @i_state: dynamic state flags - * @i_bmap: pointer on i_bmap_data - * @i_bmap_data: raw block mapping - * @i_xattr: - * @i_dir_start_lookup: page index of last successful search - * @i_cno: checkpoint number for GC inode - * @i_btnode_cache: cached pages of b-tree nodes - * @i_dirty: list for connecting dirty files - * @xattr_sem: semaphore for extended attributes processing - * @i_bh: buffer contains disk inode - * @i_root: root object of the current filesystem tree - * @vfs_inode: VFS inode object +/* + * nilfs inode data in memory */ struct nilfs_inode_info { __u32 i_flags; diff --git a/trunk/fs/nilfs2/sufile.c b/trunk/fs/nilfs2/sufile.c index 3127e9f438a7..c5b7653a4391 100644 --- a/trunk/fs/nilfs2/sufile.c +++ b/trunk/fs/nilfs2/sufile.c @@ -30,13 +30,7 @@ #include "mdt.h" #include "sufile.h" -/** - * struct nilfs_sufile_info - on-memory private data of sufile - * @mi: on-memory private data of metadata file - * @ncleansegs: number of clean segments - * @allocmin: lower limit of allocatable segment range - * @allocmax: upper limit of allocatable segment range - */ + struct nilfs_sufile_info { struct nilfs_mdt_info mi; unsigned long ncleansegs;/* number of clean segments */ diff --git a/trunk/fs/nilfs2/super.c b/trunk/fs/nilfs2/super.c index 6522cac6057c..d57c42f974ea 100644 --- a/trunk/fs/nilfs2/super.c +++ b/trunk/fs/nilfs2/super.c @@ -677,6 +677,7 @@ static const struct super_operations nilfs_sops = { .destroy_inode = nilfs_destroy_inode, .dirty_inode = nilfs_dirty_inode, /* .write_inode = nilfs_write_inode, */ + /* .put_inode = nilfs_put_inode, */ /* .drop_inode = nilfs_drop_inode, */ .evict_inode = nilfs_evict_inode, .put_super = nilfs_put_super, @@ -684,6 +685,8 @@ static const struct super_operations nilfs_sops = { .sync_fs = nilfs_sync_fs, .freeze_fs = nilfs_freeze, .unfreeze_fs = nilfs_unfreeze, + /* .write_super_lockfs */ + /* .unlockfs */ .statfs = nilfs_statfs, .remount_fs = nilfs_remount, /* .umount_begin */ @@ -945,8 +948,6 @@ static int nilfs_attach_snapshot(struct super_block *s, __u64 cno, struct nilfs_root *root; int ret; - mutex_lock(&nilfs->ns_snapshot_mount_mutex); - down_read(&nilfs->ns_segctor_sem); ret = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile, cno); up_read(&nilfs->ns_segctor_sem); @@ -971,7 +972,6 @@ static int nilfs_attach_snapshot(struct super_block *s, __u64 cno, ret = nilfs_get_root_dentry(s, root, root_dentry); nilfs_put_root(root); out: - mutex_unlock(&nilfs->ns_snapshot_mount_mutex); return ret; } diff --git a/trunk/fs/nilfs2/the_nilfs.c b/trunk/fs/nilfs2/the_nilfs.c index 41e6a04a561f..501b7f8b739f 100644 --- a/trunk/fs/nilfs2/the_nilfs.c +++ b/trunk/fs/nilfs2/the_nilfs.c @@ -76,7 +76,6 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev) nilfs->ns_bdev = bdev; atomic_set(&nilfs->ns_ndirtyblks, 0); init_rwsem(&nilfs->ns_sem); - mutex_init(&nilfs->ns_snapshot_mount_mutex); INIT_LIST_HEAD(&nilfs->ns_dirty_files); INIT_LIST_HEAD(&nilfs->ns_gc_inodes); spin_lock_init(&nilfs->ns_inode_lock); diff --git a/trunk/fs/nilfs2/the_nilfs.h b/trunk/fs/nilfs2/the_nilfs.h index 6eee4177807b..9992b11312ff 100644 --- a/trunk/fs/nilfs2/the_nilfs.h +++ b/trunk/fs/nilfs2/the_nilfs.h @@ -47,13 +47,11 @@ enum { * @ns_flags: flags * @ns_bdev: block device * @ns_sem: semaphore for shared states - * @ns_snapshot_mount_mutex: mutex to protect snapshot mounts * @ns_sbh: buffer heads of on-disk super blocks * @ns_sbp: pointers to super block data * @ns_sbwtime: previous write time of super block * @ns_sbwcount: write count of super block * @ns_sbsize: size of valid data in super block - * @ns_mount_state: file system state * @ns_seg_seq: segment sequence counter * @ns_segnum: index number of the latest full segment. * @ns_nextnum: index number of the full segment index to be used next @@ -101,7 +99,6 @@ struct the_nilfs { struct block_device *ns_bdev; struct rw_semaphore ns_sem; - struct mutex ns_snapshot_mount_mutex; /* * used for @@ -232,8 +229,9 @@ THE_NILFS_FNS(SB_DIRTY, sb_dirty) * @count: refcount of this structure * @nilfs: nilfs object * @ifile: inode file + * @root: root inode * @inodes_count: number of inodes - * @blocks_count: number of blocks + * @blocks_count: number of blocks (Reserved) */ struct nilfs_root { __u64 cno; diff --git a/trunk/fs/ntfs/super.c b/trunk/fs/ntfs/super.c index 2bc149d6a784..b341492542ca 100644 --- a/trunk/fs/ntfs/super.c +++ b/trunk/fs/ntfs/super.c @@ -2660,14 +2660,31 @@ static const struct super_operations ntfs_sops = { .alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */ .destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */ #ifdef NTFS_RW + //.dirty_inode = NULL, /* VFS: Called from + // __mark_inode_dirty(). */ .write_inode = ntfs_write_inode, /* VFS: Write dirty inode to disk. */ + //.drop_inode = NULL, /* VFS: Called just after the + // inode reference count has + // been decreased to zero. + // NOTE: The inode lock is + // held. See fs/inode.c:: + // generic_drop_inode(). */ + //.delete_inode = NULL, /* VFS: Delete inode from disk. + // Called when i_count becomes + // 0 and i_nlink is also 0. */ + //.write_super = NULL, /* Flush dirty super block to + // disk. */ + //.sync_fs = NULL, /* ? */ + //.write_super_lockfs = NULL, /* ? */ + //.unlockfs = NULL, /* ? */ #endif /* NTFS_RW */ .put_super = ntfs_put_super, /* Syscall: umount. */ .statfs = ntfs_statfs, /* Syscall: statfs */ .remount_fs = ntfs_remount, /* Syscall: mount -o remount. */ .evict_inode = ntfs_evict_big_inode, /* VFS: Called when an inode is removed from memory. */ + //.umount_begin = NULL, /* Forced umount. */ .show_options = ntfs_show_options, /* Show mount options in proc. */ }; diff --git a/trunk/fs/ocfs2/localalloc.c b/trunk/fs/ocfs2/localalloc.c index a9f78c74d687..210c35237548 100644 --- a/trunk/fs/ocfs2/localalloc.c +++ b/trunk/fs/ocfs2/localalloc.c @@ -784,10 +784,14 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc) { - u32 count; + int i; + u8 *buffer; + u32 count = 0; struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc); - count = memweight(la->la_bitmap, le16_to_cpu(la->la_size)); + buffer = la->la_bitmap; + for (i = 0; i < le16_to_cpu(la->la_size); i++) + count += hweight8(buffer[i]); trace_ocfs2_local_alloc_count_bits(count); return count; diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 1b6c84cbdb73..2772208338f8 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -695,6 +695,8 @@ static int __mem_open(struct inode *inode, struct file *file, unsigned int mode) mmput(mm); } + /* OK to pass negative loff_t, we can catch out-of-range */ + file->f_mode |= FMODE_UNSIGNED_OFFSET; file->private_data = mm; return 0; @@ -702,12 +704,7 @@ static int __mem_open(struct inode *inode, struct file *file, unsigned int mode) static int mem_open(struct inode *inode, struct file *file) { - int ret = __mem_open(inode, file, PTRACE_MODE_ATTACH); - - /* OK to pass negative loff_t, we can catch out-of-range */ - file->f_mode |= FMODE_UNSIGNED_OFFSET; - - return ret; + return __mem_open(inode, file, PTRACE_MODE_ATTACH); } static ssize_t mem_rw(struct file *file, char __user *buf, @@ -830,16 +827,15 @@ static ssize_t environ_read(struct file *file, char __user *buf, if (!atomic_inc_not_zero(&mm->mm_users)) goto free; while (count > 0) { - size_t this_len, max_len; - int retval; - - if (src >= (mm->env_end - mm->env_start)) - break; + int this_len, retval, max_len; this_len = mm->env_end - (mm->env_start + src); - max_len = min_t(size_t, PAGE_SIZE, count); - this_len = min(max_len, this_len); + if (this_len <= 0) + break; + + max_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; + this_len = (this_len > max_len) ? max_len : this_len; retval = access_remote_vm(mm, (mm->env_start + src), page, this_len, 0); diff --git a/trunk/fs/qnx4/bitmap.c b/trunk/fs/qnx4/bitmap.c index 76a7a697b778..22e0d60e53ef 100644 --- a/trunk/fs/qnx4/bitmap.c +++ b/trunk/fs/qnx4/bitmap.c @@ -17,6 +17,23 @@ #include #include "qnx4.h" +static void count_bits(register const char *bmPart, register int size, + int *const tf) +{ + char b; + int tot = *tf; + + if (size > QNX4_BLOCK_SIZE) { + size = QNX4_BLOCK_SIZE; + } + do { + b = *bmPart++; + tot += 8 - hweight8(b); + size--; + } while (size != 0); + *tf = tot; +} + unsigned long qnx4_count_free_blocks(struct super_block *sb) { int start = le32_to_cpu(qnx4_sb(sb)->BitMap->di_first_xtnt.xtnt_blk) - 1; @@ -27,16 +44,13 @@ unsigned long qnx4_count_free_blocks(struct super_block *sb) struct buffer_head *bh; while (total < size) { - int bytes = min(size - total, QNX4_BLOCK_SIZE); - if ((bh = sb_bread(sb, start + offset)) == NULL) { printk(KERN_ERR "qnx4: I/O error in counting free blocks\n"); break; } - total_free += bytes * BITS_PER_BYTE - - memweight(bh->b_data, bytes); + count_bits(bh->b_data, size - total, &total_free); brelse(bh); - total += bytes; + total += QNX4_BLOCK_SIZE; offset++; } diff --git a/trunk/fs/xattr.c b/trunk/fs/xattr.c index 4d45b7189e7e..1d7ac3790458 100644 --- a/trunk/fs/xattr.c +++ b/trunk/fs/xattr.c @@ -427,7 +427,6 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, { ssize_t error; void *kvalue = NULL; - void *vvalue = NULL; char kname[XATTR_NAME_MAX + 1]; error = strncpy_from_user(kname, name, sizeof(kname)); @@ -439,13 +438,9 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, if (size) { if (size > XATTR_SIZE_MAX) size = XATTR_SIZE_MAX; - kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); - if (!kvalue) { - vvalue = vmalloc(size); - if (!vvalue) - return -ENOMEM; - kvalue = vvalue; - } + kvalue = kzalloc(size, GFP_KERNEL); + if (!kvalue) + return -ENOMEM; } error = vfs_getxattr(d, kname, kvalue, size); @@ -457,10 +452,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, than XATTR_SIZE_MAX bytes. Not possible. */ error = -E2BIG; } - if (vvalue) - vfree(vvalue); - else - kfree(kvalue); + kfree(kvalue); return error; } diff --git a/trunk/include/asm-generic/fcntl.h b/trunk/include/asm-generic/fcntl.h index a48937d4a5ea..9e5b0356e2bb 100644 --- a/trunk/include/asm-generic/fcntl.h +++ b/trunk/include/asm-generic/fcntl.h @@ -120,10 +120,6 @@ #define F_GETOWN_EX 16 #endif -#ifndef F_GETOWNER_UIDS -#define F_GETOWNER_UIDS 17 -#endif - #define F_OWNER_TID 0 #define F_OWNER_PID 1 #define F_OWNER_PGRP 2 diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index d9a754474878..9547daddf813 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -386,7 +386,6 @@ header-y += utime.h header-y += utsname.h header-y += uuid.h header-y += uvcvideo.h -header-y += v4l2-common.h header-y += v4l2-dv-timings.h header-y += v4l2-mediabus.h header-y += v4l2-subdev.h diff --git a/trunk/include/linux/aio.h b/trunk/include/linux/aio.h index 31ff6dba4872..b1a520ec8b59 100644 --- a/trunk/include/linux/aio.h +++ b/trunk/include/linux/aio.h @@ -126,20 +126,22 @@ struct kiocb { struct eventfd_ctx *ki_eventfd; }; -static inline bool is_sync_kiocb(struct kiocb *kiocb) -{ - return kiocb->ki_key == KIOCB_SYNC_KEY; -} - -static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) -{ - *kiocb = (struct kiocb) { - .ki_users = 1, - .ki_key = KIOCB_SYNC_KEY, - .ki_filp = filp, - .ki_obj.tsk = current, - }; -} +#define is_sync_kiocb(iocb) ((iocb)->ki_key == KIOCB_SYNC_KEY) +#define init_sync_kiocb(x, filp) \ + do { \ + struct task_struct *tsk = current; \ + (x)->ki_flags = 0; \ + (x)->ki_users = 1; \ + (x)->ki_key = KIOCB_SYNC_KEY; \ + (x)->ki_filp = (filp); \ + (x)->ki_ctx = NULL; \ + (x)->ki_cancel = NULL; \ + (x)->ki_retry = NULL; \ + (x)->ki_dtor = NULL; \ + (x)->ki_obj.tsk = tsk; \ + (x)->ki_user_data = 0; \ + (x)->private = NULL; \ + } while (0) #define AIO_RING_MAGIC 0xa10a10a1 #define AIO_RING_COMPAT_FEATURES 1 @@ -159,6 +161,8 @@ struct aio_ring { struct io_event io_events[0]; }; /* 128 bytes + ring size */ +#define aio_ring_avail(info, ring) (((ring)->head + (info)->nr - 1 - (ring)->tail) % (info)->nr) + #define AIO_RING_PAGES 8 struct aio_ring_info { unsigned long mmap_base; @@ -173,12 +177,6 @@ struct aio_ring_info { struct page *internal_pages[AIO_RING_PAGES]; }; -static inline unsigned aio_ring_avail(struct aio_ring_info *info, - struct aio_ring *ring) -{ - return (ring->head + info->nr - 1 - ring->tail) % info->nr; -} - struct kioctx { atomic_t users; int dead; diff --git a/trunk/include/linux/clk.h b/trunk/include/linux/clk.h index b3ac22d0fc1f..2fd6a4234531 100644 --- a/trunk/include/linux/clk.h +++ b/trunk/include/linux/clk.h @@ -84,43 +84,6 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb); #endif -/** - * clk_prepare - prepare a clock source - * @clk: clock source - * - * This prepares the clock source for use. - * - * Must not be called from within atomic context. - */ -#ifdef CONFIG_HAVE_CLK_PREPARE -int clk_prepare(struct clk *clk); -#else -static inline int clk_prepare(struct clk *clk) -{ - might_sleep(); - return 0; -} -#endif - -/** - * clk_unprepare - undo preparation of a clock source - * @clk: clock source - * - * This undoes a previously prepared clock. The caller must balance - * the number of prepare and unprepare calls. - * - * Must not be called from within atomic context. - */ -#ifdef CONFIG_HAVE_CLK_PREPARE -void clk_unprepare(struct clk *clk); -#else -static inline void clk_unprepare(struct clk *clk) -{ - might_sleep(); -} -#endif - -#ifdef CONFIG_HAVE_CLK /** * clk_get - lookup and obtain a reference to a clock producer. * @dev: device for clock "consumer" @@ -158,6 +121,24 @@ struct clk *clk_get(struct device *dev, const char *id); */ struct clk *devm_clk_get(struct device *dev, const char *id); +/** + * clk_prepare - prepare a clock source + * @clk: clock source + * + * This prepares the clock source for use. + * + * Must not be called from within atomic context. + */ +#ifdef CONFIG_HAVE_CLK_PREPARE +int clk_prepare(struct clk *clk); +#else +static inline int clk_prepare(struct clk *clk) +{ + might_sleep(); + return 0; +} +#endif + /** * clk_enable - inform the system when the clock source should be running. * @clk: clock source @@ -186,6 +167,47 @@ int clk_enable(struct clk *clk); */ void clk_disable(struct clk *clk); + +/** + * clk_unprepare - undo preparation of a clock source + * @clk: clock source + * + * This undoes a previously prepared clock. The caller must balance + * the number of prepare and unprepare calls. + * + * Must not be called from within atomic context. + */ +#ifdef CONFIG_HAVE_CLK_PREPARE +void clk_unprepare(struct clk *clk); +#else +static inline void clk_unprepare(struct clk *clk) +{ + might_sleep(); +} +#endif + +/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ +static inline int clk_prepare_enable(struct clk *clk) +{ + int ret; + + ret = clk_prepare(clk); + if (ret) + return ret; + ret = clk_enable(clk); + if (ret) + clk_unprepare(clk); + + return ret; +} + +/* clk_disable_unprepare helps cases using clk_disable in non-atomic context. */ +static inline void clk_disable_unprepare(struct clk *clk) +{ + clk_disable(clk); + clk_unprepare(clk); +} + /** * clk_get_rate - obtain the current clock rate (in Hz) for a clock source. * This is only valid once the clock source has been enabled. @@ -276,78 +298,6 @@ struct clk *clk_get_parent(struct clk *clk); */ struct clk *clk_get_sys(const char *dev_id, const char *con_id); -#else /* !CONFIG_HAVE_CLK */ - -static inline struct clk *clk_get(struct device *dev, const char *id) -{ - return NULL; -} - -static inline struct clk *devm_clk_get(struct device *dev, const char *id) -{ - return NULL; -} - -static inline void clk_put(struct clk *clk) {} - -static inline void devm_clk_put(struct device *dev, struct clk *clk) {} - -static inline int clk_enable(struct clk *clk) -{ - return 0; -} - -static inline void clk_disable(struct clk *clk) {} - -static inline unsigned long clk_get_rate(struct clk *clk) -{ - return 0; -} - -static inline int clk_set_rate(struct clk *clk, unsigned long rate) -{ - return 0; -} - -static inline long clk_round_rate(struct clk *clk, unsigned long rate) -{ - return 0; -} - -static inline int clk_set_parent(struct clk *clk, struct clk *parent) -{ - return 0; -} - -static inline struct clk *clk_get_parent(struct clk *clk) -{ - return NULL; -} - -#endif - -/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ -static inline int clk_prepare_enable(struct clk *clk) -{ - int ret; - - ret = clk_prepare(clk); - if (ret) - return ret; - ret = clk_enable(clk); - if (ret) - clk_unprepare(clk); - - return ret; -} - -/* clk_disable_unprepare helps cases using clk_disable in non-atomic context. */ -static inline void clk_disable_unprepare(struct clk *clk) -{ - clk_disable(clk); - clk_unprepare(clk); -} - /** * clk_add_alias - add a new clock alias * @alias: name for clock alias diff --git a/trunk/include/linux/compat.h b/trunk/include/linux/compat.h index 09b28b7369d7..4e890394ef99 100644 --- a/trunk/include/linux/compat.h +++ b/trunk/include/linux/compat.h @@ -265,9 +265,9 @@ long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, #else long compat_sys_semctl(int semid, int semnum, int cmd, int arg); long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp, - compat_ssize_t msgsz, int msgflg); + size_t msgsz, int msgflg); long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp, - compat_ssize_t msgsz, long msgtyp, int msgflg); + size_t msgsz, long msgtyp, int msgflg); long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg); #endif long compat_sys_msgctl(int first, int second, void __user *uptr); diff --git a/trunk/include/linux/i2c.h b/trunk/include/linux/i2c.h index 5970266930a2..1d0fe4877b1f 100644 --- a/trunk/include/linux/i2c.h +++ b/trunk/include/linux/i2c.h @@ -68,9 +68,6 @@ extern int i2c_master_recv(const struct i2c_client *client, char *buf, */ extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); -/* Unlocked flavor */ -extern int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, - int num); /* This is the very generalized SMBus access routine. You probably do not want to use this, though; one of the functions below may be much easier, diff --git a/trunk/include/linux/kern_levels.h b/trunk/include/linux/kern_levels.h deleted file mode 100644 index 866caaa9e2bb..000000000000 --- a/trunk/include/linux/kern_levels.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __KERN_LEVELS_H__ -#define __KERN_LEVELS_H__ - -#define KERN_SOH "\001" /* ASCII Start Of Header */ -#define KERN_SOH_ASCII '\001' - -#define KERN_EMERG KERN_SOH "0" /* system is unusable */ -#define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */ -#define KERN_CRIT KERN_SOH "2" /* critical conditions */ -#define KERN_ERR KERN_SOH "3" /* error conditions */ -#define KERN_WARNING KERN_SOH "4" /* warning conditions */ -#define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */ -#define KERN_INFO KERN_SOH "6" /* informational */ -#define KERN_DEBUG KERN_SOH "7" /* debug-level messages */ - -#define KERN_DEFAULT KERN_SOH "d" /* the default kernel loglevel */ - -/* - * Annotation for a "continued" line of log printout (only done after a - * line that had no enclosing \n). Only to be used by core/arch code - * during early bootup (a continued line is not SMP-safe otherwise). - */ -#define KERN_CONT "" - -#endif diff --git a/trunk/include/linux/platform_data/lp855x.h b/trunk/include/linux/lp855x.h similarity index 96% rename from trunk/include/linux/platform_data/lp855x.h rename to trunk/include/linux/lp855x.h index cc76f1f18f18..781a490a451b 100644 --- a/trunk/include/linux/platform_data/lp855x.h +++ b/trunk/include/linux/lp855x.h @@ -47,6 +47,12 @@ (LP8556_I2C_ONLY << BRT_MODE_SHFT)) #define LP8556_COMB2_CONFIG (LP8556_COMBINED2 << BRT_MODE_SHFT) +/* ROM area boundary */ +#define EEPROM_START (0xA0) +#define EEPROM_END (0xA7) +#define EPROM_START (0xA0) +#define EPROM_END (0xAF) + enum lp855x_chip_id { LP8550, LP8551, diff --git a/trunk/include/linux/nilfs2_fs.h b/trunk/include/linux/nilfs2_fs.h index 98755767c7b0..89bd4a4dcfb4 100644 --- a/trunk/include/linux/nilfs2_fs.h +++ b/trunk/include/linux/nilfs2_fs.h @@ -293,7 +293,7 @@ struct nilfs_dir_entry { __le64 inode; /* Inode number */ __le16 rec_len; /* Directory entry length */ __u8 name_len; /* Name length */ - __u8 file_type; /* Dir entry type (file, dir, etc) */ + __u8 file_type; char name[NILFS_NAME_LEN]; /* File name */ char pad; }; @@ -395,7 +395,7 @@ union nilfs_binfo { }; /** - * struct nilfs_segment_summary - segment summary header + * struct nilfs_segment_summary - segment summary * @ss_datasum: checksum of data * @ss_sumsum: checksum of segment summary * @ss_magic: magic number @@ -683,9 +683,9 @@ struct nilfs_sufile_header { /** * nilfs_suinfo - segment usage information - * @sui_lastmod: timestamp of last modification - * @sui_nblocks: number of written blocks in segment - * @sui_flags: segment usage flags + * @sui_lastmod: + * @sui_nblocks: + * @sui_flags: */ struct nilfs_suinfo { __u64 sui_lastmod; @@ -716,10 +716,9 @@ enum { }; /** - * struct nilfs_cpmode - change checkpoint mode structure - * @cm_cno: checkpoint number - * @cm_mode: mode of checkpoint - * @cm_pad: padding + * struct nilfs_cpmode - + * @cc_cno: + * @cc_mode: */ struct nilfs_cpmode { __u64 cm_cno; @@ -729,11 +728,11 @@ struct nilfs_cpmode { /** * struct nilfs_argv - argument vector - * @v_base: pointer on data array from userspace - * @v_nmembs: number of members in data array - * @v_size: size of data array in bytes - * @v_flags: flags - * @v_index: start number of target data items + * @v_base: + * @v_nmembs: + * @v_size: + * @v_flags: + * @v_index: */ struct nilfs_argv { __u64 v_base; @@ -744,9 +743,9 @@ struct nilfs_argv { }; /** - * struct nilfs_period - period of checkpoint numbers - * @p_start: start checkpoint number (inclusive) - * @p_end: end checkpoint number (exclusive) + * struct nilfs_period - + * @p_start: + * @p_end: */ struct nilfs_period { __u64 p_start; @@ -754,7 +753,7 @@ struct nilfs_period { }; /** - * struct nilfs_cpstat - checkpoint statistics + * struct nilfs_cpstat - * @cs_cno: checkpoint number * @cs_ncps: number of checkpoints * @cs_nsss: number of snapshots @@ -766,7 +765,7 @@ struct nilfs_cpstat { }; /** - * struct nilfs_sustat - segment usage statistics + * struct nilfs_sustat - * @ss_nsegs: number of segments * @ss_ncleansegs: number of clean segments * @ss_ndirtysegs: number of dirty segments @@ -785,10 +784,10 @@ struct nilfs_sustat { /** * struct nilfs_vinfo - virtual block number information - * @vi_vblocknr: virtual block number - * @vi_start: start checkpoint number (inclusive) - * @vi_end: end checkpoint number (exclusive) - * @vi_blocknr: disk block number + * @vi_vblocknr: + * @vi_start: + * @vi_end: + * @vi_blocknr: */ struct nilfs_vinfo { __u64 vi_vblocknr; @@ -798,15 +797,7 @@ struct nilfs_vinfo { }; /** - * struct nilfs_vdesc - descriptor of virtual block number - * @vd_ino: inode number - * @vd_cno: checkpoint number - * @vd_vblocknr: virtual block number - * @vd_period: period of checkpoint numbers - * @vd_blocknr: disk block number - * @vd_offset: logical block offset inside a file - * @vd_flags: flags (data or node block) - * @vd_pad: padding + * struct nilfs_vdesc - */ struct nilfs_vdesc { __u64 vd_ino; @@ -820,13 +811,7 @@ struct nilfs_vdesc { }; /** - * struct nilfs_bdesc - descriptor of disk block number - * @bd_ino: inode number - * @bd_oblocknr: disk block address (for skipping dead blocks) - * @bd_blocknr: disk block address - * @bd_offset: logical block offset inside a file - * @bd_level: level in the b-tree organization - * @bd_pad: padding + * struct nilfs_bdesc - */ struct nilfs_bdesc { __u64 bd_ino; diff --git a/trunk/include/linux/platform_data/mv_usb.h b/trunk/include/linux/platform_data/mv_usb.h index 944b01dd103e..d94804aca764 100644 --- a/trunk/include/linux/platform_data/mv_usb.h +++ b/trunk/include/linux/platform_data/mv_usb.h @@ -52,4 +52,13 @@ struct mv_usb_platform_data { int (*set_vbus)(unsigned int vbus); int (*private_init)(void __iomem *opregs, void __iomem *phyregs); }; + +#ifndef CONFIG_HAVE_CLK +/* Dummy stub for clk framework */ +#define clk_get(dev, id) NULL +#define clk_put(clock) do {} while (0) +#define clk_enable(clock) do {} while (0) +#define clk_disable(clock) do {} while (0) +#endif + #endif diff --git a/trunk/include/linux/printk.h b/trunk/include/linux/printk.h index 9afc01e5a0a6..1bec2f7a2d42 100644 --- a/trunk/include/linux/printk.h +++ b/trunk/include/linux/printk.h @@ -2,34 +2,27 @@ #define __KERNEL_PRINTK__ #include -#include extern const char linux_banner[]; extern const char linux_proc_banner[]; -static inline int printk_get_level(const char *buffer) -{ - if (buffer[0] == KERN_SOH_ASCII && buffer[1]) { - switch (buffer[1]) { - case '0' ... '7': - case 'd': /* KERN_DEFAULT */ - return buffer[1]; - } - } - return 0; -} - -static inline const char *printk_skip_level(const char *buffer) -{ - if (printk_get_level(buffer)) { - switch (buffer[1]) { - case '0' ... '7': - case 'd': /* KERN_DEFAULT */ - return buffer + 2; - } - } - return buffer; -} +#define KERN_EMERG "<0>" /* system is unusable */ +#define KERN_ALERT "<1>" /* action must be taken immediately */ +#define KERN_CRIT "<2>" /* critical conditions */ +#define KERN_ERR "<3>" /* error conditions */ +#define KERN_WARNING "<4>" /* warning conditions */ +#define KERN_NOTICE "<5>" /* normal but significant condition */ +#define KERN_INFO "<6>" /* informational */ +#define KERN_DEBUG "<7>" /* debug-level messages */ + +/* Use the default kernel loglevel */ +#define KERN_DEFAULT "" +/* + * Annotation for a "continued" line of log printout (only done after a + * line that had no enclosing \n). Only to be used by core/arch code + * during early bootup (a continued line is not SMP-safe otherwise). + */ +#define KERN_CONT "" extern int console_printk[]; diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 68dcffaa62a0..a721cef7e2d4 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -334,14 +334,6 @@ static inline void lockup_detector_init(void) } #endif -#if defined(CONFIG_LOCKUP_DETECTOR) && defined(CONFIG_SUSPEND) -void lockup_detector_bootcpu_resume(void); -#else -static inline void lockup_detector_bootcpu_resume(void) -{ -} -#endif - #ifdef CONFIG_DETECT_HUNG_TASK extern unsigned int sysctl_hung_task_panic; extern unsigned long sysctl_hung_task_check_count; @@ -414,11 +406,6 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) {} extern void set_dumpable(struct mm_struct *mm, int value); extern int get_dumpable(struct mm_struct *mm); -/* get/set_dumpable() values */ -#define SUID_DUMPABLE_DISABLED 0 -#define SUID_DUMPABLE_ENABLED 1 -#define SUID_DUMPABLE_SAFE 2 - /* mm flags */ /* dumpable bits */ #define MMF_DUMPABLE 0 /* core dump is permitted */ diff --git a/trunk/include/linux/shm.h b/trunk/include/linux/shm.h index edd086883ccb..92808b86703b 100644 --- a/trunk/include/linux/shm.h +++ b/trunk/include/linux/shm.h @@ -107,14 +107,12 @@ struct shmid_kernel /* private to the kernel */ #define SHM_NORESERVE 010000 /* don't check for reservations */ #ifdef CONFIG_SYSVIPC -long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr, - unsigned long shmlba); +long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr); extern int is_file_shm_hugepages(struct file *file); extern void exit_shm(struct task_struct *task); #else static inline long do_shmat(int shmid, char __user *shmaddr, - int shmflg, unsigned long *addr, - unsigned long shmlba) + int shmflg, unsigned long *addr) { return -ENOSYS; } diff --git a/trunk/include/linux/string.h b/trunk/include/linux/string.h index ffe0442e18d2..e033564f10ba 100644 --- a/trunk/include/linux/string.h +++ b/trunk/include/linux/string.h @@ -145,7 +145,4 @@ static inline bool strstarts(const char *str, const char *prefix) return strncmp(str, prefix, strlen(prefix)) == 0; } #endif - -extern size_t memweight(const void *ptr, size_t bytes); - #endif /* _LINUX_STRING_H_ */ diff --git a/trunk/include/linux/uvcvideo.h b/trunk/include/linux/uvcvideo.h index 3b081862b9e8..f46a53f060d7 100644 --- a/trunk/include/linux/uvcvideo.h +++ b/trunk/include/linux/uvcvideo.h @@ -58,8 +58,7 @@ struct uvc_xu_control_mapping { struct uvc_xu_control_query { __u8 unit; __u8 selector; - __u8 query; /* Video Class-Specific Request Code, */ - /* defined in linux/usb/video.h A.8. */ + __u8 query; __u16 size; __u8 __user *data; }; diff --git a/trunk/include/linux/v4l2-common.h b/trunk/include/linux/v4l2-common.h deleted file mode 100644 index 0fa8b64c3cdb..000000000000 --- a/trunk/include/linux/v4l2-common.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * include/linux/v4l2-common.h - * - * Common V4L2 and V4L2 subdev definitions. - * - * Users are advised to #include this file either through videodev2.h - * (V4L2) or through v4l2-subdev.h (V4L2 subdev) rather than to refer - * to this file directly. - * - * Copyright (C) 2012 Nokia Corporation - * Contact: Sakari Ailus - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __V4L2_COMMON__ -#define __V4L2_COMMON__ - -/* - * - * Selection interface definitions - * - */ - -/* Current cropping area */ -#define V4L2_SEL_TGT_CROP 0x0000 -/* Default cropping area */ -#define V4L2_SEL_TGT_CROP_DEFAULT 0x0001 -/* Cropping bounds */ -#define V4L2_SEL_TGT_CROP_BOUNDS 0x0002 -/* Current composing area */ -#define V4L2_SEL_TGT_COMPOSE 0x0100 -/* Default composing area */ -#define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101 -/* Composing bounds */ -#define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102 -/* Current composing area plus all padding pixels */ -#define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103 - -/* Backward compatibility target definitions --- to be removed. */ -#define V4L2_SEL_TGT_CROP_ACTIVE V4L2_SEL_TGT_CROP -#define V4L2_SEL_TGT_COMPOSE_ACTIVE V4L2_SEL_TGT_COMPOSE -#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL \ - V4L2_SEL_TGT_CROP -#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL \ - V4L2_SEL_TGT_COMPOSE - -/* Selection flags */ -#define V4L2_SEL_FLAG_GE (1 << 0) -#define V4L2_SEL_FLAG_LE (1 << 1) -#define V4L2_SEL_FLAG_KEEP_CONFIG (1 << 2) - -/* Backward compatibility flag definitions --- to be removed. */ -#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE V4L2_SEL_FLAG_GE -#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE V4L2_SEL_FLAG_LE -#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG V4L2_SEL_FLAG_KEEP_CONFIG - -#endif /* __V4L2_COMMON__ */ diff --git a/trunk/include/linux/v4l2-subdev.h b/trunk/include/linux/v4l2-subdev.h index 8c57ee9872bb..812019ee1e06 100644 --- a/trunk/include/linux/v4l2-subdev.h +++ b/trunk/include/linux/v4l2-subdev.h @@ -25,7 +25,6 @@ #include #include -#include #include /** @@ -124,14 +123,27 @@ struct v4l2_subdev_frame_interval_enum { __u32 reserved[9]; }; +#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE (1 << 0) +#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE (1 << 1) +#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG (1 << 2) + +/* active cropping area */ +#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL 0x0000 +/* cropping bounds */ +#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS 0x0002 +/* current composing area */ +#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL 0x0100 +/* composing bounds */ +#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS 0x0102 + + /** * struct v4l2_subdev_selection - selection info * * @which: either V4L2_SUBDEV_FORMAT_ACTIVE or V4L2_SUBDEV_FORMAT_TRY * @pad: pad number, as reported by the media API - * @target: Selection target, used to choose one of possible rectangles, - * defined in v4l2-common.h; V4L2_SEL_TGT_* . - * @flags: constraint flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*. + * @target: selection target, used to choose one of possible rectangles + * @flags: constraint flags * @r: coordinates of the selection window * @reserved: for future use, set to zero for now * diff --git a/trunk/include/linux/videodev2.h b/trunk/include/linux/videodev2.h index 5d78910f926c..2039c5d3292e 100644 --- a/trunk/include/linux/videodev2.h +++ b/trunk/include/linux/videodev2.h @@ -64,7 +64,6 @@ #include #include #include -#include /* * Common stuff for both V4L1 and V4L2 @@ -658,7 +657,7 @@ struct v4l2_buffer { struct v4l2_plane *planes; } m; __u32 length; - __u32 reserved2; + __u32 input; __u32 reserved; }; @@ -672,6 +671,7 @@ struct v4l2_buffer { /* Buffer is ready, but the data contained within is corrupted. */ #define V4L2_BUF_FLAG_ERROR 0x0040 #define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ +#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ #define V4L2_BUF_FLAG_PREPARED 0x0400 /* Buffer is prepared for queuing */ /* Cache handling flags */ #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800 @@ -761,12 +761,32 @@ struct v4l2_crop { struct v4l2_rect c; }; +/* Hints for adjustments of selection rectangle */ +#define V4L2_SEL_FLAG_GE 0x00000001 +#define V4L2_SEL_FLAG_LE 0x00000002 + +/* Selection targets */ + +/* Current cropping area */ +#define V4L2_SEL_TGT_CROP_ACTIVE 0x0000 +/* Default cropping area */ +#define V4L2_SEL_TGT_CROP_DEFAULT 0x0001 +/* Cropping bounds */ +#define V4L2_SEL_TGT_CROP_BOUNDS 0x0002 +/* Current composing area */ +#define V4L2_SEL_TGT_COMPOSE_ACTIVE 0x0100 +/* Default composing area */ +#define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101 +/* Composing bounds */ +#define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102 +/* Current composing area plus all padding pixels */ +#define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103 + /** * struct v4l2_selection - selection info * @type: buffer type (do not use *_MPLANE types) - * @target: Selection target, used to choose one of possible rectangles; - * defined in v4l2-common.h; V4L2_SEL_TGT_* . - * @flags: constraints flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*. + * @target: selection target, used to choose one of possible rectangles + * @flags: constraints flags * @r: coordinates of selection window * @reserved: for future use, rounds structure size to 64 bytes, set to zero * @@ -2019,8 +2039,6 @@ struct v4l2_modulator { /* Flags for the 'capability' field */ #define V4L2_TUNER_CAP_LOW 0x0001 #define V4L2_TUNER_CAP_NORM 0x0002 -#define V4L2_TUNER_CAP_HWSEEK_BOUNDED 0x0004 -#define V4L2_TUNER_CAP_HWSEEK_WRAP 0x0008 #define V4L2_TUNER_CAP_STEREO 0x0010 #define V4L2_TUNER_CAP_LANG2 0x0020 #define V4L2_TUNER_CAP_SAP 0x0020 diff --git a/trunk/include/media/adv7393.h b/trunk/include/media/adv7393.h deleted file mode 100644 index b28edf351842..000000000000 --- a/trunk/include/media/adv7393.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * ADV7393 header file - * - * Copyright (C) 2010-2012 ADVANSEE - http://www.advansee.com/ - * Benoît Thébaudeau - * - * Based on ADV7343 driver, - * - * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed .as is. WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef ADV7393_H -#define ADV7393_H - -#define ADV7393_COMPOSITE_ID (0) -#define ADV7393_COMPONENT_ID (1) -#define ADV7393_SVIDEO_ID (2) - -#endif /* End of #ifndef ADV7393_H */ diff --git a/trunk/include/media/gpio-ir-recv.h b/trunk/include/media/gpio-ir-recv.h index 0142736a59db..67797bf5d432 100644 --- a/trunk/include/media/gpio-ir-recv.h +++ b/trunk/include/media/gpio-ir-recv.h @@ -14,10 +14,8 @@ #define __GPIO_IR_RECV_H__ struct gpio_ir_recv_platform_data { - int gpio_nr; - bool active_low; - u64 allowed_protos; - const char *map_name; + int gpio_nr; + bool active_low; }; #endif /* __GPIO_IR_RECV_H__ */ diff --git a/trunk/include/media/mt9t001.h b/trunk/include/media/mt9t001.h index 03fd63edd133..e839a78bb9c5 100644 --- a/trunk/include/media/mt9t001.h +++ b/trunk/include/media/mt9t001.h @@ -3,7 +3,6 @@ struct mt9t001_platform_data { unsigned int clk_pol:1; - unsigned int ext_clk; }; #endif diff --git a/trunk/include/media/v4l2-chip-ident.h b/trunk/include/media/v4l2-chip-ident.h index 58f914a40b20..7395c815939d 100644 --- a/trunk/include/media/v4l2-chip-ident.h +++ b/trunk/include/media/v4l2-chip-ident.h @@ -180,9 +180,6 @@ enum { /* module adv7343: just ident 7343 */ V4L2_IDENT_ADV7343 = 7343, - /* module adv7393: just ident 7393 */ - V4L2_IDENT_ADV7393 = 7393, - /* module saa7706h: just ident 7706 */ V4L2_IDENT_SAA7706H = 7706, diff --git a/trunk/include/media/v4l2-dev.h b/trunk/include/media/v4l2-dev.h index 5c416cdc88d5..a056e6ee1b68 100644 --- a/trunk/include/media/v4l2-dev.h +++ b/trunk/include/media/v4l2-dev.h @@ -100,9 +100,6 @@ struct video_device /* Control handler associated with this device node. May be NULL. */ struct v4l2_ctrl_handler *ctrl_handler; - /* vb2_queue associated with this device node. May be NULL. */ - struct vb2_queue *queue; - /* Priority state. If NULL, then v4l2_dev->prio will be used. */ struct v4l2_prio_state *prio; diff --git a/trunk/include/media/v4l2-ioctl.h b/trunk/include/media/v4l2-ioctl.h index 19e93523c2d8..d8b76f7392f8 100644 --- a/trunk/include/media/v4l2-ioctl.h +++ b/trunk/include/media/v4l2-ioctl.h @@ -295,19 +295,28 @@ struct v4l2_ioctl_ops { #define V4L2_DEBUG_IOCTL 0x01 #define V4L2_DEBUG_IOCTL_ARG 0x02 +/* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */ +#define v4l_print_ioctl(name, cmd) \ + do { \ + printk(KERN_DEBUG "%s: ", name); \ + v4l_printk_ioctl(cmd); \ + } while (0) + +/* Use this macro in I2C drivers where 'client' is the struct i2c_client + pointer */ +#define v4l_i2c_print_ioctl(client, cmd) \ + do { \ + v4l_client_printk(KERN_DEBUG, client, ""); \ + v4l_printk_ioctl(cmd); \ + } while (0) + /* Video standard functions */ extern const char *v4l2_norm_to_name(v4l2_std_id id); extern void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod); extern int v4l2_video_std_construct(struct v4l2_standard *vs, int id, const char *name); -/* Prints the ioctl in a human-readable format. If prefix != NULL, - then do printk(KERN_DEBUG "%s: ", prefix) first. */ -extern void v4l_printk_ioctl(const char *prefix, unsigned int cmd); - -/* Internal use only: get the mutex (if any) that we need to lock for the - given command. */ -struct video_device; -extern struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd); +/* Prints the ioctl in a human-readable format */ +extern void v4l_printk_ioctl(unsigned int cmd); /* names for fancy debug output */ extern const char *v4l2_field_names[]; diff --git a/trunk/include/media/videobuf-core.h b/trunk/include/media/videobuf-core.h index 8c6e825940e5..90ed895e217d 100644 --- a/trunk/include/media/videobuf-core.h +++ b/trunk/include/media/videobuf-core.h @@ -72,6 +72,7 @@ struct videobuf_buffer { unsigned int height; unsigned int bytesperline; /* use only if != 0 */ unsigned long size; + unsigned int input; enum v4l2_field field; enum videobuf_state state; struct list_head stream; /* QBUF/DQBUF list */ @@ -141,6 +142,7 @@ struct videobuf_queue { wait_queue_head_t wait; /* wait if queue is empty */ enum v4l2_buf_type type; + unsigned int inputs; /* for V4L2_BUF_FLAG_INPUT */ unsigned int msize; enum v4l2_field field; enum v4l2_field last; /* for field=V4L2_FIELD_ALTERNATE */ diff --git a/trunk/include/media/videobuf2-core.h b/trunk/include/media/videobuf2-core.h index 8dd9b6cc296b..a15d1f1b319e 100644 --- a/trunk/include/media/videobuf2-core.h +++ b/trunk/include/media/videobuf2-core.h @@ -244,23 +244,12 @@ struct vb2_ops { void (*buf_queue)(struct vb2_buffer *vb); }; -struct v4l2_fh; - /** * struct vb2_queue - a videobuf queue * * @type: queue type (see V4L2_BUF_TYPE_* in linux/videodev2.h * @io_modes: supported io methods (see vb2_io_modes enum) * @io_flags: additional io flags (see vb2_fileio_flags enum) - * @lock: pointer to a mutex that protects the vb2_queue struct. The - * driver can set this to a mutex to let the v4l2 core serialize - * the queuing ioctls. If the driver wants to handle locking - * itself, then this should be set to NULL. This lock is not used - * by the videobuf2 core API. - * @owner: The filehandle that 'owns' the buffers, i.e. the filehandle - * that called reqbufs, create_buffers or started fileio. - * This field is not used by the videobuf2 core API, but it allows - * drivers to easily associate an owner filehandle with the queue. * @ops: driver-specific callbacks * @mem_ops: memory allocator specific callbacks * @drv_priv: driver private data @@ -284,8 +273,6 @@ struct vb2_queue { enum v4l2_buf_type type; unsigned int io_modes; unsigned int io_flags; - struct mutex *lock; - struct v4l2_fh *owner; const struct vb2_ops *ops; const struct vb2_mem_ops *mem_ops; @@ -417,45 +404,4 @@ vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no) return 0; } -/* - * The following functions are not part of the vb2 core API, but are simple - * helper functions that you can use in your struct v4l2_file_operations, - * struct v4l2_ioctl_ops and struct vb2_ops. They will serialize if vb2_queue->lock - * or video_device->lock is set, and they will set and test vb2_queue->owner - * to check if the calling filehandle is permitted to do the queuing operation. - */ - -/* struct v4l2_ioctl_ops helpers */ - -int vb2_ioctl_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *p); -int vb2_ioctl_create_bufs(struct file *file, void *priv, - struct v4l2_create_buffers *p); -int vb2_ioctl_prepare_buf(struct file *file, void *priv, - struct v4l2_buffer *p); -int vb2_ioctl_querybuf(struct file *file, void *priv, struct v4l2_buffer *p); -int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p); -int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p); -int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i); -int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i); - -/* struct v4l2_file_operations helpers */ - -int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma); -int vb2_fop_release(struct file *file); -ssize_t vb2_fop_write(struct file *file, char __user *buf, - size_t count, loff_t *ppos); -ssize_t vb2_fop_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos); -unsigned int vb2_fop_poll(struct file *file, poll_table *wait); -#ifndef CONFIG_MMU -unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags); -#endif - -/* struct vb2_ops helpers, only use if vq->lock is non-NULL. */ - -void vb2_ops_wait_prepare(struct vb2_queue *vq); -void vb2_ops_wait_finish(struct vb2_queue *vq); - #endif /* _MEDIA_VIDEOBUF2_CORE_H */ diff --git a/trunk/include/media/videobuf2-dma-contig.h b/trunk/include/media/videobuf2-dma-contig.h index 8197f87d6c61..19ae1e350567 100644 --- a/trunk/include/media/videobuf2-dma-contig.h +++ b/trunk/include/media/videobuf2-dma-contig.h @@ -1,5 +1,5 @@ /* - * videobuf2-dma-contig.h - DMA contig memory allocator for videobuf2 + * videobuf2-dma-coherent.h - DMA coherent memory allocator for videobuf2 * * Copyright (C) 2010 Samsung Electronics * @@ -10,8 +10,8 @@ * the Free Software Foundation. */ -#ifndef _MEDIA_VIDEOBUF2_DMA_CONTIG_H -#define _MEDIA_VIDEOBUF2_DMA_CONTIG_H +#ifndef _MEDIA_VIDEOBUF2_DMA_COHERENT_H +#define _MEDIA_VIDEOBUF2_DMA_COHERENT_H #include #include diff --git a/trunk/ipc/compat.c b/trunk/ipc/compat.c index ad9518eb26e0..a6df704f521e 100644 --- a/trunk/ipc/compat.c +++ b/trunk/ipc/compat.c @@ -118,7 +118,7 @@ extern int sem_ctls[]; static inline int compat_ipc_parse_version(int *cmd) { -#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION +#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC int version = *cmd & IPC_64; /* this is tricky: architectures that have support for the old @@ -373,21 +373,21 @@ long compat_sys_semctl(int semid, int semnum, int cmd, int arg) } long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp, - compat_ssize_t msgsz, int msgflg) + size_t msgsz, int msgflg) { compat_long_t mtype; if (get_user(mtype, &msgp->mtype)) return -EFAULT; - return do_msgsnd(msqid, mtype, msgp->mtext, (ssize_t)msgsz, msgflg); + return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); } long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp, - compat_ssize_t msgsz, long msgtyp, int msgflg) + size_t msgsz, long msgtyp, int msgflg) { long err, mtype; - err = do_msgrcv(msqid, &mtype, msgp->mtext, (ssize_t)msgsz, msgtyp, msgflg); + err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg); if (err < 0) goto out; @@ -514,10 +514,6 @@ long compat_sys_msgctl(int first, int second, void __user *uptr) return err; } -#ifndef COMPAT_SHMLBA -#define COMPAT_SHMLBA SHMLBA -#endif - #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, void __user *uptr) @@ -528,7 +524,7 @@ long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, if (version == 1) return -EINVAL; - err = do_shmat(first, uptr, second, &raddr, COMPAT_SHMLBA); + err = do_shmat(first, uptr, second, &raddr); if (err < 0) return err; uaddr = compat_ptr(third); @@ -540,7 +536,7 @@ long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg) unsigned long ret; long err; - err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret, COMPAT_SHMLBA); + err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret); if (err) return err; force_successful_syscall_return(); diff --git a/trunk/ipc/shm.c b/trunk/ipc/shm.c index 00faa05cf72a..41c1285d697a 100644 --- a/trunk/ipc/shm.c +++ b/trunk/ipc/shm.c @@ -953,8 +953,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) * "raddr" thing points to kernel space, and there has to be a wrapper around * this. */ -long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, - unsigned long shmlba) +long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) { struct shmid_kernel *shp; unsigned long addr; @@ -974,9 +973,9 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, if (shmid < 0) goto out; else if ((addr = (ulong)shmaddr)) { - if (addr & (shmlba - 1)) { + if (addr & (SHMLBA-1)) { if (shmflg & SHM_RND) - addr &= ~(shmlba - 1); /* round down */ + addr &= ~(SHMLBA-1); /* round down */ else #ifndef __ARCH_FORCE_SHMLBA if (addr & ~PAGE_MASK) @@ -1108,7 +1107,7 @@ SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg) unsigned long ret; long err; - err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA); + err = do_shmat(shmid, shmaddr, shmflg, &ret); if (err) return err; force_successful_syscall_return(); diff --git a/trunk/ipc/syscall.c b/trunk/ipc/syscall.c index 0d1e32ce048e..1d6f53f6b562 100644 --- a/trunk/ipc/syscall.c +++ b/trunk/ipc/syscall.c @@ -73,7 +73,7 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, default: { unsigned long raddr; ret = do_shmat(first, (char __user *)ptr, - second, &raddr, SHMLBA); + second, &raddr); if (ret) return ret; return put_user(raddr, (unsigned long __user *) third); diff --git a/trunk/ipc/util.c b/trunk/ipc/util.c index eb07fd356f27..75261a31d48d 100644 --- a/trunk/ipc/util.c +++ b/trunk/ipc/util.c @@ -804,7 +804,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, return ERR_PTR(err); } -#ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION +#ifdef __ARCH_WANT_IPC_PARSE_VERSION /** @@ -826,7 +826,7 @@ int ipc_parse_version (int *cmd) } } -#endif /* CONFIG_ARCH_WANT_IPC_PARSE_VERSION */ +#endif /* __ARCH_WANT_IPC_PARSE_VERSION */ #ifdef CONFIG_PROC_FS struct ipc_proc_iter { diff --git a/trunk/ipc/util.h b/trunk/ipc/util.h index 850ef3e962cb..6f5c20bedaab 100644 --- a/trunk/ipc/util.h +++ b/trunk/ipc/util.h @@ -130,7 +130,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, struct ipc_ids *ids, int id, int cmd, struct ipc64_perm *perm, int extra_perm); -#ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION +#ifndef __ARCH_WANT_IPC_PARSE_VERSION /* On IA-64, we always use the "64-bit version" of the IPC structures. */ # define ipc_parse_version(cmd) IPC_64 #else diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 8efac1fe56bc..ff1cad3b7bdc 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -114,10 +114,6 @@ int nr_processes(void) return total; } -void __weak arch_release_task_struct(struct task_struct *tsk) -{ -} - #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR static struct kmem_cache *task_struct_cachep; @@ -126,17 +122,17 @@ static inline struct task_struct *alloc_task_struct_node(int node) return kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node); } +void __weak arch_release_task_struct(struct task_struct *tsk) { } + static inline void free_task_struct(struct task_struct *tsk) { + arch_release_task_struct(tsk); kmem_cache_free(task_struct_cachep, tsk); } #endif -void __weak arch_release_thread_info(struct thread_info *ti) -{ -} - #ifndef CONFIG_ARCH_THREAD_INFO_ALLOCATOR +void __weak arch_release_thread_info(struct thread_info *ti) { } /* * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a @@ -154,6 +150,7 @@ static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, static inline void free_thread_info(struct thread_info *ti) { + arch_release_thread_info(ti); free_pages((unsigned long)ti, THREAD_SIZE_ORDER); } # else @@ -167,6 +164,7 @@ static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, static void free_thread_info(struct thread_info *ti) { + arch_release_thread_info(ti); kmem_cache_free(thread_info_cache, ti); } @@ -207,12 +205,10 @@ static void account_kernel_stack(struct thread_info *ti, int account) void free_task(struct task_struct *tsk) { account_kernel_stack(tsk->stack, -1); - arch_release_thread_info(tsk->stack); free_thread_info(tsk->stack); rt_mutex_debug_task_free(tsk); ftrace_graph_exit_task(tsk); put_seccomp_filter(tsk); - arch_release_task_struct(tsk); free_task_struct(tsk); } EXPORT_SYMBOL(free_task); @@ -302,16 +298,23 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) return NULL; ti = alloc_thread_info_node(tsk, node); - if (!ti) - goto free_tsk; + if (!ti) { + free_task_struct(tsk); + return NULL; + } err = arch_dup_task_struct(tsk, orig); - if (err) - goto free_ti; + /* + * We defer looking at err, because we will need this setup + * for the clean up path to work correctly. + */ tsk->stack = ti; - setup_thread_stack(tsk, orig); + + if (err) + goto out; + clear_user_return_notifier(tsk); clear_tsk_need_resched(tsk); stackend = end_of_stack(tsk); @@ -335,9 +338,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) return tsk; -free_ti: +out: free_thread_info(ti); -free_tsk: free_task_struct(tsk); return NULL; } @@ -389,8 +391,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) } charge = 0; if (mpnt->vm_flags & VM_ACCOUNT) { - unsigned long len = vma_pages(mpnt); - + unsigned long len; + len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; if (security_vm_enough_memory_mm(oldmm, len)) /* sic */ goto fail_nomem; charge = len; diff --git a/trunk/kernel/kexec.c b/trunk/kernel/kexec.c index 0668d58d6413..4e2e472f6aeb 100644 --- a/trunk/kernel/kexec.c +++ b/trunk/kernel/kexec.c @@ -1424,7 +1424,7 @@ static void update_vmcoreinfo_note(void) void crash_save_vmcoreinfo(void) { - vmcoreinfo_append_str("CRASHTIME=%ld\n", get_seconds()); + vmcoreinfo_append_str("CRASHTIME=%ld", get_seconds()); update_vmcoreinfo_note(); } diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 6f99aead66c6..ff2c7cb86d77 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -45,13 +45,6 @@ extern int max_threads; static struct workqueue_struct *khelper_wq; -/* - * kmod_thread_locker is used for deadlock avoidance. There is no explicit - * locking to protect this global - it is private to the singleton khelper - * thread and should only ever be modified by that thread. - */ -static const struct task_struct *kmod_thread_locker; - #define CAP_BSET (void *)1 #define CAP_PI (void *)2 @@ -228,13 +221,6 @@ static int ____call_usermodehelper(void *data) return 0; } -static int call_helper(void *data) -{ - /* Worker thread started blocking khelper thread. */ - kmod_thread_locker = current; - return ____call_usermodehelper(data); -} - static void call_usermodehelper_freeinfo(struct subprocess_info *info) { if (info->cleanup) @@ -309,12 +295,9 @@ static void __call_usermodehelper(struct work_struct *work) if (wait == UMH_WAIT_PROC) pid = kernel_thread(wait_for_helper, sub_info, CLONE_FS | CLONE_FILES | SIGCHLD); - else { - pid = kernel_thread(call_helper, sub_info, + else + pid = kernel_thread(____call_usermodehelper, sub_info, CLONE_VFORK | SIGCHLD); - /* Worker thread stopped blocking khelper thread. */ - kmod_thread_locker = NULL; - } switch (wait) { case UMH_NO_WAIT: @@ -565,16 +548,6 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) retval = -EBUSY; goto out; } - /* - * Worker thread must not wait for khelper thread at below - * wait_for_completion() if the thread was created with CLONE_VFORK - * flag, for khelper thread is already waiting for the thread at - * wait_for_completion() in do_fork(). - */ - if (wait != UMH_NO_WAIT && current == kmod_thread_locker) { - retval = -EBUSY; - goto out; - } sub_info->complete = &done; sub_info->wait = wait; @@ -604,12 +577,6 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) return retval; } -/* - * call_usermodehelper_fns() will not run the caller-provided cleanup function - * if a memory allocation failure is experienced. So the caller might need to - * check the call_usermodehelper_fns() return value: if it is -ENOMEM, perform - * the necessaary cleanup within the caller. - */ int call_usermodehelper_fns( char *path, char **argv, char **envp, int wait, int (*init)(struct subprocess_info *info, struct cred *new), diff --git a/trunk/kernel/panic.c b/trunk/kernel/panic.c index e1b2822fff97..d2a5f4ecc6dd 100644 --- a/trunk/kernel/panic.c +++ b/trunk/kernel/panic.c @@ -74,14 +74,6 @@ void panic(const char *fmt, ...) long i, i_next = 0; int state = 0; - /* - * Disable local interrupts. This will prevent panic_smp_self_stop - * from deadlocking the first cpu that invokes the panic, since - * there is nothing to prevent an interrupt handler (that runs - * after the panic_lock is acquired) from invoking panic again. - */ - local_irq_disable(); - /* * It's possible to come here directly from a panic-assertion and * not have preempt disabled. Some functions called from here want diff --git a/trunk/kernel/power/suspend.c b/trunk/kernel/power/suspend.c index 1da39ea248fd..c8b7446b27df 100644 --- a/trunk/kernel/power/suspend.c +++ b/trunk/kernel/power/suspend.c @@ -178,9 +178,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); - /* Kick the lockup detector */ - lockup_detector_bootcpu_resume(); - Enable_cpus: enable_nonboot_cpus(); diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index 6a76ab9d4476..50c96b5651b6 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -389,10 +389,8 @@ static ssize_t devkmsg_writev(struct kiocb *iocb, const struct iovec *iv, line = buf; for (i = 0; i < count; i++) { - if (copy_from_user(line, iv[i].iov_base, iv[i].iov_len)) { - ret = -EFAULT; + if (copy_from_user(line, iv[i].iov_base, iv[i].iov_len)) goto out; - } line += iv[i].iov_len; } @@ -1542,23 +1540,17 @@ asmlinkage int vprintk_emit(int facility, int level, lflags |= LOG_NEWLINE; } - /* strip kernel syslog prefix and extract log level or control flags */ - if (facility == 0) { - int kern_level = printk_get_level(text); - - if (kern_level) { - const char *end_of_header = printk_skip_level(text); - switch (kern_level) { - case '0' ... '7': - if (level == -1) - level = kern_level - '0'; - case 'd': /* KERN_DEFAULT */ - lflags |= LOG_PREFIX; - case 'c': /* KERN_CONT */ - break; - } - text_len -= end_of_header - text; - text = (char *)end_of_header; + /* strip syslog prefix and extract log level or control flags */ + if (text[0] == '<' && text[1] && text[2] == '>') { + switch (text[1]) { + case '0' ... '7': + if (level == -1) + level = text[1] - '0'; + case 'd': /* KERN_DEFAULT */ + lflags |= LOG_PREFIX; + case 'c': /* KERN_CONT */ + text += 3; + text_len -= 3; } } diff --git a/trunk/kernel/resource.c b/trunk/kernel/resource.c index 34d45886ee84..dc8b47764443 100644 --- a/trunk/kernel/resource.c +++ b/trunk/kernel/resource.c @@ -7,8 +7,6 @@ * Arbitrary resource management. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -793,28 +791,8 @@ void __init reserve_region_with_split(struct resource *root, resource_size_t start, resource_size_t end, const char *name) { - int abort = 0; - write_lock(&resource_lock); - if (root->start > start || root->end < end) { - pr_err("requested range [0x%llx-0x%llx] not in root %pr\n", - (unsigned long long)start, (unsigned long long)end, - root); - if (start > root->end || end < root->start) - abort = 1; - else { - if (end > root->end) - end = root->end; - if (start < root->start) - start = root->start; - pr_err("fixing request to [0x%llx-0x%llx]\n", - (unsigned long long)start, - (unsigned long long)end); - } - dump_stack(); - } - if (!abort) - __reserve_region_with_split(root, start, end, name); + __reserve_region_with_split(root, start, end, name); write_unlock(&resource_lock); } diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index 241507f23eca..2d39a84cd857 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -2015,6 +2015,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, break; } me->pdeath_signal = arg2; + error = 0; break; case PR_GET_PDEATHSIG: error = put_user(me->pdeath_signal, (int __user *)arg2); @@ -2028,6 +2029,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, break; } set_dumpable(me->mm, arg2); + error = 0; break; case PR_SET_UNALIGN: @@ -2054,7 +2056,10 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, case PR_SET_TIMING: if (arg2 != PR_TIMING_STATISTICAL) error = -EINVAL; + else + error = 0; break; + case PR_SET_NAME: comm[sizeof(me->comm)-1] = 0; if (strncpy_from_user(comm, (char __user *)arg2, @@ -2062,19 +2067,20 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, return -EFAULT; set_task_comm(me, comm); proc_comm_connector(me); - break; + return 0; case PR_GET_NAME: get_task_comm(comm, me); if (copy_to_user((char __user *)arg2, comm, sizeof(comm))) return -EFAULT; - break; + return 0; case PR_GET_ENDIAN: error = GET_ENDIAN(me, arg2); break; case PR_SET_ENDIAN: error = SET_ENDIAN(me, arg2); break; + case PR_GET_SECCOMP: error = prctl_get_seccomp(); break; @@ -2102,6 +2108,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, current->default_timer_slack_ns; else current->timer_slack_ns = arg2; + error = 0; break; case PR_MCE_KILL: if (arg4 | arg5) @@ -2127,6 +2134,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, default: return -EINVAL; } + error = 0; break; case PR_MCE_KILL_GET: if (arg2 | arg3 | arg4 | arg5) @@ -2145,6 +2153,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, break; case PR_SET_CHILD_SUBREAPER: me->signal->is_child_subreaper = !!arg2; + error = 0; break; case PR_GET_CHILD_SUBREAPER: error = put_user(me->signal->is_child_subreaper, @@ -2186,52 +2195,46 @@ static void argv_cleanup(struct subprocess_info *info) argv_free(info->argv); } -static int __orderly_poweroff(void) +/** + * orderly_poweroff - Trigger an orderly system poweroff + * @force: force poweroff if command execution fails + * + * This may be called from any context to trigger a system shutdown. + * If the orderly shutdown fails, it will force an immediate shutdown. + */ +int orderly_poweroff(bool force) { int argc; - char **argv; + char **argv = argv_split(GFP_ATOMIC, poweroff_cmd, &argc); static char *envp[] = { "HOME=/", "PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL }; - int ret; + int ret = -ENOMEM; - argv = argv_split(GFP_ATOMIC, poweroff_cmd, &argc); if (argv == NULL) { printk(KERN_WARNING "%s failed to allocate memory for \"%s\"\n", __func__, poweroff_cmd); - return -ENOMEM; + goto out; } ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_NO_WAIT, NULL, argv_cleanup, NULL); +out: + if (likely(!ret)) + return 0; + if (ret == -ENOMEM) argv_free(argv); - return ret; -} - -/** - * orderly_poweroff - Trigger an orderly system poweroff - * @force: force poweroff if command execution fails - * - * This may be called from any context to trigger a system shutdown. - * If the orderly shutdown fails, it will force an immediate shutdown. - */ -int orderly_poweroff(bool force) -{ - int ret = __orderly_poweroff(); - - if (ret && force) { + if (force) { printk(KERN_WARNING "Failed to start orderly shutdown: " "forcing the issue\n"); - /* - * I guess this should try to kick off some daemon to sync and - * poweroff asap. Or not even bother syncing if we're doing an - * emergency shutdown? - */ + /* I guess this should try to kick off some daemon to + sync and poweroff asap. Or not even bother syncing + if we're doing an emergency shutdown? */ emergency_sync(); kernel_power_off(); } diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 97186b99b0e4..4ab11879aeb4 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -175,11 +174,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); #endif -static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos); -static int proc_dostring_coredump(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos); - #ifdef CONFIG_MAGIC_SYSRQ /* Note: sysrq code uses it's own private copy */ static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE; @@ -416,7 +410,7 @@ static struct ctl_table kern_table[] = { .data = core_pattern, .maxlen = CORENAME_MAX_SIZE, .mode = 0644, - .proc_handler = proc_dostring_coredump, + .proc_handler = proc_dostring, }, { .procname = "core_pipe_limit", @@ -1504,7 +1498,7 @@ static struct ctl_table fs_table[] = { .data = &suid_dumpable, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec_minmax_coredump, + .proc_handler = proc_dointvec_minmax, .extra1 = &zero, .extra2 = &two, }, @@ -1557,10 +1551,7 @@ static struct ctl_table dev_table[] = { int __init sysctl_init(void) { - struct ctl_table_header *hdr; - - hdr = register_sysctl_table(sysctl_base_table); - kmemleak_not_leak(hdr); + register_sysctl_table(sysctl_base_table); return 0; } @@ -2018,34 +2009,6 @@ int proc_dointvec_minmax(struct ctl_table *table, int write, do_proc_dointvec_minmax_conv, ¶m); } -static void validate_coredump_safety(void) -{ - if (suid_dumpable == SUID_DUMPABLE_SAFE && - core_pattern[0] != '/' && core_pattern[0] != '|') { - printk(KERN_WARNING "Unsafe core_pattern used with "\ - "suid_dumpable=2. Pipe handler or fully qualified "\ - "core dump path required.\n"); - } -} - -static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - int error = proc_dointvec_minmax(table, write, buffer, lenp, ppos); - if (!error) - validate_coredump_safety(); - return error; -} - -static int proc_dostring_coredump(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - int error = proc_dostring(table, write, buffer, lenp, ppos); - if (!error) - validate_coredump_safety(); - return error; -} - static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos, diff --git a/trunk/kernel/taskstats.c b/trunk/kernel/taskstats.c index d0a32796550f..e66046456f4f 100644 --- a/trunk/kernel/taskstats.c +++ b/trunk/kernel/taskstats.c @@ -436,11 +436,6 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS, sizeof(struct cgroupstats)); - if (na == NULL) { - rc = -EMSGSIZE; - goto err; - } - stats = nla_data(na); memset(stats, 0, sizeof(*stats)); diff --git a/trunk/kernel/watchdog.c b/trunk/kernel/watchdog.c index 69add8a9da68..4b1dfba70f7c 100644 --- a/trunk/kernel/watchdog.c +++ b/trunk/kernel/watchdog.c @@ -575,7 +575,7 @@ int proc_dowatchdog(struct ctl_table *table, int write, /* * Create/destroy watchdog threads as CPUs come and go: */ -static int +static int __cpuinit cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { int hotcpu = (unsigned long)hcpu; @@ -610,27 +610,10 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) return NOTIFY_OK; } -static struct notifier_block cpu_nfb = { +static struct notifier_block __cpuinitdata cpu_nfb = { .notifier_call = cpu_callback }; -#ifdef CONFIG_SUSPEND -/* - * On exit from suspend we force an offline->online transition on the boot CPU - * so that the PMU state that was lost while in suspended state gets set up - * properly for the boot CPU. This information is required for restarting the - * NMI watchdog. - */ -void lockup_detector_bootcpu_resume(void) -{ - void *cpu = (void *)(long)smp_processor_id(); - - cpu_callback(&cpu_nfb, CPU_DEAD_FROZEN, cpu); - cpu_callback(&cpu_nfb, CPU_UP_PREPARE_FROZEN, cpu); - cpu_callback(&cpu_nfb, CPU_ONLINE_FROZEN, cpu); -} -#endif - void __init lockup_detector_init(void) { void *cpu = (void *)(long)smp_processor_id(); diff --git a/trunk/lib/Kconfig b/trunk/lib/Kconfig index bb94c1ba616a..bfdbb1ff0aa3 100644 --- a/trunk/lib/Kconfig +++ b/trunk/lib/Kconfig @@ -340,9 +340,6 @@ config NLATTR config GENERIC_ATOMIC64 bool -config ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE - def_bool y if GENERIC_ATOMIC64 - config LRU_CACHE tristate diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index 2403a63b5da5..4a186508bf8b 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -1084,105 +1084,18 @@ config LKDTM Documentation on how to use the module can be found in Documentation/fault-injection/provoke-crashes.txt -config NOTIFIER_ERROR_INJECTION - tristate "Notifier error injection" - depends on DEBUG_KERNEL - select DEBUG_FS - help - This option provides the ability to inject artifical errors to - specified notifier chain callbacks. It is useful to test the error - handling of notifier call chain failures. - - Say N if unsure. - config CPU_NOTIFIER_ERROR_INJECT tristate "CPU notifier error injection module" - depends on HOTPLUG_CPU && NOTIFIER_ERROR_INJECTION + depends on HOTPLUG_CPU && DEBUG_KERNEL help This option provides a kernel module that can be used to test - the error handling of the cpu notifiers by injecting artifical - errors to CPU notifier chain callbacks. It is controlled through - debugfs interface under /sys/kernel/debug/notifier-error-inject/cpu - - If the notifier call chain should be failed with some events - notified, write the error code to "actions//error". - - Example: Inject CPU offline error (-1 == -EPERM) - - # cd /sys/kernel/debug/notifier-error-inject/cpu - # echo -1 > actions/CPU_DOWN_PREPARE/error - # echo 0 > /sys/devices/system/cpu/cpu1/online - bash: echo: write error: Operation not permitted + the error handling of the cpu notifiers To compile this code as a module, choose M here: the module will be called cpu-notifier-error-inject. If unsure, say N. -config PM_NOTIFIER_ERROR_INJECT - tristate "PM notifier error injection module" - depends on PM && NOTIFIER_ERROR_INJECTION - default m if PM_DEBUG - help - This option provides the ability to inject artifical errors to - PM notifier chain callbacks. It is controlled through debugfs - interface /sys/kernel/debug/notifier-error-inject/pm - - If the notifier call chain should be failed with some events - notified, write the error code to "actions//error". - - Example: Inject PM suspend error (-12 = -ENOMEM) - - # cd /sys/kernel/debug/notifier-error-inject/pm/ - # echo -12 > actions/PM_SUSPEND_PREPARE/error - # echo mem > /sys/power/state - bash: echo: write error: Cannot allocate memory - - To compile this code as a module, choose M here: the module will - be called pm-notifier-error-inject. - - If unsure, say N. - -config MEMORY_NOTIFIER_ERROR_INJECT - tristate "Memory hotplug notifier error injection module" - depends on MEMORY_HOTPLUG_SPARSE && NOTIFIER_ERROR_INJECTION - help - This option provides the ability to inject artifical errors to - memory hotplug notifier chain callbacks. It is controlled through - debugfs interface under /sys/kernel/debug/notifier-error-inject/memory - - If the notifier call chain should be failed with some events - notified, write the error code to "actions//error". - - Example: Inject memory hotplug offline error (-12 == -ENOMEM) - - # cd /sys/kernel/debug/notifier-error-inject/memory - # echo -12 > actions/MEM_GOING_OFFLINE/error - # echo offline > /sys/devices/system/memory/memoryXXX/state - bash: echo: write error: Cannot allocate memory - - To compile this code as a module, choose M here: the module will - be called pSeries-reconfig-notifier-error-inject. - - If unsure, say N. - -config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT - tristate "pSeries reconfig notifier error injection module" - depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION - help - This option provides the ability to inject artifical errors to - pSeries reconfig notifier chain callbacks. It is controlled - through debugfs interface under - /sys/kernel/debug/notifier-error-inject/pSeries-reconfig/ - - If the notifier call chain should be failed with some events - notified, write the error code to "actions//error". - - To compile this code as a module, choose M here: the module will - be called memory-notifier-error-inject. - - If unsure, say N. - config FAULT_INJECTION bool "Fault-injection framework" depends on DEBUG_KERNEL diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index 9cb4104f47d9..2f2be5a8734c 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -22,7 +22,7 @@ lib-y += kobject.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \ - bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o + bsearch.o find_last_bit.o find_next_bit.o llist.o obj-y += kstrtox.o obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o @@ -90,12 +90,7 @@ obj-$(CONFIG_AUDIT_GENERIC) += audit.o obj-$(CONFIG_SWIOTLB) += swiotlb.o obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o -obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o -obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o -obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o -obj-$(CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT) += \ - pSeries-reconfig-notifier-error-inject.o lib-$(CONFIG_GENERIC_BUG) += bug.o diff --git a/trunk/lib/atomic64_test.c b/trunk/lib/atomic64_test.c index 00bca223d1e1..cb99b91c3a1d 100644 --- a/trunk/lib/atomic64_test.c +++ b/trunk/lib/atomic64_test.c @@ -114,7 +114,8 @@ static __init int test_atomic64(void) r += one; BUG_ON(v.counter != r); -#ifdef CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE +#if defined(CONFIG_X86) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || \ + defined(CONFIG_S390) || defined(_ASM_GENERIC_ATOMIC64_H) || defined(CONFIG_ARM) INIT(onestwos); BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1)); r -= one; @@ -128,7 +129,7 @@ static __init int test_atomic64(void) BUG_ON(atomic64_dec_if_positive(&v) != (-one - one)); BUG_ON(v.counter != r); #else -#warning Please implement atomic64_dec_if_positive for your architecture and select the above Kconfig symbol +#warning Please implement atomic64_dec_if_positive for your architecture, and add it to the IF above #endif INIT(onestwos); diff --git a/trunk/lib/cpu-notifier-error-inject.c b/trunk/lib/cpu-notifier-error-inject.c index 707ca24f7b18..4dc20321b0d5 100644 --- a/trunk/lib/cpu-notifier-error-inject.c +++ b/trunk/lib/cpu-notifier-error-inject.c @@ -1,45 +1,58 @@ #include -#include #include - -#include "notifier-error-inject.h" +#include +#include static int priority; +static int cpu_up_prepare_error; +static int cpu_down_prepare_error; + module_param(priority, int, 0); MODULE_PARM_DESC(priority, "specify cpu notifier priority"); -static struct notifier_err_inject cpu_notifier_err_inject = { - .actions = { - { NOTIFIER_ERR_INJECT_ACTION(CPU_UP_PREPARE) }, - { NOTIFIER_ERR_INJECT_ACTION(CPU_UP_PREPARE_FROZEN) }, - { NOTIFIER_ERR_INJECT_ACTION(CPU_DOWN_PREPARE) }, - { NOTIFIER_ERR_INJECT_ACTION(CPU_DOWN_PREPARE_FROZEN) }, - {} - } -}; +module_param(cpu_up_prepare_error, int, 0644); +MODULE_PARM_DESC(cpu_up_prepare_error, + "specify error code to inject CPU_UP_PREPARE action"); -static struct dentry *dir; +module_param(cpu_down_prepare_error, int, 0644); +MODULE_PARM_DESC(cpu_down_prepare_error, + "specify error code to inject CPU_DOWN_PREPARE action"); -static int err_inject_init(void) +static int err_inject_cpu_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) { - int err; + int err = 0; + + switch (action) { + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: + err = cpu_up_prepare_error; + break; + case CPU_DOWN_PREPARE: + case CPU_DOWN_PREPARE_FROZEN: + err = cpu_down_prepare_error; + break; + } + if (err) + printk(KERN_INFO "Injecting error (%d) at cpu notifier\n", err); - dir = notifier_err_inject_init("cpu", notifier_err_inject_dir, - &cpu_notifier_err_inject, priority); - if (IS_ERR(dir)) - return PTR_ERR(dir); + return notifier_from_errno(err); +} - err = register_hotcpu_notifier(&cpu_notifier_err_inject.nb); - if (err) - debugfs_remove_recursive(dir); +static struct notifier_block err_inject_cpu_notifier = { + .notifier_call = err_inject_cpu_callback, +}; + +static int err_inject_init(void) +{ + err_inject_cpu_notifier.priority = priority; - return err; + return register_hotcpu_notifier(&err_inject_cpu_notifier); } static void err_inject_exit(void) { - unregister_hotcpu_notifier(&cpu_notifier_err_inject.nb); - debugfs_remove_recursive(dir); + unregister_hotcpu_notifier(&err_inject_cpu_notifier); } module_init(err_inject_init); diff --git a/trunk/lib/crc32.c b/trunk/lib/crc32.c index 61774b8db4de..b0d278fb1d91 100644 --- a/trunk/lib/crc32.c +++ b/trunk/lib/crc32.c @@ -74,9 +74,7 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256]) size_t i; # endif const u32 *t0=tab[0], *t1=tab[1], *t2=tab[2], *t3=tab[3]; -# if CRC_LE_BITS != 32 const u32 *t4 = tab[4], *t5 = tab[5], *t6 = tab[6], *t7 = tab[7]; -# endif u32 q; /* Align it */ diff --git a/trunk/lib/memory-notifier-error-inject.c b/trunk/lib/memory-notifier-error-inject.c deleted file mode 100644 index e6239bf0b0df..000000000000 --- a/trunk/lib/memory-notifier-error-inject.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include - -#include "notifier-error-inject.h" - -static int priority; -module_param(priority, int, 0); -MODULE_PARM_DESC(priority, "specify memory notifier priority"); - -static struct notifier_err_inject memory_notifier_err_inject = { - .actions = { - { NOTIFIER_ERR_INJECT_ACTION(MEM_GOING_ONLINE) }, - { NOTIFIER_ERR_INJECT_ACTION(MEM_GOING_OFFLINE) }, - {} - } -}; - -static struct dentry *dir; - -static int err_inject_init(void) -{ - int err; - - dir = notifier_err_inject_init("memory", notifier_err_inject_dir, - &memory_notifier_err_inject, priority); - if (IS_ERR(dir)) - return PTR_ERR(dir); - - err = register_memory_notifier(&memory_notifier_err_inject.nb); - if (err) - debugfs_remove_recursive(dir); - - return err; -} - -static void err_inject_exit(void) -{ - unregister_memory_notifier(&memory_notifier_err_inject.nb); - debugfs_remove_recursive(dir); -} - -module_init(err_inject_init); -module_exit(err_inject_exit); - -MODULE_DESCRIPTION("memory notifier error injection module"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Akinobu Mita "); diff --git a/trunk/lib/memweight.c b/trunk/lib/memweight.c deleted file mode 100644 index e35fc8771893..000000000000 --- a/trunk/lib/memweight.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include - -/** - * memweight - count the total number of bits set in memory area - * @ptr: pointer to the start of the area - * @bytes: the size of the area - */ -size_t memweight(const void *ptr, size_t bytes) -{ - size_t ret = 0; - size_t longs; - const unsigned char *bitmap = ptr; - - for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long); - bytes--, bitmap++) - ret += hweight8(*bitmap); - - longs = bytes / sizeof(long); - if (longs) { - BUG_ON(longs >= INT_MAX / BITS_PER_LONG); - ret += bitmap_weight((unsigned long *)bitmap, - longs * BITS_PER_LONG); - bytes -= longs * sizeof(long); - bitmap += longs * sizeof(long); - } - /* - * The reason that this last loop is distinct from the preceding - * bitmap_weight() call is to compute 1-bits in the last region smaller - * than sizeof(long) properly on big-endian systems. - */ - for (; bytes > 0; bytes--, bitmap++) - ret += hweight8(*bitmap); - - return ret; -} -EXPORT_SYMBOL(memweight); diff --git a/trunk/lib/notifier-error-inject.c b/trunk/lib/notifier-error-inject.c deleted file mode 100644 index 44b92cb6224f..000000000000 --- a/trunk/lib/notifier-error-inject.c +++ /dev/null @@ -1,112 +0,0 @@ -#include - -#include "notifier-error-inject.h" - -static int debugfs_errno_set(void *data, u64 val) -{ - *(int *)data = clamp_t(int, val, -MAX_ERRNO, 0); - return 0; -} - -static int debugfs_errno_get(void *data, u64 *val) -{ - *val = *(int *)data; - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set, - "%lld\n"); - -static struct dentry *debugfs_create_errno(const char *name, mode_t mode, - struct dentry *parent, int *value) -{ - return debugfs_create_file(name, mode, parent, value, &fops_errno); -} - -static int notifier_err_inject_callback(struct notifier_block *nb, - unsigned long val, void *p) -{ - int err = 0; - struct notifier_err_inject *err_inject = - container_of(nb, struct notifier_err_inject, nb); - struct notifier_err_inject_action *action; - - for (action = err_inject->actions; action->name; action++) { - if (action->val == val) { - err = action->error; - break; - } - } - if (err) - pr_info("Injecting error (%d) to %s\n", err, action->name); - - return notifier_from_errno(err); -} - -struct dentry *notifier_err_inject_dir; -EXPORT_SYMBOL_GPL(notifier_err_inject_dir); - -struct dentry *notifier_err_inject_init(const char *name, struct dentry *parent, - struct notifier_err_inject *err_inject, int priority) -{ - struct notifier_err_inject_action *action; - mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; - struct dentry *dir; - struct dentry *actions_dir; - - err_inject->nb.notifier_call = notifier_err_inject_callback; - err_inject->nb.priority = priority; - - dir = debugfs_create_dir(name, parent); - if (!dir) - return ERR_PTR(-ENOMEM); - - actions_dir = debugfs_create_dir("actions", dir); - if (!actions_dir) - goto fail; - - for (action = err_inject->actions; action->name; action++) { - struct dentry *action_dir; - - action_dir = debugfs_create_dir(action->name, actions_dir); - if (!action_dir) - goto fail; - - /* - * Create debugfs r/w file containing action->error. If - * notifier call chain is called with action->val, it will - * fail with the error code - */ - if (!debugfs_create_errno("error", mode, action_dir, - &action->error)) - goto fail; - } - return dir; -fail: - debugfs_remove_recursive(dir); - return ERR_PTR(-ENOMEM); -} -EXPORT_SYMBOL_GPL(notifier_err_inject_init); - -static int __init err_inject_init(void) -{ - notifier_err_inject_dir = - debugfs_create_dir("notifier-error-inject", NULL); - - if (!notifier_err_inject_dir) - return -ENOMEM; - - return 0; -} - -static void __exit err_inject_exit(void) -{ - debugfs_remove_recursive(notifier_err_inject_dir); -} - -module_init(err_inject_init); -module_exit(err_inject_exit); - -MODULE_DESCRIPTION("Notifier error injection module"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Akinobu Mita "); diff --git a/trunk/lib/notifier-error-inject.h b/trunk/lib/notifier-error-inject.h deleted file mode 100644 index 99b3b6fc470b..000000000000 --- a/trunk/lib/notifier-error-inject.h +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include - -struct notifier_err_inject_action { - unsigned long val; - int error; - const char *name; -}; - -#define NOTIFIER_ERR_INJECT_ACTION(action) \ - .name = #action, .val = (action), - -struct notifier_err_inject { - struct notifier_block nb; - struct notifier_err_inject_action actions[]; - /* The last slot must be terminated with zero sentinel */ -}; - -extern struct dentry *notifier_err_inject_dir; - -extern struct dentry *notifier_err_inject_init(const char *name, - struct dentry *parent, struct notifier_err_inject *err_inject, - int priority); diff --git a/trunk/lib/pSeries-reconfig-notifier-error-inject.c b/trunk/lib/pSeries-reconfig-notifier-error-inject.c deleted file mode 100644 index 7f7c98dcd5c4..000000000000 --- a/trunk/lib/pSeries-reconfig-notifier-error-inject.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -#include - -#include "notifier-error-inject.h" - -static int priority; -module_param(priority, int, 0); -MODULE_PARM_DESC(priority, "specify pSeries reconfig notifier priority"); - -static struct notifier_err_inject reconfig_err_inject = { - .actions = { - { NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_ADD) }, - { NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_REMOVE) }, - { NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_ADD) }, - { NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_REMOVE) }, - {} - } -}; - -static struct dentry *dir; - -static int err_inject_init(void) -{ - int err; - - dir = notifier_err_inject_init("pSeries-reconfig", - notifier_err_inject_dir, &reconfig_err_inject, priority); - if (IS_ERR(dir)) - return PTR_ERR(dir); - - err = pSeries_reconfig_notifier_register(&reconfig_err_inject.nb); - if (err) - debugfs_remove_recursive(dir); - - return err; -} - -static void err_inject_exit(void) -{ - pSeries_reconfig_notifier_unregister(&reconfig_err_inject.nb); - debugfs_remove_recursive(dir); -} - -module_init(err_inject_init); -module_exit(err_inject_exit); - -MODULE_DESCRIPTION("pSeries reconfig notifier error injection module"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Akinobu Mita "); diff --git a/trunk/lib/pm-notifier-error-inject.c b/trunk/lib/pm-notifier-error-inject.c deleted file mode 100644 index c094b2dedc23..000000000000 --- a/trunk/lib/pm-notifier-error-inject.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include - -#include "notifier-error-inject.h" - -static int priority; -module_param(priority, int, 0); -MODULE_PARM_DESC(priority, "specify PM notifier priority"); - -static struct notifier_err_inject pm_notifier_err_inject = { - .actions = { - { NOTIFIER_ERR_INJECT_ACTION(PM_HIBERNATION_PREPARE) }, - { NOTIFIER_ERR_INJECT_ACTION(PM_SUSPEND_PREPARE) }, - { NOTIFIER_ERR_INJECT_ACTION(PM_RESTORE_PREPARE) }, - {} - } -}; - -static struct dentry *dir; - -static int err_inject_init(void) -{ - int err; - - dir = notifier_err_inject_init("pm", notifier_err_inject_dir, - &pm_notifier_err_inject, priority); - if (IS_ERR(dir)) - return PTR_ERR(dir); - - err = register_pm_notifier(&pm_notifier_err_inject.nb); - if (err) - debugfs_remove_recursive(dir); - - return err; -} - -static void err_inject_exit(void) -{ - unregister_pm_notifier(&pm_notifier_err_inject.nb); - debugfs_remove_recursive(dir); -} - -module_init(err_inject_init); -module_exit(err_inject_exit); - -MODULE_DESCRIPTION("PM notifier error injection module"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Akinobu Mita "); diff --git a/trunk/lib/scatterlist.c b/trunk/lib/scatterlist.c index fadae774a20c..e719adf695bf 100644 --- a/trunk/lib/scatterlist.c +++ b/trunk/lib/scatterlist.c @@ -279,6 +279,14 @@ int __sg_alloc_table(struct sg_table *table, unsigned int nents, if (!left) sg_mark_end(&sg[sg_size - 1]); + /* + * only really needed for mempool backed sg allocations (like + * SCSI), a possible improvement here would be to pass the + * table pointer into the allocator and let that clear these + * flags + */ + gfp_mask &= ~__GFP_WAIT; + gfp_mask |= __GFP_HIGH; prv = sg; } while (left); diff --git a/trunk/lib/spinlock_debug.c b/trunk/lib/spinlock_debug.c index eb10578ae055..e91fbc23fff1 100644 --- a/trunk/lib/spinlock_debug.c +++ b/trunk/lib/spinlock_debug.c @@ -58,7 +58,7 @@ static void spin_dump(raw_spinlock_t *lock, const char *msg) printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n", msg, raw_smp_processor_id(), current->comm, task_pid_nr(current)); - printk(KERN_EMERG " lock: %pS, .magic: %08x, .owner: %s/%d, " + printk(KERN_EMERG " lock: %ps, .magic: %08x, .owner: %s/%d, " ".owner_cpu: %d\n", lock, lock->magic, owner ? owner->comm : "", diff --git a/trunk/lib/vsprintf.c b/trunk/lib/vsprintf.c index 0e337541f005..c3f36d415bdf 100644 --- a/trunk/lib/vsprintf.c +++ b/trunk/lib/vsprintf.c @@ -654,50 +654,6 @@ char *resource_string(char *buf, char *end, struct resource *res, return string(buf, end, sym, spec); } -static noinline_for_stack -char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec, - const char *fmt) -{ - int i, len = 1; /* if we pass '%ph[CDN]', field witdh remains - negative value, fallback to the default */ - char separator; - - if (spec.field_width == 0) - /* nothing to print */ - return buf; - - if (ZERO_OR_NULL_PTR(addr)) - /* NULL pointer */ - return string(buf, end, NULL, spec); - - switch (fmt[1]) { - case 'C': - separator = ':'; - break; - case 'D': - separator = '-'; - break; - case 'N': - separator = 0; - break; - default: - separator = ' '; - break; - } - - if (spec.field_width > 0) - len = min_t(int, spec.field_width, 64); - - for (i = 0; i < len && buf < end - 1; i++) { - buf = hex_byte_pack(buf, addr[i]); - - if (buf < end && separator && i != len - 1) - *buf++ = separator; - } - - return buf; -} - static noinline_for_stack char *mac_address_string(char *buf, char *end, u8 *addr, struct printf_spec spec, const char *fmt) @@ -706,28 +662,15 @@ char *mac_address_string(char *buf, char *end, u8 *addr, char *p = mac_addr; int i; char separator; - bool reversed = false; - switch (fmt[1]) { - case 'F': + if (fmt[1] == 'F') { /* FDDI canonical format */ separator = '-'; - break; - - case 'R': - reversed = true; - /* fall through */ - - default: + } else { separator = ':'; - break; } for (i = 0; i < 6; i++) { - if (reversed) - p = hex_byte_pack(p, addr[5 - i]); - else - p = hex_byte_pack(p, addr[i]); - + p = hex_byte_pack(p, addr[i]); if (fmt[0] == 'M' && i != 5) *p++ = separator; } @@ -990,7 +933,6 @@ int kptr_restrict __read_mostly; * - 'm' For a 6-byte MAC address, it prints the hex address without colons * - 'MF' For a 6-byte MAC FDDI address, it prints the address * with a dash-separated hex notation - * - '[mM]R For a 6-byte MAC address, Reverse order (Bluetooth) * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4) * IPv6 uses colon separated network-order 16 bit hex with leading 0's @@ -1018,13 +960,6 @@ int kptr_restrict __read_mostly; * correctness of the format string and va_list arguments. * - 'K' For a kernel pointer that should be hidden from unprivileged users * - 'NF' For a netdev_features_t - * - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with - * a certain separator (' ' by default): - * C colon - * D dash - * N no separator - * The maximum supported length is 64 bytes of the input. Consider - * to use print_hex_dump() for the larger input. * * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 * function pointers are really function descriptors, which contain a @@ -1058,12 +993,9 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, case 'R': case 'r': return resource_string(buf, end, ptr, spec, fmt); - case 'h': - return hex_string(buf, end, ptr, spec, fmt); case 'M': /* Colon separated: 00:01:02:03:04:05 */ case 'm': /* Contiguous: 000102030405 */ - /* [mM]F (FDDI) */ - /* [mM]R (Reverse order; Bluetooth) */ + /* [mM]F (FDDI, bit reversed) */ return mac_address_string(buf, end, ptr, spec, fmt); case 'I': /* Formatted IP supported * 4: 1.2.3.4 @@ -1098,8 +1030,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, * %pK cannot be used in IRQ context because its test * for CAP_SYSLOG would be meaningless. */ - if (kptr_restrict && (in_irq() || in_serving_softirq() || - in_nmi())) { + if (in_irq() || in_serving_softirq() || in_nmi()) { if (spec.field_width == -1) spec.field_width = default_width; return string(buf, end, "pK-error", spec); @@ -1349,12 +1280,8 @@ int format_decode(const char *fmt, struct printf_spec *spec) * %pI6c print an IPv6 address as specified by RFC 5952 * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper * case. - * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 - * bytes of the input) * %n is ignored * - * ** Please update Documentation/printk-formats.txt when making changes ** - * * The return value is the number of characters which would * be generated for the given input, excluding the trailing * '\0', as per ISO C99. If you want to have the exact diff --git a/trunk/mm/memory-failure.c b/trunk/mm/memory-failure.c index 6de0d613bbe6..de4ce7058450 100644 --- a/trunk/mm/memory-failure.c +++ b/trunk/mm/memory-failure.c @@ -1433,8 +1433,8 @@ static int soft_offline_huge_page(struct page *page, int flags) /* Keep page count to indicate a given hugepage is isolated. */ list_add(&hpage->lru, &pagelist); - ret = migrate_huge_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, false, - MIGRATE_SYNC); + ret = migrate_huge_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, 0, + true); if (ret) { struct page *page1, *page2; list_for_each_entry_safe(page1, page2, &pagelist, lru) @@ -1563,7 +1563,7 @@ int soft_offline_page(struct page *page, int flags) page_is_file_cache(page)); list_add(&page->lru, &pagelist); ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, - false, MIGRATE_SYNC); + 0, MIGRATE_SYNC); if (ret) { putback_lru_pages(&pagelist); pr_info("soft offline: %#lx: migration failed %d, type %lx\n", diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index 913d6bdfdda3..e5bd60ff48e3 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -1600,17 +1600,13 @@ sub process { # Check signature styles if (!$in_header_lines && - $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { + $line =~ /^(\s*)($signature_tags)(\s*)(.*)/) { my $space_before = $1; my $sign_off = $2; my $space_after = $3; my $email = $4; my $ucfirst_sign_off = ucfirst(lc($sign_off)); - if ($sign_off !~ /$signature_tags/) { - WARN("BAD_SIGN_OFF", - "Non-standard signature: $sign_off\n" . $herecurr); - } if (defined $space_before && $space_before ne "") { WARN("BAD_SIGN_OFF", "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr); @@ -1852,8 +1848,8 @@ sub process { my $pos = pos_last_openparen($rest); if ($pos >= 0) { - $line =~ /^(\+| )([ \t]*)/; - my $newindent = $2; + $line =~ /^\+([ \t]*)/; + my $newindent = $1; my $goodtabindent = $oldindent . "\t" x ($pos / 8) . @@ -2988,45 +2984,6 @@ sub process { } } -# do {} while (0) macro tests: -# single-statement macros do not need to be enclosed in do while (0) loop, -# macro should not end with a semicolon - if ($^V && $^V ge 5.10.0 && - $realfile !~ m@/vmlinux.lds.h$@ && - $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { - my $ln = $linenr; - my $cnt = $realcnt; - my ($off, $dstat, $dcond, $rest); - my $ctx = ''; - ($dstat, $dcond, $ln, $cnt, $off) = - ctx_statement_block($linenr, $realcnt, 0); - $ctx = $dstat; - - $dstat =~ s/\\\n.//g; - - if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { - my $stmts = $2; - my $semis = $3; - - $ctx =~ s/\n*$//; - my $cnt = statement_rawlines($ctx); - my $herectx = $here . "\n"; - - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } - - if (($stmts =~ tr/;/;/) == 1) { - WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", - "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); - } - if (defined $semis && $semis ne "") { - WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", - "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); - } - } - } - # make sure symbols are always wrapped with VMLINUX_SYMBOL() ... # all assignments may have only one of the following with an assignment: # . @@ -3304,12 +3261,6 @@ sub process { "sizeof(& should be avoided\n" . $herecurr); } -# check for sizeof without parenthesis - if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { - WARN("SIZEOF_PARENTHESIS", - "sizeof $1 should be sizeof($1)\n" . $herecurr); - } - # check for line continuations in quoted strings with odd counts of " if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { WARN("LINE_CONTINUATIONS", @@ -3358,22 +3309,6 @@ sub process { } } -# check usleep_range arguments - if ($^V && $^V ge 5.10.0 && - defined $stat && - $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { - my $min = $1; - my $max = $7; - if ($min eq $max) { - WARN("USLEEP_RANGE", - "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); - } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && - $min > $max) { - WARN("USLEEP_RANGE", - "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); - } - } - # check for new externs in .c files. if ($realfile =~ /\.c$/ && defined $stat && $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 6c77f63c7591..79690f401a58 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -3185,7 +3185,6 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd, case F_GETFL: case F_GETOWN: case F_GETSIG: - case F_GETOWNER_UIDS: /* Just check FD__USE permission */ err = file_has_perm(cred, file, 0); break; diff --git a/trunk/sound/core/misc.c b/trunk/sound/core/misc.c index 30e027ecf4da..768167925409 100644 --- a/trunk/sound/core/misc.c +++ b/trunk/sound/core/misc.c @@ -68,7 +68,6 @@ void __snd_printk(unsigned int level, const char *path, int line, { va_list args; #ifdef CONFIG_SND_VERBOSE_PRINTK - int kern_level; struct va_format vaf; char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV"; #endif @@ -82,16 +81,12 @@ void __snd_printk(unsigned int level, const char *path, int line, #ifdef CONFIG_SND_VERBOSE_PRINTK vaf.fmt = format; vaf.va = &args; - - kern_level = printk_get_level(format); - if (kern_level) { - const char *end_of_header = printk_skip_level(format); - memcpy(verbose_fmt, format, end_of_header - format); - vaf.fmt = end_of_header; + if (format[0] == '<' && format[2] == '>') { + memcpy(verbose_fmt, format, 3); + vaf.fmt = format + 3; } else if (level) - memcpy(verbose_fmt, KERN_DEBUG, sizeof(KERN_DEBUG) - 1); + memcpy(verbose_fmt, KERN_DEBUG, 3); printk(verbose_fmt, sanity_file_name(path), line, &vaf); - #else vprintk(format, args); #endif diff --git a/trunk/sound/i2c/other/tea575x-tuner.c b/trunk/sound/i2c/other/tea575x-tuner.c index b29b88f93c9e..7eca25fae413 100644 --- a/trunk/sound/i2c/other/tea575x-tuner.c +++ b/trunk/sound/i2c/other/tea575x-tuner.c @@ -197,8 +197,6 @@ static int vidioc_g_tuner(struct file *file, void *priv, strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; - if (!tea->cannot_read_data) - v->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED; v->rangelow = FREQ_LO; v->rangehigh = FREQ_HI; v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; @@ -307,7 +305,7 @@ static int vidioc_s_hw_freq_seek(struct file *file, void *fh, } tea->val &= ~TEA575X_BIT_SEARCH; snd_tea575x_set_freq(tea); - return -ENODATA; + return -EAGAIN; } static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) diff --git a/trunk/tools/testing/fault-injection/failcmd.sh b/trunk/tools/testing/fault-injection/failcmd.sh deleted file mode 100644 index 1776e924b202..000000000000 --- a/trunk/tools/testing/fault-injection/failcmd.sh +++ /dev/null @@ -1,219 +0,0 @@ -#!/bin/bash -# -# NAME -# failcmd.sh - run a command with injecting slab/page allocation failures -# -# SYNOPSIS -# failcmd.sh --help -# failcmd.sh [] command [arguments] -# -# DESCRIPTION -# Run command with injecting slab/page allocation failures by fault -# injection. -# -# NOTE: you need to run this script as root. -# - -usage() -{ - cat >&2 <&2 - exit 1 -fi - -DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3}'` - -if [ ! -d "$DEBUGFS" ]; then - echo debugfs is not mounted >&2 - exit 1 -fi - -FAILCMD_TYPE=${FAILCMD_TYPE:-failslab} -FAULTATTR=$DEBUGFS/$FAILCMD_TYPE - -if [ ! -d $FAULTATTR ]; then - echo $FAILCMD_TYPE is not available >&2 - exit 1 -fi - -LONGOPTS=probability:,interval:,times:,space:,verbose:,task-filter: -LONGOPTS=$LONGOPTS,stacktrace-depth:,require-start:,require-end: -LONGOPTS=$LONGOPTS,reject-start:,reject-end:,oom-kill-allocating-task:,help - -if [ $FAILCMD_TYPE = failslab ]; then - LONGOPTS=$LONGOPTS,ignore-gfp-wait:,cache-filter: -elif [ $FAILCMD_TYPE = fail_page_alloc ]; then - LONGOPTS=$LONGOPTS,ignore-gfp-wait:,ignore-gfp-highmem:,min-order: -fi - -TEMP=`getopt -o p:i:t:s:v:h --long $LONGOPTS -n 'failcmd.sh' -- "$@"` - -if [ $? != 0 ]; then - usage - exit 1 -fi - -eval set -- "$TEMP" - -fault_attr_default() -{ - echo N > $FAULTATTR/task-filter - echo 0 > $FAULTATTR/probability - echo 1 > $FAULTATTR/times -} - -fault_attr_default - -oom_kill_allocating_task_saved=`cat /proc/sys/vm/oom_kill_allocating_task` - -restore_values() -{ - fault_attr_default - echo $oom_kill_allocating_task_saved \ - > /proc/sys/vm/oom_kill_allocating_task -} - -# -# Default options -# -declare -i oom_kill_allocating_task=1 -declare task_filter=Y -declare -i probability=1 -declare -i times=1 - -while true; do - case "$1" in - -p|--probability) - probability=$2 - shift 2 - ;; - -i|--interval) - echo $2 > $FAULTATTR/interval - shift 2 - ;; - -t|--times) - times=$2 - shift 2 - ;; - -s|--space) - echo $2 > $FAULTATTR/space - shift 2 - ;; - -v|--verbose) - echo $2 > $FAULTATTR/verbose - shift 2 - ;; - --task-filter) - task_filter=$2 - shift 2 - ;; - --stacktrace-depth) - echo $2 > $FAULTATTR/stacktrace-depth - shift 2 - ;; - --require-start) - echo $2 > $FAULTATTR/require-start - shift 2 - ;; - --require-end) - echo $2 > $FAULTATTR/require-end - shift 2 - ;; - --reject-start) - echo $2 > $FAULTATTR/reject-start - shift 2 - ;; - --reject-end) - echo $2 > $FAULTATTR/reject-end - shift 2 - ;; - --oom-kill-allocating-task) - oom_kill_allocating_task=$2 - shift 2 - ;; - --ignore-gfp-wait) - echo $2 > $FAULTATTR/ignore-gfp-wait - shift 2 - ;; - --cache-filter) - echo $2 > $FAULTATTR/cache_filter - shift 2 - ;; - --ignore-gfp-highmem) - echo $2 > $FAULTATTR/ignore-gfp-highmem - shift 2 - ;; - --min-order) - echo $2 > $FAULTATTR/min-order - shift 2 - ;; - -h|--help) - usage - exit 0 - shift - ;; - --) - shift - break - ;; - esac -done - -[ -z "$@" ] && exit 0 - -echo $oom_kill_allocating_task > /proc/sys/vm/oom_kill_allocating_task -echo $task_filter > $FAULTATTR/task-filter -echo $probability > $FAULTATTR/probability -echo $times > $FAULTATTR/times - -trap "restore_values" SIGINT SIGTERM EXIT - -cmd="echo 1 > /proc/self/make-it-fail && exec $@" -bash -c "$cmd" diff --git a/trunk/tools/testing/selftests/Makefile b/trunk/tools/testing/selftests/Makefile index 85baf11e2acd..a4162e15c25f 100644 --- a/trunk/tools/testing/selftests/Makefile +++ b/trunk/tools/testing/selftests/Makefile @@ -1,4 +1,4 @@ -TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug +TARGETS = breakpoints kcmp mqueue vm all: for TARGET in $(TARGETS); do \ diff --git a/trunk/tools/testing/selftests/cpu-hotplug/Makefile b/trunk/tools/testing/selftests/cpu-hotplug/Makefile deleted file mode 100644 index 7c9c20ff578a..000000000000 --- a/trunk/tools/testing/selftests/cpu-hotplug/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: - -run_tests: - ./on-off-test.sh - -clean: diff --git a/trunk/tools/testing/selftests/cpu-hotplug/on-off-test.sh b/trunk/tools/testing/selftests/cpu-hotplug/on-off-test.sh deleted file mode 100644 index bdde7cf428bb..000000000000 --- a/trunk/tools/testing/selftests/cpu-hotplug/on-off-test.sh +++ /dev/null @@ -1,221 +0,0 @@ -#!/bin/bash - -SYSFS= - -prerequisite() -{ - msg="skip all tests:" - - if [ $UID != 0 ]; then - echo $msg must be run as root >&2 - exit 0 - fi - - SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` - - if [ ! -d "$SYSFS" ]; then - echo $msg sysfs is not mounted >&2 - exit 0 - fi - - if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then - echo $msg cpu hotplug is not supported >&2 - exit 0 - fi -} - -# -# list all hot-pluggable CPUs -# -hotpluggable_cpus() -{ - local state=${1:-.\*} - - for cpu in $SYSFS/devices/system/cpu/cpu*; do - if [ -f $cpu/online ] && grep -q $state $cpu/online; then - echo ${cpu##/*/cpu} - fi - done -} - -hotplaggable_offline_cpus() -{ - hotpluggable_cpus 0 -} - -hotpluggable_online_cpus() -{ - hotpluggable_cpus 1 -} - -cpu_is_online() -{ - grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online -} - -cpu_is_offline() -{ - grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online -} - -online_cpu() -{ - echo 1 > $SYSFS/devices/system/cpu/cpu$1/online -} - -offline_cpu() -{ - echo 0 > $SYSFS/devices/system/cpu/cpu$1/online -} - -online_cpu_expect_success() -{ - local cpu=$1 - - if ! online_cpu $cpu; then - echo $FUNCNAME $cpu: unexpected fail >&2 - elif ! cpu_is_online $cpu; then - echo $FUNCNAME $cpu: unexpected offline >&2 - fi -} - -online_cpu_expect_fail() -{ - local cpu=$1 - - if online_cpu $cpu 2> /dev/null; then - echo $FUNCNAME $cpu: unexpected success >&2 - elif ! cpu_is_offline $cpu; then - echo $FUNCNAME $cpu: unexpected online >&2 - fi -} - -offline_cpu_expect_success() -{ - local cpu=$1 - - if ! offline_cpu $cpu; then - echo $FUNCNAME $cpu: unexpected fail >&2 - elif ! cpu_is_offline $cpu; then - echo $FUNCNAME $cpu: unexpected offline >&2 - fi -} - -offline_cpu_expect_fail() -{ - local cpu=$1 - - if offline_cpu $cpu 2> /dev/null; then - echo $FUNCNAME $cpu: unexpected success >&2 - elif ! cpu_is_online $cpu; then - echo $FUNCNAME $cpu: unexpected offline >&2 - fi -} - -error=-12 -priority=0 - -while getopts e:hp: opt; do - case $opt in - e) - error=$OPTARG - ;; - h) - echo "Usage $0 [ -e errno ] [ -p notifier-priority ]" - exit - ;; - p) - priority=$OPTARG - ;; - esac -done - -if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then - echo "error code must be -4095 <= errno < 0" >&2 - exit 1 -fi - -prerequisite - -# -# Online all hot-pluggable CPUs -# -for cpu in `hotplaggable_offline_cpus`; do - online_cpu_expect_success $cpu -done - -# -# Offline all hot-pluggable CPUs -# -for cpu in `hotpluggable_online_cpus`; do - offline_cpu_expect_success $cpu -done - -# -# Online all hot-pluggable CPUs again -# -for cpu in `hotplaggable_offline_cpus`; do - online_cpu_expect_success $cpu -done - -# -# Test with cpu notifier error injection -# - -DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` -NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu - -prerequisite_extra() -{ - msg="skip extra tests:" - - /sbin/modprobe -q -r cpu-notifier-error-inject - /sbin/modprobe -q cpu-notifier-error-inject priority=$priority - - if [ ! -d "$DEBUGFS" ]; then - echo $msg debugfs is not mounted >&2 - exit 0 - fi - - if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then - echo $msg cpu-notifier-error-inject module is not available >&2 - exit 0 - fi -} - -prerequisite_extra - -# -# Offline all hot-pluggable CPUs -# -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error -for cpu in `hotpluggable_online_cpus`; do - offline_cpu_expect_success $cpu -done - -# -# Test CPU hot-add error handling (offline => online) -# -echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error -for cpu in `hotplaggable_offline_cpus`; do - online_cpu_expect_fail $cpu -done - -# -# Online all hot-pluggable CPUs -# -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error -for cpu in `hotplaggable_offline_cpus`; do - online_cpu_expect_success $cpu -done - -# -# Test CPU hot-remove error handling (online => offline) -# -echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error -for cpu in `hotpluggable_online_cpus`; do - offline_cpu_expect_fail $cpu -done - -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error -/sbin/modprobe -q -r cpu-notifier-error-inject diff --git a/trunk/tools/testing/selftests/memory-hotplug/Makefile b/trunk/tools/testing/selftests/memory-hotplug/Makefile deleted file mode 100644 index 7c9c20ff578a..000000000000 --- a/trunk/tools/testing/selftests/memory-hotplug/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: - -run_tests: - ./on-off-test.sh - -clean: diff --git a/trunk/tools/testing/selftests/memory-hotplug/on-off-test.sh b/trunk/tools/testing/selftests/memory-hotplug/on-off-test.sh deleted file mode 100644 index a2816f631542..000000000000 --- a/trunk/tools/testing/selftests/memory-hotplug/on-off-test.sh +++ /dev/null @@ -1,230 +0,0 @@ -#!/bin/bash - -SYSFS= - -prerequisite() -{ - msg="skip all tests:" - - if [ $UID != 0 ]; then - echo $msg must be run as root >&2 - exit 0 - fi - - SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` - - if [ ! -d "$SYSFS" ]; then - echo $msg sysfs is not mounted >&2 - exit 0 - fi - - if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then - echo $msg memory hotplug is not supported >&2 - exit 0 - fi -} - -# -# list all hot-pluggable memory -# -hotpluggable_memory() -{ - local state=${1:-.\*} - - for memory in $SYSFS/devices/system/memory/memory*; do - if grep -q 1 $memory/removable && - grep -q $state $memory/state; then - echo ${memory##/*/memory} - fi - done -} - -hotplaggable_offline_memory() -{ - hotpluggable_memory offline -} - -hotpluggable_online_memory() -{ - hotpluggable_memory online -} - -memory_is_online() -{ - grep -q online $SYSFS/devices/system/memory/memory$1/state -} - -memory_is_offline() -{ - grep -q offline $SYSFS/devices/system/memory/memory$1/state -} - -online_memory() -{ - echo online > $SYSFS/devices/system/memory/memory$1/state -} - -offline_memory() -{ - echo offline > $SYSFS/devices/system/memory/memory$1/state -} - -online_memory_expect_success() -{ - local memory=$1 - - if ! online_memory $memory; then - echo $FUNCNAME $memory: unexpected fail >&2 - elif ! memory_is_online $memory; then - echo $FUNCNAME $memory: unexpected offline >&2 - fi -} - -online_memory_expect_fail() -{ - local memory=$1 - - if online_memory $memory 2> /dev/null; then - echo $FUNCNAME $memory: unexpected success >&2 - elif ! memory_is_offline $memory; then - echo $FUNCNAME $memory: unexpected online >&2 - fi -} - -offline_memory_expect_success() -{ - local memory=$1 - - if ! offline_memory $memory; then - echo $FUNCNAME $memory: unexpected fail >&2 - elif ! memory_is_offline $memory; then - echo $FUNCNAME $memory: unexpected offline >&2 - fi -} - -offline_memory_expect_fail() -{ - local memory=$1 - - if offline_memory $memory 2> /dev/null; then - echo $FUNCNAME $memory: unexpected success >&2 - elif ! memory_is_online $memory; then - echo $FUNCNAME $memory: unexpected offline >&2 - fi -} - -error=-12 -priority=0 -ratio=10 - -while getopts e:hp:r: opt; do - case $opt in - e) - error=$OPTARG - ;; - h) - echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]" - exit - ;; - p) - priority=$OPTARG - ;; - r) - ratio=$OPTARG - ;; - esac -done - -if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then - echo "error code must be -4095 <= errno < 0" >&2 - exit 1 -fi - -prerequisite - -# -# Online all hot-pluggable memory -# -for memory in `hotplaggable_offline_memory`; do - online_memory_expect_success $memory -done - -# -# Offline $ratio percent of hot-pluggable memory -# -for memory in `hotpluggable_online_memory`; do - if [ $((RANDOM % 100)) -lt $ratio ]; then - offline_memory_expect_success $memory - fi -done - -# -# Online all hot-pluggable memory again -# -for memory in `hotplaggable_offline_memory`; do - online_memory_expect_success $memory -done - -# -# Test with memory notifier error injection -# - -DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` -NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory - -prerequisite_extra() -{ - msg="skip extra tests:" - - /sbin/modprobe -q -r memory-notifier-error-inject - /sbin/modprobe -q memory-notifier-error-inject priority=$priority - - if [ ! -d "$DEBUGFS" ]; then - echo $msg debugfs is not mounted >&2 - exit 0 - fi - - if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then - echo $msg memory-notifier-error-inject module is not available >&2 - exit 0 - fi -} - -prerequisite_extra - -# -# Offline $ratio percent of hot-pluggable memory -# -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error -for memory in `hotpluggable_online_memory`; do - if [ $((RANDOM % 100)) -lt $ratio ]; then - offline_memory_expect_success $memory - fi -done - -# -# Test memory hot-add error handling (offline => online) -# -echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error -for memory in `hotplaggable_offline_memory`; do - online_memory_expect_fail $memory -done - -# -# Online all hot-pluggable memory -# -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error -for memory in `hotplaggable_offline_memory`; do - online_memory_expect_success $memory -done - -# -# Test memory hot-remove error handling (online => offline) -# -echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error -for memory in `hotpluggable_online_memory`; do - offline_memory_expect_fail $memory -done - -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error -/sbin/modprobe -q -r memory-notifier-error-inject