[PATCH v5 1/3] v4l: Add multi-planar API definitions to the V4L2 API
Multi-planar API is as a backwards-compatible extension of the V4L2 API, which allows video buffers to consist of one or more planes. Planes are separate memory buffers; each has its own mapping, backed by usually separate physical memory buffers. Many different uses for the multi-planar API are possible, examples include: - embedded devices requiring video components to be placed in physically separate buffers, e.g. for Samsung S3C/S5P SoC series' video codec, Y and interleaved Cb/Cr components reside in buffers in different memory banks; - applications may receive (or choose to store) video data of one video buffer in separate memory buffers; such data would have to be temporarily copied together into one buffer before passing it to a V4L2 device; - applications or drivers may want to pass metadata related to a buffer and it may not be possible to place it in the same buffer, together with video data. Signed-off-by: Pawel Osciak p.osc...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Reviewed-by: Marek Szyprowski m.szyprow...@samsung.com --- drivers/media/video/v4l2-ioctl.c |2 + include/linux/videodev2.h| 126 +- 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 0eeceae..a830bbd 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -168,6 +168,8 @@ const char *v4l2_type_names[] = { [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = sliced-vbi-cap, [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = sliced-vbi-out, [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = vid-out-overlay, + [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = vid-cap-mplane, + [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = vid-out-mplane, }; EXPORT_SYMBOL(v4l2_type_names); diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 047f7e6..0379f07 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -70,6 +70,7 @@ * Moved from videodev.h */ #define VIDEO_MAX_FRAME 32 +#define VIDEO_MAX_PLANES 8 #ifndef __KERNEL__ @@ -157,9 +158,23 @@ enum v4l2_buf_type { /* Experimental */ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, #endif + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 17, + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 18, V4L2_BUF_TYPE_PRIVATE = 0x80, }; +#define V4L2_TYPE_IS_MULTIPLANAR(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \ +|| (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + +#define V4L2_TYPE_IS_OUTPUT(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \ +|| (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \ +|| (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \ +|| (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY\ +|| (type) == V4L2_BUF_TYPE_VBI_OUTPUT \ +|| (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) + enum v4l2_tuner_type { V4L2_TUNER_RADIO = 1, V4L2_TUNER_ANALOG_TV = 2, @@ -245,6 +260,11 @@ struct v4l2_capability { #define V4L2_CAP_HW_FREQ_SEEK 0x0400 /* Can do hardware frequency seek */ #define V4L2_CAP_RDS_OUTPUT0x0800 /* Is an RDS encoder */ +/* Is a video capture device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x1000 +/* Is a video output device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x2000 + #define V4L2_CAP_TUNER 0x0001 /* has a tuner */ #define V4L2_CAP_AUDIO 0x0002 /* has audio support */ #define V4L2_CAP_RADIO 0x0004 /* is a radio device */ @@ -514,6 +534,63 @@ struct v4l2_requestbuffers { __u32 reserved[2]; }; +/** + * struct v4l2_plane - plane info for multi-planar buffers + * @bytesused: number of bytes occupied by data in the plane (payload) + * @mem_offset:when memory in the associated struct v4l2_buffer is + * V4L2_MEMORY_MMAP, equals the offset from the start of + * the device memory for this plane (or is a cookie that + * should be passed to mmap() called on the video node) + * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer + * pointing + * to this plane + * @length:size of this plane (NOT the payload) in bytes + * @data_offset: offset in plane to the start of data/end of header, + * if relevant + * + * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer + * with two planes can have one plane for Y, and another for interleaved CbCr + * components. Each plane can reside in a separate memory buffer, or even in + *
[PATCH v5 0/3] Multi-planar video format and buffer support for the V4L2 API
Hello, After 9 months since the first proposal, lots of discussion and many changes, including an almost full redesign between versions 3 and 4, I present the patches that add the fifth version of the multi-planar API for V4L2. I am posting patches first for everyone to be able to take a look early and would be grateful for some indication of your acceptance. More documentation (DocBook) is on the way. Documentation in textual form can be found below. Changes since v4: - struct v4l2_pix_format_mplane: * does not include a struct v4l2_pix_format anymore, replaced with concrete fields * new field: num_planes - renamed fields in struct v4l2_plane (to prevent ambiguity): * mem_off - mem_offset * data_off - data_offset - renamed field in struct v4l2_format (for consistency): * mp_pix - pix_mp Contents: [PATCH v5 1/3] v4l: Add multi-planar API definitions to the V4L2 API [PATCH v5 2/3] v4l: Add multi-planar ioctl handling code [PATCH v5 3/3] v4l: Add compat functions for the multi-planar API === I. Rationale === Some embedded devices (including Samsung S3C/S5P SoC series) require physically separate memory buffers for placing video components. For example, S5P SoC video codec uses one buffer for Y and another for interleaved CbCr components. This cannot be achieved with the current V4L2 API. One of the reasons is that v4l2_buffer struct can only hold one pointer/offset to a video buffer. As the proposal evolved, we found more uses for separate planes per buffer, for non-embedded systems as well. Some examples include: - applications may receive (or choose to store) video data of one video buffer in separate memory buffers; such data would have to be temporarily copied together into one buffer before passing it to a V4L2 device; - applications or drivers may want to pass metadata related to a buffer and it may not be possible to place it in the same buffer together with video data; Example features to be implemented in the future: - allowing video data to be stored in driver-provided memory (MMAP type) while metadata in application-provided buffers (USEPTR type) - useful for drivers that require coefficient matrices, that take or return header/metadata, etc. - allowing variable number of planes passed to each QBUF/DQBUF operations, differing between calls. === II. Short introduction === To establish a consistent nomenclature, for the remainder of this document: - multi-planar indicates a call/format used with multi-planar API, irrespective of the number of planes; - 1-plane format, n-plane formats indicate the number of planes in a format and have nothing to do with the API used; 1-plane formats can be used with the multi-planar API; * The changes are fully backwards-compatible with the current V4L2 API. * All multi-planar calls and types can be recognized by their utilization of new buffer type defines (see below). * Multi-planar API can be used as a superset of both APIs and can replace the single-planar API; old formats can be used as 1-plane multi-planar formats. * A format translation layer is also introduced, new drivers and applications do not have to implement both API versions. A driver that only implements the multi-planar version will still be able to transparently communicate with applications that only use single-planar calls (but those applications will only be able to use the driver's 1-plane formats). The other way around is also possible - a driver that only implements the single-planar API can be used by a multi-planar-API-only application fully. * Applications can query for multi-planar capabilities by means of the standard VIDIOC_QUERYCAP call. * Affected ioctls are those that operate on either pix formats or buffers, which are interpreted in a different way when one of the new buffer types is passed in their corresponding fields: - VIDIOC_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT, VIDIOC_ENUM_FMT; - VIDIOC_QBUF, VIDIOC_DQBUF, VIDIOC_QUERYBUF - VIDIOC_REQBUF (accepts new buffer types, behavior unchanged) * Fourcc codes differ across plane counts, e.g. a 1-plane YCbCr fourcc is different from that of an, otherwise identical, 2-plane YCbCr. On the other hand, a 1-plane format uses the same fourcc code in both versions of the API. * Applications do not have to support both APIs, it is enough to just use the multi-planar version, as it will be transparently converted to single-planar API for 1-plane-format-only drivers. Of course, it is not possible to set a format with more than 1-plane for a single-planar-only driver, but applications should not try this in the first place. They should use formats returned from ENUM_FMT only and those will be 1-plane only. === III. Multi-planar API format
[PATCH v5 3/3] v4l: Add compat functions for the multi-planar API
Add multi-planar ioctl handling to the 32bit compatibility layer. Signed-off-by: Pawel Osciak p.osc...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/media/video/v4l2-compat-ioctl32.c | 221 + 1 files changed, 190 insertions(+), 31 deletions(-) diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index 9004a5f..90bf865 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c @@ -303,6 +303,14 @@ static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pi return 0; } +static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp, + struct v4l2_pix_format_mplane __user *up) +{ + if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane))) + return -EFAULT; + return 0; +} + static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) { if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) @@ -310,6 +318,14 @@ static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pi return 0; } +static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp, + struct v4l2_pix_format_mplane __user *up) +{ + if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane))) + return -EFAULT; + return 0; +} + static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) { if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) @@ -342,6 +358,7 @@ struct v4l2_format32 { enum v4l2_buf_type type; union { struct v4l2_pix_format pix; + struct v4l2_pix_format_mplane pix_mp; struct v4l2_window32win; struct v4l2_vbi_format vbi; struct v4l2_sliced_vbi_format sliced; @@ -358,6 +375,10 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: return get_v4l2_pix_format(kp-fmt.pix, up-fmt.pix); + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + return get_v4l2_pix_format_mplane(kp-fmt.pix_mp, + up-fmt.pix_mp); case V4L2_BUF_TYPE_VIDEO_OVERLAY: case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: return get_v4l2_window32(kp-fmt.win, up-fmt.win); @@ -389,6 +410,10 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: return put_v4l2_pix_format(kp-fmt.pix, up-fmt.pix); + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + return put_v4l2_pix_format_mplane(kp-fmt.pix_mp, + up-fmt.pix_mp); case V4L2_BUF_TYPE_VIDEO_OVERLAY: case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: return put_v4l2_window32(kp-fmt.win, up-fmt.win); @@ -442,6 +467,17 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 return 0; } +struct v4l2_plane32 { + __u32 bytesused; + __u32 length; + union { + __u32 mem_offset; + compat_long_t userptr; + } m; + __u32 data_offset; + __u32 reserved[11]; +}; + struct v4l2_buffer32 { __u32 index; enum v4l2_buf_type type; @@ -457,14 +493,64 @@ struct v4l2_buffer32 { union { __u32 offset; compat_long_t userptr; + compat_caddr_t planes; } m; __u32 length; __u32 input; __u32 reserved; }; +static int get_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32, + enum v4l2_memory memory) +{ + void __user *up_pln; + compat_long_t p; + + if (copy_in_user(up, up32, 2 * sizeof(__u32)) || + copy_in_user(up-data_offset, up32-data_offset, + sizeof(__u32))) + return -EFAULT; + + if (memory == V4L2_MEMORY_USERPTR) { + if (get_user(p, up32-m.userptr)) + return -EFAULT; + up_pln = compat_ptr(p); + if (put_user((unsigned long)up_pln, up-m.userptr)) + return -EFAULT; + } else { + if (copy_in_user(up-m.mem_offset, up32-m.mem_offset, +
[PATCH v5 2/3] v4l: Add multi-planar ioctl handling code
Add multi-planar API core ioctl handling and conversion functions. Signed-off-by: Pawel Osciak p.osc...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Reviewed-by: Marek Szyprowski m.szyprow...@samsung.com --- drivers/media/video/v4l2-ioctl.c | 418 ++ include/media/v4l2-ioctl.h | 16 ++ 2 files changed, 390 insertions(+), 44 deletions(-) diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index a830bbd..3b2880a 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -476,20 +476,33 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd, struct v4l2_buffer *p) { struct v4l2_timecode *tc = p-timecode; + struct v4l2_plane *plane; + int i; dbgarg(cmd, %02ld:%02d:%02d.%08ld index=%d, type=%s, - bytesused=%d, flags=0x%08d, - field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n, + 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-bytesused, p-flags, - p-field, p-sequence, - prt_names(p-memory, v4l2_memory_names), - p-m.userptr, p-length); + p-flags, p-field, p-sequence, + prt_names(p-memory, v4l2_memory_names)); + + if (V4L2_TYPE_IS_MULTIPLANAR(p-type) p-m.planes) { + for (i = 0; i p-length; ++i) { + plane = p-m.planes[i]; + 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 { + dbgarg2(bytesused=%d, offset/userptr=0x%08lx, length=%d\n, + p-bytesused, p-m.userptr, p-length); + } + dbgarg2(timecode=%02d:%02d:%02d type=%d, flags=0x%08d, frames=%d, userbits=0x%08x\n, tc-hours, tc-minutes, tc-seconds, @@ -517,6 +530,27 @@ static inline void v4l_print_pix_fmt(struct video_device *vfd, fmt-bytesperline, fmt-sizeimage, fmt-colorspace); }; +static inline void v4l_print_pix_fmt_mplane(struct video_device *vfd, + struct v4l2_pix_format_mplane *fmt) +{ + int i; + + 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); + + 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 inline void v4l_print_ext_ctrls(unsigned int cmd, struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals) { @@ -570,7 +604,12 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (ops-vidioc_g_fmt_vid_cap) + if (ops-vidioc_g_fmt_vid_cap || + ops-vidioc_g_fmt_vid_cap_mplane) + return 0; + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + if (ops-vidioc_g_fmt_vid_cap_mplane) return 0; break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: @@ -578,7 +617,12 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) return 0; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (ops-vidioc_g_fmt_vid_out) + if (ops-vidioc_g_fmt_vid_out || + ops-vidioc_g_fmt_vid_out_mplane) + return 0; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + if (ops-vidioc_g_fmt_vid_out_mplane) return 0; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: @@ -609,12 +653,70 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) return -EINVAL;
Re: [PATCH v2]Resend:videobuf_dma_sg: a new implementation for mmap
Hi, On Friday 30 July 2010 02:08:02 Figo.zhang wrote: a mmap issue for videobuf-dma-sg: it will alloc a new page for mmaping when it encounter page fault at video_vm_ops-fault(). pls see http://www.spinics.net/lists/linux-media/msg21243.html a new implementation for mmap, it translate to vmalloc to page at video_vm_ops-fault(). in v2, if mem-dma.vmalloc is NULL at video_vm_ops-fault(), it will alloc memory by vmlloc_32(). You're replacing allocation in videobuf_vm_fault by allocationg in videobuf_vm_fault. I don't see the point. videobuf_vm_fault needs to go away completely. This has been discussed previously: fixing videobuf is not really possible. A videobuf2 implementation is needed and is (slowly) being worked on. I wouldn't bother with this patch, just drop it. Signed-off-by: Figo.zhang figo1...@gmail.com --- drivers/media/video/videobuf-dma-sg.c | 50 +++-- 1 files changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 8359e6b..f7295da 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -201,10 +201,11 @@ int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, dprintk(1, init kernel [%d pages]\n, nr_pages); dma-direction = direction; - dma-vmalloc = vmalloc_32(nr_pages PAGE_SHIFT); - if (NULL == dma-vmalloc) { - dprintk(1, vmalloc_32(%d pages) failed\n, nr_pages); - return -ENOMEM; + if (!dma-vmalloc) + dma-vmalloc = vmalloc_32(nr_pages PAGE_SHIFT); + if (NULL == dma-vmalloc) { + dprintk(1, vmalloc_32(%d pages) failed\n, nr_pages); + return -ENOMEM; } dprintk(1, vmalloc is at addr 0x%08lx, size=%d\n, @@ -397,16 +398,47 @@ static void videobuf_vm_close(struct vm_area_struct *vma) */ static int videobuf_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - struct page *page; + struct page *page = NULL; + struct videobuf_mapping *map = vma-vm_private_data; + struct videobuf_queue *q = map-q; + struct videobuf_dma_sg_memory *mem = NULL; + + unsigned long offset; + unsigned long page_nr; + int first; dprintk(3, fault: fault @ %08lx [vma %08lx-%08lx]\n, (unsigned long)vmf-virtual_address, vma-vm_start, vma-vm_end); - page = alloc_page(GFP_USER | __GFP_DMA32); - if (!page) - return VM_FAULT_OOM; - clear_user_highpage(page, (unsigned long)vmf-virtual_address); + mutex_lock(q-vb_lock); + offset = (unsigned long)vmf-virtual_address - vma-vm_start; + page_nr = offset PAGE_SHIFT; + + for (first = 0; first VIDEO_MAX_FRAME; first++) { + if (NULL == q-bufs[first]) + continue; + + MAGIC_CHECK(mem-magic, MAGIC_SG_MEM); + + if (q-bufs[first]-map == map) + break; + } + + mem = q-bufs[first]-priv; + if (!mem) + return VM_FAULT_SIGBUS; + if (!mem-dma.vmalloc) { + mem-dma.vmalloc = vmalloc_32(PAGE_ALIGN(q-bufs[first]-size)); + if (NULL == mem-dma.vmalloc) { + dprintk(1, %s: vmalloc_32() failed\n, __func__); + return VM_FAULT_OOM; + } + } else + page = vmalloc_to_page(mem-dma.vmalloc+ + (offset (~PAGE_MASK))); + mutex_unlock(q-vb_lock); + vmf-page = page; return 0; -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 04/13] IR: fix locking in ir_raw_event_work
On Thu, 2010-07-29 at 22:42 -0400, Andy Walls wrote: On Fri, 2010-07-30 at 05:17 +0300, Maxim Levitsky wrote: It is prefectly possible to have ir_raw_event_work running concurently on two cpus, thus we must protect it from that situation. Yup, the work is marked as not pending (and hence reschedulable) just before the work handler is run. Maybe better solution is to ditch the workqueue at all and use good 'ol thread per receiver, and just wake it up... I suppose you could also use a single threaded workqueue instead of a mutex, and let a bit test provide exclusivity. With the mutex, when the second thread finally obtains the lock, there will likely not be anything for it to do. Mutex there is for another reason, to protect against decoder insert/removal. However, I think its best just to use a bare kthread for the purpose of this. Best regards, Maxim Levitsky -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] [PATCH 1/6] SoC Camera: add driver for OMAP1 camera interface
Hi Janusz Thanks once more for the patches, from your patches it is obvious, that you've spent quite a bit of time on them and you have not just copy-pasted various bits and pieces from other drivers, just filling your hardware details, but you also actually understand a lot of what is actually going on in there. So, I think, fixing remaining mostly minor issues shouldn't be too difficult for you either. On Sun, 18 Jul 2010, Janusz Krzysztofik wrote: This is a V4L2 driver for TI OMAP1 SoC camera interface. Two versions of the driver are provided, using either videobuf-dma-contig or videobuf-dma-sg. The former uses less processing power, but often fails to allocate contignuous buffer memory. The latter is free of this problem, but generates tens of DMA interrupts per frame. Hm, would it be difficult to first try contig, and if it fails - fall back to sg? In its present state buffer management in your driver is pretty difficult to follow. At the VERY least you have to extensively document your buffer manipulations. Better yet clean it up. AFAIU, your ready pointer is pretty much unused in the contiguous case. Or you can easily get rid of it. So, I think, a very welcome improvement to the driver would be a cleaner separation between the two cases. Don't try that much to reuse the code as much as possible. Would be much better to have clean separation between the two implementations - whether dynamically switchable at runtime or at config time - would be best to separate the two implementations to the point, where each of them becomes understandable and maintainable. So, I will do a pretty formal review this time and wait for v2. And in v2 I'd like to at the very least see detailed buffer-management documentation, or - better yet - a rework with a clean separation. Both versions work stable for me, even under heavy load, on my OMAP1510 based Amstrad Delta videophone, that is the oldest, least powerfull OMAP1 implementation. The interface generally works in pass-through mode. Since input data byte endianess can be swapped, it provides up to two v4l2 pixel formats per each of several soc_mbus formats that have their swapped endian counterparts. Boards using this driver can provide it with the followning information: - if and what freqency clock is expected by an on-board camera sensor, - what is the maximum pixel clock that should be accepted from the sensor, - what is the polarity of the sensor provided pixel clock, - if the interface GPIO line is connected to a sensor reset/powerdown input and what is the input polarity. Created and tested against linux-2.6.35-rc3 on Amstrad Delta. Signed-off-by: Janusz Krzysztofik jkrzy...@tis.icnet.pl --- drivers/media/video/Kconfig| 14 drivers/media/video/Makefile |1 drivers/media/video/omap1_camera.c | 1656 + include/media/omap1_camera.h | 16 4 files changed, 1687 insertions(+) --- linux-2.6.35-rc3.orig/include/media/omap1_camera.h1970-01-01 01:00:00.0 +0100 +++ linux-2.6.35-rc3/include/media/omap1_camera.h 2010-07-18 01:31:57.0 +0200 @@ -0,0 +1,16 @@ A copyright / licence header here, please +#ifndef __MEDIA_OMAP1_CAMERA_H_ +#define __MEDIA_OMAP1_CAMERA_H_ + +#define OMAP1_CAMERA_IOSIZE 0x1c + +struct omap1_cam_platform_data { + unsigned long camexclk_khz; + unsigned long lclk_khz_max; + unsigned long flags; +}; + +#define OMAP1_CAMERA_LCLK_RISING BIT(0) +#define OMAP1_CAMERA_RST_LOW BIT(1) +#define OMAP1_CAMERA_RST_HIGHBIT(2) Then you need to #include linux/bitops.h + +#endif /* __MEDIA_OMAP1_CAMERA_H_ */ --- linux-2.6.35-rc3.orig/drivers/media/video/Kconfig 2010-06-26 15:55:29.0 +0200 +++ linux-2.6.35-rc3/drivers/media/video/Kconfig 2010-07-02 04:12:02.0 +0200 @@ -962,6 +962,20 @@ config VIDEO_SH_MOBILE_CEU ---help--- This is a v4l2 driver for the SuperH Mobile CEU Interface +config VIDEO_OMAP1 + tristate OMAP1 Camera Interface driver + depends on VIDEO_DEV ARCH_OMAP1 SOC_CAMERA + select VIDEOBUF_DMA_CONTIG if !VIDEO_OMAP1_SG + ---help--- + This is a v4l2 driver for the TI OMAP1 camera interface + +if VIDEO_OMAP1 Don't think you need this if, the depends on below should suffice. +config VIDEO_OMAP1_SG + bool Scatter-gather mode + depends on VIDEO_OMAP1 EXPERIMENTAL + select VIDEOBUF_DMA_SG +endif + config VIDEO_OMAP2 tristate OMAP2 Camera Capture Interface driver depends on VIDEO_DEV ARCH_OMAP2 --- linux-2.6.35-rc3.orig/drivers/media/video/Makefile2010-06-26 15:55:29.0 +0200 +++ linux-2.6.35-rc3/drivers/media/video/Makefile 2010-06-26 17:28:09.0 +0200 @@ -165,6 +165,7 @@ obj-$(CONFIG_VIDEO_MX1) += mx1_camera. obj-$(CONFIG_VIDEO_MX3) +=
Re: [PATCH 13/13] IR: Port ene driver to new IR subsystem and enable it.
On Thu, 2010-07-29 at 23:46 -0400, Andy Walls wrote: On Thu, 2010-07-29 at 22:39 -0400, Jon Smirl wrote: On Thu, Jul 29, 2010 at 10:17 PM, Maxim Levitsky maximlevit...@gmail.com wrote: note that error_adjustment module option is added. This allows to reduce input samples by a percent. This makes input on my system more correct. Default is 4% as it works best here. Note that only normal input is adjusted. I don't know what adjustments to apply to fan tachometer input. Maybe it is accurate already. Do you have the manual for the ENE chip in English? or do you read Chinese? The datasheet for a similar chip, the KB3700, is out there in English, but it doesn't have CIR. You might find these links mildly interesting: http://www.coreboot.org/Embedded_controller http://wiki.laptop.org/go/Embedded_controller http://lists.laptop.org/pipermail/openec/2008-July/000108.html Nope, I have read that. Regards, Andy Maybe you can figure out why the readings are off by 4%. I suspect that someone has set a clock divider wrong when programming the chip. For example setting the divider for a 25Mhz clock when the clock is actually 26Mhz would cause the error you are seeing. Or they just made a mistake in computing the divisor. It is probably a bug in the BIOS of your laptop. If that's the case you could add a quirk in the system boot code to fix the register setting. I figured out how windows driver compensates for the offset, and do the same in my driver. I think the problem is solved. Best regards, Maxim Levitsky -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/9 v3] IR: few fixes, additions and ENE driver
Hi, This is mostly same patchset. I addressed the comments of Andy Walls. Now IR decoding is done by a separate thread, and this fixes the race, and unnesesary performance loss due to it. Best regards, Maxim Levitsky -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/13] IR: minor fixes:
* lirc: Don't propagate reset event to userspace * lirc: Remove strange logic from lirc that would make first sample always be pulse * Make TO_US macro actualy print what it should. Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/ir-core-priv.h |4 +--- drivers/media/IR/ir-lirc-codec.c | 14 -- drivers/media/IR/ir-raw-event.c |3 +++ 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index babd520..dc26e2b 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h @@ -76,7 +76,6 @@ struct ir_raw_event_ctrl { struct lirc_codec { struct ir_input_dev *ir_dev; struct lirc_driver *drv; - int lircdata; } lirc; }; @@ -104,10 +103,9 @@ static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration) ev-duration -= duration; } -#define TO_US(duration)(((duration) + 500) / 1000) +#define TO_US(duration)DIV_ROUND_CLOSEST((duration), 1000) #define TO_STR(is_pulse) ((is_pulse) ? pulse : space) #define IS_RESET(ev) (ev.duration == 0) - /* * Routines from ir-sysfs.c - Meant to be called only internally inside * ir-core diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c index 3ba482d..8ca01fd 100644 --- a/drivers/media/IR/ir-lirc-codec.c +++ b/drivers/media/IR/ir-lirc-codec.c @@ -32,6 +32,7 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) { struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + int sample; if (!(ir_dev-raw-enabled_protocols IR_TYPE_LIRC)) return 0; @@ -39,18 +40,21 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) if (!ir_dev-raw-lirc.drv || !ir_dev-raw-lirc.drv-rbuf) return -EINVAL; + if (IS_RESET(ev)) + return 0; + IR_dprintk(2, LIRC data transfer started (%uus %s)\n, TO_US(ev.duration), TO_STR(ev.pulse)); - ir_dev-raw-lirc.lircdata += ev.duration / 1000; + + sample = ev.duration / 1000; if (ev.pulse) - ir_dev-raw-lirc.lircdata |= PULSE_BIT; + sample |= PULSE_BIT; lirc_buffer_write(ir_dev-raw-lirc.drv-rbuf, - (unsigned char *) ir_dev-raw-lirc.lircdata); + (unsigned char *) sample); wake_up(ir_dev-raw-lirc.drv-rbuf-wait_poll); - ir_dev-raw-lirc.lircdata = 0; return 0; } @@ -224,8 +228,6 @@ static int ir_lirc_register(struct input_dev *input_dev) ir_dev-raw-lirc.drv = drv; ir_dev-raw-lirc.ir_dev = ir_dev; - ir_dev-raw-lirc.lircdata = PULSE_MASK; - return 0; lirc_register_failed: diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index 6f192ef..51f65da 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c @@ -66,6 +66,9 @@ int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev) if (!ir-raw) return -EINVAL; + IR_dprintk(2, sample: (05%dus %s)\n, + TO_US(ev-duration), TO_STR(ev-pulse)); + if (kfifo_in(ir-raw-kfifo, ev, sizeof(*ev)) != sizeof(*ev)) return -ENOMEM; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/13] IR: Kconfig fixes
Move IR drives below separate menu. This allows to disable them. Also correct a typo. Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/Kconfig | 10 +++--- 1 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig index e557ae0..fc48a3f 100644 --- a/drivers/media/IR/Kconfig +++ b/drivers/media/IR/Kconfig @@ -1,8 +1,10 @@ -config IR_CORE - tristate +menuconfig IR_CORE + tristate Infrared remote controller adapters depends on INPUT default INPUT +if IR_CORE + config VIDEO_IR tristate depends on IR_CORE @@ -16,7 +18,7 @@ config LIRC Enable this option to build the Linux Infrared Remote Control (LIRC) core device interface driver. The LIRC interface passes raw IR to and from userspace, where the - LIRC daemon handles protocol decoding for IR reception ann + LIRC daemon handles protocol decoding for IR reception and encoding for IR transmitting (aka blasting). source drivers/media/IR/keymaps/Kconfig @@ -102,3 +104,5 @@ config IR_MCEUSB To compile this driver as a module, choose M here: the module will be called mceusb. + +endif #IR_CORE -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/13] IR: replace spinlock with mutex.
Some handlers (lirc for example) allocates memory on initialization, doing so in atomic context is cumbersome. Fixes warning about sleeping function in atomic context. Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/ir-raw-event.c | 28 ++-- 1 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index 51f65da..9d5c029 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c @@ -13,7 +13,7 @@ */ #include linux/workqueue.h -#include linux/spinlock.h +#include linux/mutex.h #include linux/sched.h #include ir-core-priv.h @@ -24,7 +24,7 @@ static LIST_HEAD(ir_raw_client_list); /* Used to handle IR raw handler extensions */ -static DEFINE_SPINLOCK(ir_raw_handler_lock); +static DEFINE_MUTEX(ir_raw_handler_lock); static LIST_HEAD(ir_raw_handler_list); static u64 available_protocols; @@ -41,10 +41,10 @@ static void ir_raw_event_work(struct work_struct *work) container_of(work, struct ir_raw_event_ctrl, rx_work); while (kfifo_out(raw-kfifo, ev, sizeof(ev)) == sizeof(ev)) { - spin_lock(ir_raw_handler_lock); + mutex_lock(ir_raw_handler_lock); list_for_each_entry(handler, ir_raw_handler_list, list) handler-decode(raw-input_dev, ev); - spin_unlock(ir_raw_handler_lock); + mutex_unlock(ir_raw_handler_lock); raw-prev_ev = ev; } } @@ -150,9 +150,9 @@ u64 ir_raw_get_allowed_protocols() { u64 protocols; - spin_lock(ir_raw_handler_lock); + mutex_lock(ir_raw_handler_lock); protocols = available_protocols; - spin_unlock(ir_raw_handler_lock); + mutex_unlock(ir_raw_handler_lock); return protocols; } @@ -180,12 +180,12 @@ int ir_raw_event_register(struct input_dev *input_dev) return rc; } - spin_lock(ir_raw_handler_lock); + mutex_lock(ir_raw_handler_lock); list_add_tail(ir-raw-list, ir_raw_client_list); list_for_each_entry(handler, ir_raw_handler_list, list) if (handler-raw_register) handler-raw_register(ir-raw-input_dev); - spin_unlock(ir_raw_handler_lock); + mutex_unlock(ir_raw_handler_lock); return 0; } @@ -200,12 +200,12 @@ void ir_raw_event_unregister(struct input_dev *input_dev) cancel_work_sync(ir-raw-rx_work); - spin_lock(ir_raw_handler_lock); + mutex_lock(ir_raw_handler_lock); list_del(ir-raw-list); list_for_each_entry(handler, ir_raw_handler_list, list) if (handler-raw_unregister) handler-raw_unregister(ir-raw-input_dev); - spin_unlock(ir_raw_handler_lock); + mutex_unlock(ir_raw_handler_lock); kfifo_free(ir-raw-kfifo); kfree(ir-raw); @@ -220,13 +220,13 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) { struct ir_raw_event_ctrl *raw; - spin_lock(ir_raw_handler_lock); + mutex_lock(ir_raw_handler_lock); list_add_tail(ir_raw_handler-list, ir_raw_handler_list); if (ir_raw_handler-raw_register) list_for_each_entry(raw, ir_raw_client_list, list) ir_raw_handler-raw_register(raw-input_dev); available_protocols |= ir_raw_handler-protocols; - spin_unlock(ir_raw_handler_lock); + mutex_unlock(ir_raw_handler_lock); return 0; } @@ -236,13 +236,13 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) { struct ir_raw_event_ctrl *raw; - spin_lock(ir_raw_handler_lock); + mutex_lock(ir_raw_handler_lock); list_del(ir_raw_handler-list); if (ir_raw_handler-raw_unregister) list_for_each_entry(raw, ir_raw_client_list, list) ir_raw_handler-raw_unregister(raw-input_dev); available_protocols = ~ir_raw_handler-protocols; - spin_unlock(ir_raw_handler_lock); + mutex_unlock(ir_raw_handler_lock); } EXPORT_SYMBOL(ir_raw_handler_unregister); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/13] IR: fix locking in ir_raw_event_work
It is prefectly possible to have ir_raw_event_work running concurently on two cpus, thus we must protect it from that situation. Just switch to a thread that we wake up as soon as we have data. This also ensures that this thread doesn't run unnessesarly. Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/ir-core-priv.h |2 +- drivers/media/IR/ir-raw-event.c | 42 -- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index dc26e2b..84c7a9a 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h @@ -32,7 +32,7 @@ struct ir_raw_handler { struct ir_raw_event_ctrl { struct list_headlist; /* to keep track of raw clients */ - struct work_struct rx_work;/* for the rx decoding workqueue */ + struct task_struct *thread; struct kfifokfifo; /* fifo for the pulse/space durations */ ktime_t last_event; /* when last event occurred */ enum raw_event_type last_type; /* last event type */ diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index 9d5c029..d0c18db 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c @@ -12,9 +12,10 @@ * GNU General Public License for more details. */ -#include linux/workqueue.h +#include linux/kthread.h #include linux/mutex.h #include linux/sched.h +#include linux/freezer.h #include ir-core-priv.h /* Define the max number of pulse/space transitions to buffer */ @@ -33,20 +34,30 @@ static u64 available_protocols; static struct work_struct wq_load; #endif -static void ir_raw_event_work(struct work_struct *work) +static int ir_raw_event_thread(void *data) { struct ir_raw_event ev; struct ir_raw_handler *handler; - struct ir_raw_event_ctrl *raw = - container_of(work, struct ir_raw_event_ctrl, rx_work); + struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; + + while (!kthread_should_stop()) { + try_to_freeze(); - while (kfifo_out(raw-kfifo, ev, sizeof(ev)) == sizeof(ev)) { mutex_lock(ir_raw_handler_lock); - list_for_each_entry(handler, ir_raw_handler_list, list) - handler-decode(raw-input_dev, ev); + + while (kfifo_out(raw-kfifo, ev, sizeof(ev)) == sizeof(ev)) { + list_for_each_entry(handler, ir_raw_handler_list, list) + handler-decode(raw-input_dev, ev); + raw-prev_ev = ev; + } + mutex_unlock(ir_raw_handler_lock); - raw-prev_ev = ev; + + set_current_state(TASK_INTERRUPTIBLE); + schedule(); } + + return 0; } /** @@ -141,7 +152,7 @@ void ir_raw_event_handle(struct input_dev *input_dev) if (!ir-raw) return; - schedule_work(ir-raw-rx_work); + wake_up_process(ir-raw-thread); } EXPORT_SYMBOL_GPL(ir_raw_event_handle); @@ -170,7 +181,7 @@ int ir_raw_event_register(struct input_dev *input_dev) return -ENOMEM; ir-raw-input_dev = input_dev; - INIT_WORK(ir-raw-rx_work, ir_raw_event_work); + ir-raw-enabled_protocols = ~0; rc = kfifo_alloc(ir-raw-kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, GFP_KERNEL); @@ -180,6 +191,15 @@ int ir_raw_event_register(struct input_dev *input_dev) return rc; } + ir-raw-thread = kthread_run(ir_raw_event_thread, ir-raw, + rc%u, (unsigned int)ir-devno); + + if (IS_ERR(ir-raw-thread)) { + kfree(ir-raw); + ir-raw = NULL; + return PTR_ERR(ir-raw-thread); + } + mutex_lock(ir_raw_handler_lock); list_add_tail(ir-raw-list, ir_raw_client_list); list_for_each_entry(handler, ir_raw_handler_list, list) @@ -198,7 +218,7 @@ void ir_raw_event_unregister(struct input_dev *input_dev) if (!ir-raw) return; - cancel_work_sync(ir-raw-rx_work); + kthread_stop(ir-raw-thread); mutex_lock(ir_raw_handler_lock); list_del(ir-raw-list); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/13] IR: JVC: make repeat work
Currently, jvc decoder will attempt misdetect next press as a repeat of last keypress, therefore second keypress isn't detected. Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/ir-jvc-decoder.c | 14 +- 1 files changed, 13 insertions(+), 1 deletions(-) diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c index 8894d8b..77a89c4 100644 --- a/drivers/media/IR/ir-jvc-decoder.c +++ b/drivers/media/IR/ir-jvc-decoder.c @@ -32,6 +32,7 @@ enum jvc_state { STATE_BIT_SPACE, STATE_TRAILER_PULSE, STATE_TRAILER_SPACE, + STATE_CHECK_REPEAT, }; /** @@ -60,6 +61,7 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev) IR_dprintk(2, JVC decode started at state %d (%uus %s)\n, data-state, TO_US(ev.duration), TO_STR(ev.pulse)); +again: switch (data-state) { case STATE_INACTIVE: @@ -149,8 +151,18 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev) } data-count = 0; - data-state = STATE_BIT_PULSE; + data-state = STATE_CHECK_REPEAT; return 0; + + case STATE_CHECK_REPEAT: + if (!ev.pulse) + break; + + if (eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2)) + data-state = STATE_INACTIVE; + else + data-state = STATE_BIT_PULSE; + goto again; } out: -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/13] IR: nec decoder: fix repeat.
Repeat space is 4 units, not 8. Current code would never trigger a repeat. However that isn't true for NECX, so repeat there must be handled differently. Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/ir-nec-decoder.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index 52e0f37..1c0cf03 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c @@ -20,7 +20,7 @@ #define NEC_HEADER_PULSE (16 * NEC_UNIT) #define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */ #define NEC_HEADER_SPACE (8 * NEC_UNIT) -#define NEC_REPEAT_SPACE (8 * NEC_UNIT) +#define NEC_REPEAT_SPACE (4 * NEC_UNIT) #define NEC_BIT_PULSE (1 * NEC_UNIT) #define NEC_BIT_0_SPACE(1 * NEC_UNIT) #define NEC_BIT_1_SPACE(3 * NEC_UNIT) -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/13] IR: Allow not to compile keymaps in.
Currently, ir device registration fails if keymap requested by driver is not found. Fix that by always compiling in the empty keymap, and using it as a failback. Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/ir-core-priv.h |3 +- drivers/media/IR/ir-sysfs.c |2 + drivers/media/IR/keymaps/Makefile |1 - drivers/media/IR/keymaps/rc-empty.c | 44 --- drivers/media/IR/rc-map.c | 23 ++ include/media/ir-core.h |8 - 6 files changed, 33 insertions(+), 48 deletions(-) delete mode 100644 drivers/media/IR/keymaps/rc-empty.c diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index 08383b9..e9c3cce 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h @@ -125,7 +125,8 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); void ir_raw_init(void); - +int ir_rcmap_init(void); +void ir_rcmap_cleanup(void); /* * Decoder initialization code * diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index a841e51..936dff8 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c @@ -341,6 +341,7 @@ static int __init ir_core_init(void) /* Initialize/load the decoders/keymap code that will be used */ ir_raw_init(); + ir_rcmap_init(); return 0; } @@ -348,6 +349,7 @@ static int __init ir_core_init(void) static void __exit ir_core_exit(void) { class_unregister(ir_input_class); + ir_rcmap_cleanup(); } module_init(ir_core_init); diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile index 86d3d1f..24992cd 100644 --- a/drivers/media/IR/keymaps/Makefile +++ b/drivers/media/IR/keymaps/Makefile @@ -17,7 +17,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-dm1105-nec.o \ rc-dntv-live-dvb-t.o \ rc-dntv-live-dvbt-pro.o \ - rc-empty.o \ rc-em-terratec.o \ rc-encore-enltv2.o \ rc-encore-enltv.o \ diff --git a/drivers/media/IR/keymaps/rc-empty.c b/drivers/media/IR/keymaps/rc-empty.c deleted file mode 100644 index 3b338d8..000 --- a/drivers/media/IR/keymaps/rc-empty.c +++ /dev/null @@ -1,44 +0,0 @@ -/* empty.h - Keytable for empty Remote Controller - * - * keymap imported from ir-keymaps.c - * - * Copyright (c) 2010 by Mauro Carvalho Chehab mche...@redhat.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; either version 2 of the License, or - * (at your option) any later version. - */ - -#include media/rc-map.h - -/* empty keytable, can be used as placeholder for not-yet created keytables */ - -static struct ir_scancode empty[] = { - { 0x2a, KEY_COFFEE }, -}; - -static struct rc_keymap empty_map = { - .map = { - .scan= empty, - .size= ARRAY_SIZE(empty), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ - .name= RC_MAP_EMPTY, - } -}; - -static int __init init_rc_map_empty(void) -{ - return ir_register_map(empty_map); -} - -static void __exit exit_rc_map_empty(void) -{ - ir_unregister_map(empty_map); -} - -module_init(init_rc_map_empty) -module_exit(exit_rc_map_empty) - -MODULE_LICENSE(GPL); -MODULE_AUTHOR(Mauro Carvalho Chehab mche...@redhat.com); diff --git a/drivers/media/IR/rc-map.c b/drivers/media/IR/rc-map.c index 46a8f15..689143f 100644 --- a/drivers/media/IR/rc-map.c +++ b/drivers/media/IR/rc-map.c @@ -82,3 +82,26 @@ void ir_unregister_map(struct rc_keymap *map) } EXPORT_SYMBOL_GPL(ir_unregister_map); + +static struct ir_scancode empty[] = { + { 0x2a, KEY_COFFEE }, +}; + +static struct rc_keymap empty_map = { + .map = { + .scan= empty, + .size= ARRAY_SIZE(empty), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name= RC_MAP_EMPTY, + } +}; + +int ir_rcmap_init(void) +{ + return ir_register_map(empty_map); +} + +void ir_rcmap_cleanup(void) +{ + ir_unregister_map(empty_map); +} diff --git a/include/media/ir-core.h b/include/media/ir-core.h index 513e60d..197d05a 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h @@ -110,8 +110,12 @@ static inline int ir_input_register(struct input_dev *dev, return -EINVAL; ir_codes = get_rc_map(map_name); - if (!ir_codes) - return -EINVAL; + if (!ir_codes) { + ir_codes = get_rc_map(RC_MAP_EMPTY); + + if (!ir_codes) + return -EINVAL; + } rc =
[PATCH 07/13] IR: NECX: support repeat
This adds support for repeat detecting for NECX variant Tested with uneversal remote Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/ir-core-priv.h |1 + drivers/media/IR/ir-nec-decoder.c | 16 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index 84c7a9a..08383b9 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h @@ -45,6 +45,7 @@ struct ir_raw_event_ctrl { int state; unsigned count; u32 bits; + bool is_nec_x; } nec; struct rc5_dec { int state; diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index 1c0cf03..59127b1 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c @@ -26,6 +26,7 @@ #define NEC_BIT_1_SPACE(3 * NEC_UNIT) #defineNEC_TRAILER_PULSE (1 * NEC_UNIT) #defineNEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */ +#define NECX_REPEAT_BITS 1 enum nec_state { STATE_INACTIVE, @@ -67,8 +68,11 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) if (!ev.pulse) break; - if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) - !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2)) + if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2)) + data-is_nec_x = false; + else if (eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2)) + data-is_nec_x = true; + else break; data-count = 0; @@ -105,6 +109,14 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) if (ev.pulse) break; + if (geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2) + data-is_nec_x data-count == NECX_REPEAT_BITS) { + IR_dprintk(1, Repeat last key\n); + ir_repeat(input_dev); + data-state = STATE_INACTIVE; + return 0; + } + data-bits = 1; if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) data-bits |= 1; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/13] IR: add helper function for hardware with small o/b buffer.
Some ir input devices have small buffer, and interrupt the host each time it is full (or half full) Add a helper that automaticly handles timeouts, and also automaticly merges samples of same time (space-space) Such samples might be placed by hardware because size of sample in the buffer is small (a byte for example). Also remove constness from ir_dev_props, because it now contains timeout settings that driver might want to change Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/ir-core-priv.h |1 + drivers/media/IR/ir-keytable.c |2 +- drivers/media/IR/ir-raw-event.c | 84 +++ include/media/ir-core.h | 23 +- 4 files changed, 106 insertions(+), 4 deletions(-) diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index e9c3cce..30ff52c 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h @@ -41,6 +41,7 @@ struct ir_raw_event_ctrl { /* raw decoder state follows */ struct ir_raw_event prev_ev; + struct ir_raw_event this_ev; struct nec_dec { int state; unsigned count; diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 94a8577..34b9c07 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -428,7 +428,7 @@ static void ir_close(struct input_dev *input_dev) */ int __ir_input_register(struct input_dev *input_dev, const struct ir_scancode_table *rc_tab, - const struct ir_dev_props *props, + struct ir_dev_props *props, const char *driver_name) { struct ir_input_dev *ir_dev; diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index d0c18db..43094e7 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c @@ -140,6 +140,90 @@ int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type typ EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); /** + * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing + * @input_dev: the struct input_dev device descriptor + * @type: the type of the event that has occurred + * + * This routine (which may be called from an interrupt context) works + * in similiar manner to ir_raw_event_store_edge. + * This routine is intended for devices with limited internal buffer + * It automerges samples of same type, and handles timeouts + */ +int ir_raw_event_store_with_filter(struct input_dev *input_dev, + struct ir_raw_event *ev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + struct ir_raw_event_ctrl *raw = ir-raw; + + if (!raw || !ir-props) + return -EINVAL; + + /* Ignore spaces in idle mode */ + if (ir-idle !ev-pulse) + return 0; + else if (ir-idle) + ir_raw_event_set_idle(input_dev, 0); + + if (!raw-this_ev.duration) { + raw-this_ev = *ev; + } else if (ev-pulse == raw-this_ev.pulse) { + raw-this_ev.duration += ev-duration; + } else { + ir_raw_event_store(input_dev, raw-this_ev); + raw-this_ev = *ev; + } + + /* Enter idle mode if nessesary */ + if (!ev-pulse ir-props-timeout + raw-this_ev.duration = ir-props-timeout) + ir_raw_event_set_idle(input_dev, 1); + return 0; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); + +void ir_raw_event_set_idle(struct input_dev *input_dev, int idle) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + struct ir_raw_event_ctrl *raw = ir-raw; + ktime_t now; + u64 delta; + + if (!ir-props) + return; + + if (!ir-raw) + goto out; + + if (idle) { + IR_dprintk(2, enter idle mode\n); + raw-last_event = ktime_get(); + } else { + IR_dprintk(2, exit idle mode\n); + + now = ktime_get(); + delta = ktime_to_ns(ktime_sub(now, ir-raw-last_event)); + + WARN_ON(raw-this_ev.pulse); + + raw-this_ev.duration = + min(raw-this_ev.duration + delta, + (u64)IR_MAX_DURATION); + + ir_raw_event_store(input_dev, raw-this_ev); + + if (raw-this_ev.duration == IR_MAX_DURATION) + ir_raw_event_reset(input_dev); + + raw-this_ev.duration = 0; + } +out: + if (ir-props-s_idle) + ir-props-s_idle(ir-props-priv, idle); + ir-idle = idle; +} +EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); + +/** * ir_raw_event_handle() - schedules the decoding of stored ir data * @input_dev: the struct input_dev device descriptor *
[PATCH 11/13] IR: report unknown scancodes the in-kernel decoders found.
This way it is possible to use evtest to create keymap for unknown remote. Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/ir-keytable.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 34b9c07..ba7678a 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -339,6 +339,8 @@ void ir_repeat(struct input_dev *dev) spin_lock_irqsave(ir-keylock, flags); + input_event(dev, EV_MSC, MSC_SCAN, ir-last_scancode); + if (!ir-keypressed) goto out; @@ -370,6 +372,8 @@ void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) spin_lock_irqsave(ir-keylock, flags); + input_event(dev, EV_MSC, MSC_SCAN, scancode); + /* Repeat event? */ if (ir-keypressed ir-last_scancode == scancode @@ -383,9 +387,11 @@ void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) ir-last_toggle = toggle; ir-last_keycode = keycode; + if (keycode == KEY_RESERVED) goto out; + /* Register a keypress */ ir-keypressed = true; IR_dprintk(1, %s: key down event, key 0x%04x, scancode 0x%04x\n, @@ -480,6 +486,8 @@ int __ir_input_register(struct input_dev *input_dev, set_bit(EV_KEY, input_dev-evbit); set_bit(EV_REP, input_dev-evbit); + set_bit(EV_MSC, input_dev-evbit); + set_bit(MSC_SCAN, input_dev-mscbit); if (ir_setkeytable(input_dev, ir_dev-rc_tab, rc_tab)) { rc = -ENOMEM; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/13] IR: extend interfaces to support more device settings LIRC: add new IOCTL that enables learning mode (wide band receiver)
Still missing features: carrier report timeout reports. Will need to pack these into ir_raw_event Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- drivers/media/IR/ir-core-priv.h |1 + drivers/media/IR/ir-lirc-codec.c | 112 +++--- include/media/ir-core.h | 14 + include/media/lirc.h |5 ++- 4 files changed, 112 insertions(+), 20 deletions(-) diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index 30ff52c..52253b4 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h @@ -78,6 +78,7 @@ struct ir_raw_event_ctrl { struct lirc_codec { struct ir_input_dev *ir_dev; struct lirc_driver *drv; + int carrier_low; } lirc; }; diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c index 8ca01fd..5d5150f 100644 --- a/drivers/media/IR/ir-lirc-codec.c +++ b/drivers/media/IR/ir-lirc-codec.c @@ -46,7 +46,6 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) IR_dprintk(2, LIRC data transfer started (%uus %s)\n, TO_US(ev.duration), TO_STR(ev.pulse)); - sample = ev.duration / 1000; if (ev.pulse) sample |= PULSE_BIT; @@ -96,13 +95,14 @@ out: return ret; } -static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) +static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, + unsigned long __user arg) { struct lirc_codec *lirc; struct ir_input_dev *ir_dev; int ret = 0; void *drv_data; - unsigned long val; + unsigned long val = 0; lirc = lirc_get_pdata(filep); if (!lirc) @@ -114,47 +114,106 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long ar drv_data = ir_dev-props-priv; - switch (cmd) { - case LIRC_SET_TRANSMITTER_MASK: + if (_IOC_DIR(cmd) _IOC_WRITE) { ret = get_user(val, (unsigned long *)arg); if (ret) return ret; + } + + switch (cmd) { + + /* legacy support */ + case LIRC_GET_SEND_MODE: + val = LIRC_CAN_SEND_PULSE LIRC_CAN_SEND_MASK; + break; + + case LIRC_SET_SEND_MODE: + if (val != (LIRC_MODE_PULSE LIRC_CAN_SEND_MASK)) + return -EINVAL; + break; - if (ir_dev-props ir_dev-props-s_tx_mask) + /* TX settings */ + case LIRC_SET_TRANSMITTER_MASK: + if (ir_dev-props-s_tx_mask) ret = ir_dev-props-s_tx_mask(drv_data, (u32)val); else return -EINVAL; break; case LIRC_SET_SEND_CARRIER: - ret = get_user(val, (unsigned long *)arg); - if (ret) - return ret; - - if (ir_dev-props ir_dev-props-s_tx_carrier) + if (ir_dev-props-s_tx_carrier) ir_dev-props-s_tx_carrier(drv_data, (u32)val); else return -EINVAL; break; - case LIRC_GET_SEND_MODE: - val = LIRC_CAN_SEND_PULSE LIRC_CAN_SEND_MASK; - ret = put_user(val, (unsigned long *)arg); + case LIRC_SET_SEND_DUTY_CYCLE: + if (!ir_dev-props-s_tx_duty_cycle) + return -ENOSYS; + + if (val = 0 || val = 100) + return -EINVAL; + + ir_dev-props-s_tx_duty_cycle(ir_dev-props-priv, val); break; - case LIRC_SET_SEND_MODE: - ret = get_user(val, (unsigned long *)arg); - if (ret) - return ret; + /* RX settings */ + case LIRC_SET_REC_CARRIER: + if (ir_dev-props-s_rx_carrier_range) + ret = ir_dev-props-s_rx_carrier_range( + ir_dev-props-priv, + ir_dev-raw-lirc.carrier_low, val); + else + return -ENOSYS; - if (val != (LIRC_MODE_PULSE LIRC_CAN_SEND_MASK)) + if (!ret) + ir_dev-raw-lirc.carrier_low = 0; + break; + + case LIRC_SET_REC_CARRIER_RANGE: + if (val = 0) + ir_dev-raw-lirc.carrier_low = val; + break; + + + case LIRC_GET_REC_RESOLUTION: + val = ir_dev-props-rx_resolution; + break; + + case LIRC_SET_WIDEBAND_RECEIVER: + if (ir_dev-props-s_learning_mode) + return ir_dev-props-s_learning_mode( + ir_dev-props-priv, !!val); + else + return -ENOSYS; + + /*
[PATCH 13/13] IR: Port ene driver to new IR subsystem and enable it.
Signed-off-by: Maxim Levitsky maximlevit...@gmail.com --- MAINTAINERS |6 + drivers/media/IR/Kconfig | 14 + drivers/media/IR/Makefile |1 + drivers/media/IR/ene_ir.c | 595 + drivers/media/IR/ene_ir.h | 51 ++--- 5 files changed, 265 insertions(+), 402 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 56a36d7..587785a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2188,6 +2188,12 @@ F: drivers/misc/cb710/ F: drivers/mmc/host/cb710-mmc.* F: include/linux/cb710.h +ENE KB2426 (ENE0100/ENE020XX) INFRARED RECEIVER +M: Maxim Levitsky maximlevit...@gmail.com +S: Maintained +F: drivers/media/IR/ene_ir.c +F: drivers/media/IR/ene_ir.h + EPSON 1355 FRAMEBUFFER DRIVER M: Christopher Hoover c...@murgatroid.com M: Christopher Hoover c...@hpl.hp.com diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig index fc48a3f..3f62bf9 100644 --- a/drivers/media/IR/Kconfig +++ b/drivers/media/IR/Kconfig @@ -105,4 +105,18 @@ config IR_MCEUSB To compile this driver as a module, choose M here: the module will be called mceusb. +config IR_ENE + tristate ENE eHome Receiver/Transciever (pnp id: ENE0100/ENE02xxx) + depends on PNP + depends on IR_CORE + ---help--- + Say Y here to enable support for integrated infrared receiver + /transciever made by ENE. + + You can see if you have it by looking at lspnp output. + Output should include ENE0100 ENE0200 or something similiar. + + To compile this driver as a module, choose M here: the + module will be called ene_ir. + endif #IR_CORE diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile index 2ae4f3a..3262a68 100644 --- a/drivers/media/IR/Makefile +++ b/drivers/media/IR/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o # stand-alone IR receivers/transmitters obj-$(CONFIG_IR_IMON) += imon.o obj-$(CONFIG_IR_MCEUSB) += mceusb.o +obj-$(CONFIG_IR_ENE) += ene_ir.o diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c index 9d11caf..de1e5c4 100644 --- a/drivers/media/IR/ene_ir.c +++ b/drivers/media/IR/ene_ir.c @@ -1,5 +1,5 @@ /* - * driver for ENE KB3926 B/C/D CIR (also known as ENE0100/ENE0200/ENE0201) + * driver for ENE KB3926 B/C/D CIR (pnp id: ENE0XXX) * * Copyright (C) 2010 Maxim Levitsky maximlevit...@gmail.com * @@ -25,20 +25,20 @@ #include linux/io.h #include linux/interrupt.h #include linux/sched.h -#include linux/uaccess.h -#include lirc_ene0100.h +#include linux/slab.h +#include linux/input.h +#include media/ir-core.h +#include media/ir-common.h +#include ene_ir.h static int sample_period = -1; static int enable_idle = 1; -static int enable_duty_carrier; static int input = 1; static int debug; static int txsim; -static void ene_rx_set_idle(struct ene_device *dev, int idle); static int ene_irq_status(struct ene_device *dev); -static void ene_send_sample(struct ene_device *dev, unsigned long sample); /* read a hardware register */ static u8 ene_hw_read_reg(struct ene_device *dev, u16 reg) @@ -85,6 +85,7 @@ static int ene_hw_detect(struct ene_device *dev) u8 hw_revision, old_ver; u8 tmp; u8 fw_capabilities; + int pll_freq; tmp = ene_hw_read_reg(dev, ENE_HW_UNK); ene_hw_write_reg(dev, ENE_HW_UNK, tmp ~ENE_HW_UNK_CLR); @@ -96,6 +97,17 @@ static int ene_hw_detect(struct ene_device *dev) hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION); old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD); + pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) 4) + + (ene_hw_read_reg(dev, ENE_PLLFRL) 2); + + if (pll_freq != 1000) + dev-rx_period_adjust = 4; + else + dev-rx_period_adjust = 2; + + + ene_printk(KERN_NOTICE, PLL freq = %d\n, pll_freq); + if (hw_revision == 0xFF) { ene_printk(KERN_WARNING, device seems to be disabled\n); @@ -160,7 +172,7 @@ static int ene_hw_detect(struct ene_device *dev) } /* this enables/disables IR input via gpio40*/ -static void ene_enable_gpio40_recieve(struct ene_device *dev, int enable) +static void ene_enable_gpio40_receive(struct ene_device *dev, int enable) { ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, enable ? 0 : ENE_CIR_CONF2_GPIO40DIS, @@ -168,13 +180,13 @@ static void ene_enable_gpio40_recieve(struct ene_device *dev, int enable) } /* this enables/disables IR via standard input */ -static void ene_enable_normal_recieve(struct ene_device *dev, int enable) +static void ene_enable_normal_receive(struct ene_device *dev, int enable) { ene_hw_write_reg(dev, ENE_CIR_CONF1, enable ? ENE_CIR_CONF1_RX_ON : 0); } /* this enables/disables IR input via unused fan tachtometer input */ -static void ene_enable_fan_recieve(struct ene_device *dev, int enable) +static
Re: [PATCH v2]Resend:videobuf_dma_sg: a new implementation for mmap
On Fri, 2010-07-30 at 11:31 +0200, Laurent Pinchart wrote: Hi, On Friday 30 July 2010 02:08:02 Figo.zhang wrote: a mmap issue for videobuf-dma-sg: it will alloc a new page for mmaping when it encounter page fault at video_vm_ops-fault(). pls see http://www.spinics.net/lists/linux-media/msg21243.html a new implementation for mmap, it translate to vmalloc to page at video_vm_ops-fault(). in v2, if mem-dma.vmalloc is NULL at video_vm_ops-fault(), it will alloc memory by vmlloc_32(). You're replacing allocation in videobuf_vm_fault by allocationg in videobuf_vm_fault. I don't see the point. videobuf_vm_fault needs to go away completely. in now videobuf code, the mmap alloc a new buf, the capture dma buffer using vmalloc() alloc buffer, how is relationship with them? in usrspace , the mmap region will not the actual capture dma data, how is work? This has been discussed previously: fixing videobuf is not really possible. A videobuf2 implementation is needed and is (slowly) being worked on. hi Mauro, do you think this is a issue for videobuf-dma-sg? I wouldn't bother with this patch, just drop it. Signed-off-by: Figo.zhang figo1...@gmail.com --- drivers/media/video/videobuf-dma-sg.c | 50 +++-- 1 files changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 8359e6b..f7295da 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -201,10 +201,11 @@ int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, dprintk(1, init kernel [%d pages]\n, nr_pages); dma-direction = direction; - dma-vmalloc = vmalloc_32(nr_pages PAGE_SHIFT); - if (NULL == dma-vmalloc) { - dprintk(1, vmalloc_32(%d pages) failed\n, nr_pages); - return -ENOMEM; + if (!dma-vmalloc) + dma-vmalloc = vmalloc_32(nr_pages PAGE_SHIFT); + if (NULL == dma-vmalloc) { + dprintk(1, vmalloc_32(%d pages) failed\n, nr_pages); + return -ENOMEM; } dprintk(1, vmalloc is at addr 0x%08lx, size=%d\n, @@ -397,16 +398,47 @@ static void videobuf_vm_close(struct vm_area_struct *vma) */ static int videobuf_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - struct page *page; + struct page *page = NULL; + struct videobuf_mapping *map = vma-vm_private_data; + struct videobuf_queue *q = map-q; + struct videobuf_dma_sg_memory *mem = NULL; + + unsigned long offset; + unsigned long page_nr; + int first; dprintk(3, fault: fault @ %08lx [vma %08lx-%08lx]\n, (unsigned long)vmf-virtual_address, vma-vm_start, vma-vm_end); - page = alloc_page(GFP_USER | __GFP_DMA32); - if (!page) - return VM_FAULT_OOM; - clear_user_highpage(page, (unsigned long)vmf-virtual_address); + mutex_lock(q-vb_lock); + offset = (unsigned long)vmf-virtual_address - vma-vm_start; + page_nr = offset PAGE_SHIFT; + + for (first = 0; first VIDEO_MAX_FRAME; first++) { + if (NULL == q-bufs[first]) + continue; + + MAGIC_CHECK(mem-magic, MAGIC_SG_MEM); + + if (q-bufs[first]-map == map) + break; + } + + mem = q-bufs[first]-priv; + if (!mem) + return VM_FAULT_SIGBUS; + if (!mem-dma.vmalloc) { + mem-dma.vmalloc = vmalloc_32(PAGE_ALIGN(q-bufs[first]-size)); + if (NULL == mem-dma.vmalloc) { + dprintk(1, %s: vmalloc_32() failed\n, __func__); + return VM_FAULT_OOM; + } + } else + page = vmalloc_to_page(mem-dma.vmalloc+ + (offset (~PAGE_MASK))); + mutex_unlock(q-vb_lock); + vmf-page = page; return 0; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2]Resend:videobuf_dma_sg: a new implementation for mmap
On Fri, 2010-07-30 at 11:31 +0200, Laurent Pinchart wrote: Hi, On Friday 30 July 2010 02:08:02 Figo.zhang wrote: a mmap issue for videobuf-dma-sg: it will alloc a new page for mmaping when it encounter page fault at video_vm_ops-fault(). pls see http://www.spinics.net/lists/linux-media/msg21243.html a new implementation for mmap, it translate to vmalloc to page at video_vm_ops-fault(). in v2, if mem-dma.vmalloc is NULL at video_vm_ops-fault(), it will alloc memory by vmlloc_32(). You're replacing allocation in videobuf_vm_fault by allocationg in videobuf_vm_fault. I don't see the point. videobuf_vm_fault needs to go away completely. in now videobuf code, the mmap alloc a new buf, the capture dma buffer using vmalloc() alloc buffer, how is relationship with them? in usrspace , the mmap region will not the actual capture dma data, how is work? This has been discussed previously: fixing videobuf is not really possible. A videobuf2 implementation is needed and is (slowly) being worked on. hi Mauro, do you think this is a issue for videobuf-dma-sg? I wouldn't bother with this patch, just drop it. Signed-off-by: Figo.zhang figo1...@gmail.com --- drivers/media/video/videobuf-dma-sg.c | 50 +++-- 1 files changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 8359e6b..f7295da 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -201,10 +201,11 @@ int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, dprintk(1, init kernel [%d pages]\n, nr_pages); dma-direction = direction; - dma-vmalloc = vmalloc_32(nr_pages PAGE_SHIFT); - if (NULL == dma-vmalloc) { - dprintk(1, vmalloc_32(%d pages) failed\n, nr_pages); - return -ENOMEM; + if (!dma-vmalloc) + dma-vmalloc = vmalloc_32(nr_pages PAGE_SHIFT); + if (NULL == dma-vmalloc) { + dprintk(1, vmalloc_32(%d pages) failed\n, nr_pages); + return -ENOMEM; } dprintk(1, vmalloc is at addr 0x%08lx, size=%d\n, @@ -397,16 +398,47 @@ static void videobuf_vm_close(struct vm_area_struct *vma) */ static int videobuf_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - struct page *page; + struct page *page = NULL; + struct videobuf_mapping *map = vma-vm_private_data; + struct videobuf_queue *q = map-q; + struct videobuf_dma_sg_memory *mem = NULL; + + unsigned long offset; + unsigned long page_nr; + int first; dprintk(3, fault: fault @ %08lx [vma %08lx-%08lx]\n, (unsigned long)vmf-virtual_address, vma-vm_start, vma-vm_end); - page = alloc_page(GFP_USER | __GFP_DMA32); - if (!page) - return VM_FAULT_OOM; - clear_user_highpage(page, (unsigned long)vmf-virtual_address); + mutex_lock(q-vb_lock); + offset = (unsigned long)vmf-virtual_address - vma-vm_start; + page_nr = offset PAGE_SHIFT; + + for (first = 0; first VIDEO_MAX_FRAME; first++) { + if (NULL == q-bufs[first]) + continue; + + MAGIC_CHECK(mem-magic, MAGIC_SG_MEM); + + if (q-bufs[first]-map == map) + break; + } + + mem = q-bufs[first]-priv; + if (!mem) + return VM_FAULT_SIGBUS; + if (!mem-dma.vmalloc) { + mem-dma.vmalloc = vmalloc_32(PAGE_ALIGN(q-bufs[first]-size)); + if (NULL == mem-dma.vmalloc) { + dprintk(1, %s: vmalloc_32() failed\n, __func__); + return VM_FAULT_OOM; + } + } else + page = vmalloc_to_page(mem-dma.vmalloc+ + (offset (~PAGE_MASK))); + mutex_unlock(q-vb_lock); + vmf-page = page; return 0; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 13/13] IR: Port ene driver to new IR subsystem and enable it.
On Fri, Jul 30, 2010 at 7:36 AM, Maxim Levitsky maximlevit...@gmail.com wrote: On Thu, 2010-07-29 at 23:46 -0400, Andy Walls wrote: On Thu, 2010-07-29 at 22:39 -0400, Jon Smirl wrote: On Thu, Jul 29, 2010 at 10:17 PM, Maxim Levitsky maximlevit...@gmail.com wrote: note that error_adjustment module option is added. This allows to reduce input samples by a percent. This makes input on my system more correct. Default is 4% as it works best here. Note that only normal input is adjusted. I don't know what adjustments to apply to fan tachometer input. Maybe it is accurate already. Do you have the manual for the ENE chip in English? or do you read Chinese? The datasheet for a similar chip, the KB3700, is out there in English, but it doesn't have CIR. You might find these links mildly interesting: http://www.coreboot.org/Embedded_controller http://wiki.laptop.org/go/Embedded_controller http://lists.laptop.org/pipermail/openec/2008-July/000108.html Nope, I have read that. Regards, Andy Maybe you can figure out why the readings are off by 4%. I suspect that someone has set a clock divider wrong when programming the chip. For example setting the divider for a 25Mhz clock when the clock is actually 26Mhz would cause the error you are seeing. Or they just made a mistake in computing the divisor. It is probably a bug in the BIOS of your laptop. Â If that's the case you could add a quirk in the system boot code to fix the register setting. I figured out how windows driver compensates for the offset, and do the same in my driver. I think the problem is solved. Should that be a = or = instead of !=? + if (pll_freq != 1000) Programming the PLL wrong would cause the 4% error. hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION); old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD); + pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) 4) + + (ene_hw_read_reg(dev, ENE_PLLFRL) 2); + + if (pll_freq != 1000) + dev-rx_period_adjust = 4; + else + dev-rx_period_adjust = 2; + + + ene_printk(KERN_NOTICE, PLL freq = %d\n, pll_freq); + if (hw_revision == 0xFF) { Best regards, Maxim Levitsky -- Jon Smirl jonsm...@gmail.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 13/13] IR: Port ene driver to new IR subsystem and enable it.
On Fri, 2010-07-30 at 07:51 -0400, Jon Smirl wrote: On Fri, Jul 30, 2010 at 7:36 AM, Maxim Levitsky maximlevit...@gmail.com wrote: On Thu, 2010-07-29 at 23:46 -0400, Andy Walls wrote: On Thu, 2010-07-29 at 22:39 -0400, Jon Smirl wrote: On Thu, Jul 29, 2010 at 10:17 PM, Maxim Levitsky maximlevit...@gmail.com wrote: note that error_adjustment module option is added. This allows to reduce input samples by a percent. This makes input on my system more correct. Default is 4% as it works best here. Note that only normal input is adjusted. I don't know what adjustments to apply to fan tachometer input. Maybe it is accurate already. Do you have the manual for the ENE chip in English? or do you read Chinese? The datasheet for a similar chip, the KB3700, is out there in English, but it doesn't have CIR. You might find these links mildly interesting: http://www.coreboot.org/Embedded_controller http://wiki.laptop.org/go/Embedded_controller http://lists.laptop.org/pipermail/openec/2008-July/000108.html Nope, I have read that. Regards, Andy Maybe you can figure out why the readings are off by 4%. I suspect that someone has set a clock divider wrong when programming the chip. For example setting the divider for a 25Mhz clock when the clock is actually 26Mhz would cause the error you are seeing. Or they just made a mistake in computing the divisor. It is probably a bug in the BIOS of your laptop. If that's the case you could add a quirk in the system boot code to fix the register setting. I figured out how windows driver compensates for the offset, and do the same in my driver. I think the problem is solved. Should that be a = or = instead of !=? + if (pll_freq != 1000) This is how its done in windows driver. Programming the PLL wrong would cause the 4% error. hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION); old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD); + pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) 4) + + (ene_hw_read_reg(dev, ENE_PLLFRL) 2); + + if (pll_freq != 1000) + dev-rx_period_adjust = 4; + else + dev-rx_period_adjust = 2; + + + ene_printk(KERN_NOTICE, PLL freq = %d\n, pll_freq); + if (hw_revision == 0xFF) { Best regards, Maxim Levitsky -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 13/13] IR: Port ene driver to new IR subsystem and enable it.
On Fri, Jul 30, 2010 at 7:54 AM, Maxim Levitsky maximlevit...@gmail.com wrote: On Fri, 2010-07-30 at 07:51 -0400, Jon Smirl wrote: On Fri, Jul 30, 2010 at 7:36 AM, Maxim Levitsky maximlevit...@gmail.com wrote: On Thu, 2010-07-29 at 23:46 -0400, Andy Walls wrote: On Thu, 2010-07-29 at 22:39 -0400, Jon Smirl wrote: On Thu, Jul 29, 2010 at 10:17 PM, Maxim Levitsky maximlevit...@gmail.com wrote: note that error_adjustment module option is added. This allows to reduce input samples by a percent. This makes input on my system more correct. Default is 4% as it works best here. Note that only normal input is adjusted. I don't know what adjustments to apply to fan tachometer input. Maybe it is accurate already. Do you have the manual for the ENE chip in English? or do you read Chinese? The datasheet for a similar chip, the KB3700, is out there in English, but it doesn't have CIR. You might find these links mildly interesting: http://www.coreboot.org/Embedded_controller http://wiki.laptop.org/go/Embedded_controller http://lists.laptop.org/pipermail/openec/2008-July/000108.html Nope, I have read that. Regards, Andy Maybe you can figure out why the readings are off by 4%. I suspect that someone has set a clock divider wrong when programming the chip. For example setting the divider for a 25Mhz clock when the clock is actually 26Mhz would cause the error you are seeing. Or they just made a mistake in computing the divisor. It is probably a bug in the BIOS of your laptop. Â If that's the case you could add a quirk in the system boot code to fix the register setting. I figured out how windows driver compensates for the offset, and do the same in my driver. I think the problem is solved. Should that be a = or = instead of !=? + Â Â Â if (pll_freq != 1000) This is how its done in windows driver. That doesn't mean it is bug free. Experimenting with changing the PLL frequency register may correct the error. Try taking 96% of pll_freq and write it back into these register. This would be easy to fix with a manual. The root problem is almost certainly a bug in the way the PLLs were programmed. I don't like putting in fudge factors like the 4% correction. What happens if a later version of the hardware has fixed firmware? I normal user is never going to figure out that they need to change the fudge factor. + pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) 4) + + (ene_hw_read_reg(dev, ENE_PLLFRL) 2); + Programming the PLL wrong would cause the 4% error. Â Â Â Â hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION); Â Â Â Â old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD); + Â Â Â pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) 4) + + Â Â Â Â Â Â Â (ene_hw_read_reg(dev, ENE_PLLFRL) 2); + + Â Â Â if (pll_freq != 1000) + Â Â Â Â Â Â Â dev-rx_period_adjust = 4; + Â Â Â else + Â Â Â Â Â Â Â dev-rx_period_adjust = 2; + + + Â Â Â ene_printk(KERN_NOTICE, PLL freq = %d\n, pll_freq); + Â Â Â Â if (hw_revision == 0xFF) { Best regards, Maxim Levitsky -- Jon Smirl jonsm...@gmail.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 13/13] IR: Port ene driver to new IR subsystem and enable it.
On Fri, Jul 30, 2010 at 8:02 AM, Jon Smirl jonsm...@gmail.com wrote: On Fri, Jul 30, 2010 at 7:54 AM, Maxim Levitsky maximlevit...@gmail.com wrote: On Fri, 2010-07-30 at 07:51 -0400, Jon Smirl wrote: On Fri, Jul 30, 2010 at 7:36 AM, Maxim Levitsky maximlevit...@gmail.com wrote: On Thu, 2010-07-29 at 23:46 -0400, Andy Walls wrote: On Thu, 2010-07-29 at 22:39 -0400, Jon Smirl wrote: On Thu, Jul 29, 2010 at 10:17 PM, Maxim Levitsky maximlevit...@gmail.com wrote: note that error_adjustment module option is added. This allows to reduce input samples by a percent. This makes input on my system more correct. Default is 4% as it works best here. Note that only normal input is adjusted. I don't know what adjustments to apply to fan tachometer input. Maybe it is accurate already. Do you have the manual for the ENE chip in English? or do you read Chinese? The datasheet for a similar chip, the KB3700, is out there in English, but it doesn't have CIR. You might find these links mildly interesting: http://www.coreboot.org/Embedded_controller http://wiki.laptop.org/go/Embedded_controller http://lists.laptop.org/pipermail/openec/2008-July/000108.html Nope, I have read that. Regards, Andy Maybe you can figure out why the readings are off by 4%. I suspect that someone has set a clock divider wrong when programming the chip. For example setting the divider for a 25Mhz clock when the clock is actually 26Mhz would cause the error you are seeing. Or they just made a mistake in computing the divisor. It is probably a bug in the BIOS of your laptop. Â If that's the case you could add a quirk in the system boot code to fix the register setting. I figured out how windows driver compensates for the offset, and do the same in my driver. I think the problem is solved. Should that be a = or = instead of !=? + Â Â Â if (pll_freq != 1000) This is how its done in windows driver. That doesn't mean it is bug free. Experimenting with changing the PLL frequency register may correct the error. Â Try taking 96% of pll_freq and write it back into these register. This would be easy to fix with a manual. The root problem is almost certainly a bug in the way the PLLs were programmed. I don't like putting in fudge factors like the 4% correction. What happens if a later version of the hardware has fixed firmware? I normal user is never going to figure out that they need to change the fudge factor. + Â Â Â pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) 4) + + Â Â Â Â Â Â Â (ene_hw_read_reg(dev, ENE_PLLFRL) 2); I can understand the shift of the high bits, but that shift of the low bits is unlikely. A manual would tell us if it is right. + Programming the PLL wrong would cause the 4% error. Â Â Â Â hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION); Â Â Â Â old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD); + Â Â Â pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) 4) + + Â Â Â Â Â Â Â (ene_hw_read_reg(dev, ENE_PLLFRL) 2); + + Â Â Â if (pll_freq != 1000) + Â Â Â Â Â Â Â dev-rx_period_adjust = 4; + Â Â Â else + Â Â Â Â Â Â Â dev-rx_period_adjust = 2; + + + Â Â Â ene_printk(KERN_NOTICE, PLL freq = %d\n, pll_freq); + Â Â Â Â if (hw_revision == 0xFF) { Best regards, Maxim Levitsky -- Jon Smirl jonsm...@gmail.com -- Jon Smirl jonsm...@gmail.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 13/13] IR: Port ene driver to new IR subsystem and enable it.
On Fri, 2010-07-30 at 08:07 -0400, Jon Smirl wrote: On Fri, Jul 30, 2010 at 8:02 AM, Jon Smirl jonsm...@gmail.com wrote: On Fri, Jul 30, 2010 at 7:54 AM, Maxim Levitsky maximlevit...@gmail.com wrote: On Fri, 2010-07-30 at 07:51 -0400, Jon Smirl wrote: On Fri, Jul 30, 2010 at 7:36 AM, Maxim Levitsky maximlevit...@gmail.com wrote: On Thu, 2010-07-29 at 23:46 -0400, Andy Walls wrote: On Thu, 2010-07-29 at 22:39 -0400, Jon Smirl wrote: On Thu, Jul 29, 2010 at 10:17 PM, Maxim Levitsky maximlevit...@gmail.com wrote: note that error_adjustment module option is added. This allows to reduce input samples by a percent. This makes input on my system more correct. Default is 4% as it works best here. Note that only normal input is adjusted. I don't know what adjustments to apply to fan tachometer input. Maybe it is accurate already. Do you have the manual for the ENE chip in English? or do you read Chinese? The datasheet for a similar chip, the KB3700, is out there in English, but it doesn't have CIR. You might find these links mildly interesting: http://www.coreboot.org/Embedded_controller http://wiki.laptop.org/go/Embedded_controller http://lists.laptop.org/pipermail/openec/2008-July/000108.html Nope, I have read that. Regards, Andy Maybe you can figure out why the readings are off by 4%. I suspect that someone has set a clock divider wrong when programming the chip. For example setting the divider for a 25Mhz clock when the clock is actually 26Mhz would cause the error you are seeing. Or they just made a mistake in computing the divisor. It is probably a bug in the BIOS of your laptop. If that's the case you could add a quirk in the system boot code to fix the register setting. I figured out how windows driver compensates for the offset, and do the same in my driver. I think the problem is solved. Should that be a = or = instead of !=? + if (pll_freq != 1000) This is how its done in windows driver. That doesn't mean it is bug free. This PLL frequency is likely to be chip internal frequency. And windows driver doesn't touch it. Its embedded controller, so I don't want to touch things I am not sure about. Experimenting with changing the PLL frequency register may correct the error. Try taking 96% of pll_freq and write it back into these register. This would be easy to fix with a manual. The root problem is almost certainly a bug in the way the PLLs were programmed. I don't like putting in fudge factors like the 4% correction. What happens if a later version of the hardware has fixed firmware? I normal user is never going to figure out that they need to change the fudge factor. I don't think that is a hardware bug, rather a limitation. Lets leave it as is. I will soon publish the driver on launchpad or something like that and try to contact users I debugged that driver with, and then see what ranges PLL register takes. + pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) 4) + + (ene_hw_read_reg(dev, ENE_PLLFRL) 2); I can understand the shift of the high bits, but that shift of the low bits is unlikely. A manual would tell us if it is right. This shift is correct (according to datasheet, which contains mostly useless info, but it does dociment this reg briefly.) Best regards, Maxim Levitsky -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [media-ctl PATCH 1/3] Create initial .gitignore file
Hi Sergio, Thanks for the patch, and sorry for the delay. Applied. On Wednesday 14 July 2010 18:17:24 Sergio Aguirre wrote: The idea of this file is to ignore build generated files, and also the standard patches subfolder, used by quilt for example. Signed-off-by: Sergio Aguirre saagui...@ti.com --- .gitignore |4 1 files changed, 4 insertions(+), 0 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000..1e56cf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +media-ctl + +patches/* -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [media-ctl PATCH 2/3] Just include kernel headers
Hi Sergio, On Wednesday 14 July 2010 18:17:25 Sergio Aguirre wrote: We shouldn't require full kernel source for this. That's right in theory, but I then get $ make KDIR=/home/laurent/src/arm/kernel/ arm-none-linux-gnueabi-gcc -O2 -Wall -fpic -I. -I/home/laurent/src/arm/kernel//include-c -o media.o media.c In file included from /opt/cs/arm-2009q1/bin/../arm-none-linux-gnueabi/libc/usr/include/asm/types.h:4, from /home/laurent/src/arm/kernel//include/linux/types.h:4, from /home/laurent/src/arm/kernel//include/linux/videodev2.h:66, from media.c:31: /home/laurent/src/arm/kernel//include/asm-generic/int-ll64.h:11:29: error: asm/bitsperlong.h: No such file or directory make: *** [media.o] Error 1 when building against a kernel tree. Signed-off-by: Sergio Aguirre saagui...@ti.com --- Makefile |6 ++ 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index bf4cf55..300ed7e 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,9 @@ -SRCARCH ?= arm CROSS_COMPILE ?= arm-none-linux-gnueabi- -KDIR ?= /usr/src/linux +HDIR ?= /usr/include -KINC := -I$(KDIR)/include -I$(KDIR)/arch/$(SRCARCH)/include CC := $(CROSS_COMPILE)gcc -CFLAGS = -O2 -Wall -fpic -I. $(KINC) +CFLAGS = -O2 -Wall -fpic -I$(HDIR) OBJS = media.o main.o options.o subdev.o all: media-ctl -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH v3 03/10] media: Entities, pads and links
Hi Laurent, And thanks for the patch! Laurent Pinchart wrote: ... diff --git a/include/media/media-device.h b/include/media/media-device.h index bd559b0..ac96847 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -23,8 +23,10 @@ #include linux/device.h #include linux/list.h +#include linux/spinlock.h #include media/media-devnode.h +#include media/media-entity.h /* Each instance of a media device should create the media_device struct, * either stand-alone or embedded in a larger struct. @@ -40,9 +42,23 @@ struct media_device { */ struct device *dev; struct media_devnode devnode; + + u32 entity_id; + struct list_head entities; + + /* Protects the entities list */ + spinlock_t lock; }; int __must_check media_device_register(struct media_device *mdev); void media_device_unregister(struct media_device *mdev); +int __must_check media_device_register_entity(struct media_device *mdev, + struct media_entity *entity); +void media_device_unregister_entity(struct media_entity *entity); + +/* Iterate over all entities. */ +#define media_device_for_each_entity(entity, mdev) \ + list_for_each_entry(entity, (mdev)-entities, list) + #endif diff --git a/include/media/media-entity.h b/include/media/media-entity.h new file mode 100644 index 000..37a25bf --- /dev/null +++ b/include/media/media-entity.h @@ -0,0 +1,85 @@ +#ifndef _MEDIA_ENTITY_H +#define _MEDIA_ENTITY_H + +#include linux/list.h + +#define MEDIA_ENTITY_TYPE_NODE (1 16) About that 16 there, could that be replaced by a #define instead? Like MEDIA_ENTITY_TYPE_SHIFT? (I don't think we'd need MEDIA_ENTITY_SUBTYPE_SHIFT.) +#define MEDIA_ENTITY_TYPE_NODE_V4L (MEDIA_ENTITY_TYPE_NODE + 1) +#define MEDIA_ENTITY_TYPE_NODE_FB(MEDIA_ENTITY_TYPE_NODE + 2) +#define MEDIA_ENTITY_TYPE_NODE_ALSA (MEDIA_ENTITY_TYPE_NODE + 3) +#define MEDIA_ENTITY_TYPE_NODE_DVB (MEDIA_ENTITY_TYPE_NODE + 4) + +#define MEDIA_ENTITY_TYPE_SUBDEV (2 16) +#define MEDIA_ENTITY_TYPE_SUBDEV_VID_DECODER (MEDIA_ENTITY_TYPE_SUBDEV + 1) +#define MEDIA_ENTITY_TYPE_SUBDEV_VID_ENCODER (MEDIA_ENTITY_TYPE_SUBDEV + 2) +#define MEDIA_ENTITY_TYPE_SUBDEV_MISC (MEDIA_ENTITY_TYPE_SUBDEV + 3) + +#define MEDIA_LINK_FLAG_ACTIVE (1 0) +#define MEDIA_LINK_FLAG_IMMUTABLE(1 1) + +#define MEDIA_PAD_FLAG_INPUT (1 0) +#define MEDIA_PAD_FLAG_OUTPUT(1 1) + +struct media_link { + struct media_pad *source; /* Source pad */ + struct media_pad *sink; /* Sink pad */ + struct media_link *other; /* Link in the reverse direction */ + unsigned long flags;/* Link flags (MEDIA_LINK_FLAG_*) */ +}; + +struct media_pad { + struct media_entity *entity;/* Entity this pad belongs to */ + u16 index; /* Pad index in the entity pads array */ + unsigned long flags;/* Pad flags (MEDIA_PAD_FLAG_*) */ +}; + +struct media_entity { + struct list_head list; + struct media_device *parent;/* Media device this entity belongs to*/ + u32 id; /* Entity ID, unique in the parent media + * device context */ + const char *name; /* Entity name */ + u32 type; /* Entity type (MEDIA_ENTITY_TYPE_*) */ + + u8 num_pads;/* Number of input and output pads */ Hans suggested u16 for pads. This is a kernel structure but still it'd be good to keep them the same IMO, even if that u16 was there for the future. u8 is used on some function arguments as well for these purposes. + u8 num_links; /* Number of existing links, both active + * and inactive */ + u8 num_backlinks; /* Number of backlinks */ + u8 max_links; /* Maximum number of links */ Same for these. + struct media_pad *pads; /* Pads array (num_pads elements) */ + struct media_link *links; /* Links array (max_links elements)*/ + + union { + /* Node specifications */ + struct { + u32 major; + u32 minor; How about dev_t here? + } v4l; + struct { + u32 major; + u32 minor; And here. + } fb; + int alsa; + int dvb; + + /* Sub-device specifications */ + /* Nothing needed yet */ + }; +}; + +#define MEDIA_ENTITY_TYPE_MASK 0x +#define MEDIA_ENTITY_SUBTYPE_MASK0x + +#define media_entity_type(entity) \ +
Re: [media-ctl PATCH 2/3] Just include kernel headers
Hi Sergio, On Friday 30 July 2010 16:10:08 Aguirre, Sergio wrote: On Friday 30 July 2010 8:45 AM Laurent Pinchart wrote: On Wednesday 14 July 2010 18:17:25 Sergio Aguirre wrote: We shouldn't require full kernel source for this. That's right in theory, but I then get $ make KDIR=/home/laurent/src/arm/kernel/ arm-none-linux-gnueabi-gcc -O2 -Wall -fpic -I. - I/home/laurent/src/arm/kernel//include-c -o media.o media.c In file included from /opt/cs/arm-2009q1/bin/../arm-none-linux- gnueabi/libc/usr/include/asm/types.h:4, from /home/laurent/src/arm/kernel//include/linux/types.h:4, from /home/laurent/src/arm/kernel//include/linux/videodev2.h:66, from media.c:31: /home/laurent/src/arm/kernel//include/asm-generic/int-ll64.h:11:29: error: asm/bitsperlong.h: No such file or directory make: *** [media.o] Error 1 when building against a kernel tree. KDIR doesn't exist anymore. By the result of your log, I don't see how that value got passed into the makefile... Are you sure you applied the patch correctly? I haven't, I've just removed the arch include dir from KDIR in the Makefile. The end result is the same. -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v5 0/3] Multi-planar video format and buffer support for the V4L2 API
Snip struct v4l2_format { enum v4l2_buf_type type; union { struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ + struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ __u8raw_data[200]; /* user-defined */ } fmt; }; For the new buffer types mp_pix member is chosen. For those buffer types, struct v4l2_pix_format_mplane is used: Typo. replae mp_pix with pix_mp /** * struct v4l2_pix_format_mplane - multiplanar format definition * @width: image width in pixels * @height: image height in pixels * @pixelformat:little endian four character code (fourcc) * @field: field order (for interlaced video) * @colorspace: supplemental to pixelformat * @plane_fmt: per-plane information * @num_planes: number of planes for this format and number of valid Snip 7. Format conversion -- v4l2 core ioctl handling includes a simple conversion layer that allows translation - when possible - between multi-planar and single-planar APIs, transparently to drivers and applications. The table below summarizes conversion behavior for cases when driver and application use different API versions: --- | Application MP -- Driver SP -- Application MP G_FMT |always OK | always OK S_FMT |-EINVAL | always OK TRY_FMT |-EINVAL | always OK --- | Application SP -- Driver MP -- Application SP G_FMT |always OK | -EBUSY S_FMT |always OK | -EBUSY and WARN() TRY_FMT |always OK | -EBUSY and WARN() What is the logic behind using -EBUSY for this? Why not -EINVAL? Also why use WARN()? Legend: - SP - single-planar API used (NOT format!) - MP - multi-planar API used (NOT format!) - always OK - conversion is always valid irrespective of number of planes - -EINVAL - if an MP application tries to TRY or SET a format with more than 1 plane, EINVAL is returned from the conversion function (of course, 1-plane multi-planar formats work and are converted) - -EBUSY - if an MP driver returns a more than 1-plane format to an SP application, the conversion layer returns EBUSY to the application; this is useful in cases when the driver is currently set to a more than 1-plane format, SP application would not be able to understand it) - -EBUSY and WARN() - there is only one reason for which SET or TRY from an SP application would result in a driver returning a more than 1- plane format - when the driver adjusts a 1-plane format to a more than 1-plane format. This should not happen and is a bug in driver, hence a WARN_ON(). Application receives EBUSY. Suppose, S_FMT/TRY_FMT is called with UYVY format and driver supports only NV12 (2 plane) only, then for Application SP -- Driver MP -- Application SP I guess in this case, new drivers that supports multi-plane format would have to return old NV12 format code (for backward compatibility). Is this handled by driver or translation layer? Application MP -- Driver SP -- Application MP In this case, new driver would return new NV12 format code and have no issue. Not sure what translation layer does in this scenario. snip === V. Using ioctl()s and mmap() === * Format calls (VIDIOC_S/TRY/G_FMT) are converted transparently across APIs by the ioctl handling code, where possible. Conversion from single-planar to multi-planar cannot fail, but the other way around is possible only for 1-plane formats. Possible errors in conversion are described below. Could you explain what you mean by conversion of formats? The idea of the translation layer functionality is not clear to me. An example would help. Murali -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [media-ctl PATCH 2/3] Just include kernel headers
Hi Laurent, -Original Message- From: Laurent Pinchart [mailto:laurent.pinch...@ideasonboard.com] Sent: Friday, July 30, 2010 9:24 AM To: Aguirre, Sergio Cc: linux-media@vger.kernel.org Subject: Re: [media-ctl PATCH 2/3] Just include kernel headers Hi Sergio, On Friday 30 July 2010 16:10:08 Aguirre, Sergio wrote: On Friday 30 July 2010 8:45 AM Laurent Pinchart wrote: On Wednesday 14 July 2010 18:17:25 Sergio Aguirre wrote: We shouldn't require full kernel source for this. That's right in theory, but I then get $ make KDIR=/home/laurent/src/arm/kernel/ arm-none-linux-gnueabi-gcc -O2 -Wall -fpic -I. - I/home/laurent/src/arm/kernel//include-c -o media.o media.c In file included from /opt/cs/arm-2009q1/bin/../arm-none-linux- gnueabi/libc/usr/include/asm/types.h:4, from /home/laurent/src/arm/kernel//include/linux/types.h:4, from /home/laurent/src/arm/kernel//include/linux/videodev2.h:66, from media.c:31: /home/laurent/src/arm/kernel//include/asm-generic/int-ll64.h:11:29: error: asm/bitsperlong.h: No such file or directory make: *** [media.o] Error 1 when building against a kernel tree. KDIR doesn't exist anymore. By the result of your log, I don't see how that value got passed into the makefile... Are you sure you applied the patch correctly? I haven't, I've just removed the arch include dir from KDIR in the Makefile. The end result is the same. Hmm.. I think this is expected, since the kernel headers folder generated with make ARCH=arm INSTALL_HDR_PATH=your-fs-root headers_install Is not the same as just reading the kernel source include folder. Some #ifdef get resolved depending on the arch, and the headers are rebuilt. See : Documentation/make/headers_install.txt So, I guess it's not as simple as just removing the arch include folder. Regards, Sergio -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/20] mt9m111: Added indication that MT9M131 is supported by this driver
From: Philipp Wiesner p.wies...@phytec.de Added this info to Kconfig and mt9m111.c, some comment cleanup, replaced 'mt9m11x'-statements by clarifications or driver name. Driver is fully compatible to mt9m131 which has only additional functions compared to mt9m111. Those aren't used anyway at the moment. Signed-off-by: Philipp Wiesner p.wies...@phytec.de --- drivers/media/video/Kconfig |5 +++-- drivers/media/video/mt9m111.c | 37 +++-- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index cdbbbe4..0e8cf24 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -871,10 +871,11 @@ config SOC_CAMERA_MT9M001 and colour models. config SOC_CAMERA_MT9M111 - tristate mt9m111 and mt9m112 support + tristate mt9m111, mt9m112 and mt9m131 support depends on SOC_CAMERA I2C help - This driver supports MT9M111 and MT9M112 cameras from Micron + This driver supports MT9M111, MT9M112 and MT9M131 cameras from + Micron/Aptina config SOC_CAMERA_MT9T031 tristate mt9t031 support diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index d35f536..e934559 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -1,5 +1,5 @@ /* - * Driver for MT9M111/MT9M112 CMOS Image Sensor from Micron + * Driver for MT9M111/MT9M112/MT9M131 CMOS Image Sensor from Micron/Aptina * * Copyright (C) 2008, Robert Jarzmik robert.jarz...@free.fr * @@ -19,11 +19,14 @@ #include media/soc_camera.h /* - * mt9m111 and mt9m112 i2c address is 0x5d or 0x48 (depending on SAddr pin) + * MT9M111, MT9M112 and MT9M131: + * i2c address is 0x48 or 0x5d (depending on SADDR pin) * The platform has to define i2c_board_info and call i2c_register_board_info() */ -/* mt9m111: Sensor register addresses */ +/* + * Sensor core register addresses (0x000..0x0ff) + */ #define MT9M111_CHIP_VERSION 0x000 #define MT9M111_ROW_START 0x001 #define MT9M111_COLUMN_START 0x002 @@ -72,8 +75,9 @@ #define MT9M111_CTXT_CTRL_LED_FLASH_EN (1 2) #define MT9M111_CTXT_CTRL_VBLANK_SEL_B (1 1) #define MT9M111_CTXT_CTRL_HBLANK_SEL_B (1 0) + /* - * mt9m111: Colorpipe register addresses (0x100..0x1ff) + * Colorpipe register addresses (0x100..0x1ff) */ #define MT9M111_OPER_MODE_CTRL 0x106 #define MT9M111_OUTPUT_FORMAT_CTRL 0x108 @@ -109,8 +113,9 @@ #define MT9M111_OUTFMT_SWAP_YCbCr_C_Y (1 1) #define MT9M111_OUTFMT_SWAP_RGB_EVEN (1 1) #define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr(1 0) + /* - * mt9m111: Camera control register addresses (0x200..0x2ff not implemented) + * Camera control register addresses (0x200..0x2ff not implemented) */ #define reg_read(reg) mt9m111_reg_read(client, MT9M111_##reg) @@ -160,7 +165,8 @@ enum mt9m111_context { struct mt9m111 { struct v4l2_subdev subdev; - int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ + int model; /* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code */ + /* from v4l2-chip-ident.h */ enum mt9m111_context context; struct v4l2_rect rect; const struct mt9m111_datafmt *fmt; @@ -934,7 +940,7 @@ static int mt9m111_init(struct i2c_client *client) if (!ret) ret = mt9m111_set_autoexposure(client, mt9m111-autoexposure); if (ret) - dev_err(client-dev, mt9m11x init failed: %d\n, ret); + dev_err(client-dev, mt9m111 init failed: %d\n, ret); return ret; } @@ -970,21 +976,24 @@ static int mt9m111_video_probe(struct soc_camera_device *icd, data = reg_read(CHIP_VERSION); switch (data) { - case 0x143a: /* MT9M111 */ + case 0x143a: /* MT9M111 or MT9M131 */ mt9m111-model = V4L2_IDENT_MT9M111; + dev_info(client-dev, + Detected a MT9M111/MT9M131 chip ID %x\n, data); break; case 0x148c: /* MT9M112 */ mt9m111-model = V4L2_IDENT_MT9M112; + dev_info(client-dev, Detected a MT9M112 chip ID %x\n, data); break; default: ret = -ENODEV; dev_err(client-dev, - No MT9M11x chip detected, register read %x\n, data); + No MT9M111/MT9M112/MT9M131 chip detected, + register read %x\n, + data); goto ei2c; } - dev_info(client-dev, Detected a MT9M11x chip ID %x\n, data); - ei2c: return ret; } @@ -1034,13 +1043,13 @@ static int mt9m111_probe(struct i2c_client *client, int ret; if (!icd) { - dev_err(client-dev, MT9M11x: missing soc-camera data!\n); + dev_err(client-dev, mt9m111: soc-camera data missing!\n); return
[PATCH 03/20] mt9m111: register cleanup hex to dec bitoffset
Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c | 16 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 39dff7c..c72c4b0 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -100,14 +100,14 @@ #define MT9M111_OUTFMT_BYPASS_IFP (1 10) #define MT9M111_OUTFMT_INV_PIX_CLOCK (1 9) #define MT9M111_OUTFMT_RGB (1 8) -#define MT9M111_OUTFMT_RGB565 (0x0 6) -#define MT9M111_OUTFMT_RGB555 (0x1 6) -#define MT9M111_OUTFMT_RGB444x (0x2 6) -#define MT9M111_OUTFMT_RGBx444 (0x3 6) -#define MT9M111_OUTFMT_TST_RAMP_OFF(0x0 4) -#define MT9M111_OUTFMT_TST_RAMP_COL(0x1 4) -#define MT9M111_OUTFMT_TST_RAMP_ROW(0x2 4) -#define MT9M111_OUTFMT_TST_RAMP_FRAME (0x3 4) +#define MT9M111_OUTFMT_RGB565 (0 6) +#define MT9M111_OUTFMT_RGB555 (1 6) +#define MT9M111_OUTFMT_RGB444x (2 6) +#define MT9M111_OUTFMT_RGBx444 (3 6) +#define MT9M111_OUTFMT_TST_RAMP_OFF(0 4) +#define MT9M111_OUTFMT_TST_RAMP_COL(1 4) +#define MT9M111_OUTFMT_TST_RAMP_ROW(2 4) +#define MT9M111_OUTFMT_TST_RAMP_FRAME (3 4) #define MT9M111_OUTFMT_SHIFT_3_UP (1 3) #define MT9M111_OUTFMT_AVG_CHROMA (1 2) #define MT9M111_OUTFMT_SWAP_YCbCr_C_Y (1 1) -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/20] MT9M111/MT9M131
Hi everyone, the following patchseries was created in a rewrite process of the mt9m111 camera driver while it was tested for support of the very similar silicon mt9m121. Some patches add functionality like panning or test pattern generation or adjust rectengular positioning while others do some restructuring. It has been tested as functional. Comments on this are very welcome. Michael Grzeschik (19): mt9m111: init chip after read CHIP_VERSION mt9m111: register cleanup hex to dec bitoffset mt9m111: added new bit offset defines mt9m111: added default row/col/width/height values mt9m111: changed MAX_{HEIGHT,WIDTH} values to silicon pixelcount mt9m111: changed MIN_DARK_COLS to MT9M131 spec count mt9m111: cropcap use defined default rect properties in defrect mt9m111: cropcap check if type is CAPTURE mt9m111: rewrite make_rect for positioning in debug mt9m111: added mt9m111 format structure mt9m111: s_crop add calculation of output size mt9m111: s_crop check for VIDEO_CAPTURE type mt9m111: added reg_mask function mt9m111: rewrite setup_rect, added soft_crop for smooth panning mt9m111: added more supported BE colour formats mt9m111: rewrite set_pixfmt mt9m111: make use of testpattern in debug mode mt9m111: try_fmt rewrite to use preset values mt9m111: s_fmt make use of try_fmt Philipp Wiesner (1): mt9m111: Added indication that MT9M131 is supported by this driver drivers/media/video/Kconfig |5 +- drivers/media/video/mt9m111.c | 596 ++--- 2 files changed, 377 insertions(+), 224 deletions(-) -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/20] mt9m111: changed MIN_DARK_COLS to MT9M131 spec count
Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 2080615..f024cc5 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -130,7 +130,7 @@ #define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val)) #define MT9M111_MIN_DARK_ROWS 8 -#define MT9M111_MIN_DARK_COLS 24 +#define MT9M111_MIN_DARK_COLS 26 #define MT9M111_MAX_HEIGHT 1032 #define MT9M111_MAX_WIDTH 1288 #define MT9M111_DEF_DARK_ROWS 12 -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/20] mt9m111: cropcap use defined default rect properties in defrect
Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index f024cc5..3b19274 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -480,7 +480,10 @@ static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) a-bounds.top = MT9M111_MIN_DARK_ROWS; a-bounds.width = MT9M111_MAX_WIDTH; a-bounds.height= MT9M111_MAX_HEIGHT; - a-defrect = a-bounds; + a-defrect.left = MT9M111_DEF_DARK_COLS; + a-defrect.top = MT9M111_DEF_DARK_ROWS; + a-defrect.width= MT9M111_DEF_WIDTH; + a-defrect.height = MT9M111_DEF_HEIGHT; a-type = V4L2_BUF_TYPE_VIDEO_CAPTURE; a-pixelaspect.numerator= 1; a-pixelaspect.denominator = 1; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 13/20] mt9m111: s_crop check for VIDEO_CAPTURE type
Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 2758a97..4dbaf31 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -478,6 +478,9 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) u32 pixheight = mt9m111-format.mf.height; int ret; + if (a-type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + format.rect = a-c; format.mf = mt9m111-format.mf; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/20] mt9m111: rewrite make_rect for positioning in debug
If DEBUG is defined it is possible to set upper left corner Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c | 31 +++ 1 files changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index e8d8e9b..db5ac32 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -428,14 +428,7 @@ static int mt9m111_make_rect(struct i2c_client *client, struct v4l2_rect *rect) { struct mt9m111 *mt9m111 = to_mt9m111(client); - - if (mt9m111-fmt-code == V4L2_MBUS_FMT_SBGGR8_1X8 || - mt9m111-fmt-code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { - /* Bayer format - even size lengths */ - rect-width = ALIGN(rect-width, 2); - rect-height= ALIGN(rect-height, 2); - /* Let the user play with the starting pixel */ - } + enum v4l2_mbus_pixelcode code = mt9m111-fmt-code; /* FIXME: the datasheet doesn't specify minimum sizes */ soc_camera_limit_side(rect-left, rect-width, @@ -444,6 +437,28 @@ static int mt9m111_make_rect(struct i2c_client *client, soc_camera_limit_side(rect-top, rect-height, MT9M111_MIN_DARK_ROWS, 2, MT9M111_MAX_HEIGHT); + switch (code) { + case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: + /* unprocessed Bayer pattern format, IFP is bypassed */ +#ifndef DEBUG + /* assure that Bayer sequence is BGGR */ + /* in debug mode, let user play with starting pixel */ + rect-left = ALIGN(rect-left, 2); + rect-top = ALIGN(rect-top, 2) + 1; +#endif + case V4L2_MBUS_FMT_SBGGR8_1X8: + /* processed Bayer pattern format, sequence is fixed */ + /* assure even side lengths for both Bayer modes */ + rect-width = ALIGN(rect-width, 2); + rect-height= ALIGN(rect-height, 2); + default: + /* needed to avoid compiler warnings */; + } + + dev_dbg(client-dev, %s: rect: left=%d top=%d width=%d height=%d + mf: pixelcode=%d\n, __func__, rect-left, rect-top, + rect-width, rect-height, code); + return mt9m111_setup_rect(client, rect); } -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 20/20] mt9m111: s_fmt make use of try_fmt
Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c | 60 +++-- 1 files changed, 28 insertions(+), 32 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index f472ca1..ec758ae 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -697,38 +697,6 @@ static int mt9m111_set_pixfmt(struct i2c_client *client, return ret; } -static int mt9m111_s_fmt(struct v4l2_subdev *sd, -struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = sd-priv; - const struct mt9m111_datafmt *fmt; - struct mt9m111 *mt9m111 = to_mt9m111(client); - struct v4l2_rect *rect; - struct mt9m111_format format; - int ret; - - fmt = mt9m111_find_datafmt(mf-code, mt9m111_colour_fmts, - ARRAY_SIZE(mt9m111_colour_fmts)); - if (!fmt) - return -EINVAL; - - format.rect = mt9m111-format.rect; - format.mf = *mf; - rect= format.rect; - - dev_dbg(client-dev, - %s code=%x left=%d, top=%d, width=%d, height=%d\n, __func__, - mf-code, rect-left, rect-top, rect-width, rect-height); - - ret = mt9m111_make_rect(client, format); - if (!ret) - ret = mt9m111_set_pixfmt(client, format.mf.code); - if (!ret) - mt9m111-format = format; - - return ret; -} - static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { @@ -763,6 +731,34 @@ static int mt9m111_try_fmt(struct v4l2_subdev *sd, return 0; } +static int mt9m111_s_fmt(struct v4l2_subdev *sd, +struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = sd-priv; + struct mt9m111 *mt9m111 = to_mt9m111(client); + struct mt9m111_format format; + int ret; + + dev_dbg(client-dev, %s: mf: width=%d height=%d pixelcode=%d + field=%x colorspace=%x\n, __func__, mf-width, mf-height, + mf-code, mf-field, mf-colorspace); + + ret = mt9m111_try_fmt(sd, mf); + + if (!ret) { + format.rect = mt9m111-format.rect; + format.mf = *mf; + + ret = mt9m111_make_rect(client, format); + } + if (!ret) + ret = mt9m111_set_pixfmt(client, format.mf.code); + if (!ret) + mt9m111-format = format; + + return ret; +} + static int mt9m111_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) { -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/20] mt9m111: added reg_mask function
reg_mask is basically the same as clearing setting registers, but it is more convenient and faster (saves one rw cycle). Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 4dbaf31..161c751 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -128,6 +128,8 @@ #define reg_write(reg, val) mt9m111_reg_write(client, MT9M111_##reg, (val)) #define reg_set(reg, val) mt9m111_reg_set(client, MT9M111_##reg, (val)) #define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val)) +#define reg_mask(reg, val, mask) mt9m111_reg_mask(client, MT9M111_##reg, \ + (val), (mask)) #define MT9M111_MIN_DARK_ROWS 8 #define MT9M111_MIN_DARK_COLS 26 @@ -265,6 +267,15 @@ static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg, return mt9m111_reg_write(client, reg, ret ~data); } +static int mt9m111_reg_mask(struct i2c_client *client, const u16 reg, + const u16 data, const u16 mask) +{ + int ret; + + ret = mt9m111_reg_read(client, reg); + return mt9m111_reg_write(client, reg, (ret ~mask) | data); +} + static int mt9m111_set_context(struct i2c_client *client, enum mt9m111_context ctxt) { -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 16/20] mt9m111: added more supported BE colour formats
Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 11a68b6..6da9f48 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -175,7 +175,9 @@ static const struct mt9m111_datafmt mt9m111_colour_fmts[] = { {V4L2_MBUS_FMT_YUYV8_2X8_BE, V4L2_COLORSPACE_JPEG}, {V4L2_MBUS_FMT_YVYU8_2X8_BE, V4L2_COLORSPACE_JPEG}, {V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, + {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, }; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 15/20] mt9m111: rewrite setup_rect, added soft_crop for smooth panning
-soft_crop: enables the use of the sensors cropping abilities instead of using real roi. This is needed to make use of the 'pan' registers for smooth panning. Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c | 106 +++- 1 files changed, 82 insertions(+), 24 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 161c751..11a68b6 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -87,12 +87,16 @@ */ #define MT9M111_OPER_MODE_CTRL 0x106 #define MT9M111_OUTPUT_FORMAT_CTRL 0x108 +#define MT9M111_REDUCER_XPAN_B 0x19f #define MT9M111_REDUCER_XZOOM_B0x1a0 #define MT9M111_REDUCER_XSIZE_B0x1a1 +#define MT9M111_REDUCER_YPAN_B 0x1a2 #define MT9M111_REDUCER_YZOOM_B0x1a3 #define MT9M111_REDUCER_YSIZE_B0x1a4 +#define MT9M111_REDUCER_XPAN_A 0x1a5 #define MT9M111_REDUCER_XZOOM_A0x1a6 #define MT9M111_REDUCER_XSIZE_A0x1a7 +#define MT9M111_REDUCER_YPAN_A 0x1a8 #define MT9M111_REDUCER_YZOOM_A0x1a9 #define MT9M111_REDUCER_YSIZE_A0x1aa @@ -101,7 +105,8 @@ #define MT9M111_OPMODE_AUTOEXPO_EN (1 14) #define MT9M111_OPMODE_AUTOWHITEBAL_EN (1 1) - +#define MT9M111_OUTFMT_CFA_1ST_ROW_BLUE(1 1) +#define MT9M111_OUTFMT_CFA_1ST_COL_R_B (1 0) #define MT9M111_OUTFMT_PROCESSED_BAYER (1 14) #define MT9M111_OUTFMT_BYPASS_IFP (1 10) #define MT9M111_OUTFMT_INV_PIX_CLOCK (1 9) @@ -140,6 +145,11 @@ #define MT9M111_DEF_HEIGHT 1024 #define MT9M111_DEF_WIDTH 1280 +static int soft_crop; +module_param(soft_crop, int, S_IRUGO); +MODULE_PARM_DESC(soft_crop, Enables soft-cropping and thus the use of + pan register); + /* MT9M111 has only one fixed colorspace per pixelcode */ struct mt9m111_datafmt { enum v4l2_mbus_pixelcodecode; @@ -296,42 +306,90 @@ static int mt9m111_setup_rect(struct i2c_client *client, struct mt9m111_format *format) { struct v4l2_rect *rect = format-rect; - int ret, is_raw_format; - int width = rect-width; - int height = rect-height; - - if (format-mf.code == V4L2_MBUS_FMT_SBGGR8_1X8 || - format-mf.code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) - is_raw_format = 1; - else - is_raw_format = 0; + struct v4l2_mbus_framefmt *mf = format-mf; + enum v4l2_mbus_pixelcode *code = format-mf.code; + u16 data_outfmt1 = 0, mask_outfmt1; + u16 colum_start, row_start, window_width, window_height, xpan, ypan; + int ret; - ret = reg_write(COLUMN_START, rect-left); - if (!ret) - ret = reg_write(ROW_START, rect-top); + dev_dbg(client-dev, %s: rect: left=%d top=%d width=%d height=%d + mf: pixelcode=%d\n, __func__, rect-left, rect-top, + rect-width, rect-height, *code); - if (is_raw_format) { + if (*code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { + ret = reg_write(COLUMN_START, rect-left); if (!ret) - ret = reg_write(WINDOW_WIDTH, width); + ret = reg_write(ROW_START, rect-top); if (!ret) - ret = reg_write(WINDOW_HEIGHT, height); + ret = reg_write(WINDOW_WIDTH, rect-width); + if (!ret) + ret = reg_write(WINDOW_HEIGHT, rect-height); } else { + if (soft_crop) { + /* use 'soft cropping' through ZOOM and PAN registers */ + /* enables use of smart zooming and panning functions */ + colum_start = MT9M111_MIN_DARK_COLS; + row_start = MT9M111_MIN_DARK_ROWS; + window_width= MT9M111_MAX_WIDTH; + window_height = MT9M111_MAX_HEIGHT; + xpan= rect-left - MT9M111_MIN_DARK_COLS; + ypan= rect-top - MT9M111_MIN_DARK_ROWS; + } else { + /* use real cropping, smaller roi increases framerate */ + colum_start = rect-left; + row_start = rect-top; + window_width= rect-width; + window_height = rect-height; + xpan= 0; + ypan= 0; + } + + ret = reg_write(COLUMN_START, colum_start); + if (!ret) + ret = reg_write(ROW_START, row_start); if (!ret) - ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH); +
[PATCH 17/20] mt9m111: rewrite set_pixfmt
removed pixfmt helper functions and option flags setting the configuration register directly in set_pixfmt Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c | 142 - 1 files changed, 56 insertions(+), 86 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 6da9f48..f327177 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -104,7 +104,10 @@ #define MT9M111_OUTPUT_FORMAT_CTRL2_B 0x19b #define MT9M111_OPMODE_AUTOEXPO_EN (1 14) +#define MT9M111_OPMODE_FLICKER_DET_EN (1 7) #define MT9M111_OPMODE_AUTOWHITEBAL_EN (1 1) +#define MT9M111_OUTFMT_FLIP_BAYER_COL (1 9) +#define MT9M111_OUTFMT_FLIP_BAYER_ROW (1 8) #define MT9M111_OUTFMT_CFA_1ST_ROW_BLUE(1 1) #define MT9M111_OUTFMT_CFA_1ST_COL_R_B (1 0) #define MT9M111_OUTFMT_PROCESSED_BAYER (1 14) @@ -124,6 +127,7 @@ #define MT9M111_OUTFMT_SWAP_YCbCr_C_Y (1 1) #define MT9M111_OUTFMT_SWAP_RGB_EVEN (1 1) #define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr(1 0) +#define MT9M111_OUTFMT_SWAP_RGB_R_B(1 0) /* * Camera control register addresses (0x200..0x2ff not implemented) @@ -204,10 +208,6 @@ struct mt9m111 { unsigned int powered:1; unsigned int hflip:1; unsigned int vflip:1; - unsigned int swap_rgb_even_odd:1; - unsigned int swap_rgb_red_blue:1; - unsigned int swap_yuv_y_chromas:1; - unsigned int swap_yuv_cb_cr:1; unsigned int autowhitebalance:1; }; @@ -397,68 +397,6 @@ static int mt9m111_setup_rect(struct i2c_client *client, return ret; } -static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt) -{ - int ret; - - ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); - if (!ret) - ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt); - return ret; -} - -static int mt9m111_setfmt_bayer8(struct i2c_client *client) -{ - return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER | - MT9M111_OUTFMT_RGB); -} - -static int mt9m111_setfmt_bayer10(struct i2c_client *client) -{ - return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_BYPASS_IFP); -} - -static int mt9m111_setfmt_rgb565(struct i2c_client *client) -{ - struct mt9m111 *mt9m111 = to_mt9m111(client); - int val = 0; - - if (mt9m111-swap_rgb_red_blue) - val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; - if (mt9m111-swap_rgb_even_odd) - val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; - val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; - - return mt9m111_setup_pixfmt(client, val); -} - -static int mt9m111_setfmt_rgb555(struct i2c_client *client) -{ - struct mt9m111 *mt9m111 = to_mt9m111(client); - int val = 0; - - if (mt9m111-swap_rgb_red_blue) - val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; - if (mt9m111-swap_rgb_even_odd) - val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; - val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; - - return mt9m111_setup_pixfmt(client, val); -} - -static int mt9m111_setfmt_yuv(struct i2c_client *client) -{ - struct mt9m111 *mt9m111 = to_mt9m111(client); - int val = 0; - - if (mt9m111-swap_yuv_cb_cr) - val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; - if (mt9m111-swap_yuv_y_chromas) - val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; - - return mt9m111_setup_pixfmt(client, val); -} - static int mt9m111_enable(struct i2c_client *client) { struct mt9m111 *mt9m111 = to_mt9m111(client); @@ -616,41 +554,49 @@ static int mt9m111_g_fmt(struct v4l2_subdev *sd, static int mt9m111_set_pixfmt(struct i2c_client *client, enum v4l2_mbus_pixelcode code) { - struct mt9m111 *mt9m111 = to_mt9m111(client); + u16 data_outfmt1 = 0, data_outfmt2 = 0, mask_outfmt1, mask_outfmt2; + u16 data_opermod; int ret; + data_opermod = MT9M111_OPMODE_AUTOEXPO_EN | + MT9M111_OPMODE_FLICKER_DET_EN | MT9M111_OPMODE_AUTOWHITEBAL_EN; + switch (code) { case V4L2_MBUS_FMT_SBGGR8_1X8: - ret = mt9m111_setfmt_bayer8(client); + data_outfmt1 = MT9M111_OUTFMT_FLIP_BAYER_ROW; + data_outfmt2 = MT9M111_OUTFMT_PROCESSED_BAYER | + MT9M111_OUTFMT_RGB; break; case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: - ret = mt9m111_setfmt_bayer10(client); + data_outfmt2 = MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_RGB; break; case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: - ret = mt9m111_setfmt_rgb555(client); + data_outfmt2 = MT9M111_OUTFMT_SWAP_RGB_EVEN | + MT9M111_OUTFMT_RGB | + MT9M111_OUTFMT_RGB555; +
[PATCH 19/20] mt9m111: try_fmt rewrite to use preset values
make use of the format.rect boundery values Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c | 41 +++-- 1 files changed, 19 insertions(+), 22 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 799a735..f472ca1 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -733,35 +733,32 @@ static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd-priv; + struct mt9m111 *mt9m111 = to_mt9m111(client); + struct v4l2_rect rect = mt9m111-format.rect; const struct mt9m111_datafmt *fmt; - bool bayer = mf-code == V4L2_MBUS_FMT_SBGGR8_1X8 || - mf-code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE; fmt = mt9m111_find_datafmt(mf-code, mt9m111_colour_fmts, ARRAY_SIZE(mt9m111_colour_fmts)); if (!fmt) return -EINVAL; - /* -* With Bayer format enforce even side lengths, but let the user play -* with the starting pixel -*/ + mf-code= fmt-code; + mf-colorspace = fmt-colorspace; + mf-field = V4L2_FIELD_NONE; - if (mf-height MT9M111_MAX_HEIGHT) - mf-height = MT9M111_MAX_HEIGHT; - else if (mf-height 2) - mf-height = 2; - else if (bayer) - mf-height = ALIGN(mf-height, 2); - - if (mf-width MT9M111_MAX_WIDTH) - mf-width = MT9M111_MAX_WIDTH; - else if (mf-width 2) - mf-width = 2; - else if (bayer) - mf-width = ALIGN(mf-width, 2); - - mf-colorspace = fmt-colorspace; + if (mf-code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { + mf-width = rect.width; + mf-height = rect.height; + } else { + if (mf-width rect.width) + mf-width = rect.width; + if (mf-height rect.height) + mf-height = rect.height; + } + + dev_dbg(client-dev, %s: mf: width=%d height=%d pixelcode=%d + field=%x colorspace=%x\n, __func__, mf-width, mf-height, + mf-code, mf-field, mf-colorspace); return 0; } -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 18/20] mt9m111: make use of testpattern in debug mode
Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c | 63 + 1 files changed, 63 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index f327177..799a735 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -87,6 +87,7 @@ */ #define MT9M111_OPER_MODE_CTRL 0x106 #define MT9M111_OUTPUT_FORMAT_CTRL 0x108 +#define MT9M111_TEST_PATTERN_GEN 0x148 #define MT9M111_REDUCER_XPAN_B 0x19f #define MT9M111_REDUCER_XZOOM_B0x1a0 #define MT9M111_REDUCER_XSIZE_B0x1a1 @@ -110,6 +111,15 @@ #define MT9M111_OUTFMT_FLIP_BAYER_ROW (1 8) #define MT9M111_OUTFMT_CFA_1ST_ROW_BLUE(1 1) #define MT9M111_OUTFMT_CFA_1ST_COL_R_B (1 0) +#define MT9M111_TST_PATT_OFF (0 0) +#define MT9M111_TST_PATT_1 (1 0) +#define MT9M111_TST_PATT_2 (2 0) +#define MT9M111_TST_PATT_3 (3 0) +#define MT9M111_TST_PATT_4 (4 0) +#define MT9M111_TST_PATT_5 (5 0) +#define MT9M111_TST_PATT_6 (6 0) +#define MT9M111_TST_PATT_COLORBARS (7 0) +#define MT9M111_TST_PATT_FORCE_WB_GAIN_1 (1 7) #define MT9M111_OUTFMT_PROCESSED_BAYER (1 14) #define MT9M111_OUTFMT_BYPASS_IFP (1 10) #define MT9M111_OUTFMT_INV_PIX_CLOCK (1 9) @@ -149,6 +159,13 @@ #define MT9M111_DEF_HEIGHT 1024 #define MT9M111_DEF_WIDTH 1280 +#ifdef DEBUG +static int testpattern; +module_param(testpattern, int, S_IRUGO); +MODULE_PARM_DESC(testpattern, Test pattern: a number from 1 to 10, 0 for + normal usage); +#endif + static int soft_crop; module_param(soft_crop, int, S_IRUGO); MODULE_PARM_DESC(soft_crop, Enables soft-cropping and thus the use of @@ -556,6 +573,9 @@ static int mt9m111_set_pixfmt(struct i2c_client *client, { u16 data_outfmt1 = 0, data_outfmt2 = 0, mask_outfmt1, mask_outfmt2; u16 data_opermod; +#ifdef DEBUG + u16 pattern = 0; +#endif int ret; data_opermod = MT9M111_OPMODE_AUTOEXPO_EN | @@ -616,6 +636,49 @@ static int mt9m111_set_pixfmt(struct i2c_client *client, ret = reg_mask(OUTPUT_FORMAT_CTRL, data_outfmt1, mask_outfmt1); +#ifdef DEBUG + switch (testpattern) { + case 1: + pattern = MT9M111_TST_PATT_1 | MT9M111_TST_PATT_FORCE_WB_GAIN_1; + break; + case 2: + pattern = MT9M111_TST_PATT_2 | MT9M111_TST_PATT_FORCE_WB_GAIN_1; + break; + case 3: + pattern = MT9M111_TST_PATT_3 | MT9M111_TST_PATT_FORCE_WB_GAIN_1; + break; + case 4: + pattern = MT9M111_TST_PATT_4 | MT9M111_TST_PATT_FORCE_WB_GAIN_1; + break; + case 5: + pattern = MT9M111_TST_PATT_5 | MT9M111_TST_PATT_FORCE_WB_GAIN_1; + break; + case 6: + pattern = MT9M111_TST_PATT_6 | MT9M111_TST_PATT_FORCE_WB_GAIN_1; + break; + case 7: + pattern = MT9M111_TST_PATT_COLORBARS | + MT9M111_TST_PATT_FORCE_WB_GAIN_1; + break; + case 8: + data_outfmt2 |= MT9M111_OUTFMT_TST_RAMP_COL; + break; + case 9: + data_outfmt2 |= MT9M111_OUTFMT_TST_RAMP_ROW; + break; + case 10: + data_outfmt2 |= MT9M111_OUTFMT_TST_RAMP_FRAME; + break; + } + + dev_dbg(client-dev, %s: using testpattern %d\n, __func__, + testpattern); + + if (!ret) + ret = mt9m111_reg_set(client, + MT9M111_TEST_PATTERN_GEN, pattern); +#endif + if (!ret) ret = reg_mask(OUTPUT_FORMAT_CTRL2_A, data_outfmt2, mask_outfmt2); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/20] mt9m111: added default row/col/width/height values
Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index aeb2241..5f0c55e 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -133,6 +133,10 @@ #define MT9M111_MIN_DARK_COLS 24 #define MT9M111_MAX_HEIGHT 1024 #define MT9M111_MAX_WIDTH 1280 +#define MT9M111_DEF_DARK_ROWS 12 +#define MT9M111_DEF_DARK_COLS 30 +#define MT9M111_DEF_HEIGHT 1024 +#define MT9M111_DEF_WIDTH 1280 /* MT9M111 has only one fixed colorspace per pixelcode */ struct mt9m111_datafmt { -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/20] mt9m111: changed MAX_{HEIGHT,WIDTH} values to silicon pixelcount
Signed-off-by: Philipp Wiesner p.wies...@phytec.de Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/media/video/mt9m111.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 5f0c55e..2080615 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -131,8 +131,8 @@ #define MT9M111_MIN_DARK_ROWS 8 #define MT9M111_MIN_DARK_COLS 24 -#define MT9M111_MAX_HEIGHT 1024 -#define MT9M111_MAX_WIDTH 1280 +#define MT9M111_MAX_HEIGHT 1032 +#define MT9M111_MAX_WIDTH 1288 #define MT9M111_DEF_DARK_ROWS 12 #define MT9M111_DEF_DARK_COLS 30 #define MT9M111_DEF_HEIGHT 1024 -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [media-ctl PATCH 2/3] Just include kernel headers
Hi Sergio, On Friday 30 July 2010 16:47:22 Aguirre, Sergio wrote: On Friday 30 July 2010 9:24 AM Laurent Pinchart wrote: On Friday 30 July 2010 16:10:08 Aguirre, Sergio wrote: On Friday 30 July 2010 8:45 AM Laurent Pinchart wrote: On Wednesday 14 July 2010 18:17:25 Sergio Aguirre wrote: We shouldn't require full kernel source for this. That's right in theory, but I then get $ make KDIR=/home/laurent/src/arm/kernel/ arm-none-linux-gnueabi-gcc -O2 -Wall -fpic -I. - I/home/laurent/src/arm/kernel//include-c -o media.o media.c In file included from /opt/cs/arm-2009q1/bin/../arm-none-linux- gnueabi/libc/usr/include/asm/types.h:4, from /home/laurent/src/arm/kernel//include/linux/types.h:4, from /home/laurent/src/arm/kernel//include/linux/videodev2.h:66, from media.c:31: /home/laurent/src/arm/kernel//include/asm-generic/int-ll64.h:11:29: error: asm/bitsperlong.h: No such file or directory make: *** [media.o] Error 1 when building against a kernel tree. KDIR doesn't exist anymore. By the result of your log, I don't see how that value got passed into the makefile... Are you sure you applied the patch correctly? I haven't, I've just removed the arch include dir from KDIR in the Makefile. The end result is the same. Hmm.. I think this is expected, since the kernel headers folder generated with make ARCH=arm INSTALL_HDR_PATH=your-fs-root headers_install Is not the same as just reading the kernel source include folder. Some #ifdef get resolved depending on the arch, and the headers are rebuilt. See : Documentation/make/headers_install.txt So, I guess it's not as simple as just removing the arch include folder. Ideally the application should be built against installed kernel headers, bug given the early stage of development of the media controller, I expect most people to build it against a kernel tree. I would like to keep the Makefile as-is for now, and change it when the media controller patches will reach the mainline kernel. -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [media-ctl PATCH 2/3] Just include kernel headers
Hi Laurent, -Original Message- From: Laurent Pinchart [mailto:laurent.pinch...@ideasonboard.com] Sent: Friday, July 30, 2010 10:40 AM To: Aguirre, Sergio Cc: linux-media@vger.kernel.org Subject: Re: [media-ctl PATCH 2/3] Just include kernel headers Hi Sergio, snip Ideally the application should be built against installed kernel headers, bug given the early stage of development of the media controller, I expect most people to build it against a kernel tree. I would like to keep the Makefile as-is for now, and change it when the media controller patches will reach the mainline kernel. Ok, understood. Not a problem. Regards, Sergio -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PULL] soc-camera, sh-vou, v4l2 for 2.6.36
Em 29-07-2010 06:31, Guennadi Liakhovetski escreveu: Hi Mauro The following changes since commit c57fd88318988f17731e446fe1d8498f506fdd44: V4L/DVB: uvcvideo: Add support for Manta MM-353 Plako (2010-07-05 19:47:16 -0300) are available in the git repository at: git://linuxtv.org/gliakhovetski/v4l-dvb.git for-2.6.36 Guennadi Liakhovetski (8): mediabus: fix ambiguous pixel code names V4L2: avoid name conflicts in macros This patch is incomplete, as other macros use sd without declaring it as an argument, like: #define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...)\ __v4l2_device_call_subdevs(v4l2_dev,\ !(grpid) || sd-grp_id == (grpid), o, f , ##args) To make things even worse, some drivers have their own opinion about it, like: #define cx18_call_hw(cx, hw, o, f, args...) \ __v4l2_device_call_subdevs((cx)-v4l2_dev, \ !(hw) || (sd-grp_id (hw)), o, f , ##args) The result is that this patch breaks the compilation on several drivers. It is not your patch's fault. the problem is that those macros have something to hide. If sd is a parameter of the macro, they should have being declaring sd into their lists of arguments. Please provide a version that will properly address those problems. As the other patches don't seem to need this change (at least, all compiled fine here), I'll drop this patch and apply the remaining ones. Cheers, Mauro -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] [PATCH 1/6] SoC Camera: add driver for OMAP1 camera interface
Friday 30 July 2010 13:07:42 Guennadi Liakhovetski napisaĆ(a): Hi Janusz Thanks once more for the patches, from your patches it is obvious, that you've spent quite a bit of time on them and you have not just copy-pasted various bits and pieces from other drivers, just filling your hardware details, but you also actually understand a lot of what is actually going on in there. So, I think, fixing remaining mostly minor issues shouldn't be too difficult for you either. Hi Guennadi, Thanks for your review time. I only tried to get the driver really working, not only looking good ;). On Sun, 18 Jul 2010, Janusz Krzysztofik wrote: This is a V4L2 driver for TI OMAP1 SoC camera interface. Two versions of the driver are provided, using either videobuf-dma-contig or videobuf-dma-sg. The former uses less processing power, but often fails to allocate contignuous buffer memory. The latter is free of this problem, but generates tens of DMA interrupts per frame. Hm, would it be difficult to first try contig, and if it fails - fall back to sg? Hmm, let me think about it. In its present state buffer management in your driver is pretty difficult to follow. At the VERY least you have to extensively document your buffer manipulations. Better yet clean it up. AFAIU, your ready pointer is pretty much unused in the contiguous case. Or you can easily get rid of it. I was sure the ready pointer was essential for both paths. However, things tend to change as more and more optimizations / cleanups are applied, so I have to verify it again. So, I think, a very welcome improvement to the driver would be a cleaner separation between the two cases. Don't try that much to reuse the code as much as possible. Would be much better to have clean separation between the two implementations - whether dynamically switchable at runtime or at config time - would be best to separate the two implementations to the point, where each of them becomes understandable and maintainable. You are right. My approach was probably more adequate at development time, when I was trying to aviod error-prone code duplication. As soon as both paths get stable, they can be split for better readability. I'll take care of this. So, I will do a pretty formal review this time and wait for v2. And in v2 I'd like to at the very least see detailed buffer-management documentation, or - better yet - a rework with a clean separation. OK. ... --- linux-2.6.35-rc3.orig/include/media/omap1_camera.h 1970-01-01 01:00:00.0 +0100 +++ linux-2.6.35-rc3/include/media/omap1_camera.h 2010-07-18 01:31:57.0 +0200 @@ -0,0 +1,16 @@ A copyright / licence header here, please OK. +#ifndef __MEDIA_OMAP1_CAMERA_H_ +#define __MEDIA_OMAP1_CAMERA_H_ + +#define OMAP1_CAMERA_IOSIZE0x1c + +struct omap1_cam_platform_data { + unsigned long camexclk_khz; + unsigned long lclk_khz_max; + unsigned long flags; +}; + +#define OMAP1_CAMERA_LCLK_RISING BIT(0) +#define OMAP1_CAMERA_RST_LOW BIT(1) +#define OMAP1_CAMERA_RST_HIGH BIT(2) Then you need to #include linux/bitops.h OK. Since I always tend to optimise out redundant includes of header files that are otherwise included indirectly, please verify if there are more of them that you would prefere included explicitly. + +#endif /* __MEDIA_OMAP1_CAMERA_H_ */ --- linux-2.6.35-rc3.orig/drivers/media/video/Kconfig 2010-06-26 15:55:29.0 +0200 +++ linux-2.6.35-rc3/drivers/media/video/Kconfig2010-07-02 04:12:02.0 +0200 @@ -962,6 +962,20 @@ config VIDEO_SH_MOBILE_CEU ---help--- This is a v4l2 driver for the SuperH Mobile CEU Interface +config VIDEO_OMAP1 + tristate OMAP1 Camera Interface driver + depends on VIDEO_DEV ARCH_OMAP1 SOC_CAMERA + select VIDEOBUF_DMA_CONTIG if !VIDEO_OMAP1_SG + ---help--- + This is a v4l2 driver for the TI OMAP1 camera interface + +if VIDEO_OMAP1 Don't think you need this if, the depends on below should suffice. OK. My intention was to get it indented, and now I see it works like this even if not enclosed with if-endif. Will drop the if-endif if the compile time SG option survives. +config VIDEO_OMAP1_SG + bool Scatter-gather mode + depends on VIDEO_OMAP1 EXPERIMENTAL + select VIDEOBUF_DMA_SG +endif + ... +#ifndef CONFIG_VIDEO_OMAP1_SG +#include media/videobuf-dma-contig.h +#else +#include media/videobuf-dma-sg.h +#endif I think, you can just include both headers. OK. ... +#define CAM_EXCLK_6MHz 600 +#define CAM_EXCLK_8MHz 800 +#define CAM_EXCLK_9_6MHz960 +#define CAM_EXCLK_12MHz1200 +#define CAM_EXCLK_24MHz2400 Why do you need this? Your platform specifies the EXCLK frequency directly in kHz, then you multiplly it by 1000 to get pcdev-camexclk in Hz, then
Re: [PATCH 0/9 v3] IR: few fixes, additions and ENE driver
Em 30-07-2010 08:38, Maxim Levitsky escreveu: Hi, This is mostly same patchset. I addressed the comments of Andy Walls. Now IR decoding is done by a separate thread, and this fixes the race, and unnesesary performance loss due to it. Best regards, Maxim Levitsky Hmm... some change at this changeset is trying to divide a 64 bits integer at the LIRC driver. This is causing the following error: Jul 30 16:45:23 agua kernel: [23834.179871] lirc_dev: IR Remote Control driver registered, major 251 Jul 30 16:45:23 agua kernel: [23834.181884] ir_lirc_codec: Unknown symbol __udivdi3 (err 0) you should, instead use do_div for doing that. Another fix would be to define the timeout constants as int or u32. Cheers, Mauro -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[cron job] v4l-dvb daily build 2.6.22 and up: ERRORS, 2.6.16-2.6.21: ERRORS
This message is generated daily by a cron job that builds v4l-dvb for the kernels and architectures in the list below. Results of the daily build of v4l-dvb: date:Fri Jul 30 19:00:16 CEST 2010 path:http://www.linuxtv.org/hg/v4l-dvb changeset: 14993:9652f85e688a git master: f6760aa024199cfbce564311dc4bc4d47b6fb349 git media-master: 1c1371c2fe53ded8ede3a0404c9415fbf3321328 gcc version: i686-linux-gcc (GCC) 4.4.3 host hardware:x86_64 host os: 2.6.32.5 linux-2.6.32.6-armv5: OK linux-2.6.33-armv5: OK linux-2.6.34-armv5: WARNINGS linux-2.6.35-rc1-armv5: ERRORS linux-2.6.32.6-armv5-davinci: OK linux-2.6.33-armv5-davinci: OK linux-2.6.34-armv5-davinci: WARNINGS linux-2.6.35-rc1-armv5-davinci: ERRORS linux-2.6.32.6-armv5-ixp: WARNINGS linux-2.6.33-armv5-ixp: WARNINGS linux-2.6.34-armv5-ixp: WARNINGS linux-2.6.35-rc1-armv5-ixp: ERRORS linux-2.6.32.6-armv5-omap2: OK linux-2.6.33-armv5-omap2: OK linux-2.6.34-armv5-omap2: WARNINGS linux-2.6.35-rc1-armv5-omap2: ERRORS linux-2.6.22.19-i686: ERRORS linux-2.6.23.17-i686: ERRORS linux-2.6.24.7-i686: WARNINGS linux-2.6.25.20-i686: WARNINGS linux-2.6.26.8-i686: WARNINGS linux-2.6.27.44-i686: WARNINGS linux-2.6.28.10-i686: WARNINGS linux-2.6.29.1-i686: WARNINGS linux-2.6.30.10-i686: WARNINGS linux-2.6.31.12-i686: OK linux-2.6.32.6-i686: OK linux-2.6.33-i686: OK linux-2.6.34-i686: WARNINGS linux-2.6.35-rc1-i686: ERRORS linux-2.6.32.6-m32r: OK linux-2.6.33-m32r: OK linux-2.6.34-m32r: WARNINGS linux-2.6.35-rc1-m32r: ERRORS linux-2.6.32.6-mips: OK linux-2.6.33-mips: OK linux-2.6.34-mips: WARNINGS linux-2.6.35-rc1-mips: ERRORS linux-2.6.32.6-powerpc64: OK linux-2.6.33-powerpc64: OK linux-2.6.34-powerpc64: WARNINGS linux-2.6.35-rc1-powerpc64: ERRORS linux-2.6.22.19-x86_64: ERRORS linux-2.6.23.17-x86_64: ERRORS linux-2.6.24.7-x86_64: WARNINGS linux-2.6.25.20-x86_64: WARNINGS linux-2.6.26.8-x86_64: WARNINGS linux-2.6.27.44-x86_64: WARNINGS linux-2.6.28.10-x86_64: WARNINGS linux-2.6.29.1-x86_64: WARNINGS linux-2.6.30.10-x86_64: WARNINGS linux-2.6.31.12-x86_64: OK linux-2.6.32.6-x86_64: OK linux-2.6.33-x86_64: OK linux-2.6.34-x86_64: WARNINGS linux-2.6.35-rc1-x86_64: ERRORS linux-git-armv5: WARNINGS linux-git-armv5-davinci: WARNINGS linux-git-armv5-ixp: WARNINGS linux-git-armv5-omap2: WARNINGS linux-git-i686: WARNINGS linux-git-m32r: OK linux-git-mips: OK linux-git-powerpc64: OK linux-git-x86_64: WARNINGS spec: ERRORS spec-git: OK sparse: ERRORS linux-2.6.16.62-i686: ERRORS linux-2.6.17.14-i686: ERRORS linux-2.6.18.8-i686: ERRORS linux-2.6.19.7-i686: ERRORS linux-2.6.20.21-i686: ERRORS linux-2.6.21.7-i686: ERRORS linux-2.6.16.62-x86_64: ERRORS linux-2.6.17.14-x86_64: ERRORS linux-2.6.18.8-x86_64: ERRORS linux-2.6.19.7-x86_64: ERRORS linux-2.6.20.21-x86_64: ERRORS linux-2.6.21.7-x86_64: ERRORS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Friday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Friday.tar.bz2 The V4L-DVB specification from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/media.html -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 06/13] IR: nec decoder: fix repeat.
Em 30-07-2010 08:38, Maxim Levitsky escreveu: Repeat space is 4 units, not 8. Current code would never trigger a repeat. Yes, this fixed the issue: Jul 30 16:53:52 agua kernel: [24343.507577] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.507588] ir_nec_decode: Repeat last key Jul 30 16:53:52 agua kernel: [24343.507590] ir_nec_decode: NEC scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.507592] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.507595] ir_nec_decode: Repeat last key Jul 30 16:53:52 agua kernel: [24343.724242] ir_nec_decode: NEC scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.724246] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.724257] ir_nec_decode: Repeat last key Jul 30 16:53:52 agua kernel: [24343.724259] ir_nec_decode: NEC scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.724261] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.724264] ir_nec_decode: Repeat last key Jul 30 16:53:53 agua kernel: [24343.937576] ir_nec_decode: NEC scancode 0x0009 Jul 30 16:53:53 agua kernel: [24343.937580] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:53 agua kernel: [24343.937592] ir_nec_decode: Repeat last key Jul 30 16:53:53 agua kernel: [24343.937594] ir_nec_decode: NEC scancode 0x0009 Jul 30 16:53:53 agua kernel: [24343.937596] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:53 agua kernel: [24343.937599] ir_nec_decode: Repeat last key However that isn't true for NECX, so repeat there must be handled differently. Signed-off-by: Maxim Levitsky maximlevit...@gmail.com Please preserve Andy's reviewed-by: when re-submitting a patch. --- drivers/media/IR/ir-nec-decoder.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index 52e0f37..1c0cf03 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c @@ -20,7 +20,7 @@ #define NEC_HEADER_PULSE (16 * NEC_UNIT) #define NECX_HEADER_PULSE(8 * NEC_UNIT) /* Less common NEC variant */ #define NEC_HEADER_SPACE (8 * NEC_UNIT) -#define NEC_REPEAT_SPACE (8 * NEC_UNIT) +#define NEC_REPEAT_SPACE (4 * NEC_UNIT) #define NEC_BIT_PULSE(1 * NEC_UNIT) #define NEC_BIT_0_SPACE (1 * NEC_UNIT) #define NEC_BIT_1_SPACE (3 * NEC_UNIT) -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/9 v3] IR: few fixes, additions and ENE driver
On Fri, 2010-07-30 at 16:33 -0300, Mauro Carvalho Chehab wrote: Em 30-07-2010 08:38, Maxim Levitsky escreveu: Hi, This is mostly same patchset. I addressed the comments of Andy Walls. Now IR decoding is done by a separate thread, and this fixes the race, and unnesesary performance loss due to it. Best regards, Maxim Levitsky Hmm... some change at this changeset is trying to divide a 64 bits integer at the LIRC driver. This is causing the following error: Jul 30 16:45:23 agua kernel: [23834.179871] lirc_dev: IR Remote Control driver registered, major 251 Jul 30 16:45:23 agua kernel: [23834.181884] ir_lirc_codec: Unknown symbol __udivdi3 (err 0) you should, instead use do_div for doing that. Another fix would be to define the timeout constants as int or u32. I know about that, but forgot, sorry. Sure, will do. Best regards, Maxim Levitsky -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 06/13] IR: nec decoder: fix repeat.
On Fri, 2010-07-30 at 16:36 -0300, Mauro Carvalho Chehab wrote: Em 30-07-2010 08:38, Maxim Levitsky escreveu: Repeat space is 4 units, not 8. Current code would never trigger a repeat. Yes, this fixed the issue: Jul 30 16:53:52 agua kernel: [24343.507577] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.507588] ir_nec_decode: Repeat last key Jul 30 16:53:52 agua kernel: [24343.507590] ir_nec_decode: NEC scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.507592] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.507595] ir_nec_decode: Repeat last key Jul 30 16:53:52 agua kernel: [24343.724242] ir_nec_decode: NEC scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.724246] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.724257] ir_nec_decode: Repeat last key Jul 30 16:53:52 agua kernel: [24343.724259] ir_nec_decode: NEC scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.724261] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:52 agua kernel: [24343.724264] ir_nec_decode: Repeat last key Jul 30 16:53:53 agua kernel: [24343.937576] ir_nec_decode: NEC scancode 0x0009 Jul 30 16:53:53 agua kernel: [24343.937580] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:53 agua kernel: [24343.937592] ir_nec_decode: Repeat last key Jul 30 16:53:53 agua kernel: [24343.937594] ir_nec_decode: NEC scancode 0x0009 Jul 30 16:53:53 agua kernel: [24343.937596] ir_getkeycode: unknown key for scancode 0x0009 Jul 30 16:53:53 agua kernel: [24343.937599] ir_nec_decode: Repeat last key However that isn't true for NECX, so repeat there must be handled differently. Signed-off-by: Maxim Levitsky maximlevit...@gmail.com Please preserve Andy's reviewed-by: when re-submitting a patch. Yep, sorry about that! Although, if I change a patch, I shouldn't preserve signed-off, reviewed-by, lines, right? Best regards, Maxim Levitsky --- drivers/media/IR/ir-nec-decoder.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index 52e0f37..1c0cf03 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c @@ -20,7 +20,7 @@ #define NEC_HEADER_PULSE (16 * NEC_UNIT) #define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */ #define NEC_HEADER_SPACE (8 * NEC_UNIT) -#define NEC_REPEAT_SPACE (8 * NEC_UNIT) +#define NEC_REPEAT_SPACE (4 * NEC_UNIT) #define NEC_BIT_PULSE (1 * NEC_UNIT) #define NEC_BIT_0_SPACE(1 * NEC_UNIT) #define NEC_BIT_1_SPACE(3 * NEC_UNIT) -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] v4l: Use v4l2_get_subdevdata instead of accessing v4l2_subdev::priv
Replace direct access to the v4l2_subdev priv field with the inline v4l2_get_subdevdata method. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/media/video/mt9m001.c| 26 +- drivers/media/video/mt9m111.c| 20 ++-- drivers/media/video/mt9t031.c| 24 drivers/media/video/mt9t112.c| 14 +++--- drivers/media/video/mt9v022.c| 26 +- drivers/media/video/ov772x.c | 18 +- drivers/media/video/ov9640.c | 12 ++-- drivers/media/video/rj54n1cb0c.c | 26 +- drivers/media/video/soc_camera.c |2 +- drivers/media/video/tw9910.c | 20 ++-- 10 files changed, 94 insertions(+), 94 deletions(-) diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 79f096d..fcb4cd9 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -157,7 +157,7 @@ static int mt9m001_init(struct i2c_client *client) static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable) { - struct i2c_client *client = sd-priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); /* Switch to master normal mode or stop sensor readout */ if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) 0) @@ -206,7 +206,7 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) { - struct i2c_client *client = sd-priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); struct v4l2_rect rect = a-c; struct soc_camera_device *icd = client-dev.platform_data; @@ -271,7 +271,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) { - struct i2c_client *client = sd-priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); a-c= mt9m001-rect; @@ -297,7 +297,7 @@ static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) static int mt9m001_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct i2c_client *client = sd-priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); mf-width = mt9m001-rect.width; @@ -312,7 +312,7 @@ static int mt9m001_g_fmt(struct v4l2_subdev *sd, static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct i2c_client *client = sd-priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); struct v4l2_crop a = { .c = { @@ -340,7 +340,7 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd, static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct i2c_client *client = sd-priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); const struct mt9m001_datafmt *fmt; @@ -367,7 +367,7 @@ static int mt9m001_try_fmt(struct v4l2_subdev *sd, static int mt9m001_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) { - struct i2c_client *client = sd-priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); if (id-match.type != V4L2_CHIP_MATCH_I2C_ADDR) @@ -386,7 +386,7 @@ static int mt9m001_g_chip_ident(struct v4l2_subdev *sd, static int mt9m001_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { - struct i2c_client *client = sd-priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); if (reg-match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg-reg 0xff) return -EINVAL; @@ -406,7 +406,7 @@ static int mt9m001_g_register(struct v4l2_subdev *sd, static int mt9m001_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { - struct i2c_client *client = sd-priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); if (reg-match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg-reg 0xff) return -EINVAL; @@ -468,7 +468,7 @@ static struct soc_camera_ops mt9m001_ops = { static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - struct i2c_client *client = sd-priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); int data; @@ -494,7 +494,7 @@ static int mt9m001_g_ctrl(struct
[PATCH 2/2] v4l: Add a v4l2_subdev host private data field
The existing priv field stores subdev private data owned by the subdev driver. Host (bridge) drivers might need to store per-subdev host-specific data, such as a pointer to platform data. Add a v4l2_subdev host_priv field to store host-specific data, and rename the existing priv field to dev_priv. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Documentation/video4linux/v4l2-framework.txt |5 + include/media/v4l2-subdev.h | 20 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index e831aac..f5fdb39 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -192,6 +192,11 @@ You also need a way to go from the low-level struct to v4l2_subdev. For the common i2c_client struct the i2c_set_clientdata() call is used to store a v4l2_subdev pointer, for other busses you may have to use other methods. +Bridges might also need to store per-subdev private data, such as a pointer to +bridge-specific per-subdev private data. The v4l2_subdev structure provides +host private data for that purpose that can be accessed with +v4l2_get_subdev_hostdata() and v4l2_set_subdev_hostdata(). + From the bridge driver perspective you load the sub-device module and somehow obtain the v4l2_subdev pointer. For i2c devices this is easy: you call i2c_get_clientdata(). For other busses something similar needs to be done. diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 02c6f4d..fcdd247 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -420,17 +420,28 @@ struct v4l2_subdev { /* can be used to group similar subdevs, value is driver-specific */ u32 grp_id; /* pointer to private data */ - void *priv; + void *dev_priv; + void *host_priv; }; static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p) { - sd-priv = p; + sd-dev_priv = p; } static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd) { - return sd-priv; + return sd-dev_priv; +} + +static inline void v4l2_set_subdev_hostdata(struct v4l2_subdev *sd, void *p) +{ + sd-host_priv = p; +} + +static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd) +{ + return sd-host_priv; } static inline void v4l2_subdev_init(struct v4l2_subdev *sd, @@ -444,7 +455,8 @@ static inline void v4l2_subdev_init(struct v4l2_subdev *sd, sd-flags = 0; sd-name[0] = '\0'; sd-grp_id = 0; - sd-priv = NULL; + sd-dev_priv = NULL; + sd-host_priv = NULL; } /* Call an ops of a v4l2_subdev, doing the right checks against -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 10/13] IR: extend interfaces to support more device settings LIRC: add new IOCTL that enables learning mode (wide band receiver)
Hi! Maxim Levitsky maximlevit...@gmail.com wrote: Still missing features: carrier report timeout reports. Will need to pack these into ir_raw_event Hm, this patch changes the LIRC interface but I can't see the according patch to the documentation. [...] * @tx_ir: transmit IR * @s_idle: optional: enable/disable hardware idle mode, upon which, + current * device doesn't interrupt host untill it sees IR data +=== Huh? + device doesn't interrupt host untill it sees IR data + * @s_learning_mode: enable wide band receiver used for learning + patched s/untill/until/ [...] #define LIRC_CAN_MEASURE_CARRIER 0x0200 +#define LIRC_CAN_HAVE_WIDEBAND_RECEIVER 0x0400 LIRC_CAN_USE_WIDEBAND_RECEIVER [...] @@ -145,7 +146,7 @@ * if enabled from the next key press on the driver will send * LIRC_MODE2_FREQUENCY packets */ -#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x001d, __u32) +#define LIRC_SET_MEASURE_CARRIER_MODE_IOW('i', 0x001d, __u32) /* * to set a range use @@ -162,4 +163,6 @@ #define LIRC_SETUP_START _IO('i', 0x0021) #define LIRC_SETUP_END _IO('i', 0x0022) +#define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x0023, __u32) If you really want this new ioctl, then it should be clarified how it behaves in relation to LIRC_SET_MEASURE_CARRIER_MODE. Do you have to enable the wide-band receiver explicitly before you can enable carrier reports or does enabling carrier reports implicitly switch to the wide-band receiver? What happens if carrier mode is enabled and you explicitly turn off the wide-band receiver? And while we're at interface stuff: Do we really need LIRC_SETUP_START and LIRC_SETUP_END? It is only used once in lircd during startup. Christoph -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 10/13] IR: extend interfaces to support more device settings LIRC: add new IOCTL that enables learning mode (wide band receiver)
On Fri, 2010-07-30 at 23:22 +0200, Christoph Bartelmus wrote: Hi! Maxim Levitsky maximlevit...@gmail.com wrote: Still missing features: carrier report timeout reports. Will need to pack these into ir_raw_event Hm, this patch changes the LIRC interface but I can't see the according patch to the documentation. [...] * @tx_ir: transmit IR * @s_idle: optional: enable/disable hardware idle mode, upon which, + current * device doesn't interrupt host untill it sees IR data +=== Huh? :-) + device doesn't interrupt host untill it sees IR data + * @s_learning_mode: enable wide band receiver used for learning + patched s/untill/until/ [...] #define LIRC_CAN_MEASURE_CARRIER 0x0200 +#define LIRC_CAN_HAVE_WIDEBAND_RECEIVER 0x0400 LIRC_CAN_USE_WIDEBAND_RECEIVER OK. [...] @@ -145,7 +146,7 @@ * if enabled from the next key press on the driver will send * LIRC_MODE2_FREQUENCY packets */ -#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x001d, __u32) +#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x001d, __u32) /* * to set a range use @@ -162,4 +163,6 @@ #define LIRC_SETUP_START _IO('i', 0x0021) #define LIRC_SETUP_END _IO('i', 0x0022) +#define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x0023, __u32) If you really want this new ioctl, then it should be clarified how it behaves in relation to LIRC_SET_MEASURE_CARRIER_MODE. In my opinion, I won't need the LIRC_SET_MEASURE_CARRIER_MODE, I would just optionally turn that on in learning mode. You disagree, and since that is not important (besides TX and learning features are present only at fraction of ENE devices. The only user I did the debugging with, doesn't seem to want to help debug that code anymore...) But anyway, in current state I want these features to be independent. Driver will enable learning mode if it have to. I'll add the documentation. Do you have to enable the wide-band receiver explicitly before you can enable carrier reports or does enabling carrier reports implicitly switch to the wide-band receiver? I would implicitly switch the learning mode on, untill user turns off the carrier reports. What happens if carrier mode is enabled and you explicitly turn off the wide-band receiver? Wouldn't it be better to have one ioctl for both after all? And while we're at interface stuff: Do we really need LIRC_SETUP_START and LIRC_SETUP_END? It is only used once in lircd during startup. I don't think so. Best regards, Maxim Levitsky -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[no subject]
-- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html