diff --git a/[refs] b/[refs]
index 8a1866d7d2a9..be339d7ba983 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: a79960e576ebca9dbf24489b562689f2be7e9ff0
+refs/heads/master: 5aea0fac0fb295b0f2528cd03f93541bcd5c78e3
diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile
index 325cfd1d6d99..ab8300f67182 100644
--- a/trunk/Documentation/DocBook/Makefile
+++ b/trunk/Documentation/DocBook/Makefile
@@ -8,7 +8,7 @@
DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
- writing_usb_driver.xml networking.xml \
+ procfs-guide.xml writing_usb_driver.xml networking.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
@@ -32,10 +32,10 @@ PS_METHOD = $(prefer-db2x)
###
# The targets that may be used.
-PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs xmldoclinks
+PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs media
BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
-xmldocs: $(BOOKS) xmldoclinks
+xmldocs: $(BOOKS)
sgmldocs: xmldocs
PS := $(patsubst %.xml, %.ps, $(BOOKS))
@@ -45,24 +45,15 @@ PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
pdfdocs: $(PDF)
HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
-htmldocs: $(HTML)
+htmldocs: media $(HTML)
$(call build_main_index)
- $(call build_images)
MAN := $(patsubst %.xml, %.9, $(BOOKS))
mandocs: $(MAN)
-build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
- cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/
-
-xmldoclinks:
-ifneq ($(objtree),$(srctree))
- for dep in dvb media-entities.tmpl media-indices.tmpl v4l; do \
- rm -f $(objtree)/Documentation/DocBook/$$dep \
- && ln -s $(srctree)/Documentation/DocBook/$$dep $(objtree)/Documentation/DocBook/ \
- || exit; \
- done
-endif
+media:
+ mkdir -p $(srctree)/Documentation/DocBook/media/
+ cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(srctree)/Documentation/DocBook/media/
installmandocs: mandocs
mkdir -p /usr/local/man/man9/
@@ -74,7 +65,7 @@ KERNELDOC = $(srctree)/scripts/kernel-doc
DOCPROC = $(objtree)/scripts/basic/docproc
XMLTOFLAGS = -m $(srctree)/Documentation/DocBook/stylesheet.xsl
-XMLTOFLAGS += --skip-validation
+#XMLTOFLAGS += --skip-validation
###
# DOCPROC is used for two purposes:
@@ -110,6 +101,17 @@ endif
# Changes in kernel-doc force a rebuild of all documentation
$(BOOKS): $(KERNELDOC)
+###
+# procfs guide uses a .c file as example code.
+# This requires an explicit dependency
+C-procfs-example = procfs_example.xml
+C-procfs-example2 = $(addprefix $(obj)/,$(C-procfs-example))
+$(obj)/procfs-guide.xml: $(C-procfs-example2)
+
+# List of programs to build
+##oops, this is a kernel module::hostprogs-y := procfs_example
+obj-m += procfs_example.o
+
# Tell kbuild to always build the programs
always := $(hostprogs-y)
@@ -236,7 +238,7 @@ clean-files := $(DOCBOOKS) \
$(patsubst %.xml, %.pdf, $(DOCBOOKS)) \
$(patsubst %.xml, %.html, $(DOCBOOKS)) \
$(patsubst %.xml, %.9, $(DOCBOOKS)) \
- $(index)
+ $(C-procfs-example) $(index)
clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man
diff --git a/trunk/Documentation/DocBook/media-entities.tmpl b/trunk/Documentation/DocBook/media-entities.tmpl
index c725cb852c54..bb5ab741220e 100644
--- a/trunk/Documentation/DocBook/media-entities.tmpl
+++ b/trunk/Documentation/DocBook/media-entities.tmpl
@@ -23,7 +23,6 @@
VIDIOC_ENUMINPUT ">
VIDIOC_ENUMOUTPUT ">
VIDIOC_ENUMSTD ">
-VIDIOC_ENUM_DV_PRESETS ">
VIDIOC_ENUM_FMT ">
VIDIOC_ENUM_FRAMEINTERVALS ">
VIDIOC_ENUM_FRAMESIZES ">
@@ -31,8 +30,6 @@
VIDIOC_G_AUDOUT ">
VIDIOC_G_CROP ">
VIDIOC_G_CTRL ">
-VIDIOC_G_DV_PRESET ">
-VIDIOC_G_DV_TIMINGS ">
VIDIOC_G_ENC_INDEX ">
VIDIOC_G_EXT_CTRLS ">
VIDIOC_G_FBUF ">
@@ -56,7 +53,6 @@
VIDIOC_QUERYCTRL ">
VIDIOC_QUERYMENU ">
VIDIOC_QUERYSTD ">
-VIDIOC_QUERY_DV_PRESET ">
VIDIOC_REQBUFS ">
VIDIOC_STREAMOFF ">
VIDIOC_STREAMON ">
@@ -64,8 +60,6 @@
VIDIOC_S_AUDOUT ">
VIDIOC_S_CROP ">
VIDIOC_S_CTRL ">
-VIDIOC_S_DV_PRESET ">
-VIDIOC_S_DV_TIMINGS ">
VIDIOC_S_EXT_CTRLS ">
VIDIOC_S_FBUF ">
VIDIOC_S_FMT ">
@@ -124,7 +118,6 @@
v4l2_audio">
v4l2_audioout">
-v4l2_bt_timings">
v4l2_buffer">
v4l2_capability">
v4l2_captureparm">
@@ -135,9 +128,6 @@
v4l2_dbg_chip_ident">
v4l2_dbg_match">
v4l2_dbg_register">
-v4l2_dv_enum_preset">
-v4l2_dv_preset">
-v4l2_dv_timings">
v4l2_enc_idx">
v4l2_enc_idx_entry">
v4l2_encoder_cmd">
@@ -253,10 +243,6 @@
-
-
-
-
@@ -347,10 +333,6 @@
-
-
-
-
diff --git a/trunk/Documentation/DocBook/media-indices.tmpl b/trunk/Documentation/DocBook/media-indices.tmpl
index 78d6031de001..9e30a236d74f 100644
--- a/trunk/Documentation/DocBook/media-indices.tmpl
+++ b/trunk/Documentation/DocBook/media-indices.tmpl
@@ -36,7 +36,6 @@
enum v4l2_preemphasis
struct v4l2_audio
struct v4l2_audioout
-struct v4l2_bt_timings
struct v4l2_buffer
struct v4l2_capability
struct v4l2_captureparm
@@ -47,9 +46,6 @@
struct v4l2_dbg_chip_ident
struct v4l2_dbg_match
struct v4l2_dbg_register
-struct v4l2_dv_enum_preset
-struct v4l2_dv_preset
-struct v4l2_dv_timings
struct v4l2_enc_idx
struct v4l2_enc_idx_entry
struct v4l2_encoder_cmd
diff --git a/trunk/Documentation/DocBook/procfs-guide.tmpl b/trunk/Documentation/DocBook/procfs-guide.tmpl
new file mode 100644
index 000000000000..9eba4b7af73d
--- /dev/null
+++ b/trunk/Documentation/DocBook/procfs-guide.tmpl
@@ -0,0 +1,626 @@
+
+
+]>
+
+
+
+ Linux Kernel Procfs Guide
+
+
+
+ Erik
+ (J.A.K.)
+ Mouw
+
+
+ mouw@nl.linux.org
+
+
+
+
+
+ This software and documentation were written while working on the
+ LART computing board
+ (http://www.lartmaker.nl/ ),
+ which was sponsored by the Delt University of Technology projects
+ Mobile Multi-media Communications and Ubiquitous Communications.
+
+
+
+
+
+
+ 1.0
+ May 30, 2001
+ Initial revision posted to linux-kernel
+
+
+ 1.1
+ June 3, 2001
+ Revised after comments from linux-kernel
+
+
+
+
+ 2001
+ Erik Mouw
+
+
+
+
+
+ This documentation is free software; you can redistribute it
+ and/or modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later
+ version.
+
+
+
+ This documentation is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+
+
+ You should have received a copy of the GNU General Public
+ License along with this program; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ MA 02111-1307 USA
+
+
+
+ For more details see the file COPYING in the source
+ distribution of Linux.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Preface
+
+
+ This guide describes the use of the procfs file system from
+ within the Linux kernel. The idea to write this guide came up on
+ the #kernelnewbies IRC channel (see http://www.kernelnewbies.org/ ),
+ when Jeff Garzik explained the use of procfs and forwarded me a
+ message Alexander Viro wrote to the linux-kernel mailing list. I
+ agreed to write it up nicely, so here it is.
+
+
+
+ I'd like to thank Jeff Garzik
+ jgarzik@pobox.com and Alexander Viro
+ viro@parcelfarce.linux.theplanet.co.uk for their input,
+ Tim Waugh twaugh@redhat.com for his Selfdocbook ,
+ and Marc Joosen marcj@historia.et.tudelft.nl for
+ proofreading.
+
+
+
+ Erik
+
+
+
+
+
+
+
+ Introduction
+
+
+ The /proc file system
+ (procfs) is a special file system in the linux kernel. It's a
+ virtual file system: it is not associated with a block device
+ but exists only in memory. The files in the procfs are there to
+ allow userland programs access to certain information from the
+ kernel (like process information in /proc/[0-9]+/ ), but also for debug
+ purposes (like /proc/ksyms ).
+
+
+
+ This guide describes the use of the procfs file system from
+ within the Linux kernel. It starts by introducing all relevant
+ functions to manage the files within the file system. After that
+ it shows how to communicate with userland, and some tips and
+ tricks will be pointed out. Finally a complete example will be
+ shown.
+
+
+
+ Note that the files in /proc/sys are sysctl files: they
+ don't belong to procfs and are governed by a completely
+ different API described in the Kernel API book.
+
+
+
+
+
+
+
+ Managing procfs entries
+
+
+ This chapter describes the functions that various kernel
+ components use to populate the procfs with files, symlinks,
+ device nodes, and directories.
+
+
+
+ A minor note before we start: if you want to use any of the
+ procfs functions, be sure to include the correct header file!
+ This should be one of the first lines in your code:
+
+
+
+#include <linux/proc_fs.h>
+
+
+
+
+
+
+ Creating a regular file
+
+
+
+ struct proc_dir_entry* create_proc_entry
+ const char* name
+ mode_t mode
+ struct proc_dir_entry* parent
+
+
+
+
+ This function creates a regular file with the name
+ name , file mode
+ mode in the directory
+ parent . To create a file in the root of
+ the procfs, use NULL as
+ parent parameter. When successful, the
+ function will return a pointer to the freshly created
+ struct proc_dir_entry ; otherwise it
+ will return NULL . describes how to do something useful with
+ regular files.
+
+
+
+ Note that it is specifically supported that you can pass a
+ path that spans multiple directories. For example
+ create_proc_entry ("drivers/via0/info" )
+ will create the via0
+ directory if necessary, with standard
+ 0755 permissions.
+
+
+
+ If you only want to be able to read the file, the function
+ create_proc_read_entry described in may be used to create and initialise
+ the procfs entry in one single call.
+
+
+
+
+
+
+
+ Creating a symlink
+
+
+
+ struct proc_dir_entry*
+ proc_symlink const
+ char* name
+ struct proc_dir_entry*
+ parent const
+ char* dest
+
+
+
+
+ This creates a symlink in the procfs directory
+ parent that points from
+ name to
+ dest . This translates in userland to
+ ln -s dest
+ name .
+
+
+
+
+ Creating a directory
+
+
+
+ struct proc_dir_entry* proc_mkdir
+ const char* name
+ struct proc_dir_entry* parent
+
+
+
+
+ Create a directory name in the procfs
+ directory parent .
+
+
+
+
+
+
+
+ Removing an entry
+
+
+
+ void remove_proc_entry
+ const char* name
+ struct proc_dir_entry* parent
+
+
+
+
+ Removes the entry name in the directory
+ parent from the procfs. Entries are
+ removed by their name , not by the
+ struct proc_dir_entry returned by the
+ various create functions. Note that this function doesn't
+ recursively remove entries.
+
+
+
+ Be sure to free the data entry from
+ the struct proc_dir_entry before
+ remove_proc_entry is called (that is: if
+ there was some data allocated, of
+ course). See for more information
+ on using the data entry.
+
+
+
+
+
+
+
+
+ Communicating with userland
+
+
+ Instead of reading (or writing) information directly from
+ kernel memory, procfs works with call back
+ functions for files: functions that are called when
+ a specific file is being read or written. Such functions have
+ to be initialised after the procfs file is created by setting
+ the read_proc and/or
+ write_proc fields in the
+ struct proc_dir_entry* that the
+ function create_proc_entry returned:
+
+
+
+struct proc_dir_entry* entry;
+
+entry->read_proc = read_proc_foo;
+entry->write_proc = write_proc_foo;
+
+
+
+ If you only want to use a the
+ read_proc , the function
+ create_proc_read_entry described in may be used to create and initialise the
+ procfs entry in one single call.
+
+
+
+
+
+ Reading data
+
+
+ The read function is a call back function that allows userland
+ processes to read data from the kernel. The read function
+ should have the following format:
+
+
+
+
+ int read_func
+ char* buffer
+ char** start
+ off_t off
+ int count
+ int* peof
+ void* data
+
+
+
+
+ The read function should write its information into the
+ buffer , which will be exactly
+ PAGE_SIZE bytes long.
+
+
+
+ The parameter
+ peof should be used to signal that the
+ end of the file has been reached by writing
+ 1 to the memory location
+ peof points to.
+
+
+
+ The data
+ parameter can be used to create a single call back function for
+ several files, see .
+
+
+
+ The rest of the parameters and the return value are described
+ by a comment in fs/proc/generic.c as follows:
+
+
+
+
+ You have three ways to return data:
+
+
+
+
+ Leave *start = NULL . (This is the default.)
+ Put the data of the requested offset at that
+ offset within the buffer. Return the number (n )
+ of bytes there are from the beginning of the
+ buffer up to the last byte of data. If the
+ number of supplied bytes (= n - offset ) is
+ greater than zero and you didn't signal eof
+ and the reader is prepared to take more data
+ you will be called again with the requested
+ offset advanced by the number of bytes
+ absorbed. This interface is useful for files
+ no larger than the buffer.
+
+
+
+
+ Set *start to an unsigned long value less than
+ the buffer address but greater than zero.
+ Put the data of the requested offset at the
+ beginning of the buffer. Return the number of
+ bytes of data placed there. If this number is
+ greater than zero and you didn't signal eof
+ and the reader is prepared to take more data
+ you will be called again with the requested
+ offset advanced by *start . This interface is
+ useful when you have a large file consisting
+ of a series of blocks which you want to count
+ and return as wholes.
+ (Hack by Paul.Russell@rustcorp.com.au)
+
+
+
+
+ Set *start to an address within the buffer.
+ Put the data of the requested offset at *start .
+ Return the number of bytes of data placed there.
+ If this number is greater than zero and you
+ didn't signal eof and the reader is prepared to
+ take more data you will be called again with the
+ requested offset advanced by the number of bytes
+ absorbed.
+
+
+
+
+
+
+ shows how to use a read call back
+ function.
+
+
+
+
+
+
+
+ Writing data
+
+
+ The write call back function allows a userland process to write
+ data to the kernel, so it has some kind of control over the
+ kernel. The write function should have the following format:
+
+
+
+
+ int write_func
+ struct file* file
+ const char* buffer
+ unsigned long count
+ void* data
+
+
+
+
+ The write function should read count
+ bytes at maximum from the buffer . Note
+ that the buffer doesn't live in the
+ kernel's memory space, so it should first be copied to kernel
+ space with copy_from_user . The
+ file parameter is usually
+ ignored. shows how to use the
+ data parameter.
+
+
+
+ Again, shows how to use this call back
+ function.
+
+
+
+
+
+
+
+ A single call back for many files
+
+
+ When a large number of almost identical files is used, it's
+ quite inconvenient to use a separate call back function for
+ each file. A better approach is to have a single call back
+ function that distinguishes between the files by using the
+ data field in struct
+ proc_dir_entry . First of all, the
+ data field has to be initialised:
+
+
+
+struct proc_dir_entry* entry;
+struct my_file_data *file_data;
+
+file_data = kmalloc(sizeof(struct my_file_data), GFP_KERNEL);
+entry->data = file_data;
+
+
+
+ The data field is a void
+ * , so it can be initialised with anything.
+
+
+
+ Now that the data field is set, the
+ read_proc and
+ write_proc can use it to distinguish
+ between files because they get it passed into their
+ data parameter:
+
+
+
+int foo_read_func(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len;
+
+ if(data == file_data) {
+ /* special case for this file */
+ } else {
+ /* normal processing */
+ }
+
+ return len;
+}
+
+
+
+ Be sure to free the data data field
+ when removing the procfs entry.
+
+
+
+
+
+
+
+
+ Tips and tricks
+
+
+
+
+
+ Convenience functions
+
+
+
+ struct proc_dir_entry* create_proc_read_entry
+ const char* name
+ mode_t mode
+ struct proc_dir_entry* parent
+ read_proc_t* read_proc
+ void* data
+
+
+
+
+ This function creates a regular file in exactly the same way
+ as create_proc_entry from does, but also allows to set the read
+ function read_proc in one call. This
+ function can set the data as well, like
+ explained in .
+
+
+
+
+
+
+ Modules
+
+
+ If procfs is being used from within a module, be sure to set
+ the owner field in the
+ struct proc_dir_entry to
+ THIS_MODULE .
+
+
+
+struct proc_dir_entry* entry;
+
+entry->owner = THIS_MODULE;
+
+
+
+
+
+
+
+ Mode and ownership
+
+
+ Sometimes it is useful to change the mode and/or ownership of
+ a procfs entry. Here is an example that shows how to achieve
+ that:
+
+
+
+struct proc_dir_entry* entry;
+
+entry->mode = S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH;
+entry->uid = 0;
+entry->gid = 100;
+
+
+
+
+
+
+
+
+
+ Example
+
+
+
+&procfsexample;
+
+
+
diff --git a/trunk/Documentation/DocBook/procfs_example.c b/trunk/Documentation/DocBook/procfs_example.c
new file mode 100644
index 000000000000..a5b11793b1e0
--- /dev/null
+++ b/trunk/Documentation/DocBook/procfs_example.c
@@ -0,0 +1,201 @@
+/*
+ * procfs_example.c: an example proc interface
+ *
+ * Copyright (C) 2001, Erik Mouw (mouw@nl.linux.org)
+ *
+ * This file accompanies the procfs-guide in the Linux kernel
+ * source. Its main use is to demonstrate the concepts and
+ * functions described in the guide.
+ *
+ * This software has been developed while working on the LART
+ * computing board (http://www.lartmaker.nl), which was sponsored
+ * by the Delt University of Technology projects Mobile Multi-media
+ * Communications and Ubiquitous Communications.
+ *
+ * This program is free software; you can redistribute
+ * it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#define MODULE_VERS "1.0"
+#define MODULE_NAME "procfs_example"
+
+#define FOOBAR_LEN 8
+
+struct fb_data_t {
+ char name[FOOBAR_LEN + 1];
+ char value[FOOBAR_LEN + 1];
+};
+
+
+static struct proc_dir_entry *example_dir, *foo_file,
+ *bar_file, *jiffies_file, *symlink;
+
+
+struct fb_data_t foo_data, bar_data;
+
+
+static int proc_read_jiffies(char *page, char **start,
+ off_t off, int count,
+ int *eof, void *data)
+{
+ int len;
+
+ len = sprintf(page, "jiffies = %ld\n",
+ jiffies);
+
+ return len;
+}
+
+
+static int proc_read_foobar(char *page, char **start,
+ off_t off, int count,
+ int *eof, void *data)
+{
+ int len;
+ struct fb_data_t *fb_data = (struct fb_data_t *)data;
+
+ /* DON'T DO THAT - buffer overruns are bad */
+ len = sprintf(page, "%s = '%s'\n",
+ fb_data->name, fb_data->value);
+
+ return len;
+}
+
+
+static int proc_write_foobar(struct file *file,
+ const char *buffer,
+ unsigned long count,
+ void *data)
+{
+ int len;
+ struct fb_data_t *fb_data = (struct fb_data_t *)data;
+
+ if(count > FOOBAR_LEN)
+ len = FOOBAR_LEN;
+ else
+ len = count;
+
+ if(copy_from_user(fb_data->value, buffer, len))
+ return -EFAULT;
+
+ fb_data->value[len] = '\0';
+
+ return len;
+}
+
+
+static int __init init_procfs_example(void)
+{
+ int rv = 0;
+
+ /* create directory */
+ example_dir = proc_mkdir(MODULE_NAME, NULL);
+ if(example_dir == NULL) {
+ rv = -ENOMEM;
+ goto out;
+ }
+ /* create jiffies using convenience function */
+ jiffies_file = create_proc_read_entry("jiffies",
+ 0444, example_dir,
+ proc_read_jiffies,
+ NULL);
+ if(jiffies_file == NULL) {
+ rv = -ENOMEM;
+ goto no_jiffies;
+ }
+
+ /* create foo and bar files using same callback
+ * functions
+ */
+ foo_file = create_proc_entry("foo", 0644, example_dir);
+ if(foo_file == NULL) {
+ rv = -ENOMEM;
+ goto no_foo;
+ }
+
+ strcpy(foo_data.name, "foo");
+ strcpy(foo_data.value, "foo");
+ foo_file->data = &foo_data;
+ foo_file->read_proc = proc_read_foobar;
+ foo_file->write_proc = proc_write_foobar;
+
+ bar_file = create_proc_entry("bar", 0644, example_dir);
+ if(bar_file == NULL) {
+ rv = -ENOMEM;
+ goto no_bar;
+ }
+
+ strcpy(bar_data.name, "bar");
+ strcpy(bar_data.value, "bar");
+ bar_file->data = &bar_data;
+ bar_file->read_proc = proc_read_foobar;
+ bar_file->write_proc = proc_write_foobar;
+
+ /* create symlink */
+ symlink = proc_symlink("jiffies_too", example_dir,
+ "jiffies");
+ if(symlink == NULL) {
+ rv = -ENOMEM;
+ goto no_symlink;
+ }
+
+ /* everything OK */
+ printk(KERN_INFO "%s %s initialised\n",
+ MODULE_NAME, MODULE_VERS);
+ return 0;
+
+no_symlink:
+ remove_proc_entry("bar", example_dir);
+no_bar:
+ remove_proc_entry("foo", example_dir);
+no_foo:
+ remove_proc_entry("jiffies", example_dir);
+no_jiffies:
+ remove_proc_entry(MODULE_NAME, NULL);
+out:
+ return rv;
+}
+
+
+static void __exit cleanup_procfs_example(void)
+{
+ remove_proc_entry("jiffies_too", example_dir);
+ remove_proc_entry("bar", example_dir);
+ remove_proc_entry("foo", example_dir);
+ remove_proc_entry("jiffies", example_dir);
+ remove_proc_entry(MODULE_NAME, NULL);
+
+ printk(KERN_INFO "%s %s removed\n",
+ MODULE_NAME, MODULE_VERS);
+}
+
+
+module_init(init_procfs_example);
+module_exit(cleanup_procfs_example);
+
+MODULE_AUTHOR("Erik Mouw");
+MODULE_DESCRIPTION("procfs examples");
+MODULE_LICENSE("GPL");
diff --git a/trunk/Documentation/DocBook/v4l/common.xml b/trunk/Documentation/DocBook/v4l/common.xml
index c65f0ac9b6ee..b1a81d246d58 100644
--- a/trunk/Documentation/DocBook/v4l/common.xml
+++ b/trunk/Documentation/DocBook/v4l/common.xml
@@ -716,41 +716,6 @@ if (-1 == ioctl (fd, &VIDIOC-S-STD;, &std_id)) {
}
-
- Digital Video (DV) Timings
-
- The video standards discussed so far has been dealing with Analog TV and the
-corresponding video timings. Today there are many more different hardware interfaces
-such as High Definition TV interfaces (HDMI), VGA, DVI connectors etc., that carry
-video signals and there is a need to extend the API to select the video timings
-for these interfaces. Since it is not possible to extend the &v4l2-std-id; due to
-the limited bits available, a new set of IOCTLs is added to set/get video timings at
-the input and output:
-
- DV Presets: Digital Video (DV) presets. These are IDs representing a
-video timing at the input/output. Presets are pre-defined timings implemented
-by the hardware according to video standards. A __u32 data type is used to represent
-a preset unlike the bit mask that is used in &v4l2-std-id; allowing future extensions
-to support as many different presets as needed.
-
-
- Custom DV Timings: This will allow applications to define more detailed
-custom video timings for the interface. This includes parameters such as width, height,
-polarities, frontporch, backporch etc.
-
-
-
- To enumerate and query the attributes of DV presets supported by a device,
-applications use the &VIDIOC-ENUM-DV-PRESETS; ioctl. To get the current DV preset,
-applications use the &VIDIOC-G-DV-PRESET; ioctl and to set a preset they use the
-&VIDIOC-S-DV-PRESET; ioctl.
- To set custom DV timings for the device, applications use the
-&VIDIOC-S-DV-TIMINGS; ioctl and to get current custom DV timings they use the
-&VIDIOC-G-DV-TIMINGS; ioctl.
- Applications can make use of the and
- flags to decide what ioctls are available to set the
-video timings for the device.
-
&sub-controls;
diff --git a/trunk/Documentation/DocBook/v4l/compat.xml b/trunk/Documentation/DocBook/v4l/compat.xml
index b9dbdf9e6d29..4d1902a54d61 100644
--- a/trunk/Documentation/DocBook/v4l/compat.xml
+++ b/trunk/Documentation/DocBook/v4l/compat.xml
@@ -2291,8 +2291,8 @@ was renamed to v4l2_chip_ident_old
New control V4L2_CID_COLORFX was added.
-
-
+
+
V4L2 in Linux 2.6.32
@@ -2322,16 +2322,8 @@ more information.
Added Remote Controller chapter, describing the default Remote Controller mapping for media devices.
-
-
-
- V4L2 in Linux 2.6.33
-
-
- Added support for Digital Video timings in order to support HDTV receivers and transmitters.
-
-
-
+
+
diff --git a/trunk/Documentation/DocBook/v4l/v4l2.xml b/trunk/Documentation/DocBook/v4l/v4l2.xml
index 060105af49e5..937b4157a5d0 100644
--- a/trunk/Documentation/DocBook/v4l/v4l2.xml
+++ b/trunk/Documentation/DocBook/v4l/v4l2.xml
@@ -74,17 +74,6 @@ Remote Controller chapter.
-
-
- Muralidharan
- Karicheri
- Documented the Digital Video timings API.
-
-
- m-karicheri2@ti.com
-
-
-
@@ -100,7 +89,7 @@ Remote Controller chapter.
2008
2009
Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
-Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab
+Rubli, Andy Walls, Mauro Carvalho Chehab
Except when explicitly stated as GPL, programming examples within
@@ -113,13 +102,6 @@ structs, ioctls) must be noted in more detail in the history chapter
(compat.sgml), along with the possible impact on existing drivers and
applications. -->
-
- 2.6.33
- 2009-12-03
- mk
- Added documentation for the Digital Video timings API.
-
-
2.6.32
2009-08-31
@@ -373,7 +355,7 @@ and discussions on the V4L mailing list.
Video for Linux Two API Specification
- Revision 2.6.33
+ Revision 2.6.32
&sub-common;
@@ -429,7 +411,6 @@ and discussions on the V4L mailing list.
&sub-encoder-cmd;
&sub-enumaudio;
&sub-enumaudioout;
- &sub-enum-dv-presets;
&sub-enum-fmt;
&sub-enum-framesizes;
&sub-enum-frameintervals;
@@ -440,8 +421,6 @@ and discussions on the V4L mailing list.
&sub-g-audioout;
&sub-g-crop;
&sub-g-ctrl;
- &sub-g-dv-preset;
- &sub-g-dv-timings;
&sub-g-enc-index;
&sub-g-ext-ctrls;
&sub-g-fbuf;
@@ -462,7 +441,6 @@ and discussions on the V4L mailing list.
&sub-querybuf;
&sub-querycap;
&sub-queryctrl;
- &sub-query-dv-preset;
&sub-querystd;
&sub-reqbufs;
&sub-s-hw-freq-seek;
diff --git a/trunk/Documentation/DocBook/v4l/videodev2.h.xml b/trunk/Documentation/DocBook/v4l/videodev2.h.xml
index 068325940658..3e282ed9f593 100644
--- a/trunk/Documentation/DocBook/v4l/videodev2.h.xml
+++ b/trunk/Documentation/DocBook/v4l/videodev2.h.xml
@@ -733,99 +733,6 @@ struct v4l2_standard {
__u32 reserved[4];
};
-/*
- * V I D E O T I M I N G S D V P R E S E T
- */
-struct v4l2_dv_preset {
- __u32 preset;
- __u32 reserved[4];
-};
-
-/*
- * D V P R E S E T S E N U M E R A T I O N
- */
-struct v4l2_dv_enum_preset {
- __u32 index;
- __u32 preset;
- __u8 name[32]; /* Name of the preset timing */
- __u32 width;
- __u32 height;
- __u32 reserved[4];
-};
-
-/*
- * D V P R E S E T V A L U E S
- */
-#define V4L2_DV_INVALID 0
-#define V4L2_DV_480P59_94 1 /* BT.1362 */
-#define V4L2_DV_576P50 2 /* BT.1362 */
-#define V4L2_DV_720P24 3 /* SMPTE 296M */
-#define V4L2_DV_720P25 4 /* SMPTE 296M */
-#define V4L2_DV_720P30 5 /* SMPTE 296M */
-#define V4L2_DV_720P50 6 /* SMPTE 296M */
-#define V4L2_DV_720P59_94 7 /* SMPTE 274M */
-#define V4L2_DV_720P60 8 /* SMPTE 274M/296M */
-#define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */
-#define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */
-#define V4L2_DV_1080I25 11 /* BT.1120 */
-#define V4L2_DV_1080I50 12 /* SMPTE 296M */
-#define V4L2_DV_1080I60 13 /* SMPTE 296M */
-#define V4L2_DV_1080P24 14 /* SMPTE 296M */
-#define V4L2_DV_1080P25 15 /* SMPTE 296M */
-#define V4L2_DV_1080P30 16 /* SMPTE 296M */
-#define V4L2_DV_1080P50 17 /* BT.1120 */
-#define V4L2_DV_1080P60 18 /* BT.1120 */
-
-/*
- * D V B T T I M I N G S
- */
-
-/* BT.656/BT.1120 timing data */
-struct v4l2_bt_timings {
- __u32 width; /* width in pixels */
- __u32 height; /* height in lines */
- __u32 interlaced; /* Interlaced or progressive */
- __u32 polarities; /* Positive or negative polarity */
- __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */
- __u32 hfrontporch; /* Horizpontal front porch in pixels */
- __u32 hsync; /* Horizontal Sync length in pixels */
- __u32 hbackporch; /* Horizontal back porch in pixels */
- __u32 vfrontporch; /* Vertical front porch in pixels */
- __u32 vsync; /* Vertical Sync length in lines */
- __u32 vbackporch; /* Vertical back porch in lines */
- __u32 il_vfrontporch; /* Vertical front porch for bottom field of
- * interlaced field formats
- */
- __u32 il_vsync; /* Vertical sync length for bottom field of
- * interlaced field formats
- */
- __u32 il_vbackporch; /* Vertical back porch for bottom field of
- * interlaced field formats
- */
- __u32 reserved[16];
-} __attribute__ ((packed));
-
-/* Interlaced or progressive format */
-#define V4L2_DV_PROGRESSIVE 0
-#define V4L2_DV_INTERLACED 1
-
-/* Polarities. If bit is not set, it is assumed to be negative polarity */
-#define V4L2_DV_VSYNC_POS_POL 0x00000001
-#define V4L2_DV_HSYNC_POS_POL 0x00000002
-
-
-/* DV timings */
-struct v4l2_dv_timings {
- __u32 type;
- union {
- struct v4l2_bt_timings bt;
- __u32 reserved[32];
- };
-} __attribute__ ((packed));
-
-/* Values for the type field */
-#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */
-
/*
* V I D E O I N P U T S
*/
@@ -837,8 +744,7 @@ struct v4l2_input {
__u32 tuner; /* Associated tuner */
v4l2_std_id std;
__u32 status;
- __u32 capabilities;
- __u32 reserved[3];
+ __u32 reserved[4];
};
/* Values for the 'type' field */
@@ -869,11 +775,6 @@ struct v4l2_input {
#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */
#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */
-/* capabilities flags */
-#define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */
-#define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */
-#define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */
-
/*
* V I D E O O U T P U T S
*/
@@ -884,19 +785,13 @@ struct v4l2_output {
__u32 audioset; /* Associated audios (bitfield) */
__u32 modulator; /* Associated modulator */
v4l2_std_id std;
- __u32 capabilities;
- __u32 reserved[3];
+ __u32 reserved[4];
};
/* Values for the 'type' field */
#define V4L2_OUTPUT_TYPE_MODULATOR 1
#define V4L2_OUTPUT_TYPE_ANALOG 2
#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
-/* capabilities flags */
-#define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */
-#define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */
-#define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */
-
/*
* C O N T R O L S
*/
@@ -1731,13 +1626,6 @@ struct v4l2_dbg_chip_ident {
#endif
#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
-#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset)
-#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset)
-#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset)
-#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset)
-#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings)
-#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings)
-
/* Reminder: when adding new ioctls please add support for them to
drivers/media/video/v4l2-compat-ioctl32.c as well! */
diff --git a/trunk/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml b/trunk/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml
deleted file mode 100644
index 1d31427edd1b..000000000000
--- a/trunk/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml
+++ /dev/null
@@ -1,238 +0,0 @@
-
-
- ioctl VIDIOC_ENUM_DV_PRESETS
- &manvol;
-
-
-
- VIDIOC_ENUM_DV_PRESETS
- Enumerate supported Digital Video presets
-
-
-
-
-
- int ioctl
- int fd
- int request
- struct v4l2_dv_enum_preset *argp
-
-
-
-
-
- Arguments
-
-
-
- fd
-
- &fd;
-
-
-
- request
-
- VIDIOC_ENUM_DV_PRESETS
-
-
-
- argp
-
-
-
-
-
-
-
-
- Description
-
- To query the attributes of a DV preset, applications initialize the
-index field and zero the reserved array of &v4l2-dv-enum-preset;
-and call the VIDIOC_ENUM_DV_PRESETS ioctl with a pointer to this
-structure. Drivers fill the rest of the structure or return an
-&EINVAL; when the index is out of bounds. To enumerate all DV Presets supported,
-applications shall begin at index zero, incrementing by one until the
-driver returns EINVAL . Drivers may enumerate a
-different set of DV presets after switching the video input or
-output.
-
-
- struct v4l2_dv_enum_presets
-
- &cs-str;
-
-
- __u32
- index
- Number of the DV preset, set by the
-application.
-
-
- __u32
- preset
- This field identifies one of the DV preset values listed in .
-
-
- __u8
- name [24]
- Name of the preset, a NUL-terminated ASCII string, for example: "720P-60", "1080I-60". This information is
-intended for the user.
-
-
- __u32
- width
- Width of the active video in pixels for the DV preset.
-
-
- __u32
- height
- Height of the active video in lines for the DV preset.
-
-
- __u32
- reserved [4]
- Reserved for future extensions. Drivers must set the array to zero.
-
-
-
-
-
-
- struct DV Presets
-
- &cs-str;
-
-
- Preset
- Preset value
- Description
-
-
-
-
-
-
-
- V4L2_DV_INVALID
- 0
- Invalid preset value.
-
-
- V4L2_DV_480P59_94
- 1
- 720x480 progressive video at 59.94 fps as per BT.1362.
-
-
- V4L2_DV_576P50
- 2
- 720x576 progressive video at 50 fps as per BT.1362.
-
-
- V4L2_DV_720P24
- 3
- 1280x720 progressive video at 24 fps as per SMPTE 296M.
-
-
- V4L2_DV_720P25
- 4
- 1280x720 progressive video at 25 fps as per SMPTE 296M.
-
-
- V4L2_DV_720P30
- 5
- 1280x720 progressive video at 30 fps as per SMPTE 296M.
-
-
- V4L2_DV_720P50
- 6
- 1280x720 progressive video at 50 fps as per SMPTE 296M.
-
-
- V4L2_DV_720P59_94
- 7
- 1280x720 progressive video at 59.94 fps as per SMPTE 274M.
-
-
- V4L2_DV_720P60
- 8
- 1280x720 progressive video at 60 fps as per SMPTE 274M/296M.
-
-
- V4L2_DV_1080I29_97
- 9
- 1920x1080 interlaced video at 29.97 fps as per BT.1120/SMPTE 274M.
-
-
- V4L2_DV_1080I30
- 10
- 1920x1080 interlaced video at 30 fps as per BT.1120/SMPTE 274M.
-
-
- V4L2_DV_1080I25
- 11
- 1920x1080 interlaced video at 25 fps as per BT.1120.
-
-
- V4L2_DV_1080I50
- 12
- 1920x1080 interlaced video at 50 fps as per SMPTE 296M.
-
-
- V4L2_DV_1080I60
- 13
- 1920x1080 interlaced video at 60 fps as per SMPTE 296M.
-
-
- V4L2_DV_1080P24
- 14
- 1920x1080 progressive video at 24 fps as per SMPTE 296M.
-
-
- V4L2_DV_1080P25
- 15
- 1920x1080 progressive video at 25 fps as per SMPTE 296M.
-
-
- V4L2_DV_1080P30
- 16
- 1920x1080 progressive video at 30 fps as per SMPTE 296M.
-
-
- V4L2_DV_1080P50
- 17
- 1920x1080 progressive video at 50 fps as per BT.1120.
-
-
- V4L2_DV_1080P60
- 18
- 1920x1080 progressive video at 60 fps as per BT.1120.
-
-
-
-
-
-
-
- &return-value;
-
-
-
- EINVAL
-
- The &v4l2-dv-enum-preset; index
-is out of bounds.
-
-
-
-
-
-
-
diff --git a/trunk/Documentation/DocBook/v4l/vidioc-enuminput.xml b/trunk/Documentation/DocBook/v4l/vidioc-enuminput.xml
index 71b868e2fb8f..414856b82473 100644
--- a/trunk/Documentation/DocBook/v4l/vidioc-enuminput.xml
+++ b/trunk/Documentation/DocBook/v4l/vidioc-enuminput.xml
@@ -124,13 +124,7 @@ current input.
__u32
- capabilities
- This field provides capabilities for the
-input. See for flags.
-
-
- __u32
- reserved [3]
+ reserved [4]
Reserved for future extensions. Drivers must set
the array to zero.
@@ -267,34 +261,6 @@ flag is set Macrovision has been detected.
-
-
-
diff --git a/trunk/Documentation/DocBook/v4l/vidioc-enumoutput.xml b/trunk/Documentation/DocBook/v4l/vidioc-enumoutput.xml
index a281d26a195f..e8d16dcd50cf 100644
--- a/trunk/Documentation/DocBook/v4l/vidioc-enumoutput.xml
+++ b/trunk/Documentation/DocBook/v4l/vidioc-enumoutput.xml
@@ -114,13 +114,7 @@ details on video standards and how to switch see
__u32
- capabilities
- This field provides capabilities for the
-output. See for flags.
-
-
- __u32
- reserved [3]
+ reserved [4]
Reserved for future extensions. Drivers must set
the array to zero.
@@ -153,34 +147,6 @@ CVBS, S-Video, RGB.
-
-
- Output capabilities
-
- &cs-def;
-
-
- V4L2_OUT_CAP_PRESETS
- 0x00000001
- This output supports setting DV presets by using VIDIOC_S_DV_PRESET.
-
-
- V4L2_OUT_CAP_CUSTOM_TIMINGS
- 0x00000002
- This output supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.
-
-
- V4L2_OUT_CAP_STD
- 0x00000004
- This output supports setting the TV standard by using VIDIOC_S_STD.
-
-
-
-
-
&return-value;
diff --git a/trunk/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml b/trunk/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml
deleted file mode 100644
index 3c6784e132f3..000000000000
--- a/trunk/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml
+++ /dev/null
@@ -1,111 +0,0 @@
-
-
- ioctl VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET
- &manvol;
-
-
-
- VIDIOC_G_DV_PRESET
- VIDIOC_S_DV_PRESET
- Query or select the DV preset of the current input or output
-
-
-
-
-
- int ioctl
- int fd
- int request
- &v4l2-dv-preset;
-*argp
-
-
-
-
-
- Arguments
-
-
-
- fd
-
- &fd;
-
-
-
- request
-
- VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET
-
-
-
- argp
-
-
-
-
-
-
-
-
- Description
- To query and select the current DV preset, applications
-use the VIDIOC_G_DV_PRESET and VIDIOC_S_DV_PRESET
-ioctls which take a pointer to a &v4l2-dv-preset; type as argument.
-Applications must zero the reserved array in &v4l2-dv-preset;.
-VIDIOC_G_DV_PRESET returns a dv preset in the field
-preset of &v4l2-dv-preset;.
-
- VIDIOC_S_DV_PRESET accepts a pointer to a &v4l2-dv-preset;
-that has the preset value to be set. Applications must zero the reserved array in &v4l2-dv-preset;.
-If the preset is not supported, it returns an &EINVAL;
-
-
-
- &return-value;
-
-
-
- EINVAL
-
- This ioctl is not supported, or the
-VIDIOC_S_DV_PRESET ,VIDIOC_S_DV_PRESET parameter was unsuitable.
-
-
-
- EBUSY
-
- The device is busy and therefore can not change the preset.
-
-
-
-
-
- struct v4l2_dv_preset
-
- &cs-str;
-
-
- __u32
- preset
- Preset value to represent the digital video timings
-
-
- __u32
- reserved[4]
- Reserved fields for future use
-
-
-
-
-
-
-
-
-
diff --git a/trunk/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml b/trunk/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml
deleted file mode 100644
index ecc19576bb8f..000000000000
--- a/trunk/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml
+++ /dev/null
@@ -1,224 +0,0 @@
-
-
- ioctl VIDIOC_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS
- &manvol;
-
-
-
- VIDIOC_G_DV_TIMINGS
- VIDIOC_S_DV_TIMINGS
- Get or set custom DV timings for input or output
-
-
-
-
-
- int ioctl
- int fd
- int request
- &v4l2-dv-timings;
-*argp
-
-
-
-
-
- Arguments
-
-
-
- fd
-
- &fd;
-
-
-
- request
-
- VIDIOC_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS
-
-
-
- argp
-
-
-
-
-
-
-
-
- Description
- To set custom DV timings for the input or output, applications use the
-VIDIOC_S_DV_TIMINGS ioctl and to get the current custom timings,
-applications use the VIDIOC_G_DV_TIMINGS ioctl. The detailed timing
-information is filled in using the structure &v4l2-dv-timings;. These ioctls take
-a pointer to the &v4l2-dv-timings; structure as argument. If the ioctl is not supported
-or the timing values are not correct, the driver returns &EINVAL;.
-
-
-
- &return-value;
-
-
-
- EINVAL
-
- This ioctl is not supported, or the
-VIDIOC_S_DV_TIMINGS parameter was unsuitable.
-
-
-
- EBUSY
-
- The device is busy and therefore can not change the timings.
-
-
-
-
-
- struct v4l2_bt_timings
-
- &cs-str;
-
-
- __u32
- width
- Width of the active video in pixels
-
-
- __u32
- height
- Height of the active video in lines
-
-
- __u32
- interlaced
- Progressive (0) or interlaced (1)
-
-
- __u32
- polarities
- This is a bit mask that defines polarities of sync signals.
-bit 0 (V4L2_DV_VSYNC_POS_POL) is for vertical sync polarity and bit 1 (V4L2_DV_HSYNC_POS_POL) is for horizontal sync polarity. If the bit is set
-(1) it is positive polarity and if is cleared (0), it is negative polarity.
-
-
- __u64
- pixelclock
- Pixel clock in Hz. Ex. 74.25MHz->74250000
-
-
- __u32
- hfrontporch
- Horizontal front porch in pixels
-
-
- __u32
- hsync
- Horizontal sync length in pixels
-
-
- __u32
- hbackporch
- Horizontal back porch in pixels
-
-
- __u32
- vfrontporch
- Vertical front porch in lines
-
-
- __u32
- vsync
- Vertical sync length in lines
-
-
- __u32
- vbackporch
- Vertical back porch in lines
-
-
- __u32
- il_vfrontporch
- Vertical front porch in lines for bottom field of interlaced field formats
-
-
- __u32
- il_vsync
- Vertical sync length in lines for bottom field of interlaced field formats
-
-
- __u32
- il_vbackporch
- Vertical back porch in lines for bottom field of interlaced field formats
-
-
-
-
-
-
- struct v4l2_dv_timings
-
- &cs-str;
-
-
- __u32
- type
-
- Type of DV timings as listed in .
-
-
- union
-
-
-
-
-
- &v4l2-bt-timings;
- bt
- Timings defined by BT.656/1120 specifications
-
-
-
- __u32
- reserved [32]
-
-
-
-
-
-
-
- DV Timing types
-
- &cs-str;
-
-
- Timing type
- value
- Description
-
-
-
-
-
-
-
- V4L2_DV_BT_656_1120
- 0
- BT.656/1120 timings
-
-
-
-
-
-
-
-
diff --git a/trunk/Documentation/DocBook/v4l/vidioc-g-std.xml b/trunk/Documentation/DocBook/v4l/vidioc-g-std.xml
index 912f8513e5da..b6f5d267e856 100644
--- a/trunk/Documentation/DocBook/v4l/vidioc-g-std.xml
+++ b/trunk/Documentation/DocBook/v4l/vidioc-g-std.xml
@@ -86,12 +86,6 @@ standards.
VIDIOC_S_STD parameter was unsuitable.
-
- EBUSY
-
- The device is busy and therefore can not change the standard
-
-
diff --git a/trunk/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml b/trunk/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml
deleted file mode 100644
index 87e4f0f6151c..000000000000
--- a/trunk/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
- ioctl VIDIOC_QUERY_DV_PRESET
- &manvol;
-
-
-
- VIDIOC_QUERY_DV_PRESET
- Sense the DV preset received by the current
-input
-
-
-
-
-
- int ioctl
- int fd
- int request
- &v4l2-dv-preset; *argp
-
-
-
-
-
- Arguments
-
-
-
- fd
-
- &fd;
-
-
-
- request
-
- VIDIOC_QUERY_DV_PRESET
-
-
-
- argp
-
-
-
-
-
-
-
-
- Description
-
- The hardware may be able to detect the current DV preset
-automatically, similar to sensing the video standard. To do so, applications
-call VIDIOC_QUERY_DV_PRESET with a pointer to a
-&v4l2-dv-preset; type. Once the hardware detects a preset, that preset is
-returned in the preset field of &v4l2-dv-preset;. When detection is not
-possible or fails, the value V4L2_DV_INVALID is returned.
-
-
-
- &return-value;
-
-
- EINVAL
-
- This ioctl is not supported.
-
-
-
- EBUSY
-
- The device is busy and therefore can not sense the preset
-
-
-
-
-
-
-
diff --git a/trunk/Documentation/DocBook/v4l/vidioc-querystd.xml b/trunk/Documentation/DocBook/v4l/vidioc-querystd.xml
index 1a9e60393091..b5a7ff934486 100644
--- a/trunk/Documentation/DocBook/v4l/vidioc-querystd.xml
+++ b/trunk/Documentation/DocBook/v4l/vidioc-querystd.xml
@@ -70,12 +70,6 @@ current video input or output.
This ioctl is not supported.
-
- EBUSY
-
- The device is busy and therefore can not detect the standard
-
-
diff --git a/trunk/Documentation/SubmitChecklist b/trunk/Documentation/SubmitChecklist
index 1053a56be3b1..78a9168ff377 100644
--- a/trunk/Documentation/SubmitChecklist
+++ b/trunk/Documentation/SubmitChecklist
@@ -15,7 +15,7 @@ kernel patches.
2: Passes allnoconfig, allmodconfig
3: Builds on multiple CPU architectures by using local cross-compile tools
- or some other build farm.
+ or something like PLM at OSDL.
4: ppc64 is a good architecture for cross-compilation checking because it
tends to use `unsigned long' for 64-bit quantities.
@@ -88,6 +88,3 @@ kernel patches.
24: All memory barriers {e.g., barrier(), rmb(), wmb()} need a comment in the
source code that explains the logic of what they are doing and why.
-
-25: If any ioctl's are added by the patch, then also update
- Documentation/ioctl/ioctl-number.txt.
diff --git a/trunk/Documentation/fb/viafb.txt b/trunk/Documentation/fb/viafb.txt
index f3e046a6a987..67dbf442b0b6 100644
--- a/trunk/Documentation/fb/viafb.txt
+++ b/trunk/Documentation/fb/viafb.txt
@@ -7,7 +7,7 @@
VIA UniChrome Family(CLE266, PM800 / CN400 / CN300,
P4M800CE / P4M800Pro / CN700 / VN800,
CX700 / VX700, K8M890, P4M890,
- CN896 / P4M900, VX800, VX855)
+ CN896 / P4M900, VX800)
[Driver features]
------------------------
@@ -154,6 +154,13 @@
0 : No Dual Edge Panel (default)
1 : Dual Edge Panel
+ viafb_video_dev:
+ This option is used to specify video output devices(CRT, DVI, LCD) for
+ duoview case.
+ For example:
+ To output video on DVI, we should use:
+ modprobe viafb viafb_video_dev=DVI...
+
viafb_lcd_port:
This option is used to specify LCD output port,
available values are "DVP0" "DVP1" "DFP_HIGHLOW" "DFP_HIGH" "DFP_LOW".
@@ -174,6 +181,9 @@ Notes:
and bpp, need to call VIAFB specified ioctl interface VIAFB_SET_DEVICE
instead of calling common ioctl function FBIOPUT_VSCREENINFO since
viafb doesn't support multi-head well, or it will cause screen crush.
+ 4. VX800 2D accelerator hasn't been supported in this driver yet. When
+ using driver on VX800, the driver will disable the acceleration
+ function as default.
[Configure viafb with "fbset" tool]
diff --git a/trunk/Documentation/filesystems/seq_file.txt b/trunk/Documentation/filesystems/seq_file.txt
index a1e2e0dda907..0d15ebccf5b0 100644
--- a/trunk/Documentation/filesystems/seq_file.txt
+++ b/trunk/Documentation/filesystems/seq_file.txt
@@ -248,7 +248,9 @@ code, that is done in the initialization code in the usual way:
{
struct proc_dir_entry *entry;
- proc_create("sequence", 0, NULL, &ct_file_ops);
+ entry = create_proc_entry("sequence", 0, NULL);
+ if (entry)
+ entry->proc_fops = &ct_file_ops;
return 0;
}
diff --git a/trunk/Documentation/gpio.txt b/trunk/Documentation/gpio.txt
index 1866c27eec69..e4e7daed2ba8 100644
--- a/trunk/Documentation/gpio.txt
+++ b/trunk/Documentation/gpio.txt
@@ -531,13 +531,6 @@ and have the following read/write attributes:
This file exists only if the pin can be configured as an
interrupt generating input pin.
- "active_low" ... reads as either 0 (false) or 1 (true). Write
- any nonzero value to invert the value attribute both
- for reading and writing. Existing and subsequent
- poll(2) support configuration via the edge attribute
- for "rising" and "falling" edges will follow this
- setting.
-
GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
controller implementing GPIOs starting at #42) and have the following
read-only attributes:
@@ -573,8 +566,6 @@ requested using gpio_request():
int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
- /* change the polarity of a GPIO node in sysfs */
- int gpio_sysfs_set_active_low(unsigned gpio, int value);
After a kernel driver requests a GPIO, it may only be made available in
the sysfs interface by gpio_export(). The driver can control whether the
@@ -589,9 +580,3 @@ After the GPIO has been exported, gpio_export_link() allows creating
symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
use this to provide the interface under their own device in sysfs with
a descriptive name.
-
-Drivers can use gpio_sysfs_set_active_low() to hide GPIO line polarity
-differences between boards from user space. This only affects the
-sysfs interface. Polarity change can be done both before and after
-gpio_export(), and previously enabled poll(2) support for either
-rising or falling edge will be reconfigured to follow this setting.
diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt
index c309515ae959..ab95d3ada5c7 100644
--- a/trunk/Documentation/kernel-parameters.txt
+++ b/trunk/Documentation/kernel-parameters.txt
@@ -2729,11 +2729,6 @@ and is between 256 and 4096 characters. It is defined in the file
vmpoff= [KNL,S390] Perform z/VM CP command after power off.
Format:
- vt.cur_default= [VT] Default cursor shape.
- Format: 0xCCBBAA, where AA, BB, and CC are the same as
- the parameters of the [?A;B;Cc escape sequence;
- see VGA-softcursor.txt. Default: 2 = underline.
-
vt.default_blu= [VT]
Format: ,,,...,
Change the default blue palette of the console.
diff --git a/trunk/Documentation/video4linux/gspca.txt b/trunk/Documentation/video4linux/gspca.txt
index 1800a62cf135..319d9838e87e 100644
--- a/trunk/Documentation/video4linux/gspca.txt
+++ b/trunk/Documentation/video4linux/gspca.txt
@@ -12,7 +12,6 @@ m5602 0402:5602 ALi Video Camera Controller
spca501 040a:0002 Kodak DVC-325
spca500 040a:0300 Kodak EZ200
zc3xx 041e:041e Creative WebCam Live!
-ov519 041e:4003 Video Blaster WebCam Go Plus
spca500 041e:400a Creative PC-CAM 300
sunplus 041e:400b Creative PC-CAM 600
sunplus 041e:4012 PC-Cam350
@@ -169,14 +168,10 @@ sunplus 055f:c650 Mustek MDC5500Z
zc3xx 055f:d003 Mustek WCam300A
zc3xx 055f:d004 Mustek WCam300 AN
conex 0572:0041 Creative Notebook cx11646
-ov519 05a9:0511 Video Blaster WebCam 3/WebCam Plus, D-Link USB Digital Video Camera
-ov519 05a9:0518 Creative WebCam
ov519 05a9:0519 OV519 Microphone
ov519 05a9:0530 OmniVision
-ov519 05a9:2800 OmniVision SuperCAM
ov519 05a9:4519 Webcam Classic
ov519 05a9:8519 OmniVision
-ov519 05a9:a511 D-Link USB Digital Video Camera
ov519 05a9:a518 D-Link DSB-C310 Webcam
sunplus 05da:1018 Digital Dream Enigma 1.3
stk014 05e1:0893 Syntek DV4000
@@ -192,7 +187,7 @@ ov534 06f8:3002 Hercules Blog Webcam
ov534 06f8:3003 Hercules Dualpix HD Weblog
sonixj 06f8:3004 Hercules Classic Silver
sonixj 06f8:3008 Hercules Deluxe Optical Glass
-pac7302 06f8:3009 Hercules Classic Link
+pac7311 06f8:3009 Hercules Classic Link
spca508 0733:0110 ViewQuest VQ110
spca501 0733:0401 Intel Create and Share
spca501 0733:0402 ViewQuest M318B
@@ -204,7 +199,6 @@ sunplus 0733:2221 Mercury Digital Pro 3.1p
sunplus 0733:3261 Concord 3045 spca536a
sunplus 0733:3281 Cyberpix S550V
spca506 0734:043b 3DeMon USB Capture aka
-ov519 0813:0002 Dual Mode USB Camera Plus
spca500 084d:0003 D-Link DSC-350
spca500 08ca:0103 Aiptek PocketDV
sunplus 08ca:0104 Aiptek PocketDVII 1.3
@@ -242,15 +236,15 @@ pac7311 093a:2603 Philips SPC 500 NC
pac7311 093a:2608 Trust WB-3300p
pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
pac7311 093a:260f SnakeCam
-pac7302 093a:2620 Apollo AC-905
-pac7302 093a:2621 PAC731x
-pac7302 093a:2622 Genius Eye 312
-pac7302 093a:2624 PAC7302
-pac7302 093a:2626 Labtec 2200
-pac7302 093a:2628 Genius iLook 300
-pac7302 093a:2629 Genious iSlim 300
-pac7302 093a:262a Webcam 300k
-pac7302 093a:262c Philips SPC 230 NC
+pac7311 093a:2620 Apollo AC-905
+pac7311 093a:2621 PAC731x
+pac7311 093a:2622 Genius Eye 312
+pac7311 093a:2624 PAC7302
+pac7311 093a:2626 Labtec 2200
+pac7311 093a:2628 Genius iLook 300
+pac7311 093a:2629 Genious iSlim 300
+pac7311 093a:262a Webcam 300k
+pac7311 093a:262c Philips SPC 230 NC
jeilinj 0979:0280 Sakar 57379
zc3xx 0ac8:0302 Z-star Vimicro zc0302
vc032x 0ac8:0321 Vimicro generic vc0321
@@ -265,7 +259,6 @@ vc032x 0ac8:c002 Sony embedded vimicro
vc032x 0ac8:c301 Samsung Q1 Ultra Premium
spca508 0af9:0010 Hama USB Sightcam 100
spca508 0af9:0011 Hama USB Sightcam 100
-ov519 0b62:0059 iBOT2 Webcam
sonixb 0c45:6001 Genius VideoCAM NB
sonixb 0c45:6005 Microdia Sweex Mini Webcam
sonixb 0c45:6007 Sonix sn9c101 + Tas5110D
@@ -325,10 +318,8 @@ sn9c20x 0c45:62b3 PC Camera (SN9C202 + OV9655)
sn9c20x 0c45:62bb PC Camera (SN9C202 + OV7660)
sn9c20x 0c45:62bc PC Camera (SN9C202 + HV7131R)
sunplus 0d64:0303 Sunplus FashionCam DXG
-ov519 0e96:c001 TRUST 380 USB2 SPACEC@M
etoms 102c:6151 Qcam Sangha CIF
etoms 102c:6251 Qcam xxxxxx VGA
-ov519 1046:9967 W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go
zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128
spca561 10fd:7e50 FlyCam Usb 100
zc3xx 10fd:8050 Typhoon Webshot II USB 300k
@@ -341,12 +332,7 @@ spca501 1776:501c Arowana 300K CMOS Camera
t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
pac207 2001:f115 D-Link DSB-C120
-sq905c 2770:9050 sq905c
-sq905c 2770:905c DualCamera
-sq905 2770:9120 Argus Digital Camera DC1512
-sq905c 2770:913d sq905c
spca500 2899:012c Toptro Industrial
-ov519 8020:ef04 ov519
spca508 8086:0110 Intel Easy PC Camera
spca500 8086:0630 Intel Pocket PC Camera
spca506 99fa:8988 Grandtec V.cap
diff --git a/trunk/Documentation/video4linux/sh_mobile_ceu_camera.txt b/trunk/Documentation/video4linux/sh_mobile_ceu_camera.txt
deleted file mode 100644
index 2ae16349a78d..000000000000
--- a/trunk/Documentation/video4linux/sh_mobile_ceu_camera.txt
+++ /dev/null
@@ -1,157 +0,0 @@
- Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
- =======================================================================
-
-Terminology
------------
-
-sensor scales: horizontal and vertical scales, configured by the sensor driver
-host scales: -"- host driver
-combined scales: sensor_scale * host_scale
-
-
-Generic scaling / cropping scheme
----------------------------------
-
--1--
-|
--2-- -\
-| --\
-| --\
-+-5-- -\ -- -3--
-| ---\
-| --- -4-- -\
-| -\
-| - -6--
-|
-| - -6'-
-| -/
-| --- -4'- -/
-| ---/
-+-5'- -/
-| -- -3'-
-| --/
-| --/
--2'- -/
-|
-|
--1'-
-
-Produced by user requests:
-
-S_CROP(left / top = (5) - (1), width / height = (5') - (5))
-S_FMT(width / height = (6') - (6))
-
-Here:
-
-(1) to (1') - whole max width or height
-(1) to (2) - sensor cropped left or top
-(2) to (2') - sensor cropped width or height
-(3) to (3') - sensor scale
-(3) to (4) - CEU cropped left or top
-(4) to (4') - CEU cropped width or height
-(5) to (5') - reverse sensor scale applied to CEU cropped width or height
-(2) to (5) - reverse sensor scale applied to CEU cropped left or top
-(6) to (6') - CEU scale - user window
-
-
-S_FMT
------
-
-Do not touch input rectangle - it is already optimal.
-
-1. Calculate current sensor scales:
-
- scale_s = ((3') - (3)) / ((2') - (2))
-
-2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
-current sensor scales onto input window - this is user S_CROP:
-
- width_u = (5') - (5) = ((4') - (4)) * scale_s
-
-3. Calculate new combined scales from "effective" input window to requested user
-window:
-
- scale_comb = width_u / ((6') - (6))
-
-4. Calculate sensor output window by applying combined scales to real input
-window:
-
- width_s_out = ((2') - (2)) / scale_comb
-
-5. Apply iterative sensor S_FMT for sensor output window.
-
- subdev->video_ops->s_fmt(.width = width_s_out)
-
-6. Retrieve sensor output window (g_fmt)
-
-7. Calculate new sensor scales:
-
- scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
-
-8. Calculate new CEU crop - apply sensor scales to previously calculated
-"effective" crop:
-
- width_ceu = (4')_new - (4)_new = width_u / scale_s_new
- left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
-
-9. Use CEU cropping to crop to the new window:
-
- ceu_crop(.width = width_ceu, .left = left_ceu)
-
-10. Use CEU scaling to scale to the requested user window:
-
- scale_ceu = width_ceu / width
-
-
-S_CROP
-------
-
-If old scale applied to new crop is invalid produce nearest new scale possible
-
-1. Calculate current combined scales.
-
- scale_comb = (((4') - (4)) / ((6') - (6))) * (((2') - (2)) / ((3') - (3)))
-
-2. Apply iterative sensor S_CROP for new input window.
-
-3. If old combined scales applied to new crop produce an impossible user window,
-adjust scales to produce nearest possible window.
-
- width_u_out = ((5') - (5)) / scale_comb
-
- if (width_u_out > max)
- scale_comb = ((5') - (5)) / max;
- else if (width_u_out < min)
- scale_comb = ((5') - (5)) / min;
-
-4. Issue G_CROP to retrieve actual input window.
-
-5. Using actual input window and calculated combined scales calculate sensor
-target output window.
-
- width_s_out = ((3') - (3)) = ((2') - (2)) / scale_comb
-
-6. Apply iterative S_FMT for new sensor target output window.
-
-7. Issue G_FMT to retrieve the actual sensor output window.
-
-8. Calculate sensor scales.
-
- scale_s = ((3') - (3)) / ((2') - (2))
-
-9. Calculate sensor output subwindow to be cropped on CEU by applying sensor
-scales to the requested window.
-
- width_ceu = ((5') - (5)) / scale_s
-
-10. Use CEU cropping for above calculated window.
-
-11. Calculate CEU scales from sensor scales from results of (10) and user window
-from (3)
-
- scale_ceu = calc_scale(((5') - (5)), &width_u_out)
-
-12. Apply CEU scales.
-
---
-Author: Guennadi Liakhovetski
diff --git a/trunk/Documentation/video4linux/v4l2-framework.txt b/trunk/Documentation/video4linux/v4l2-framework.txt
index 74d677c8b036..b806edaf3e75 100644
--- a/trunk/Documentation/video4linux/v4l2-framework.txt
+++ b/trunk/Documentation/video4linux/v4l2-framework.txt
@@ -561,8 +561,6 @@ video_device helper functions
There are a few useful helper functions:
-- file/video_device private data
-
You can set/get driver private data in the video_device struct using:
void *video_get_drvdata(struct video_device *vdev);
@@ -577,7 +575,8 @@ struct video_device *video_devdata(struct file *file);
returns the video_device belonging to the file struct.
-The video_drvdata function combines video_get_drvdata with video_devdata:
+The final helper function combines video_get_drvdata with
+video_devdata:
void *video_drvdata(struct file *file);
@@ -585,17 +584,6 @@ You can go from a video_device struct to the v4l2_device struct using:
struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
-- Device node name
-
-The video_device node kernel name can be retrieved using
-
-const char *video_device_node_name(struct video_device *vdev);
-
-The name is used as a hint by userspace tools such as udev. The function
-should be used where possible instead of accessing the video_device::num and
-video_device::minor fields.
-
-
video buffer helper functions
-----------------------------
diff --git a/trunk/arch/alpha/include/asm/elf.h b/trunk/arch/alpha/include/asm/elf.h
index 9baae8afe8a3..5c75c1b2352a 100644
--- a/trunk/arch/alpha/include/asm/elf.h
+++ b/trunk/arch/alpha/include/asm/elf.h
@@ -81,6 +81,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_ALPHA
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 8192
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/trunk/arch/arm/include/asm/elf.h b/trunk/arch/arm/include/asm/elf.h
index a399bb5730f1..6aac3f5bb2f3 100644
--- a/trunk/arch/arm/include/asm/elf.h
+++ b/trunk/arch/arm/include/asm/elf.h
@@ -101,6 +101,7 @@ extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
#define ELF_CORE_COPY_TASK_REGS dump_task_regs
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/trunk/arch/arm/mach-davinci/board-da850-evm.c b/trunk/arch/arm/mach-davinci/board-da850-evm.c
index 07de8db14581..62b98bffc158 100644
--- a/trunk/arch/arm/mach-davinci/board-da850-evm.c
+++ b/trunk/arch/arm/mach-davinci/board-da850-evm.c
@@ -339,15 +339,6 @@ static struct davinci_mmc_config da850_mmc_config = {
.version = MMC_CTLR_VERSION_2,
};
-static void da850_panel_power_ctrl(int val)
-{
- /* lcd backlight */
- gpio_set_value(DA850_LCD_BL_PIN, val);
-
- /* lcd power */
- gpio_set_value(DA850_LCD_PWR_PIN, val);
-}
-
static int da850_lcd_hw_init(void)
{
int status;
@@ -365,11 +356,17 @@ static int da850_lcd_hw_init(void)
gpio_direction_output(DA850_LCD_BL_PIN, 0);
gpio_direction_output(DA850_LCD_PWR_PIN, 0);
- /* Switch off panel power and backlight */
- da850_panel_power_ctrl(0);
+ /* disable lcd backlight */
+ gpio_set_value(DA850_LCD_BL_PIN, 0);
+
+ /* disable lcd power */
+ gpio_set_value(DA850_LCD_PWR_PIN, 0);
+
+ /* enable lcd power */
+ gpio_set_value(DA850_LCD_PWR_PIN, 1);
- /* Switch on panel power and backlight */
- da850_panel_power_ctrl(1);
+ /* enable lcd backlight */
+ gpio_set_value(DA850_LCD_BL_PIN, 1);
return 0;
}
@@ -677,7 +674,6 @@ static __init void da850_evm_init(void)
pr_warning("da850_evm_init: lcd initialization failed: %d\n",
ret);
- sharp_lk043t1dg01_pdata.panel_power_ctrl = da850_panel_power_ctrl,
ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata);
if (ret)
pr_warning("da850_evm_init: lcdc registration failed: %d\n",
diff --git a/trunk/arch/avr32/include/asm/elf.h b/trunk/arch/avr32/include/asm/elf.h
index 3b3159b710d4..d5d1d41c600a 100644
--- a/trunk/arch/avr32/include/asm/elf.h
+++ b/trunk/arch/avr32/include/asm/elf.h
@@ -77,6 +77,7 @@ typedef struct user_fpu_struct elf_fpregset_t;
#endif
#define ELF_ARCH EM_AVR32
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/trunk/arch/blackfin/include/asm/bfin-lq035q1.h b/trunk/arch/blackfin/include/asm/bfin-lq035q1.h
deleted file mode 100644
index 57bc21ac2296..000000000000
--- a/trunk/arch/blackfin/include/asm/bfin-lq035q1.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Blackfin LCD Framebuffer driver SHARP LQ035Q1DH02
- *
- * Copyright 2008-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef BFIN_LQ035Q1_H
-#define BFIN_LQ035Q1_H
-
-#define LQ035_RL (0 << 8) /* Right -> Left Scan */
-#define LQ035_LR (1 << 8) /* Left -> Right Scan */
-#define LQ035_TB (1 << 9) /* Top -> Botton Scan */
-#define LQ035_BT (0 << 9) /* Botton -> Top Scan */
-#define LQ035_BGR (1 << 11) /* Use BGR format */
-#define LQ035_RGB (0 << 11) /* Use RGB format */
-#define LQ035_NORM (1 << 13) /* Reversal */
-#define LQ035_REV (0 << 13) /* Reversal */
-
-struct bfin_lq035q1fb_disp_info {
-
- unsigned mode;
- /* GPIOs */
- int use_bl;
- unsigned gpio_bl;
-};
-
-#endif /* BFIN_LQ035Q1_H */
diff --git a/trunk/arch/blackfin/include/asm/elf.h b/trunk/arch/blackfin/include/asm/elf.h
index 5b50f0ecacf8..8e0764c81eaf 100644
--- a/trunk/arch/blackfin/include/asm/elf.h
+++ b/trunk/arch/blackfin/include/asm/elf.h
@@ -55,6 +55,7 @@ do { \
_regs->p2 = _dynamic_addr; \
} while(0)
+#define USE_ELF_CORE_DUMP
#define ELF_FDPIC_CORE_EFLAGS EF_BFIN_FDPIC
#define ELF_EXEC_PAGESIZE 4096
diff --git a/trunk/arch/cris/include/asm/elf.h b/trunk/arch/cris/include/asm/elf.h
index 8a3d8e2b33c1..0f51b10b9f4f 100644
--- a/trunk/arch/cris/include/asm/elf.h
+++ b/trunk/arch/cris/include/asm/elf.h
@@ -64,6 +64,8 @@ typedef unsigned long elf_fpregset_t;
#define EF_CRIS_VARIANT_COMMON_V10_V32 0x00000004
/* End of excerpt from {binutils}/include/elf/cris.h. */
+#define USE_ELF_CORE_DUMP
+
#define ELF_EXEC_PAGESIZE 8192
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/trunk/arch/frv/include/asm/elf.h b/trunk/arch/frv/include/asm/elf.h
index c3819804a74b..7bbf6e47f8c8 100644
--- a/trunk/arch/frv/include/asm/elf.h
+++ b/trunk/arch/frv/include/asm/elf.h
@@ -115,6 +115,7 @@ do { \
__kernel_frame0_ptr->gr29 = 0; \
} while(0)
+#define USE_ELF_CORE_DUMP
#define CORE_DUMP_USE_REGSET
#define ELF_FDPIC_CORE_EFLAGS EF_FRV_FDPIC
#define ELF_EXEC_PAGESIZE 16384
diff --git a/trunk/arch/h8300/include/asm/elf.h b/trunk/arch/h8300/include/asm/elf.h
index c24fa250d653..94e2284c8816 100644
--- a/trunk/arch/h8300/include/asm/elf.h
+++ b/trunk/arch/h8300/include/asm/elf.h
@@ -34,6 +34,7 @@ typedef unsigned long elf_fpregset_t;
#define ELF_PLAT_INIT(_r) _r->er1 = 0
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/trunk/arch/ia64/ia32/elfcore32.h b/trunk/arch/ia64/ia32/elfcore32.h
index 657725742617..9a3abf58cea3 100644
--- a/trunk/arch/ia64/ia32/elfcore32.h
+++ b/trunk/arch/ia64/ia32/elfcore32.h
@@ -11,6 +11,8 @@
#include
#include
+#define USE_ELF_CORE_DUMP 1
+
/* Override elfcore.h */
#define _LINUX_ELFCORE_H 1
typedef unsigned int elf_greg_t;
diff --git a/trunk/arch/ia64/include/asm/dma-mapping.h b/trunk/arch/ia64/include/asm/dma-mapping.h
index 7d09a09cdaad..8d3c79cd81e7 100644
--- a/trunk/arch/ia64/include/asm/dma-mapping.h
+++ b/trunk/arch/ia64/include/asm/dma-mapping.h
@@ -73,7 +73,7 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
if (!dev->dma_mask)
return 0;
- return addr + size - 1 <= *dev->dma_mask;
+ return addr + size <= *dev->dma_mask;
}
static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
diff --git a/trunk/arch/ia64/include/asm/elf.h b/trunk/arch/ia64/include/asm/elf.h
index e14108b19c09..86eddee029cb 100644
--- a/trunk/arch/ia64/include/asm/elf.h
+++ b/trunk/arch/ia64/include/asm/elf.h
@@ -25,6 +25,7 @@
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_IA_64
+#define USE_ELF_CORE_DUMP
#define CORE_DUMP_USE_REGSET
/* Least-significant four bits of ELF header's e_flags are OS-specific. The bits are
diff --git a/trunk/arch/ia64/include/asm/io.h b/trunk/arch/ia64/include/asm/io.h
index cc8335eb3110..0d9d16e2d949 100644
--- a/trunk/arch/ia64/include/asm/io.h
+++ b/trunk/arch/ia64/include/asm/io.h
@@ -424,8 +424,6 @@ __writeq (unsigned long val, volatile void __iomem *addr)
extern void __iomem * ioremap(unsigned long offset, unsigned long size);
extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
extern void iounmap (volatile void __iomem *addr);
-extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
-extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
/*
* String version of IO memory access ops:
diff --git a/trunk/arch/ia64/mm/ioremap.c b/trunk/arch/ia64/mm/ioremap.c
index 3dccdd8eb275..2a140627dfd6 100644
--- a/trunk/arch/ia64/mm/ioremap.c
+++ b/trunk/arch/ia64/mm/ioremap.c
@@ -21,12 +21,6 @@ __ioremap (unsigned long phys_addr)
return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr);
}
-void __iomem *
-early_ioremap (unsigned long phys_addr, unsigned long size)
-{
- return __ioremap(phys_addr);
-}
-
void __iomem *
ioremap (unsigned long phys_addr, unsigned long size)
{
@@ -107,11 +101,6 @@ ioremap_nocache (unsigned long phys_addr, unsigned long size)
}
EXPORT_SYMBOL(ioremap_nocache);
-void
-early_iounmap (volatile void __iomem *addr, unsigned long size)
-{
-}
-
void
iounmap (volatile void __iomem *addr)
{
diff --git a/trunk/arch/ia64/sn/pci/tioca_provider.c b/trunk/arch/ia64/sn/pci/tioca_provider.c
index efb454534e52..35b2a27d2e77 100644
--- a/trunk/arch/ia64/sn/pci/tioca_provider.c
+++ b/trunk/arch/ia64/sn/pci/tioca_provider.c
@@ -9,7 +9,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -370,7 +369,7 @@ tioca_dma_d48(struct pci_dev *pdev, u64 paddr)
static dma_addr_t
tioca_dma_mapped(struct pci_dev *pdev, unsigned long paddr, size_t req_size)
{
- int ps, ps_shift, entry, entries, mapsize;
+ int i, ps, ps_shift, entry, entries, mapsize, last_entry;
u64 xio_addr, end_xio_addr;
struct tioca_common *tioca_common;
struct tioca_kernel *tioca_kern;
@@ -411,13 +410,23 @@ tioca_dma_mapped(struct pci_dev *pdev, unsigned long paddr, size_t req_size)
map = tioca_kern->ca_pcigart_pagemap;
mapsize = tioca_kern->ca_pcigart_entries;
- entry = bitmap_find_next_zero_area(map, mapsize, 0, entries, 0);
- if (entry >= mapsize) {
+ entry = find_first_zero_bit(map, mapsize);
+ while (entry < mapsize) {
+ last_entry = find_next_bit(map, mapsize, entry);
+
+ if (last_entry - entry >= entries)
+ break;
+
+ entry = find_next_zero_bit(map, mapsize, last_entry);
+ }
+
+ if (entry > mapsize) {
kfree(ca_dmamap);
goto map_return;
}
- bitmap_set(map, entry, entries);
+ for (i = 0; i < entries; i++)
+ set_bit(entry + i, map);
bus_addr = tioca_kern->ca_pciap_base + (entry * ps);
diff --git a/trunk/arch/m32r/include/asm/elf.h b/trunk/arch/m32r/include/asm/elf.h
index 2f85412ef730..0cc34c94bf2b 100644
--- a/trunk/arch/m32r/include/asm/elf.h
+++ b/trunk/arch/m32r/include/asm/elf.h
@@ -102,6 +102,7 @@ typedef elf_fpreg_t elf_fpregset_t;
*/
#define ELF_PLAT_INIT(_r, load_addr) (_r)->r0 = 0
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE PAGE_SIZE
/*
diff --git a/trunk/arch/m68k/include/asm/elf.h b/trunk/arch/m68k/include/asm/elf.h
index 01c193d91412..0b0f49eb876b 100644
--- a/trunk/arch/m68k/include/asm/elf.h
+++ b/trunk/arch/m68k/include/asm/elf.h
@@ -59,6 +59,7 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
is actually used on ASV. */
#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0
+#define USE_ELF_CORE_DUMP
#ifndef CONFIG_SUN3
#define ELF_EXEC_PAGESIZE 4096
#else
diff --git a/trunk/arch/microblaze/include/asm/elf.h b/trunk/arch/microblaze/include/asm/elf.h
index 7d4acf2b278e..f92fc0dda006 100644
--- a/trunk/arch/microblaze/include/asm/elf.h
+++ b/trunk/arch/microblaze/include/asm/elf.h
@@ -77,6 +77,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_DATA ELFDATA2MSB
#endif
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
diff --git a/trunk/arch/mips/include/asm/elf.h b/trunk/arch/mips/include/asm/elf.h
index 7a6a35dbe529..7990694cda22 100644
--- a/trunk/arch/mips/include/asm/elf.h
+++ b/trunk/arch/mips/include/asm/elf.h
@@ -326,6 +326,7 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \
dump_task_fpu(tsk, elf_fpregs)
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE PAGE_SIZE
/* This yields a mask that user programs can use to figure out what
diff --git a/trunk/arch/mn10300/include/asm/elf.h b/trunk/arch/mn10300/include/asm/elf.h
index e5fa97cd9a14..75a70aa9fd6f 100644
--- a/trunk/arch/mn10300/include/asm/elf.h
+++ b/trunk/arch/mn10300/include/asm/elf.h
@@ -77,6 +77,7 @@ do { \
_ur->a1 = 0; _ur->a0 = 0; _ur->d1 = 0; _ur->d0 = 0; \
} while (0)
+#define USE_ELF_CORE_DUMP
#define CORE_DUMP_USE_REGSET
#define ELF_EXEC_PAGESIZE 4096
diff --git a/trunk/arch/parisc/include/asm/elf.h b/trunk/arch/parisc/include/asm/elf.h
index 19f6cb1a4a1c..9c802eb4be84 100644
--- a/trunk/arch/parisc/include/asm/elf.h
+++ b/trunk/arch/parisc/include/asm/elf.h
@@ -328,6 +328,7 @@ struct pt_regs; /* forward declaration... */
such function. */
#define ELF_PLAT_INIT(_r, load_addr) _r->gr[23] = 0
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/trunk/arch/parisc/kernel/signal.c b/trunk/arch/parisc/kernel/signal.c
index e8467e4aa8d1..fb37ac52e46c 100644
--- a/trunk/arch/parisc/kernel/signal.c
+++ b/trunk/arch/parisc/kernel/signal.c
@@ -26,7 +26,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/trunk/arch/powerpc/include/asm/dma-mapping.h b/trunk/arch/powerpc/include/asm/dma-mapping.h
index 80a973bb9e71..e281daebddca 100644
--- a/trunk/arch/powerpc/include/asm/dma-mapping.h
+++ b/trunk/arch/powerpc/include/asm/dma-mapping.h
@@ -197,7 +197,7 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
if (!dev->dma_mask)
return 0;
- return addr + size - 1 <= *dev->dma_mask;
+ return addr + size <= *dev->dma_mask;
}
static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
diff --git a/trunk/arch/powerpc/include/asm/elf.h b/trunk/arch/powerpc/include/asm/elf.h
index 17828ad411eb..014a624f4c8e 100644
--- a/trunk/arch/powerpc/include/asm/elf.h
+++ b/trunk/arch/powerpc/include/asm/elf.h
@@ -170,6 +170,7 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG];
#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
#define compat_elf_check_arch(x) ((x)->e_machine == EM_PPC)
+#define USE_ELF_CORE_DUMP
#define CORE_DUMP_USE_REGSET
#define ELF_EXEC_PAGESIZE PAGE_SIZE
diff --git a/trunk/arch/powerpc/include/asm/ptrace.h b/trunk/arch/powerpc/include/asm/ptrace.h
index cbd759e3cd78..8c341490cfc5 100644
--- a/trunk/arch/powerpc/include/asm/ptrace.h
+++ b/trunk/arch/powerpc/include/asm/ptrace.h
@@ -140,8 +140,6 @@ extern void user_enable_single_step(struct task_struct *);
extern void user_enable_block_step(struct task_struct *);
extern void user_disable_single_step(struct task_struct *);
-#define ARCH_HAS_USER_SINGLE_STEP_INFO
-
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/trunk/arch/powerpc/kernel/iommu.c b/trunk/arch/powerpc/kernel/iommu.c
index 5547ae6e6b0b..fd51578e29dd 100644
--- a/trunk/arch/powerpc/kernel/iommu.c
+++ b/trunk/arch/powerpc/kernel/iommu.c
@@ -30,7 +30,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -251,7 +251,7 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
}
ppc_md.tce_free(tbl, entry, npages);
- bitmap_clear(tbl->it_map, free_entry, npages);
+ iommu_area_free(tbl->it_map, free_entry, npages);
}
static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c
index d069ff8a7e03..804f0f30f227 100644
--- a/trunk/arch/powerpc/kernel/traps.c
+++ b/trunk/arch/powerpc/kernel/traps.c
@@ -174,15 +174,6 @@ int die(const char *str, struct pt_regs *regs, long err)
return 0;
}
-void user_single_step_siginfo(struct task_struct *tsk,
- struct pt_regs *regs, siginfo_t *info)
-{
- memset(info, 0, sizeof(*info));
- info->si_signo = SIGTRAP;
- info->si_code = TRAP_TRACE;
- info->si_addr = (void __user *)regs->nip;
-}
-
void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
{
siginfo_t info;
diff --git a/trunk/arch/s390/include/asm/elf.h b/trunk/arch/s390/include/asm/elf.h
index 354d42616c7e..e885442c1dfe 100644
--- a/trunk/arch/s390/include/asm/elf.h
+++ b/trunk/arch/s390/include/asm/elf.h
@@ -155,6 +155,7 @@ extern unsigned int vdso_enabled;
} while (0)
#define CORE_DUMP_USE_REGSET
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/trunk/arch/score/include/asm/elf.h b/trunk/arch/score/include/asm/elf.h
index f478ce94181f..43526d9fda93 100644
--- a/trunk/arch/score/include/asm/elf.h
+++ b/trunk/arch/score/include/asm/elf.h
@@ -61,6 +61,7 @@ struct task_struct;
struct pt_regs;
#define CORE_DUMP_USE_REGSET
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE PAGE_SIZE
/* This yields a mask that user programs can use to figure out what
diff --git a/trunk/arch/sh/boards/mach-ap325rxa/setup.c b/trunk/arch/sh/boards/mach-ap325rxa/setup.c
index 7a9f69663f1a..cf9dc12dfeb1 100644
--- a/trunk/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/trunk/arch/sh/boards/mach-ap325rxa/setup.c
@@ -316,23 +316,20 @@ static struct soc_camera_platform_info camera_info = {
.format_name = "UYVY",
.format_depth = 16,
.format = {
- .code = V4L2_MBUS_FMT_YUYV8_2X8_BE,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
.colorspace = V4L2_COLORSPACE_SMPTE170M,
- .field = V4L2_FIELD_NONE,
.width = 640,
.height = 480,
},
.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
.set_capture = camera_set_capture,
-};
-
-struct soc_camera_link camera_link = {
- .bus_id = 0,
- .add_device = ap325rxa_camera_add,
- .del_device = ap325rxa_camera_del,
- .module_name = "soc_camera_platform",
- .priv = &camera_info,
+ .link = {
+ .bus_id = 0,
+ .add_device = ap325rxa_camera_add,
+ .del_device = ap325rxa_camera_del,
+ .module_name = "soc_camera_platform",
+ },
};
static void dummy_release(struct device *dev)
@@ -350,7 +347,7 @@ static struct platform_device camera_device = {
static int ap325rxa_camera_add(struct soc_camera_link *icl,
struct device *dev)
{
- if (icl != &camera_link || camera_probe() <= 0)
+ if (icl != &camera_info.link || camera_probe() <= 0)
return -ENODEV;
camera_info.dev = dev;
@@ -360,7 +357,7 @@ static int ap325rxa_camera_add(struct soc_camera_link *icl,
static void ap325rxa_camera_del(struct soc_camera_link *icl)
{
- if (icl != &camera_link)
+ if (icl != &camera_info.link)
return;
platform_device_unregister(&camera_device);
@@ -473,15 +470,13 @@ static struct ov772x_camera_info ov7725_info = {
.buswidth = SOCAM_DATAWIDTH_8,
.flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
.edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0),
-};
-
-static struct soc_camera_link ov7725_link = {
- .bus_id = 0,
- .power = ov7725_power,
- .board_info = &ap325rxa_i2c_camera[0],
- .i2c_adapter_id = 0,
- .module_name = "ov772x",
- .priv = &ov7725_info,
+ .link = {
+ .bus_id = 0,
+ .power = ov7725_power,
+ .board_info = &ap325rxa_i2c_camera[0],
+ .i2c_adapter_id = 0,
+ .module_name = "ov772x",
+ },
};
static struct platform_device ap325rxa_camera[] = {
@@ -489,13 +484,13 @@ static struct platform_device ap325rxa_camera[] = {
.name = "soc-camera-pdrv",
.id = 0,
.dev = {
- .platform_data = &ov7725_link,
+ .platform_data = &ov7725_info.link,
},
}, {
.name = "soc-camera-pdrv",
.id = 1,
.dev = {
- .platform_data = &camera_link,
+ .platform_data = &camera_info.link,
},
},
};
diff --git a/trunk/arch/sh/boards/mach-kfr2r09/setup.c b/trunk/arch/sh/boards/mach-kfr2r09/setup.c
index 9038d768a525..87438d6603d6 100644
--- a/trunk/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/trunk/arch/sh/boards/mach-kfr2r09/setup.c
@@ -19,7 +19,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -256,9 +255,6 @@ static struct i2c_board_info kfr2r09_i2c_camera = {
static struct clk *camera_clk;
-/* set VIO_CKO clock to 25MHz */
-#define CEU_MCLK_FREQ 25000000
-
#define DRVCRB 0xA405018C
static int camera_power(struct device *dev, int mode)
{
@@ -271,7 +267,8 @@ static int camera_power(struct device *dev, int mode)
if (IS_ERR(camera_clk))
return PTR_ERR(camera_clk);
- rate = clk_round_rate(camera_clk, CEU_MCLK_FREQ);
+ /* set VIO_CKO clock to 25MHz */
+ rate = clk_round_rate(camera_clk, 25000000);
ret = clk_set_rate(camera_clk, rate);
if (ret < 0)
goto eclkrate;
@@ -321,17 +318,11 @@ static int camera_power(struct device *dev, int mode)
return ret;
}
-static struct rj54n1_pdata rj54n1_priv = {
- .mclk_freq = CEU_MCLK_FREQ,
- .ioctl_high = false,
-};
-
static struct soc_camera_link rj54n1_link = {
.power = camera_power,
.board_info = &kfr2r09_i2c_camera,
.i2c_adapter_id = 1,
.module_name = "rj54n1cb0c",
- .priv = &rj54n1_priv,
};
static struct platform_device kfr2r09_camera = {
diff --git a/trunk/arch/sh/boards/mach-migor/setup.c b/trunk/arch/sh/boards/mach-migor/setup.c
index 507c77be476d..9099b6da9957 100644
--- a/trunk/arch/sh/boards/mach-migor/setup.c
+++ b/trunk/arch/sh/boards/mach-migor/setup.c
@@ -432,27 +432,23 @@ static struct i2c_board_info migor_i2c_camera[] = {
static struct ov772x_camera_info ov7725_info = {
.buswidth = SOCAM_DATAWIDTH_8,
-};
-
-static struct soc_camera_link ov7725_link = {
- .power = ov7725_power,
- .board_info = &migor_i2c_camera[0],
- .i2c_adapter_id = 0,
- .module_name = "ov772x",
- .priv = &ov7725_info,
+ .link = {
+ .power = ov7725_power,
+ .board_info = &migor_i2c_camera[0],
+ .i2c_adapter_id = 0,
+ .module_name = "ov772x",
+ },
};
static struct tw9910_video_info tw9910_info = {
.buswidth = SOCAM_DATAWIDTH_8,
.mpout = TW9910_MPO_FIELD,
-};
-
-static struct soc_camera_link tw9910_link = {
- .power = tw9910_power,
- .board_info = &migor_i2c_camera[1],
- .i2c_adapter_id = 0,
- .module_name = "tw9910",
- .priv = &tw9910_info,
+ .link = {
+ .power = tw9910_power,
+ .board_info = &migor_i2c_camera[1],
+ .i2c_adapter_id = 0,
+ .module_name = "tw9910",
+ }
};
static struct platform_device migor_camera[] = {
@@ -460,13 +456,13 @@ static struct platform_device migor_camera[] = {
.name = "soc-camera-pdrv",
.id = 0,
.dev = {
- .platform_data = &ov7725_link,
+ .platform_data = &ov7725_info.link,
},
}, {
.name = "soc-camera-pdrv",
.id = 1,
.dev = {
- .platform_data = &tw9910_link,
+ .platform_data = &tw9910_info.link,
},
},
};
diff --git a/trunk/arch/sh/include/asm/elf.h b/trunk/arch/sh/include/asm/elf.h
index ac04255022b6..ccb1d93bb043 100644
--- a/trunk/arch/sh/include/asm/elf.h
+++ b/trunk/arch/sh/include/asm/elf.h
@@ -114,6 +114,7 @@ typedef struct user_fpu_struct elf_fpregset_t;
*/
#define CORE_DUMP_USE_REGSET
+#define USE_ELF_CORE_DUMP
#define ELF_FDPIC_CORE_EFLAGS EF_SH_FDPIC
#define ELF_EXEC_PAGESIZE PAGE_SIZE
diff --git a/trunk/arch/sparc/include/asm/elf_32.h b/trunk/arch/sparc/include/asm/elf_32.h
index 4269ca6ad18a..381a1b5256d6 100644
--- a/trunk/arch/sparc/include/asm/elf_32.h
+++ b/trunk/arch/sparc/include/asm/elf_32.h
@@ -104,6 +104,8 @@ typedef struct {
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
+#define USE_ELF_CORE_DUMP
+
#define ELF_EXEC_PAGESIZE 4096
diff --git a/trunk/arch/sparc/include/asm/elf_64.h b/trunk/arch/sparc/include/asm/elf_64.h
index ff66bb88537b..d42e393078c4 100644
--- a/trunk/arch/sparc/include/asm/elf_64.h
+++ b/trunk/arch/sparc/include/asm/elf_64.h
@@ -152,6 +152,7 @@ typedef struct {
(x)->e_machine == EM_SPARC32PLUS)
#define compat_start_thread start_thread32
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE PAGE_SIZE
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/trunk/arch/sparc/kernel/iommu.c b/trunk/arch/sparc/kernel/iommu.c
index 5fad94950e76..7690cc219ecc 100644
--- a/trunk/arch/sparc/kernel/iommu.c
+++ b/trunk/arch/sparc/kernel/iommu.c
@@ -11,7 +11,6 @@
#include
#include
#include
-#include
#ifdef CONFIG_PCI
#include
@@ -170,7 +169,7 @@ void iommu_range_free(struct iommu *iommu, dma_addr_t dma_addr, unsigned long np
entry = (dma_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT;
- bitmap_clear(arena->map, entry, npages);
+ iommu_area_free(arena->map, entry, npages);
}
int iommu_table_init(struct iommu *iommu, int tsbsize,
diff --git a/trunk/arch/sparc/kernel/ldc.c b/trunk/arch/sparc/kernel/ldc.c
index df39a0f0d27a..e0ba898e30cf 100644
--- a/trunk/arch/sparc/kernel/ldc.c
+++ b/trunk/arch/sparc/kernel/ldc.c
@@ -14,7 +14,6 @@
#include
#include
#include
-#include
#include
#include
@@ -1876,7 +1875,7 @@ EXPORT_SYMBOL(ldc_read);
static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages)
{
struct iommu_arena *arena = &iommu->arena;
- unsigned long n, start, end, limit;
+ unsigned long n, i, start, end, limit;
int pass;
limit = arena->limit;
@@ -1884,7 +1883,7 @@ static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages)
pass = 0;
again:
- n = bitmap_find_next_zero_area(arena->map, limit, start, npages, 0);
+ n = find_next_zero_bit(arena->map, limit, start);
end = n + npages;
if (unlikely(end >= limit)) {
if (likely(pass < 1)) {
@@ -1897,7 +1896,16 @@ static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages)
return -1;
}
}
- bitmap_set(arena->map, n, npages);
+
+ for (i = n; i < end; i++) {
+ if (test_bit(i, arena->map)) {
+ start = i + 1;
+ goto again;
+ }
+ }
+
+ for (i = n; i < end; i++)
+ __set_bit(i, arena->map);
arena->hint = end;
diff --git a/trunk/arch/sparc/mm/sun4c.c b/trunk/arch/sparc/mm/sun4c.c
index a89baf0d875a..2ffacd67c424 100644
--- a/trunk/arch/sparc/mm/sun4c.c
+++ b/trunk/arch/sparc/mm/sun4c.c
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
#include
#include
@@ -1022,12 +1021,20 @@ static char *sun4c_lockarea(char *vaddr, unsigned long size)
npages = (((unsigned long)vaddr & ~PAGE_MASK) +
size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
+ scan = 0;
local_irq_save(flags);
- base = bitmap_find_next_zero_area(sun4c_iobuffer_map, iobuffer_map_size,
- 0, npages, 0);
- if (base >= iobuffer_map_size)
- goto abend;
+ for (;;) {
+ scan = find_next_zero_bit(sun4c_iobuffer_map,
+ iobuffer_map_size, scan);
+ if ((base = scan) + npages > iobuffer_map_size) goto abend;
+ for (;;) {
+ if (scan >= base + npages) goto found;
+ if (test_bit(scan, sun4c_iobuffer_map)) break;
+ scan++;
+ }
+ }
+found:
high = ((base + npages) << PAGE_SHIFT) + sun4c_iobuffer_start;
high = SUN4C_REAL_PGDIR_ALIGN(high);
while (high > sun4c_iobuffer_high) {
diff --git a/trunk/arch/um/sys-i386/asm/elf.h b/trunk/arch/um/sys-i386/asm/elf.h
index 770885472ed4..d0da9d7c5371 100644
--- a/trunk/arch/um/sys-i386/asm/elf.h
+++ b/trunk/arch/um/sys-i386/asm/elf.h
@@ -48,6 +48,7 @@ typedef struct user_i387_struct elf_fpregset_t;
PT_REGS_EAX(regs) = 0; \
} while (0)
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
diff --git a/trunk/arch/um/sys-ppc/asm/elf.h b/trunk/arch/um/sys-ppc/asm/elf.h
index 8aacaf56508d..af9463cd8ce5 100644
--- a/trunk/arch/um/sys-ppc/asm/elf.h
+++ b/trunk/arch/um/sys-ppc/asm/elf.h
@@ -17,6 +17,8 @@ extern long elf_aux_hwcap;
#define ELF_CLASS ELFCLASS32
#endif
+#define USE_ELF_CORE_DUMP
+
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
diff --git a/trunk/arch/um/sys-x86_64/asm/elf.h b/trunk/arch/um/sys-x86_64/asm/elf.h
index 49655c83efd2..04b9e87c8dad 100644
--- a/trunk/arch/um/sys-x86_64/asm/elf.h
+++ b/trunk/arch/um/sys-x86_64/asm/elf.h
@@ -104,6 +104,7 @@ extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu);
clear_thread_flag(TIF_IA32);
#endif
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
diff --git a/trunk/arch/x86/include/asm/dma-mapping.h b/trunk/arch/x86/include/asm/dma-mapping.h
index ac91eed21061..0f6c02f3b7d4 100644
--- a/trunk/arch/x86/include/asm/dma-mapping.h
+++ b/trunk/arch/x86/include/asm/dma-mapping.h
@@ -67,7 +67,7 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
if (!dev->dma_mask)
return 0;
- return addr + size - 1 <= *dev->dma_mask;
+ return addr + size <= *dev->dma_mask;
}
static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
diff --git a/trunk/arch/x86/include/asm/elf.h b/trunk/arch/x86/include/asm/elf.h
index b4501ee223ad..8a024babe5e6 100644
--- a/trunk/arch/x86/include/asm/elf.h
+++ b/trunk/arch/x86/include/asm/elf.h
@@ -239,6 +239,7 @@ extern int force_personality32;
#endif /* !CONFIG_X86_32 */
#define CORE_DUMP_USE_REGSET
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/trunk/arch/x86/include/asm/ptrace.h b/trunk/arch/x86/include/asm/ptrace.h
index 9d369f680321..3d11fd0f44c5 100644
--- a/trunk/arch/x86/include/asm/ptrace.h
+++ b/trunk/arch/x86/include/asm/ptrace.h
@@ -292,8 +292,6 @@ extern void user_enable_block_step(struct task_struct *);
#define arch_has_block_step() (boot_cpu_data.x86 >= 6)
#endif
-#define ARCH_HAS_USER_SINGLE_STEP_INFO
-
struct user_desc;
extern int do_get_thread_area(struct task_struct *p, int idx,
struct user_desc __user *info);
diff --git a/trunk/arch/x86/include/asm/uv/bios.h b/trunk/arch/x86/include/asm/uv/bios.h
index 2751f3075d8b..7ed17ff502b9 100644
--- a/trunk/arch/x86/include/asm/uv/bios.h
+++ b/trunk/arch/x86/include/asm/uv/bios.h
@@ -76,6 +76,15 @@ union partition_info_u {
};
};
+union uv_watchlist_u {
+ u64 val;
+ struct {
+ u64 blade : 16,
+ size : 32,
+ filler : 16;
+ };
+};
+
enum uv_memprotect {
UV_MEMPROT_RESTRICT_ACCESS,
UV_MEMPROT_ALLOW_AMO,
@@ -91,7 +100,7 @@ extern s64 uv_bios_call_reentrant(enum uv_bios_cmd, u64, u64, u64, u64, u64);
extern s64 uv_bios_get_sn_info(int, int *, long *, long *, long *);
extern s64 uv_bios_freq_base(u64, u64 *);
-extern int uv_bios_mq_watchlist_alloc(unsigned long, unsigned int,
+extern int uv_bios_mq_watchlist_alloc(int, unsigned long, unsigned int,
unsigned long *);
extern int uv_bios_mq_watchlist_free(int, int);
extern s64 uv_bios_change_memprotect(u64, u64, enum uv_memprotect);
diff --git a/trunk/arch/x86/include/asm/uv/uv_hub.h b/trunk/arch/x86/include/asm/uv/uv_hub.h
index 811bfabc80b7..d1414af98559 100644
--- a/trunk/arch/x86/include/asm/uv/uv_hub.h
+++ b/trunk/arch/x86/include/asm/uv/uv_hub.h
@@ -172,8 +172,6 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
#define UV_LOCAL_MMR_SIZE (64UL * 1024 * 1024)
#define UV_GLOBAL_MMR32_SIZE (64UL * 1024 * 1024)
-#define UV_GLOBAL_GRU_MMR_BASE 0x4000000
-
#define UV_GLOBAL_MMR32_PNODE_SHIFT 15
#define UV_GLOBAL_MMR64_PNODE_SHIFT 26
@@ -234,26 +232,6 @@ static inline unsigned long uv_gpa(void *v)
return uv_soc_phys_ram_to_gpa(__pa(v));
}
-/* Top two bits indicate the requested address is in MMR space. */
-static inline int
-uv_gpa_in_mmr_space(unsigned long gpa)
-{
- return (gpa >> 62) == 0x3UL;
-}
-
-/* UV global physical address --> socket phys RAM */
-static inline unsigned long uv_gpa_to_soc_phys_ram(unsigned long gpa)
-{
- unsigned long paddr = gpa & uv_hub_info->gpa_mask;
- unsigned long remap_base = uv_hub_info->lowmem_remap_base;
- unsigned long remap_top = uv_hub_info->lowmem_remap_top;
-
- if (paddr >= remap_base && paddr < remap_base + remap_top)
- paddr -= remap_base;
- return paddr;
-}
-
-
/* gnode -> pnode */
static inline unsigned long uv_gpa_to_gnode(unsigned long gpa)
{
@@ -329,15 +307,6 @@ static inline unsigned long uv_read_global_mmr64(int pnode,
return readq(uv_global_mmr64_address(pnode, offset));
}
-/*
- * Global MMR space addresses when referenced by the GRU. (GRU does
- * NOT use socket addressing).
- */
-static inline unsigned long uv_global_gru_mmr_address(int pnode, unsigned long offset)
-{
- return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val);
-}
-
/*
* Access hub local MMRs. Faster than using global space but only local MMRs
* are accessible.
@@ -465,14 +434,6 @@ static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
}
}
-static unsigned long uv_hub_ipi_value(int apicid, int vector, int mode)
-{
- return (1UL << UVH_IPI_INT_SEND_SHFT) |
- ((apicid) << UVH_IPI_INT_APIC_ID_SHFT) |
- (mode << UVH_IPI_INT_DELIVERY_MODE_SHFT) |
- (vector << UVH_IPI_INT_VECTOR_SHFT);
-}
-
static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
{
unsigned long val;
@@ -481,7 +442,10 @@ static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
if (vector == NMI_VECTOR)
dmode = dest_NMI;
- val = uv_hub_ipi_value(apicid, vector, dmode);
+ val = (1UL << UVH_IPI_INT_SEND_SHFT) |
+ ((apicid) << UVH_IPI_INT_APIC_ID_SHFT) |
+ (dmode << UVH_IPI_INT_DELIVERY_MODE_SHFT) |
+ (vector << UVH_IPI_INT_VECTOR_SHFT);
uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
}
diff --git a/trunk/arch/x86/kernel/amd_iommu.c b/trunk/arch/x86/kernel/amd_iommu.c
index 23824fef789c..b990b5cc9541 100644
--- a/trunk/arch/x86/kernel/amd_iommu.c
+++ b/trunk/arch/x86/kernel/amd_iommu.c
@@ -19,7 +19,7 @@
#include
#include
-#include
+#include
#include
#include
#include
@@ -1162,7 +1162,7 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom,
address = (address % APERTURE_RANGE_SIZE) >> PAGE_SHIFT;
- bitmap_clear(range->bitmap, address, pages);
+ iommu_area_free(range->bitmap, address, pages);
}
diff --git a/trunk/arch/x86/kernel/bios_uv.c b/trunk/arch/x86/kernel/bios_uv.c
index b0206a211b09..63a88e1f987d 100644
--- a/trunk/arch/x86/kernel/bios_uv.c
+++ b/trunk/arch/x86/kernel/bios_uv.c
@@ -101,17 +101,21 @@ s64 uv_bios_get_sn_info(int fc, int *uvtype, long *partid, long *coher,
}
int
-uv_bios_mq_watchlist_alloc(unsigned long addr, unsigned int mq_size,
+uv_bios_mq_watchlist_alloc(int blade, unsigned long addr, unsigned int mq_size,
unsigned long *intr_mmr_offset)
{
+ union uv_watchlist_u size_blade;
u64 watchlist;
s64 ret;
+ size_blade.size = mq_size;
+ size_blade.blade = blade;
+
/*
* bios returns watchlist number or negative error number.
*/
ret = (int)uv_bios_call_irqsave(UV_BIOS_WATCHLIST_ALLOC, addr,
- mq_size, (u64)intr_mmr_offset,
+ size_blade.val, (u64)intr_mmr_offset,
(u64)&watchlist, 0);
if (ret < BIOS_STATUS_SUCCESS)
return ret;
diff --git a/trunk/arch/x86/kernel/pci-calgary_64.c b/trunk/arch/x86/kernel/pci-calgary_64.c
index 2bbde6078143..c563e4c8ff39 100644
--- a/trunk/arch/x86/kernel/pci-calgary_64.c
+++ b/trunk/arch/x86/kernel/pci-calgary_64.c
@@ -31,7 +31,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -212,7 +212,7 @@ static void iommu_range_reserve(struct iommu_table *tbl,
spin_lock_irqsave(&tbl->it_lock, flags);
- bitmap_set(tbl->it_map, index, npages);
+ iommu_area_reserve(tbl->it_map, index, npages);
spin_unlock_irqrestore(&tbl->it_lock, flags);
}
@@ -303,7 +303,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
spin_lock_irqsave(&tbl->it_lock, flags);
- bitmap_clear(tbl->it_map, entry, npages);
+ iommu_area_free(tbl->it_map, entry, npages);
spin_unlock_irqrestore(&tbl->it_lock, flags);
}
diff --git a/trunk/arch/x86/kernel/pci-gart_64.c b/trunk/arch/x86/kernel/pci-gart_64.c
index 34de53b46f87..56c0e730d3fe 100644
--- a/trunk/arch/x86/kernel/pci-gart_64.c
+++ b/trunk/arch/x86/kernel/pci-gart_64.c
@@ -23,7 +23,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -126,7 +126,7 @@ static void free_iommu(unsigned long offset, int size)
unsigned long flags;
spin_lock_irqsave(&iommu_bitmap_lock, flags);
- bitmap_clear(iommu_gart_bitmap, offset, size);
+ iommu_area_free(iommu_gart_bitmap, offset, size);
if (offset >= next_bit)
next_bit = offset + size;
spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
@@ -792,7 +792,7 @@ int __init gart_iommu_init(void)
* Out of IOMMU space handling.
* Reserve some invalid pages at the beginning of the GART.
*/
- bitmap_set(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
+ iommu_area_reserve(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
pr_info("PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
iommu_size >> 20);
diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c
index 2779321046bd..7079ddaf0731 100644
--- a/trunk/arch/x86/kernel/ptrace.c
+++ b/trunk/arch/x86/kernel/ptrace.c
@@ -1676,33 +1676,21 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
#endif
}
-static void fill_sigtrap_info(struct task_struct *tsk,
- struct pt_regs *regs,
- int error_code, int si_code,
- struct siginfo *info)
+void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
+ int error_code, int si_code)
{
+ struct siginfo info;
+
tsk->thread.trap_no = 1;
tsk->thread.error_code = error_code;
- memset(info, 0, sizeof(*info));
- info->si_signo = SIGTRAP;
- info->si_code = si_code;
- info->si_addr = user_mode_vm(regs) ? (void __user *)regs->ip : NULL;
-}
+ memset(&info, 0, sizeof(info));
+ info.si_signo = SIGTRAP;
+ info.si_code = si_code;
-void user_single_step_siginfo(struct task_struct *tsk,
- struct pt_regs *regs,
- struct siginfo *info)
-{
- fill_sigtrap_info(tsk, regs, 0, TRAP_BRKPT, info);
-}
+ /* User-mode ip? */
+ info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
-void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
- int error_code, int si_code)
-{
- struct siginfo info;
-
- fill_sigtrap_info(tsk, regs, error_code, si_code, &info);
/* Send us the fake SIGTRAP */
force_sig_info(SIGTRAP, &info, tsk);
}
@@ -1767,22 +1755,29 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs)
asmregparm void syscall_trace_leave(struct pt_regs *regs)
{
- bool step;
-
if (unlikely(current->audit_context))
audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
trace_sys_exit(regs, regs->ax);
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall_exit(regs, 0);
+
/*
* If TIF_SYSCALL_EMU is set, we only get here because of
* TIF_SINGLESTEP (i.e. this is PTRACE_SYSEMU_SINGLESTEP).
* We already reported this syscall instruction in
- * syscall_trace_enter().
+ * syscall_trace_enter(), so don't do any more now.
+ */
+ if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
+ return;
+
+ /*
+ * If we are single-stepping, synthesize a trap to follow the
+ * system call instruction.
*/
- step = unlikely(test_thread_flag(TIF_SINGLESTEP)) &&
- !test_thread_flag(TIF_SYSCALL_EMU);
- if (step || test_thread_flag(TIF_SYSCALL_TRACE))
- tracehook_report_syscall_exit(regs, step);
+ if (test_thread_flag(TIF_SINGLESTEP) &&
+ tracehook_consider_fatal_signal(current, SIGTRAP))
+ send_sigtrap(current, regs, 0, TRAP_BRKPT);
}
diff --git a/trunk/arch/xtensa/include/asm/elf.h b/trunk/arch/xtensa/include/asm/elf.h
index 5eb6d695e987..c3f53e755ca5 100644
--- a/trunk/arch/xtensa/include/asm/elf.h
+++ b/trunk/arch/xtensa/include/asm/elf.h
@@ -123,6 +123,7 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_XTENSA
+#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE PAGE_SIZE
/*
diff --git a/trunk/drivers/char/efirtc.c b/trunk/drivers/char/efirtc.c
index 53c524e7b829..26a47dc88f61 100644
--- a/trunk/drivers/char/efirtc.c
+++ b/trunk/drivers/char/efirtc.c
@@ -285,7 +285,6 @@ static const struct file_operations efi_rtc_fops = {
.unlocked_ioctl = efi_rtc_ioctl,
.open = efi_rtc_open,
.release = efi_rtc_close,
- .llseek = no_llseek,
};
static struct miscdevice efi_rtc_dev= {
diff --git a/trunk/drivers/char/ipmi/ipmi_kcs_sm.c b/trunk/drivers/char/ipmi/ipmi_kcs_sm.c
index cf82fedae099..80704875794c 100644
--- a/trunk/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/trunk/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -370,7 +370,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
return SI_SM_IDLE;
case KCS_START_OP:
- if (state != KCS_IDLE_STATE) {
+ if (state != KCS_IDLE) {
start_error_recovery(kcs,
"State machine not idle at start");
break;
diff --git a/trunk/drivers/char/sysrq.c b/trunk/drivers/char/sysrq.c
index 1ae2de7d8b4f..44203ff599da 100644
--- a/trunk/drivers/char/sysrq.c
+++ b/trunk/drivers/char/sysrq.c
@@ -339,7 +339,7 @@ static struct sysrq_key_op sysrq_term_op = {
static void moom_callback(struct work_struct *ignored)
{
- out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0, NULL);
+ out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0);
}
static DECLARE_WORK(moom_work, moom_callback);
diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c
index 50faa1fb0f06..e43fbc66aef0 100644
--- a/trunk/drivers/char/vt.c
+++ b/trunk/drivers/char/vt.c
@@ -164,9 +164,6 @@ module_param(default_utf8, int, S_IRUGO | S_IWUSR);
int global_cursor_default = -1;
module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
-static int cur_default = CUR_DEFAULT;
-module_param(cur_default, int, S_IRUGO | S_IWUSR);
-
/*
* ignore_poke: don't unblank the screen when things are typed. This is
* mainly for the privacy of braille terminal users.
@@ -1639,7 +1636,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
/* do not do set_leds here because this causes an endless tasklet loop
when the keyboard hasn't been initialized yet */
- vc->vc_cursor_type = cur_default;
+ vc->vc_cursor_type = CUR_DEFAULT;
vc->vc_complement_mask = vc->vc_s_complement_mask;
default_attr(vc);
@@ -1841,7 +1838,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
if (vc->vc_par[0])
vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
else
- vc->vc_cursor_type = cur_default;
+ vc->vc_cursor_type = CUR_DEFAULT;
return;
}
break;
diff --git a/trunk/drivers/edac/edac_mce_amd.c b/trunk/drivers/edac/edac_mce_amd.c
index 8fc91a019620..c693fcc2213c 100644
--- a/trunk/drivers/edac/edac_mce_amd.c
+++ b/trunk/drivers/edac/edac_mce_amd.c
@@ -299,12 +299,6 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
if (!handle_errors)
return;
- /*
- * GART TLB error reporting is disabled by default. Bail out early.
- */
- if (TLB_ERROR(ec) && !report_gart_errors)
- return;
-
pr_emerg(" Northbridge Error, node %d", node_id);
/*
@@ -316,9 +310,10 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
if (regs->nbsh & K8_NBSH_ERR_CPU_VAL)
pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf));
} else {
- pr_cont(", core: %d\n", fls((regs->nbsh & 0xf) - 1));
+ pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf)));
}
+
pr_emerg("%s.\n", EXT_ERR_MSG(xec));
if (BUS_ERROR(ec) && nb_bus_decoder)
@@ -338,6 +333,21 @@ static void amd_decode_fr_mce(u64 mc5_status)
static inline void amd_decode_err_code(unsigned int ec)
{
if (TLB_ERROR(ec)) {
+ /*
+ * GART errors are intended to help graphics driver developers
+ * to detect bad GART PTEs. It is recommended by AMD to disable
+ * GART table walk error reporting by default[1] (currently
+ * being disabled in mce_cpu_quirks()) and according to the
+ * comment in mce_cpu_quirks(), such GART errors can be
+ * incorrectly triggered. We may see these errors anyway and
+ * unless requested by the user, they won't be reported.
+ *
+ * [1] section 13.10.1 on BIOS and Kernel Developers Guide for
+ * AMD NPT family 0Fh processors
+ */
+ if (!report_gart_errors)
+ return;
+
pr_emerg(" Transaction: %s, Cache Level %s\n",
TT_MSG(ec), LL_MSG(ec));
} else if (MEM_ERROR(ec)) {
diff --git a/trunk/drivers/edac/i5100_edac.c b/trunk/drivers/edac/i5100_edac.c
index 7785d8ffa404..22db05a67bfb 100644
--- a/trunk/drivers/edac/i5100_edac.c
+++ b/trunk/drivers/edac/i5100_edac.c
@@ -9,11 +9,6 @@
* Intel 5100X Chipset Memory Controller Hub (MCH) - Datasheet
* http://download.intel.com/design/chipsets/datashts/318378.pdf
*
- * The intel 5100 has two independent channels. EDAC core currently
- * can not reflect this configuration so instead the chip-select
- * rows for each respective channel are layed out one after another,
- * the first half belonging to channel 0, the second half belonging
- * to channel 1.
*/
#include
#include
@@ -30,8 +25,6 @@
/* device 16, func 1 */
#define I5100_MC 0x40 /* Memory Control Register */
-#define I5100_MC_SCRBEN_MASK (1 << 7)
-#define I5100_MC_SCRBDONE_MASK (1 << 4)
#define I5100_MS 0x44 /* Memory Status Register */
#define I5100_SPDDATA 0x48 /* Serial Presence Detect Status Reg */
#define I5100_SPDCMD 0x4c /* Serial Presence Detect Command Reg */
@@ -79,21 +72,11 @@
/* bit field accessors */
-static inline u32 i5100_mc_scrben(u32 mc)
-{
- return mc >> 7 & 1;
-}
-
static inline u32 i5100_mc_errdeten(u32 mc)
{
return mc >> 5 & 1;
}
-static inline u32 i5100_mc_scrbdone(u32 mc)
-{
- return mc >> 4 & 1;
-}
-
static inline u16 i5100_spddata_rdo(u16 a)
{
return a >> 15 & 1;
@@ -282,43 +265,42 @@ static inline u32 i5100_recmemb_ras(u32 a)
}
/* some generic limits */
-#define I5100_MAX_RANKS_PER_CHAN 6
-#define I5100_CHANNELS 2
+#define I5100_MAX_RANKS_PER_CTLR 6
+#define I5100_MAX_CTLRS 2
#define I5100_MAX_RANKS_PER_DIMM 4
#define I5100_DIMM_ADDR_LINES (6 - 3) /* 64 bits / 8 bits per byte */
-#define I5100_MAX_DIMM_SLOTS_PER_CHAN 4
+#define I5100_MAX_DIMM_SLOTS_PER_CTLR 4
#define I5100_MAX_RANK_INTERLEAVE 4
#define I5100_MAX_DMIRS 5
-#define I5100_SCRUB_REFRESH_RATE (5 * 60 * HZ)
struct i5100_priv {
/* ranks on each dimm -- 0 maps to not present -- obtained via SPD */
- int dimm_numrank[I5100_CHANNELS][I5100_MAX_DIMM_SLOTS_PER_CHAN];
+ int dimm_numrank[I5100_MAX_CTLRS][I5100_MAX_DIMM_SLOTS_PER_CTLR];
/*
* mainboard chip select map -- maps i5100 chip selects to
* DIMM slot chip selects. In the case of only 4 ranks per
- * channel, the mapping is fairly obvious but not unique.
- * we map -1 -> NC and assume both channels use the same
+ * controller, the mapping is fairly obvious but not unique.
+ * we map -1 -> NC and assume both controllers use the same
* map...
*
*/
- int dimm_csmap[I5100_MAX_DIMM_SLOTS_PER_CHAN][I5100_MAX_RANKS_PER_DIMM];
+ int dimm_csmap[I5100_MAX_DIMM_SLOTS_PER_CTLR][I5100_MAX_RANKS_PER_DIMM];
/* memory interleave range */
struct {
u64 limit;
unsigned way[2];
- } mir[I5100_CHANNELS];
+ } mir[I5100_MAX_CTLRS];
/* adjusted memory interleave range register */
- unsigned amir[I5100_CHANNELS];
+ unsigned amir[I5100_MAX_CTLRS];
/* dimm interleave range */
struct {
unsigned rank[I5100_MAX_RANK_INTERLEAVE];
u64 limit;
- } dmir[I5100_CHANNELS][I5100_MAX_DMIRS];
+ } dmir[I5100_MAX_CTLRS][I5100_MAX_DMIRS];
/* memory technology registers... */
struct {
@@ -328,33 +310,30 @@ struct i5100_priv {
unsigned numbank; /* 2 or 3 lines */
unsigned numrow; /* 13 .. 16 lines */
unsigned numcol; /* 11 .. 12 lines */
- } mtr[I5100_CHANNELS][I5100_MAX_RANKS_PER_CHAN];
+ } mtr[I5100_MAX_CTLRS][I5100_MAX_RANKS_PER_CTLR];
u64 tolm; /* top of low memory in bytes */
- unsigned ranksperchan; /* number of ranks per channel */
+ unsigned ranksperctlr; /* number of ranks per controller */
struct pci_dev *mc; /* device 16 func 1 */
struct pci_dev *ch0mm; /* device 21 func 0 */
struct pci_dev *ch1mm; /* device 22 func 0 */
-
- struct delayed_work i5100_scrubbing;
- int scrub_enable;
};
-/* map a rank/chan to a slot number on the mainboard */
+/* map a rank/ctlr to a slot number on the mainboard */
static int i5100_rank_to_slot(const struct mem_ctl_info *mci,
- int chan, int rank)
+ int ctlr, int rank)
{
const struct i5100_priv *priv = mci->pvt_info;
int i;
- for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CHAN; i++) {
+ for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CTLR; i++) {
int j;
- const int numrank = priv->dimm_numrank[chan][i];
+ const int numrank = priv->dimm_numrank[ctlr][i];
for (j = 0; j < numrank; j++)
if (priv->dimm_csmap[i][j] == rank)
- return i * 2 + chan;
+ return i * 2 + ctlr;
}
return -1;
@@ -395,32 +374,32 @@ static const char *i5100_err_msg(unsigned err)
return "none";
}
-/* convert csrow index into a rank (per channel -- 0..5) */
+/* convert csrow index into a rank (per controller -- 0..5) */
static int i5100_csrow_to_rank(const struct mem_ctl_info *mci, int csrow)
{
const struct i5100_priv *priv = mci->pvt_info;
- return csrow % priv->ranksperchan;
+ return csrow % priv->ranksperctlr;
}
-/* convert csrow index into a channel (0..1) */
-static int i5100_csrow_to_chan(const struct mem_ctl_info *mci, int csrow)
+/* convert csrow index into a controller (0..1) */
+static int i5100_csrow_to_cntlr(const struct mem_ctl_info *mci, int csrow)
{
const struct i5100_priv *priv = mci->pvt_info;
- return csrow / priv->ranksperchan;
+ return csrow / priv->ranksperctlr;
}
static unsigned i5100_rank_to_csrow(const struct mem_ctl_info *mci,
- int chan, int rank)
+ int ctlr, int rank)
{
const struct i5100_priv *priv = mci->pvt_info;
- return chan * priv->ranksperchan + rank;
+ return ctlr * priv->ranksperctlr + rank;
}
static void i5100_handle_ce(struct mem_ctl_info *mci,
- int chan,
+ int ctlr,
unsigned bank,
unsigned rank,
unsigned long syndrome,
@@ -428,12 +407,12 @@ static void i5100_handle_ce(struct mem_ctl_info *mci,
unsigned ras,
const char *msg)
{
- const int csrow = i5100_rank_to_csrow(mci, chan, rank);
+ const int csrow = i5100_rank_to_csrow(mci, ctlr, rank);
printk(KERN_ERR
- "CE chan %d, bank %u, rank %u, syndrome 0x%lx, "
+ "CE ctlr %d, bank %u, rank %u, syndrome 0x%lx, "
"cas %u, ras %u, csrow %u, label \"%s\": %s\n",
- chan, bank, rank, syndrome, cas, ras,
+ ctlr, bank, rank, syndrome, cas, ras,
csrow, mci->csrows[csrow].channels[0].label, msg);
mci->ce_count++;
@@ -442,7 +421,7 @@ static void i5100_handle_ce(struct mem_ctl_info *mci,
}
static void i5100_handle_ue(struct mem_ctl_info *mci,
- int chan,
+ int ctlr,
unsigned bank,
unsigned rank,
unsigned long syndrome,
@@ -450,23 +429,23 @@ static void i5100_handle_ue(struct mem_ctl_info *mci,
unsigned ras,
const char *msg)
{
- const int csrow = i5100_rank_to_csrow(mci, chan, rank);
+ const int csrow = i5100_rank_to_csrow(mci, ctlr, rank);
printk(KERN_ERR
- "UE chan %d, bank %u, rank %u, syndrome 0x%lx, "
+ "UE ctlr %d, bank %u, rank %u, syndrome 0x%lx, "
"cas %u, ras %u, csrow %u, label \"%s\": %s\n",
- chan, bank, rank, syndrome, cas, ras,
+ ctlr, bank, rank, syndrome, cas, ras,
csrow, mci->csrows[csrow].channels[0].label, msg);
mci->ue_count++;
mci->csrows[csrow].ue_count++;
}
-static void i5100_read_log(struct mem_ctl_info *mci, int chan,
+static void i5100_read_log(struct mem_ctl_info *mci, int ctlr,
u32 ferr, u32 nerr)
{
struct i5100_priv *priv = mci->pvt_info;
- struct pci_dev *pdev = (chan) ? priv->ch1mm : priv->ch0mm;
+ struct pci_dev *pdev = (ctlr) ? priv->ch1mm : priv->ch0mm;
u32 dw;
u32 dw2;
unsigned syndrome = 0;
@@ -505,7 +484,7 @@ static void i5100_read_log(struct mem_ctl_info *mci, int chan,
else
msg = i5100_err_msg(nerr);
- i5100_handle_ce(mci, chan, bank, rank, syndrome, cas, ras, msg);
+ i5100_handle_ce(mci, ctlr, bank, rank, syndrome, cas, ras, msg);
}
if (i5100_validlog_nrecmemvalid(dw)) {
@@ -527,7 +506,7 @@ static void i5100_read_log(struct mem_ctl_info *mci, int chan,
else
msg = i5100_err_msg(nerr);
- i5100_handle_ue(mci, chan, bank, rank, syndrome, cas, ras, msg);
+ i5100_handle_ue(mci, ctlr, bank, rank, syndrome, cas, ras, msg);
}
pci_write_config_dword(pdev, I5100_VALIDLOG, dw);
@@ -555,80 +534,6 @@ static void i5100_check_error(struct mem_ctl_info *mci)
}
}
-/* The i5100 chipset will scrub the entire memory once, then
- * set a done bit. Continuous scrubbing is achieved by enqueing
- * delayed work to a workqueue, checking every few minutes if
- * the scrubbing has completed and if so reinitiating it.
- */
-
-static void i5100_refresh_scrubbing(struct work_struct *work)
-{
- struct delayed_work *i5100_scrubbing = container_of(work,
- struct delayed_work,
- work);
- struct i5100_priv *priv = container_of(i5100_scrubbing,
- struct i5100_priv,
- i5100_scrubbing);
- u32 dw;
-
- pci_read_config_dword(priv->mc, I5100_MC, &dw);
-
- if (priv->scrub_enable) {
-
- pci_read_config_dword(priv->mc, I5100_MC, &dw);
-
- if (i5100_mc_scrbdone(dw)) {
- dw |= I5100_MC_SCRBEN_MASK;
- pci_write_config_dword(priv->mc, I5100_MC, dw);
- pci_read_config_dword(priv->mc, I5100_MC, &dw);
- }
-
- schedule_delayed_work(&(priv->i5100_scrubbing),
- I5100_SCRUB_REFRESH_RATE);
- }
-}
-/*
- * The bandwidth is based on experimentation, feel free to refine it.
- */
-static int i5100_set_scrub_rate(struct mem_ctl_info *mci,
- u32 *bandwidth)
-{
- struct i5100_priv *priv = mci->pvt_info;
- u32 dw;
-
- pci_read_config_dword(priv->mc, I5100_MC, &dw);
- if (*bandwidth) {
- priv->scrub_enable = 1;
- dw |= I5100_MC_SCRBEN_MASK;
- schedule_delayed_work(&(priv->i5100_scrubbing),
- I5100_SCRUB_REFRESH_RATE);
- } else {
- priv->scrub_enable = 0;
- dw &= ~I5100_MC_SCRBEN_MASK;
- cancel_delayed_work(&(priv->i5100_scrubbing));
- }
- pci_write_config_dword(priv->mc, I5100_MC, dw);
-
- pci_read_config_dword(priv->mc, I5100_MC, &dw);
-
- *bandwidth = 5900000 * i5100_mc_scrben(dw);
-
- return 0;
-}
-
-static int i5100_get_scrub_rate(struct mem_ctl_info *mci,
- u32 *bandwidth)
-{
- struct i5100_priv *priv = mci->pvt_info;
- u32 dw;
-
- pci_read_config_dword(priv->mc, I5100_MC, &dw);
-
- *bandwidth = 5900000 * i5100_mc_scrben(dw);
-
- return 0;
-}
-
static struct pci_dev *pci_get_device_func(unsigned vendor,
unsigned device,
unsigned func)
@@ -652,19 +557,19 @@ static unsigned long __devinit i5100_npages(struct mem_ctl_info *mci,
int csrow)
{
struct i5100_priv *priv = mci->pvt_info;
- const unsigned chan_rank = i5100_csrow_to_rank(mci, csrow);
- const unsigned chan = i5100_csrow_to_chan(mci, csrow);
+ const unsigned ctlr_rank = i5100_csrow_to_rank(mci, csrow);
+ const unsigned ctlr = i5100_csrow_to_cntlr(mci, csrow);
unsigned addr_lines;
/* dimm present? */
- if (!priv->mtr[chan][chan_rank].present)
+ if (!priv->mtr[ctlr][ctlr_rank].present)
return 0ULL;
addr_lines =
I5100_DIMM_ADDR_LINES +
- priv->mtr[chan][chan_rank].numcol +
- priv->mtr[chan][chan_rank].numrow +
- priv->mtr[chan][chan_rank].numbank;
+ priv->mtr[ctlr][ctlr_rank].numcol +
+ priv->mtr[ctlr][ctlr_rank].numrow +
+ priv->mtr[ctlr][ctlr_rank].numbank;
return (unsigned long)
((unsigned long long) (1ULL << addr_lines) / PAGE_SIZE);
@@ -676,11 +581,11 @@ static void __devinit i5100_init_mtr(struct mem_ctl_info *mci)
struct pci_dev *mms[2] = { priv->ch0mm, priv->ch1mm };
int i;
- for (i = 0; i < I5100_CHANNELS; i++) {
+ for (i = 0; i < I5100_MAX_CTLRS; i++) {
int j;
struct pci_dev *pdev = mms[i];
- for (j = 0; j < I5100_MAX_RANKS_PER_CHAN; j++) {
+ for (j = 0; j < I5100_MAX_RANKS_PER_CTLR; j++) {
const unsigned addr =
(j < 4) ? I5100_MTR_0 + j * 2 :
I5100_MTR_4 + (j - 4) * 2;
@@ -739,6 +644,7 @@ static int i5100_read_spd_byte(const struct mem_ctl_info *mci,
* fill dimm chip select map
*
* FIXME:
+ * o only valid for 4 ranks per controller
* o not the only way to may chip selects to dimm slots
* o investigate if there is some way to obtain this map from the bios
*/
@@ -747,7 +653,9 @@ static void __devinit i5100_init_dimm_csmap(struct mem_ctl_info *mci)
struct i5100_priv *priv = mci->pvt_info;
int i;
- for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CHAN; i++) {
+ WARN_ON(priv->ranksperctlr != 4);
+
+ for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CTLR; i++) {
int j;
for (j = 0; j < I5100_MAX_RANKS_PER_DIMM; j++)
@@ -755,21 +663,12 @@ static void __devinit i5100_init_dimm_csmap(struct mem_ctl_info *mci)
}
/* only 2 chip selects per slot... */
- if (priv->ranksperchan == 4) {
- priv->dimm_csmap[0][0] = 0;
- priv->dimm_csmap[0][1] = 3;
- priv->dimm_csmap[1][0] = 1;
- priv->dimm_csmap[1][1] = 2;
- priv->dimm_csmap[2][0] = 2;
- priv->dimm_csmap[3][0] = 3;
- } else {
- priv->dimm_csmap[0][0] = 0;
- priv->dimm_csmap[0][1] = 1;
- priv->dimm_csmap[1][0] = 2;
- priv->dimm_csmap[1][1] = 3;
- priv->dimm_csmap[2][0] = 4;
- priv->dimm_csmap[2][1] = 5;
- }
+ priv->dimm_csmap[0][0] = 0;
+ priv->dimm_csmap[0][1] = 3;
+ priv->dimm_csmap[1][0] = 1;
+ priv->dimm_csmap[1][1] = 2;
+ priv->dimm_csmap[2][0] = 2;
+ priv->dimm_csmap[3][0] = 3;
}
static void __devinit i5100_init_dimm_layout(struct pci_dev *pdev,
@@ -778,10 +677,10 @@ static void __devinit i5100_init_dimm_layout(struct pci_dev *pdev,
struct i5100_priv *priv = mci->pvt_info;
int i;
- for (i = 0; i < I5100_CHANNELS; i++) {
+ for (i = 0; i < I5100_MAX_CTLRS; i++) {
int j;
- for (j = 0; j < I5100_MAX_DIMM_SLOTS_PER_CHAN; j++) {
+ for (j = 0; j < I5100_MAX_DIMM_SLOTS_PER_CTLR; j++) {
u8 rank;
if (i5100_read_spd_byte(mci, i, j, 5, &rank) < 0)
@@ -821,7 +720,7 @@ static void __devinit i5100_init_interleaving(struct pci_dev *pdev,
pci_read_config_word(pdev, I5100_AMIR_1, &w);
priv->amir[1] = w;
- for (i = 0; i < I5100_CHANNELS; i++) {
+ for (i = 0; i < I5100_MAX_CTLRS; i++) {
int j;
for (j = 0; j < 5; j++) {
@@ -848,7 +747,7 @@ static void __devinit i5100_init_csrows(struct mem_ctl_info *mci)
for (i = 0; i < mci->nr_csrows; i++) {
const unsigned long npages = i5100_npages(mci, i);
- const unsigned chan = i5100_csrow_to_chan(mci, i);
+ const unsigned cntlr = i5100_csrow_to_cntlr(mci, i);
const unsigned rank = i5100_csrow_to_rank(mci, i);
if (!npages)
@@ -866,7 +765,7 @@ static void __devinit i5100_init_csrows(struct mem_ctl_info *mci)
mci->csrows[i].grain = 32;
mci->csrows[i].csrow_idx = i;
mci->csrows[i].dtype =
- (priv->mtr[chan][rank].width == 4) ? DEV_X4 : DEV_X8;
+ (priv->mtr[cntlr][rank].width == 4) ? DEV_X4 : DEV_X8;
mci->csrows[i].ue_count = 0;
mci->csrows[i].ce_count = 0;
mci->csrows[i].mtype = MEM_RDDR2;
@@ -878,7 +777,7 @@ static void __devinit i5100_init_csrows(struct mem_ctl_info *mci)
mci->csrows[i].channels[0].csrow = mci->csrows + i;
snprintf(mci->csrows[i].channels[0].label,
sizeof(mci->csrows[i].channels[0].label),
- "DIMM%u", i5100_rank_to_slot(mci, chan, rank));
+ "DIMM%u", i5100_rank_to_slot(mci, cntlr, rank));
total_pages += npages;
}
@@ -916,6 +815,13 @@ static int __devinit i5100_init_one(struct pci_dev *pdev,
pci_read_config_dword(pdev, I5100_MS, &dw);
ranksperch = !!(dw & (1 << 8)) * 2 + 4;
+ if (ranksperch != 4) {
+ /* FIXME: get 6 ranks / controller to work - need hw... */
+ printk(KERN_INFO "i5100_edac: unsupported configuration.\n");
+ ret = -ENODEV;
+ goto bail_pdev;
+ }
+
/* enable error reporting... */
pci_read_config_dword(pdev, I5100_EMASK_MEM, &dw);
dw &= ~I5100_FERR_NF_MEM_ANY_MASK;
@@ -958,21 +864,11 @@ static int __devinit i5100_init_one(struct pci_dev *pdev,
mci->dev = &pdev->dev;
priv = mci->pvt_info;
- priv->ranksperchan = ranksperch;
+ priv->ranksperctlr = ranksperch;
priv->mc = pdev;
priv->ch0mm = ch0mm;
priv->ch1mm = ch1mm;
- INIT_DELAYED_WORK(&(priv->i5100_scrubbing), i5100_refresh_scrubbing);
-
- /* If scrubbing was already enabled by the bios, start maintaining it */
- pci_read_config_dword(pdev, I5100_MC, &dw);
- if (i5100_mc_scrben(dw)) {
- priv->scrub_enable = 1;
- schedule_delayed_work(&(priv->i5100_scrubbing),
- I5100_SCRUB_REFRESH_RATE);
- }
-
i5100_init_dimm_layout(pdev, mci);
i5100_init_interleaving(pdev, mci);
@@ -986,8 +882,6 @@ static int __devinit i5100_init_one(struct pci_dev *pdev,
mci->ctl_page_to_phys = NULL;
mci->edac_check = i5100_check_error;
- mci->set_sdram_scrub_rate = i5100_set_scrub_rate;
- mci->get_sdram_scrub_rate = i5100_get_scrub_rate;
i5100_init_csrows(mci);
@@ -1003,14 +897,12 @@ static int __devinit i5100_init_one(struct pci_dev *pdev,
if (edac_mc_add_mc(mci)) {
ret = -ENODEV;
- goto bail_scrub;
+ goto bail_mc;
}
return ret;
-bail_scrub:
- priv->scrub_enable = 0;
- cancel_delayed_work_sync(&(priv->i5100_scrubbing));
+bail_mc:
edac_mc_free(mci);
bail_disable_ch1:
@@ -1043,10 +935,6 @@ static void __devexit i5100_remove_one(struct pci_dev *pdev)
return;
priv = mci->pvt_info;
-
- priv->scrub_enable = 0;
- cancel_delayed_work_sync(&(priv->i5100_scrubbing));
-
pci_disable_device(pdev);
pci_disable_device(priv->ch0mm);
pci_disable_device(priv->ch1mm);
diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig
index a019b49ecc9b..57ca339924ef 100644
--- a/trunk/drivers/gpio/Kconfig
+++ b/trunk/drivers/gpio/Kconfig
@@ -206,12 +206,6 @@ config GPIO_LANGWELL
help
Say Y here to support Intel Moorestown platform GPIO.
-config GPIO_TIMBERDALE
- bool "Support for timberdale GPIO IP"
- depends on MFD_TIMBERDALE && GPIOLIB && HAS_IOMEM
- ---help---
- Add support for the GPIO IP in the timberdale FPGA.
-
comment "SPI GPIO expanders:"
config GPIO_MAX7301
diff --git a/trunk/drivers/gpio/Makefile b/trunk/drivers/gpio/Makefile
index 52fe4cf734c7..270b6d7839f5 100644
--- a/trunk/drivers/gpio/Makefile
+++ b/trunk/drivers/gpio/Makefile
@@ -13,7 +13,6 @@ obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o
obj-$(CONFIG_GPIO_PCA953X) += pca953x.o
obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
obj-$(CONFIG_GPIO_PL061) += pl061.o
-obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o
obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o
obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o
obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o
diff --git a/trunk/drivers/gpio/gpiolib.c b/trunk/drivers/gpio/gpiolib.c
index a25ad284a272..50de0f5750d8 100644
--- a/trunk/drivers/gpio/gpiolib.c
+++ b/trunk/drivers/gpio/gpiolib.c
@@ -53,7 +53,6 @@ struct gpio_desc {
#define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */
#define FLAG_TRIG_FALL 5 /* trigger on falling edge */
#define FLAG_TRIG_RISE 6 /* trigger on rising edge */
-#define FLAG_ACTIVE_LOW 7 /* sysfs value has active low */
#define PDESC_ID_SHIFT 16 /* add new flags before this one */
@@ -211,11 +210,6 @@ static DEFINE_MUTEX(sysfs_lock);
* * configures behavior of poll(2) on /value
* * available only if pin can generate IRQs on input
* * is read/write as "none", "falling", "rising", or "both"
- * /active_low
- * * configures polarity of /value
- * * is read/write as zero/nonzero
- * * also affects existing and subsequent "falling" and "rising"
- * /edge configuration
*/
static ssize_t gpio_direction_show(struct device *dev,
@@ -261,7 +255,7 @@ static ssize_t gpio_direction_store(struct device *dev,
return status ? : size;
}
-static /* const */ DEVICE_ATTR(direction, 0644,
+static const DEVICE_ATTR(direction, 0644,
gpio_direction_show, gpio_direction_store);
static ssize_t gpio_value_show(struct device *dev,
@@ -273,17 +267,10 @@ static ssize_t gpio_value_show(struct device *dev,
mutex_lock(&sysfs_lock);
- if (!test_bit(FLAG_EXPORT, &desc->flags)) {
+ if (!test_bit(FLAG_EXPORT, &desc->flags))
status = -EIO;
- } else {
- int value;
-
- value = !!gpio_get_value_cansleep(gpio);
- if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
- value = !value;
-
- status = sprintf(buf, "%d\n", value);
- }
+ else
+ status = sprintf(buf, "%d\n", !!gpio_get_value_cansleep(gpio));
mutex_unlock(&sysfs_lock);
return status;
@@ -307,8 +294,6 @@ static ssize_t gpio_value_store(struct device *dev,
status = strict_strtol(buf, 0, &value);
if (status == 0) {
- if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
- value = !value;
gpio_set_value_cansleep(gpio, value != 0);
status = size;
}
@@ -318,7 +303,7 @@ static ssize_t gpio_value_store(struct device *dev,
return status;
}
-static const DEVICE_ATTR(value, 0644,
+static /*const*/ DEVICE_ATTR(value, 0644,
gpio_value_show, gpio_value_store);
static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
@@ -367,11 +352,9 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
irq_flags = IRQF_SHARED;
if (test_bit(FLAG_TRIG_FALL, &gpio_flags))
- irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
- IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
+ irq_flags |= IRQF_TRIGGER_FALLING;
if (test_bit(FLAG_TRIG_RISE, &gpio_flags))
- irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
- IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
+ irq_flags |= IRQF_TRIGGER_RISING;
if (!pdesc) {
pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL);
@@ -492,79 +475,9 @@ static ssize_t gpio_edge_store(struct device *dev,
static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store);
-static int sysfs_set_active_low(struct gpio_desc *desc, struct device *dev,
- int value)
-{
- int status = 0;
-
- if (!!test_bit(FLAG_ACTIVE_LOW, &desc->flags) == !!value)
- return 0;
-
- if (value)
- set_bit(FLAG_ACTIVE_LOW, &desc->flags);
- else
- clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
-
- /* reconfigure poll(2) support if enabled on one edge only */
- if (dev != NULL && (!!test_bit(FLAG_TRIG_RISE, &desc->flags) ^
- !!test_bit(FLAG_TRIG_FALL, &desc->flags))) {
- unsigned long trigger_flags = desc->flags & GPIO_TRIGGER_MASK;
-
- gpio_setup_irq(desc, dev, 0);
- status = gpio_setup_irq(desc, dev, trigger_flags);
- }
-
- return status;
-}
-
-static ssize_t gpio_active_low_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- const struct gpio_desc *desc = dev_get_drvdata(dev);
- ssize_t status;
-
- mutex_lock(&sysfs_lock);
-
- if (!test_bit(FLAG_EXPORT, &desc->flags))
- status = -EIO;
- else
- status = sprintf(buf, "%d\n",
- !!test_bit(FLAG_ACTIVE_LOW, &desc->flags));
-
- mutex_unlock(&sysfs_lock);
-
- return status;
-}
-
-static ssize_t gpio_active_low_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- struct gpio_desc *desc = dev_get_drvdata(dev);
- ssize_t status;
-
- mutex_lock(&sysfs_lock);
-
- if (!test_bit(FLAG_EXPORT, &desc->flags)) {
- status = -EIO;
- } else {
- long value;
-
- status = strict_strtol(buf, 0, &value);
- if (status == 0)
- status = sysfs_set_active_low(desc, dev, value != 0);
- }
-
- mutex_unlock(&sysfs_lock);
-
- return status ? : size;
-}
-
-static const DEVICE_ATTR(active_low, 0644,
- gpio_active_low_show, gpio_active_low_store);
-
static const struct attribute *gpio_attrs[] = {
+ &dev_attr_direction.attr,
&dev_attr_value.attr,
- &dev_attr_active_low.attr,
NULL,
};
@@ -749,12 +662,12 @@ int gpio_export(unsigned gpio, bool direction_may_change)
dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
desc, ioname ? ioname : "gpio%d", gpio);
if (!IS_ERR(dev)) {
- status = sysfs_create_group(&dev->kobj,
+ if (direction_may_change)
+ status = sysfs_create_group(&dev->kobj,
&gpio_attr_group);
-
- if (!status && direction_may_change)
+ else
status = device_create_file(dev,
- &dev_attr_direction);
+ &dev_attr_value);
if (!status && gpio_to_irq(gpio) >= 0
&& (direction_may_change
@@ -831,55 +744,6 @@ int gpio_export_link(struct device *dev, const char *name, unsigned gpio)
}
EXPORT_SYMBOL_GPL(gpio_export_link);
-
-/**
- * gpio_sysfs_set_active_low - set the polarity of gpio sysfs value
- * @gpio: gpio to change
- * @value: non-zero to use active low, i.e. inverted values
- *
- * Set the polarity of /sys/class/gpio/gpioN/value sysfs attribute.
- * The GPIO does not have to be exported yet. If poll(2) support has
- * been enabled for either rising or falling edge, it will be
- * reconfigured to follow the new polarity.
- *
- * Returns zero on success, else an error.
- */
-int gpio_sysfs_set_active_low(unsigned gpio, int value)
-{
- struct gpio_desc *desc;
- struct device *dev = NULL;
- int status = -EINVAL;
-
- if (!gpio_is_valid(gpio))
- goto done;
-
- mutex_lock(&sysfs_lock);
-
- desc = &gpio_desc[gpio];
-
- if (test_bit(FLAG_EXPORT, &desc->flags)) {
- struct device *dev;
-
- dev = class_find_device(&gpio_class, NULL, desc, match_export);
- if (dev == NULL) {
- status = -ENODEV;
- goto unlock;
- }
- }
-
- status = sysfs_set_active_low(desc, dev, value);
-
-unlock:
- mutex_unlock(&sysfs_lock);
-
-done:
- if (status)
- pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
-
- return status;
-}
-EXPORT_SYMBOL_GPL(gpio_sysfs_set_active_low);
-
/**
* gpio_unexport - reverse effect of gpio_export()
* @gpio: gpio to make unavailable
@@ -1230,7 +1094,6 @@ void gpio_free(unsigned gpio)
}
desc_set_label(desc, NULL);
module_put(desc->chip->owner);
- clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
clear_bit(FLAG_REQUESTED, &desc->flags);
} else
WARN_ON(extra_checks);
diff --git a/trunk/drivers/gpio/langwell_gpio.c b/trunk/drivers/gpio/langwell_gpio.c
index 6c0ebbdc659e..4baf3d7d0f8e 100644
--- a/trunk/drivers/gpio/langwell_gpio.c
+++ b/trunk/drivers/gpio/langwell_gpio.c
@@ -123,7 +123,7 @@ static int lnw_irq_type(unsigned irq, unsigned type)
void __iomem *grer = (void __iomem *)(&lnw->reg_base->GRER[reg]);
void __iomem *gfer = (void __iomem *)(&lnw->reg_base->GFER[reg]);
- if (gpio >= lnw->chip.ngpio)
+ if (gpio < 0 || gpio > lnw->chip.ngpio)
return -EINVAL;
spin_lock_irqsave(&lnw->lock, flags);
if (type & IRQ_TYPE_EDGE_RISING)
diff --git a/trunk/drivers/gpio/timbgpio.c b/trunk/drivers/gpio/timbgpio.c
deleted file mode 100644
index a4d344ba8e5c..000000000000
--- a/trunk/drivers/gpio/timbgpio.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * timbgpio.c timberdale FPGA GPIO driver
- * Copyright (c) 2009 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Supports:
- * Timberdale FPGA GPIO
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define DRIVER_NAME "timb-gpio"
-
-#define TGPIOVAL 0x00
-#define TGPIODIR 0x04
-#define TGPIO_IER 0x08
-#define TGPIO_ISR 0x0c
-#define TGPIO_IPR 0x10
-#define TGPIO_ICR 0x14
-#define TGPIO_FLR 0x18
-#define TGPIO_LVR 0x1c
-
-struct timbgpio {
- void __iomem *membase;
- spinlock_t lock; /* mutual exclusion */
- struct gpio_chip gpio;
- int irq_base;
-};
-
-static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
- unsigned offset, bool enabled)
-{
- struct timbgpio *tgpio = container_of(gpio, struct timbgpio, gpio);
- u32 reg;
-
- spin_lock(&tgpio->lock);
- reg = ioread32(tgpio->membase + offset);
-
- if (enabled)
- reg |= (1 << index);
- else
- reg &= ~(1 << index);
-
- iowrite32(reg, tgpio->membase + offset);
- spin_unlock(&tgpio->lock);
-
- return 0;
-}
-
-static int timbgpio_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
-{
- return timbgpio_update_bit(gpio, nr, TGPIODIR, true);
-}
-
-static int timbgpio_gpio_get(struct gpio_chip *gpio, unsigned nr)
-{
- struct timbgpio *tgpio = container_of(gpio, struct timbgpio, gpio);
- u32 value;
-
- value = ioread32(tgpio->membase + TGPIOVAL);
- return (value & (1 << nr)) ? 1 : 0;
-}
-
-static int timbgpio_gpio_direction_output(struct gpio_chip *gpio,
- unsigned nr, int val)
-{
- return timbgpio_update_bit(gpio, nr, TGPIODIR, false);
-}
-
-static void timbgpio_gpio_set(struct gpio_chip *gpio,
- unsigned nr, int val)
-{
- timbgpio_update_bit(gpio, nr, TGPIOVAL, val != 0);
-}
-
-static int timbgpio_to_irq(struct gpio_chip *gpio, unsigned offset)
-{
- struct timbgpio *tgpio = container_of(gpio, struct timbgpio, gpio);
-
- if (tgpio->irq_base <= 0)
- return -EINVAL;
-
- return tgpio->irq_base + offset;
-}
-
-/*
- * GPIO IRQ
- */
-static void timbgpio_irq_disable(unsigned irq)
-{
- struct timbgpio *tgpio = get_irq_chip_data(irq);
- int offset = irq - tgpio->irq_base;
-
- timbgpio_update_bit(&tgpio->gpio, offset, TGPIO_IER, 0);
-}
-
-static void timbgpio_irq_enable(unsigned irq)
-{
- struct timbgpio *tgpio = get_irq_chip_data(irq);
- int offset = irq - tgpio->irq_base;
-
- timbgpio_update_bit(&tgpio->gpio, offset, TGPIO_IER, 1);
-}
-
-static int timbgpio_irq_type(unsigned irq, unsigned trigger)
-{
- struct timbgpio *tgpio = get_irq_chip_data(irq);
- int offset = irq - tgpio->irq_base;
- unsigned long flags;
- u32 lvr, flr;
-
- if (offset < 0 || offset > tgpio->gpio.ngpio)
- return -EINVAL;
-
- spin_lock_irqsave(&tgpio->lock, flags);
-
- lvr = ioread32(tgpio->membase + TGPIO_LVR);
- flr = ioread32(tgpio->membase + TGPIO_FLR);
-
- if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
- flr &= ~(1 << offset);
- if (trigger & IRQ_TYPE_LEVEL_HIGH)
- lvr |= 1 << offset;
- else
- lvr &= ~(1 << offset);
- }
-
- if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
- return -EINVAL;
- else {
- flr |= 1 << offset;
- /* opposite compared to the datasheet, but it mirrors the
- * reality
- */
- if (trigger & IRQ_TYPE_EDGE_FALLING)
- lvr |= 1 << offset;
- else
- lvr &= ~(1 << offset);
- }
-
- iowrite32(lvr, tgpio->membase + TGPIO_LVR);
- iowrite32(flr, tgpio->membase + TGPIO_FLR);
- iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
- spin_unlock_irqrestore(&tgpio->lock, flags);
-
- return 0;
-}
-
-static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
-{
- struct timbgpio *tgpio = get_irq_data(irq);
- unsigned long ipr;
- int offset;
-
- desc->chip->ack(irq);
- ipr = ioread32(tgpio->membase + TGPIO_IPR);
- iowrite32(ipr, tgpio->membase + TGPIO_ICR);
-
- for_each_bit(offset, &ipr, tgpio->gpio.ngpio)
- generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset));
-}
-
-static struct irq_chip timbgpio_irqchip = {
- .name = "GPIO",
- .enable = timbgpio_irq_enable,
- .disable = timbgpio_irq_disable,
- .set_type = timbgpio_irq_type,
-};
-
-static int __devinit timbgpio_probe(struct platform_device *pdev)
-{
- int err, i;
- struct gpio_chip *gc;
- struct timbgpio *tgpio;
- struct resource *iomem;
- struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
- int irq = platform_get_irq(pdev, 0);
-
- if (!pdata || pdata->nr_pins > 32) {
- err = -EINVAL;
- goto err_mem;
- }
-
- iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iomem) {
- err = -EINVAL;
- goto err_mem;
- }
-
- tgpio = kzalloc(sizeof(*tgpio), GFP_KERNEL);
- if (!tgpio) {
- err = -EINVAL;
- goto err_mem;
- }
- tgpio->irq_base = pdata->irq_base;
-
- spin_lock_init(&tgpio->lock);
-
- if (!request_mem_region(iomem->start, resource_size(iomem),
- DRIVER_NAME)) {
- err = -EBUSY;
- goto err_request;
- }
-
- tgpio->membase = ioremap(iomem->start, resource_size(iomem));
- if (!tgpio->membase) {
- err = -ENOMEM;
- goto err_ioremap;
- }
-
- gc = &tgpio->gpio;
-
- gc->label = dev_name(&pdev->dev);
- gc->owner = THIS_MODULE;
- gc->dev = &pdev->dev;
- gc->direction_input = timbgpio_gpio_direction_input;
- gc->get = timbgpio_gpio_get;
- gc->direction_output = timbgpio_gpio_direction_output;
- gc->set = timbgpio_gpio_set;
- gc->to_irq = (irq >= 0 && tgpio->irq_base > 0) ? timbgpio_to_irq : NULL;
- gc->dbg_show = NULL;
- gc->base = pdata->gpio_base;
- gc->ngpio = pdata->nr_pins;
- gc->can_sleep = 0;
-
- err = gpiochip_add(gc);
- if (err)
- goto err_chipadd;
-
- platform_set_drvdata(pdev, tgpio);
-
- /* make sure to disable interrupts */
- iowrite32(0x0, tgpio->membase + TGPIO_IER);
-
- if (irq < 0 || tgpio->irq_base <= 0)
- return 0;
-
- for (i = 0; i < pdata->nr_pins; i++) {
- set_irq_chip_and_handler_name(tgpio->irq_base + i,
- &timbgpio_irqchip, handle_simple_irq, "mux");
- set_irq_chip_data(tgpio->irq_base + i, tgpio);
-#ifdef CONFIG_ARM
- set_irq_flags(tgpio->irq_base + i, IRQF_VALID | IRQF_PROBE);
-#endif
- }
-
- set_irq_data(irq, tgpio);
- set_irq_chained_handler(irq, timbgpio_irq);
-
- return 0;
-
-err_chipadd:
- iounmap(tgpio->membase);
-err_ioremap:
- release_mem_region(iomem->start, resource_size(iomem));
-err_request:
- kfree(tgpio);
-err_mem:
- printk(KERN_ERR DRIVER_NAME": Failed to register GPIOs: %d\n", err);
-
- return err;
-}
-
-static int __devexit timbgpio_remove(struct platform_device *pdev)
-{
- int err;
- struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
- struct timbgpio *tgpio = platform_get_drvdata(pdev);
- struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- int irq = platform_get_irq(pdev, 0);
-
- if (irq >= 0 && tgpio->irq_base > 0) {
- int i;
- for (i = 0; i < pdata->nr_pins; i++) {
- set_irq_chip(tgpio->irq_base + i, NULL);
- set_irq_chip_data(tgpio->irq_base + i, NULL);
- }
-
- set_irq_handler(irq, NULL);
- set_irq_data(irq, NULL);
- }
-
- err = gpiochip_remove(&tgpio->gpio);
- if (err)
- printk(KERN_ERR DRIVER_NAME": failed to remove gpio_chip\n");
-
- iounmap(tgpio->membase);
- release_mem_region(iomem->start, resource_size(iomem));
- kfree(tgpio);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static struct platform_driver timbgpio_platform_driver = {
- .driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
- },
- .probe = timbgpio_probe,
- .remove = timbgpio_remove,
-};
-
-/*--------------------------------------------------------------------------*/
-
-static int __init timbgpio_init(void)
-{
- return platform_driver_register(&timbgpio_platform_driver);
-}
-
-static void __exit timbgpio_exit(void)
-{
- platform_driver_unregister(&timbgpio_platform_driver);
-}
-
-module_init(timbgpio_init);
-module_exit(timbgpio_exit);
-
-MODULE_DESCRIPTION("Timberdale GPIO driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Mocean Laboratories");
-MODULE_ALIAS("platform:"DRIVER_NAME);
-
diff --git a/trunk/drivers/media/IR/Kconfig b/trunk/drivers/media/IR/Kconfig
deleted file mode 100644
index 4dde7d180a32..000000000000
--- a/trunk/drivers/media/IR/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-config IR_CORE
- tristate
- depends on INPUT
- default INPUT
-
-config VIDEO_IR
- tristate
- depends on IR_CORE
- default IR_CORE
diff --git a/trunk/drivers/media/IR/Makefile b/trunk/drivers/media/IR/Makefile
deleted file mode 100644
index df5ddb4bbbf7..000000000000
--- a/trunk/drivers/media/IR/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-ir-common-objs := ir-functions.o ir-keymaps.o
-ir-core-objs := ir-keytable.o
-
-obj-$(CONFIG_IR_CORE) += ir-core.o
-obj-$(CONFIG_VIDEO_IR) += ir-common.o
diff --git a/trunk/drivers/media/Kconfig b/trunk/drivers/media/Kconfig
index a28541b2b1a2..ba69beeb0e21 100644
--- a/trunk/drivers/media/Kconfig
+++ b/trunk/drivers/media/Kconfig
@@ -99,7 +99,6 @@ config VIDEO_MEDIA
comment "Multimedia drivers"
source "drivers/media/common/Kconfig"
-source "drivers/media/IR/Kconfig"
#
# Tuner drivers for DVB and V4L
diff --git a/trunk/drivers/media/Makefile b/trunk/drivers/media/Makefile
index 499b0810d019..09a829d8a7e7 100644
--- a/trunk/drivers/media/Makefile
+++ b/trunk/drivers/media/Makefile
@@ -2,7 +2,7 @@
# Makefile for the kernel multimedia device drivers.
#
-obj-y += common/ IR/ video/
+obj-y += common/ video/
obj-$(CONFIG_VIDEO_DEV) += radio/
obj-$(CONFIG_DVB_CORE) += dvb/
diff --git a/trunk/drivers/media/common/Makefile b/trunk/drivers/media/common/Makefile
index e3ec9639321b..169b337b7c9d 100644
--- a/trunk/drivers/media/common/Makefile
+++ b/trunk/drivers/media/common/Makefile
@@ -1,6 +1,8 @@
saa7146-objs := saa7146_i2c.o saa7146_core.o
saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
+ir-common-objs := ir-functions.o ir-keymaps.o ir-keytable.o
obj-y += tuners/
obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
+obj-$(CONFIG_VIDEO_IR) += ir-common.o
diff --git a/trunk/drivers/media/IR/ir-functions.c b/trunk/drivers/media/common/ir-functions.c
similarity index 92%
rename from trunk/drivers/media/IR/ir-functions.c
rename to trunk/drivers/media/common/ir-functions.c
index 776a136616d6..e616f624ceaa 100644
--- a/trunk/drivers/media/IR/ir-functions.c
+++ b/trunk/drivers/media/common/ir-functions.c
@@ -34,6 +34,9 @@ static int repeat = 1;
module_param(repeat, int, 0444);
MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
+int media_ir_debug; /* media_ir_debug level (0,1,2) */
+module_param_named(debug, media_ir_debug, int, 0644);
+
/* -------------------------------------------------------------------------- */
static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
@@ -52,10 +55,25 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
/* -------------------------------------------------------------------------- */
int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
- int ir_type)
+ int ir_type, struct ir_scancode_table *ir_codes)
{
ir->ir_type = ir_type;
+ ir->keytable.size = ir_roundup_tablesize(ir_codes->size);
+ ir->keytable.scan = kzalloc(ir->keytable.size *
+ sizeof(struct ir_scancode), GFP_KERNEL);
+ if (!ir->keytable.scan)
+ return -ENOMEM;
+
+ IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
+ ir->keytable.size,
+ ir->keytable.size * sizeof(ir->keytable.scan));
+
+ ir_copy_table(&ir->keytable, ir_codes);
+ ir_set_keycode_table(dev, &ir->keytable);
+
+ clear_bit(0, dev->keybit);
+ set_bit(EV_KEY, dev->evbit);
if (repeat)
set_bit(EV_REP, dev->evbit);
diff --git a/trunk/drivers/media/IR/ir-keymaps.c b/trunk/drivers/media/common/ir-keymaps.c
similarity index 97%
rename from trunk/drivers/media/IR/ir-keymaps.c
rename to trunk/drivers/media/common/ir-keymaps.c
index 9bbe6b1e9871..328c973a0838 100644
--- a/trunk/drivers/media/IR/ir-keymaps.c
+++ b/trunk/drivers/media/common/ir-keymaps.c
@@ -1847,6 +1847,76 @@ struct ir_scancode_table ir_codes_hauppauge_new_table = {
};
EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
+/*
+ * Hauppauge:the newer, gray remotes (seems there are multiple
+ * slightly different versions), shipped with cx88+ivtv cards.
+ *
+ * This table contains the complete RC5 code, instead of just the data part
+ */
+static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
+ /* Keys 0 to 9 */
+ { 0x1e00, KEY_0 },
+ { 0x1e01, KEY_1 },
+ { 0x1e02, KEY_2 },
+ { 0x1e03, KEY_3 },
+ { 0x1e04, KEY_4 },
+ { 0x1e05, KEY_5 },
+ { 0x1e06, KEY_6 },
+ { 0x1e07, KEY_7 },
+ { 0x1e08, KEY_8 },
+ { 0x1e09, KEY_9 },
+
+ { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
+ { 0x1e0b, KEY_RED }, /* red button */
+ { 0x1e0c, KEY_RADIO },
+ { 0x1e0d, KEY_MENU },
+ { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
+ { 0x1e0f, KEY_MUTE },
+ { 0x1e10, KEY_VOLUMEUP },
+ { 0x1e11, KEY_VOLUMEDOWN },
+ { 0x1e12, KEY_PREVIOUS }, /* previous channel */
+ { 0x1e14, KEY_UP },
+ { 0x1e15, KEY_DOWN },
+ { 0x1e16, KEY_LEFT },
+ { 0x1e17, KEY_RIGHT },
+ { 0x1e18, KEY_VIDEO }, /* Videos */
+ { 0x1e19, KEY_AUDIO }, /* Music */
+ /* 0x1e1a: Pictures - presume this means
+ "Multimedia Home Platform" -
+ no "PICTURES" key in input.h
+ */
+ { 0x1e1a, KEY_MHP },
+
+ { 0x1e1b, KEY_EPG }, /* Guide */
+ { 0x1e1c, KEY_TV },
+ { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
+ { 0x1e1f, KEY_EXIT }, /* back/exit */
+ { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
+ { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
+ { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
+ { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
+ { 0x1e25, KEY_ENTER }, /* OK */
+ { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
+ { 0x1e29, KEY_BLUE }, /* blue key */
+ { 0x1e2e, KEY_GREEN }, /* green button */
+ { 0x1e30, KEY_PAUSE }, /* pause */
+ { 0x1e32, KEY_REWIND }, /* backward << */
+ { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
+ { 0x1e35, KEY_PLAY },
+ { 0x1e36, KEY_STOP },
+ { 0x1e37, KEY_RECORD }, /* recording */
+ { 0x1e38, KEY_YELLOW }, /* yellow key */
+ { 0x1e3b, KEY_SELECT }, /* top right button */
+ { 0x1e3c, KEY_ZOOM }, /* full */
+ { 0x1e3d, KEY_POWER }, /* system power (green button) */
+};
+
+struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
+ .scan = ir_codes_rc5_hauppauge_new,
+ .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
+};
+EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
+
static struct ir_scancode ir_codes_npgtech[] = {
{ 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
{ 0x2a, KEY_FRONT },
@@ -3244,152 +3314,3 @@ struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
};
EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
-/*************************************************************
- * COMPLETE SCANCODE TABLES
- * Instead of just a partial scancode, the tables bellow
- * contains the complete scancode and the receiver protocol
- *************************************************************/
-
-/*
- * Hauppauge:the newer, gray remotes (seems there are multiple
- * slightly different versions), shipped with cx88+ivtv cards.
- *
- * This table contains the complete RC5 code, instead of just the data part
- */
-static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
- /* Keys 0 to 9 */
- { 0x1e00, KEY_0 },
- { 0x1e01, KEY_1 },
- { 0x1e02, KEY_2 },
- { 0x1e03, KEY_3 },
- { 0x1e04, KEY_4 },
- { 0x1e05, KEY_5 },
- { 0x1e06, KEY_6 },
- { 0x1e07, KEY_7 },
- { 0x1e08, KEY_8 },
- { 0x1e09, KEY_9 },
-
- { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
- { 0x1e0b, KEY_RED }, /* red button */
- { 0x1e0c, KEY_RADIO },
- { 0x1e0d, KEY_MENU },
- { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
- { 0x1e0f, KEY_MUTE },
- { 0x1e10, KEY_VOLUMEUP },
- { 0x1e11, KEY_VOLUMEDOWN },
- { 0x1e12, KEY_PREVIOUS }, /* previous channel */
- { 0x1e14, KEY_UP },
- { 0x1e15, KEY_DOWN },
- { 0x1e16, KEY_LEFT },
- { 0x1e17, KEY_RIGHT },
- { 0x1e18, KEY_VIDEO }, /* Videos */
- { 0x1e19, KEY_AUDIO }, /* Music */
- /* 0x1e1a: Pictures - presume this means
- "Multimedia Home Platform" -
- no "PICTURES" key in input.h
- */
- { 0x1e1a, KEY_MHP },
-
- { 0x1e1b, KEY_EPG }, /* Guide */
- { 0x1e1c, KEY_TV },
- { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
- { 0x1e1f, KEY_EXIT }, /* back/exit */
- { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
- { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
- { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
- { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
- { 0x1e25, KEY_ENTER }, /* OK */
- { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
- { 0x1e29, KEY_BLUE }, /* blue key */
- { 0x1e2e, KEY_GREEN }, /* green button */
- { 0x1e30, KEY_PAUSE }, /* pause */
- { 0x1e32, KEY_REWIND }, /* backward << */
- { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
- { 0x1e35, KEY_PLAY },
- { 0x1e36, KEY_STOP },
- { 0x1e37, KEY_RECORD }, /* recording */
- { 0x1e38, KEY_YELLOW }, /* yellow key */
- { 0x1e3b, KEY_SELECT }, /* top right button */
- { 0x1e3c, KEY_ZOOM }, /* full */
- { 0x1e3d, KEY_POWER }, /* system power (green button) */
-};
-
-struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
- .scan = ir_codes_rc5_hauppauge_new,
- .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
- .ir_type = IR_TYPE_RC5,
-};
-EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
-
-/* Terratec Cinergy Hybrid T USB XS FM
- Mauro Carvalho Chehab
- */
-static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = {
- { 0x1441, KEY_HOME},
- { 0x1401, KEY_POWER2},
-
- { 0x1442, KEY_MENU}, /* DVD menu */
- { 0x1443, KEY_SUBTITLE},
- { 0x1444, KEY_TEXT}, /* Teletext */
- { 0x1445, KEY_DELETE},
-
- { 0x1402, KEY_1},
- { 0x1403, KEY_2},
- { 0x1404, KEY_3},
- { 0x1405, KEY_4},
- { 0x1406, KEY_5},
- { 0x1407, KEY_6},
- { 0x1408, KEY_7},
- { 0x1409, KEY_8},
- { 0x140a, KEY_9},
- { 0x140c, KEY_0},
-
- { 0x140b, KEY_TUNER}, /* AV */
- { 0x140d, KEY_MODE}, /* A.B */
-
- { 0x1446, KEY_TV},
- { 0x1447, KEY_DVD},
- { 0x1449, KEY_VIDEO},
- { 0x144a, KEY_RADIO}, /* Music */
- { 0x144b, KEY_CAMERA}, /* PIC */
-
- { 0x1410, KEY_UP},
- { 0x1411, KEY_LEFT},
- { 0x1412, KEY_OK},
- { 0x1413, KEY_RIGHT},
- { 0x1414, KEY_DOWN},
-
- { 0x140f, KEY_EPG},
- { 0x1416, KEY_INFO},
- { 0x144d, KEY_BACKSPACE},
-
- { 0x141c, KEY_VOLUMEUP},
- { 0x141e, KEY_VOLUMEDOWN},
-
- { 0x144c, KEY_PLAY},
- { 0x141d, KEY_MUTE},
-
- { 0x141b, KEY_CHANNELUP},
- { 0x141f, KEY_CHANNELDOWN},
-
- { 0x1417, KEY_RED},
- { 0x1418, KEY_GREEN},
- { 0x1419, KEY_YELLOW},
- { 0x141a, KEY_BLUE},
-
- { 0x1458, KEY_RECORD},
- { 0x1448, KEY_STOP},
- { 0x1440, KEY_PAUSE},
-
- { 0x1454, KEY_LAST},
- { 0x144e, KEY_REWIND},
- { 0x144f, KEY_FASTFORWARD},
- { 0x145c, KEY_NEXT},
-};
-struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = {
- .scan = ir_codes_nec_terratec_cinergy_xs,
- .size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs),
- .ir_type = IR_TYPE_NEC,
-};
-EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table);
-
diff --git a/trunk/drivers/media/IR/ir-keytable.c b/trunk/drivers/media/common/ir-keytable.c
similarity index 81%
rename from trunk/drivers/media/IR/ir-keytable.c
rename to trunk/drivers/media/common/ir-keytable.c
index bff7a5356037..26ce5bc2fdd5 100644
--- a/trunk/drivers/media/IR/ir-keytable.c
+++ b/trunk/drivers/media/common/ir-keytable.c
@@ -1,19 +1,10 @@
/* ir-register.c - handle IR scancode->keycode tables
*
* Copyright (C) 2009 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
-
#include
+
#include
#define IR_TAB_MIN_SIZE 32
@@ -81,7 +72,6 @@ int ir_roundup_tablesize(int n_elems)
return n_elems;
}
-EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
/**
* ir_copy_table() - copies a keytable, discarding the unused entries
@@ -110,7 +100,6 @@ int ir_copy_table(struct ir_scancode_table *destin,
return 0;
}
-EXPORT_SYMBOL_GPL(ir_copy_table);
/**
* ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
@@ -125,8 +114,7 @@ static int ir_getkeycode(struct input_dev *dev,
int scancode, int *keycode)
{
int elem;
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+ struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
elem = ir_seek_table(rc_tab, scancode);
if (elem >= 0) {
@@ -148,6 +136,7 @@ static int ir_getkeycode(struct input_dev *dev,
return 0;
}
+
/**
* ir_is_resize_needed() - Check if the table needs rezise
* @table: keycode table that may need to resize
@@ -297,8 +286,7 @@ static int ir_setkeycode(struct input_dev *dev,
int scancode, int keycode)
{
int rc = 0;
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+ struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
struct ir_scancode *keymap = rc_tab->scan;
unsigned long flags;
@@ -372,8 +360,7 @@ static int ir_setkeycode(struct input_dev *dev,
*/
u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+ struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
struct ir_scancode *keymap = rc_tab->scan;
int elem;
@@ -391,10 +378,9 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
/* Reports userspace that an unknown keycode were got */
return KEY_RESERVED;
}
-EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
/**
- * ir_input_register() - sets the IR keycode table and add the handlers
+ * ir_set_keycode_table() - sets the IR keycode table and add the handlers
* for keymap table get/set
* @input_dev: the struct input_dev descriptor of the device
* @rc_tab: the struct ir_scancode_table table of scancode/keymap
@@ -403,33 +389,16 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
* an IR.
* It should be called before registering the IR device.
*/
-int ir_input_register(struct input_dev *input_dev,
- struct ir_scancode_table *rc_tab)
+int ir_set_keycode_table(struct input_dev *input_dev,
+ struct ir_scancode_table *rc_tab)
{
- struct ir_input_dev *ir_dev;
- struct ir_scancode *keymap = rc_tab->scan;
- int i, rc;
-
- if (rc_tab->scan == NULL || !rc_tab->size)
- return -EINVAL;
-
- ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL);
- if (!ir_dev)
- return -ENOMEM;
+ struct ir_scancode *keymap = rc_tab->scan;
+ int i;
spin_lock_init(&rc_tab->lock);
- ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size);
- ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size *
- sizeof(struct ir_scancode), GFP_KERNEL);
- if (!ir_dev->rc_tab.scan)
- return -ENOMEM;
-
- IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
- ir_dev->rc_tab.size,
- ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan));
-
- ir_copy_table(&ir_dev->rc_tab, rc_tab);
+ if (rc_tab->scan == NULL || !rc_tab->size)
+ return -EINVAL;
/* set the bits for the keys */
IR_dprintk(1, "key map size: %d\n", rc_tab->size);
@@ -438,48 +407,23 @@ int ir_input_register(struct input_dev *input_dev,
i, keymap[i].keycode);
set_bit(keymap[i].keycode, input_dev->keybit);
}
- clear_bit(0, input_dev->keybit);
-
- set_bit(EV_KEY, input_dev->evbit);
input_dev->getkeycode = ir_getkeycode;
input_dev->setkeycode = ir_setkeycode;
- input_set_drvdata(input_dev, ir_dev);
-
- rc = input_register_device(input_dev);
- if (rc < 0) {
- kfree(rc_tab->scan);
- kfree(ir_dev);
- input_set_drvdata(input_dev, NULL);
- }
+ input_set_drvdata(input_dev, rc_tab);
- return rc;
+ return 0;
}
-EXPORT_SYMBOL_GPL(ir_input_register);
-void ir_input_unregister(struct input_dev *dev)
+void ir_input_free(struct input_dev *dev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab;
-
- if (!ir_dev)
- return;
+ struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
IR_dprintk(1, "Freed keycode table\n");
- rc_tab = &ir_dev->rc_tab;
rc_tab->size = 0;
kfree(rc_tab->scan);
rc_tab->scan = NULL;
-
- kfree(ir_dev);
- input_unregister_device(dev);
}
-EXPORT_SYMBOL_GPL(ir_input_unregister);
-
-int ir_core_debug; /* ir_debug level (0,1,2) */
-EXPORT_SYMBOL_GPL(ir_core_debug);
-module_param_named(debug, ir_core_debug, int, 0644);
+EXPORT_SYMBOL_GPL(ir_input_free);
-MODULE_AUTHOR("Mauro Carvalho Chehab ");
-MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/media/common/saa7146_fops.c b/trunk/drivers/media/common/saa7146_fops.c
index 7364b9642d00..620f655fa9c5 100644
--- a/trunk/drivers/media/common/saa7146_fops.c
+++ b/trunk/drivers/media/common/saa7146_fops.c
@@ -1,5 +1,7 @@
#include
+#define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1)
+
/****************************************************************************/
/* resource management functions, shamelessly stolen from saa7134 driver */
@@ -192,23 +194,42 @@ void saa7146_buffer_timeout(unsigned long data)
static int fops_open(struct file *file)
{
- struct video_device *vdev = video_devdata(file);
- struct saa7146_dev *dev = video_drvdata(file);
+ unsigned int minor = video_devdata(file)->minor;
+ struct saa7146_dev *h = NULL, *dev = NULL;
+ struct list_head *list;
struct saa7146_fh *fh = NULL;
int result = 0;
- enum v4l2_buf_type type;
+ enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- DEB_EE(("file:%p, dev:%s\n", file, video_device_node_name(vdev)));
+ DEB_EE(("file:%p, minor:%d\n", file, minor));
if (mutex_lock_interruptible(&saa7146_devices_lock))
return -ERESTARTSYS;
- DEB_D(("using: %p\n",dev));
+ list_for_each(list,&saa7146_devices) {
+ h = list_entry(list, struct saa7146_dev, item);
+ if( NULL == h->vv_data ) {
+ DEB_D(("device %p has not registered video devices.\n",h));
+ continue;
+ }
+ DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor));
+
+ if (h->vv_data->video_minor == minor) {
+ dev = h;
+ }
+ if (h->vv_data->vbi_minor == minor) {
+ type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ dev = h;
+ }
+ }
+ if (NULL == dev) {
+ DEB_S(("no such video device.\n"));
+ result = -ENODEV;
+ goto out;
+ }
- type = vdev->vfl_type == VFL_TYPE_GRABBER
- ? V4L2_BUF_TYPE_VIDEO_CAPTURE
- : V4L2_BUF_TYPE_VBI_CAPTURE;
+ DEB_D(("using: %p\n",dev));
/* check if an extension is registered */
if( NULL == dev->ext ) {
@@ -453,6 +474,9 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
configuration data) */
dev->ext_vv_data = ext_vv;
+ vv->video_minor = -1;
+ vv->vbi_minor = -1;
+
vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);
if( NULL == vv->d_clipping.cpu_addr ) {
ERR(("out of memory. aborting.\n"));
@@ -491,6 +515,7 @@ EXPORT_SYMBOL_GPL(saa7146_vv_release);
int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
char *name, int type)
{
+ struct saa7146_vv *vv = dev->vv_data;
struct video_device *vfd;
int err;
int i;
@@ -518,8 +543,15 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
return err;
}
- INFO(("%s: registered device %s [v4l2]\n",
- dev->name, video_device_node_name(vfd)));
+ if( VFL_TYPE_GRABBER == type ) {
+ vv->video_minor = vfd->minor;
+ INFO(("%s: registered device video%d [v4l2]\n",
+ dev->name, vfd->num));
+ } else {
+ vv->vbi_minor = vfd->minor;
+ INFO(("%s: registered device vbi%d [v4l2]\n",
+ dev->name, vfd->num));
+ }
*vid = vfd;
return 0;
@@ -528,8 +560,16 @@ EXPORT_SYMBOL_GPL(saa7146_register_device);
int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
{
+ struct saa7146_vv *vv = dev->vv_data;
+
DEB_EE(("dev:%p\n",dev));
+ if ((*vid)->vfl_type == VFL_TYPE_GRABBER) {
+ vv->video_minor = -1;
+ } else {
+ vv->vbi_minor = -1;
+ }
+
video_unregister_device(*vid);
*vid = NULL;
diff --git a/trunk/drivers/media/dvb/dm1105/dm1105.c b/trunk/drivers/media/dvb/dm1105/dm1105.c
index f0f483ac8b89..53e3f2a7d31a 100644
--- a/trunk/drivers/media/dvb/dm1105/dm1105.c
+++ b/trunk/drivers/media/dvb/dm1105/dm1105.c
@@ -589,7 +589,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
"pci-%s/ir0", pci_name(dm1105->pdev));
- err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type);
+ err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
if (err < 0) {
input_free_device(input_dev);
return err;
@@ -611,14 +611,20 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
- err = ir_input_register(input_dev, ir_codes);
+ err = input_register_device(input_dev);
+ if (err) {
+ ir_input_free(input_dev);
+ input_free_device(input_dev);
+ return err;
+ }
- return err;
+ return 0;
}
void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
{
- ir_input_unregister(dm1105->ir.input_dev);
+ ir_input_free(dm1105->ir.input_dev);
+ input_unregister_device(dm1105->ir.input_dev);
}
static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb)
diff --git a/trunk/drivers/media/dvb/dvb-usb/Kconfig b/trunk/drivers/media/dvb/dvb-usb/Kconfig
index 1b249897c9fb..2dee1bf73577 100644
--- a/trunk/drivers/media/dvb/dvb-usb/Kconfig
+++ b/trunk/drivers/media/dvb/dvb-usb/Kconfig
@@ -265,13 +265,9 @@ config DVB_USB_DW2102
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
select DVB_MT312 if !DVB_FE_CUSTOMISE
select DVB_ZL10039 if !DVB_FE_CUSTOMISE
- select DVB_DS3000 if !DVB_FE_CUSTOMISE
- select DVB_STB6100 if !DVB_FE_CUSTOMISE
- select DVB_STV6110 if !DVB_FE_CUSTOMISE
- select DVB_STV0900 if !DVB_FE_CUSTOMISE
help
- Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
- receivers.
+ Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
+ and the TeVii S650, S630.
config DVB_USB_CINERGY_T2
tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
diff --git a/trunk/drivers/media/dvb/dvb-usb/dib0700.h b/trunk/drivers/media/dvb/dvb-usb/dib0700.h
index 495a90577c5f..8b544fe79b0d 100644
--- a/trunk/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/trunk/drivers/media/dvb/dvb-usb/dib0700.h
@@ -20,22 +20,20 @@ extern int dvb_usb_dib0700_debug;
#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
#define deb_data(args...) dprintk(dvb_usb_dib0700_debug,0x08,args)
-#define REQUEST_SET_USB_XFER_LEN 0x0 /* valid only for firmware version */
- /* higher than 1.21 */
-#define REQUEST_I2C_READ 0x2
-#define REQUEST_I2C_WRITE 0x3
-#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
-#define REQUEST_JUMPRAM 0x8
-#define REQUEST_SET_CLOCK 0xB
-#define REQUEST_SET_GPIO 0xC
-#define REQUEST_ENABLE_VIDEO 0xF
+#define REQUEST_I2C_READ 0x2
+#define REQUEST_I2C_WRITE 0x3
+#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
+#define REQUEST_JUMPRAM 0x8
+#define REQUEST_SET_CLOCK 0xB
+#define REQUEST_SET_GPIO 0xC
+#define REQUEST_ENABLE_VIDEO 0xF
// 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
// 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
-#define REQUEST_SET_RC 0x11
-#define REQUEST_NEW_I2C_READ 0x12
-#define REQUEST_NEW_I2C_WRITE 0x13
-#define REQUEST_GET_VERSION 0x15
+#define REQUEST_SET_RC 0x11
+#define REQUEST_NEW_I2C_READ 0x12
+#define REQUEST_NEW_I2C_WRITE 0x13
+#define REQUEST_GET_VERSION 0x15
struct dib0700_state {
u8 channel_state;
@@ -46,8 +44,6 @@ struct dib0700_state {
u8 is_dib7000pc;
u8 fw_use_new_i2c_api;
u8 disable_streaming_master_mode;
- u32 fw_version;
- u32 nb_packet_buffer_size;
};
extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
diff --git a/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c b/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c
index 0d3c9a9a33be..db7f7f79a66c 100644
--- a/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -17,14 +17,6 @@ int dvb_usb_dib0700_ir_proto = 1;
module_param(dvb_usb_dib0700_ir_proto, int, 0644);
MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6).");
-static int nb_packet_buffer_size = 21;
-module_param(nb_packet_buffer_size, int, 0644);
-MODULE_PARM_DESC(nb_packet_buffer_size,
- "Set the dib0700 driver data buffer size. This parameter "
- "corresponds to the number of TS packets. The actual size of "
- "the data buffer corresponds to this parameter "
- "multiplied by 188 (default: 21)");
-
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -36,14 +28,10 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
REQUEST_GET_VERSION,
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
b, sizeof(b), USB_CTRL_GET_TIMEOUT);
- if (hwversion != NULL)
- *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
- if (romversion != NULL)
- *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
- if (ramversion != NULL)
- *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
- if (fwtype != NULL)
- *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
+ *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
+ *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
+ *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
+ *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
return ret;
}
@@ -109,27 +97,6 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
return dib0700_ctrl_wr(d,buf,3);
}
-static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
-{
- struct dib0700_state *st = d->priv;
- u8 b[3];
- int ret;
-
- if (st->fw_version >= 0x10201) {
- b[0] = REQUEST_SET_USB_XFER_LEN;
- b[1] = (nb_ts_packets >> 8)&0xff;
- b[2] = nb_ts_packets & 0xff;
-
- deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
-
- ret = dib0700_ctrl_wr(d, b, 3);
- } else {
- deb_info("this firmware does not allow to change the USB xfer len\n");
- ret = -EIO;
- }
- return ret;
-}
-
/*
* I2C master xfer function (supported in 1.20 firmware)
*/
@@ -361,9 +328,7 @@ static int dib0700_jumpram(struct usb_device *udev, u32 address)
int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
{
struct hexline hx;
- int pos = 0, ret, act_len, i, adap_num;
- u8 b[16];
- u32 fw_version;
+ int pos = 0, ret, act_len;
u8 buf[260];
@@ -399,34 +364,6 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw
} else
ret = -EIO;
- /* the number of ts packet has to be at least 1 */
- if (nb_packet_buffer_size < 1)
- nb_packet_buffer_size = 1;
-
- /* get the fimware version */
- usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- REQUEST_GET_VERSION,
- USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
- b, sizeof(b), USB_CTRL_GET_TIMEOUT);
- fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
-
- /* set the buffer size - DVB-USB is allocating URB buffers
- * only after the firwmare download was successful */
- for (i = 0; i < dib0700_device_count; i++) {
- for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
- adap_num++) {
- if (fw_version >= 0x10201)
- dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
- else {
- /* for fw version older than 1.20.1,
- * the buffersize has to be n times 512 */
- dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
- if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512)
- dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512;
- }
- }
- }
-
return ret;
}
@@ -434,18 +371,6 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct dib0700_state *st = adap->dev->priv;
u8 b[4];
- int ret;
-
- if ((onoff != 0) && (st->fw_version >= 0x10201)) {
- /* for firmware later than 1.20.1,
- * the USB xfer length can be set */
- ret = dib0700_set_usb_xfer_len(adap->dev,
- st->nb_packet_buffer_size);
- if (ret < 0) {
- deb_info("can not set the USB xfer len\n");
- return ret;
- }
- }
b[0] = REQUEST_ENABLE_VIDEO;
b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
@@ -490,21 +415,9 @@ static int dib0700_probe(struct usb_interface *intf,
for (i = 0; i < dib0700_device_count; i++)
if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
- &dev, adapter_nr) == 0) {
- struct dib0700_state *st = dev->priv;
- u32 hwversion, romversion, fw_version, fwtype;
-
- dib0700_get_version(dev, &hwversion, &romversion,
- &fw_version, &fwtype);
-
- deb_info("Firmware version: %x, %d, 0x%x, %d\n",
- hwversion, romversion, fw_version, fwtype);
-
- st->fw_version = fw_version;
- st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
-
+ &dev, adapter_nr) == 0)
+ {
dib0700_rc_setup(dev);
-
return 0;
}
diff --git a/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c b/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 44972d01bbd0..684146f98eb7 100644
--- a/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -18,7 +18,6 @@
#include "xc5000.h"
#include "s5h1411.h"
#include "dib0070.h"
-#include "dib0090.h"
#include "lgdt3305.h"
#include "mxl5007t.h"
@@ -131,95 +130,93 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
/* MT226x */
static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
{
- BAND_UHF,
+ BAND_UHF, // band_caps
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
- | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-
- 1130,
- 21,
-
- 0,
- 118,
-
- 0,
- 3530,
- 1,
- 0,
-
- 65535,
- 33770,
- 65535,
- 23592,
-
- 0,
- 62,
- 255,
- 64,
- 64,
- 132,
- 192,
- 80,
- 80,
-
- 17,
- 27,
- 23,
- 51,
-
- 1,
+ (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
+
+ 1130, // inv_gain
+ 21, // time_stabiliz
+
+ 0, // alpha_level
+ 118, // thlock
+
+ 0, // wbd_inv
+ 3530, // wbd_ref
+ 1, // wbd_sel
+ 0, // wbd_alpha
+
+ 65535, // agc1_max
+ 33770, // agc1_min
+ 65535, // agc2_max
+ 23592, // agc2_min
+
+ 0, // agc1_pt1
+ 62, // agc1_pt2
+ 255, // agc1_pt3
+ 64, // agc1_slope1
+ 64, // agc1_slope2
+ 132, // agc2_pt1
+ 192, // agc2_pt2
+ 80, // agc2_slope1
+ 80, // agc2_slope2
+
+ 17, // alpha_mant
+ 27, // alpha_exp
+ 23, // beta_mant
+ 51, // beta_exp
+
+ 1, // perform_agc_softsplit
}, {
- BAND_VHF | BAND_LBAND,
+ BAND_VHF | BAND_LBAND, // band_caps
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
- | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
-
- 2372,
- 21,
-
- 0,
- 118,
-
- 0,
- 3530,
- 1,
- 0,
-
- 65535,
- 0,
- 65535,
- 23592,
-
- 0,
- 128,
- 128,
- 128,
- 0,
- 128,
- 253,
- 81,
- 0,
-
- 17,
- 27,
- 23,
- 51,
-
- 1,
+ (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
+
+ 2372, // inv_gain
+ 21, // time_stabiliz
+
+ 0, // alpha_level
+ 118, // thlock
+
+ 0, // wbd_inv
+ 3530, // wbd_ref
+ 1, // wbd_sel
+ 0, // wbd_alpha
+
+ 65535, // agc1_max
+ 0, // agc1_min
+ 65535, // agc2_max
+ 23592, // agc2_min
+
+ 0, // agc1_pt1
+ 128, // agc1_pt2
+ 128, // agc1_pt3
+ 128, // agc1_slope1
+ 0, // agc1_slope2
+ 128, // agc2_pt1
+ 253, // agc2_pt2
+ 81, // agc2_slope1
+ 0, // agc2_slope2
+
+ 17, // alpha_mant
+ 27, // alpha_exp
+ 23, // beta_mant
+ 51, // beta_exp
+
+ 1, // perform_agc_softsplit
}
};
static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
- 60000, 30000,
- 1, 8, 3, 1, 0,
- 0, 0, 1, 1, 2,
- (3 << 14) | (1 << 12) | (524 << 0),
- 0,
- 20452225,
+ 60000, 30000, // internal, sampling
+ 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
+ 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
+ (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
+ 0, // ifreq
+ 20452225, // timf
};
static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
@@ -608,17 +605,17 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
}
break;
default:
- if (actlen != sizeof(buf)) {
- /* We didn't get back the 6 byte message we expected */
- err("Unexpected RC response size [%d]", actlen);
- return -1;
- }
+ if (actlen != sizeof(buf)) {
+ /* We didn't get back the 6 byte message we expected */
+ err("Unexpected RC response size [%d]", actlen);
+ return -1;
+ }
- poll_reply.report_id = buf[0];
- poll_reply.data_state = buf[1];
+ poll_reply.report_id = buf[0];
+ poll_reply.data_state = buf[1];
poll_reply.system = (buf[2] << 8) | buf[3];
- poll_reply.data = buf[4];
- poll_reply.not_data = buf[5];
+ poll_reply.data = buf[4];
+ poll_reply.not_data = buf[5];
break;
}
@@ -635,7 +632,7 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
/* Find the key in the map */
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
- rc5_data(&keymap[i]) == poll_reply.data) {
+ rc5_data(&keymap[i]) == poll_reply.data) {
*event = keymap[i].event;
found = 1;
break;
@@ -644,8 +641,8 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
if (found == 0) {
err("Unknown remote controller key: %04x %02x %02x",
- poll_reply.system,
- poll_reply.data, poll_reply.not_data);
+ poll_reply.system,
+ poll_reply.data, poll_reply.not_data);
d->last_event = 0;
return 0;
}
@@ -936,48 +933,47 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = {
/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
- BAND_UHF | BAND_VHF,
+ BAND_UHF | BAND_VHF, // band_caps
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
- | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
-
- 712,
- 41,
-
- 0,
- 118,
-
- 0,
- 4095,
- 0,
- 0,
-
- 42598,
- 17694,
- 45875,
- 2621,
- 0,
- 76,
- 139,
- 52,
- 59,
- 107,
- 172,
- 57,
- 70,
-
- 21,
- 25,
- 28,
- 48,
-
- 1,
- { 0,
- 107,
- 51800,
- 24700
+ (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
+
+ 712, // inv_gain
+ 41, // time_stabiliz
+
+ 0, // alpha_level
+ 118, // thlock
+
+ 0, // wbd_inv
+ 4095, // wbd_ref
+ 0, // wbd_sel
+ 0, // wbd_alpha
+
+ 42598, // agc1_max
+ 17694, // agc1_min
+ 45875, // agc2_max
+ 2621, // agc2_min
+ 0, // agc1_pt1
+ 76, // agc1_pt2
+ 139, // agc1_pt3
+ 52, // agc1_slope1
+ 59, // agc1_slope2
+ 107, // agc2_pt1
+ 172, // agc2_pt2
+ 57, // agc2_slope1
+ 70, // agc2_slope2
+
+ 21, // alpha_mant
+ 25, // alpha_exp
+ 28, // beta_mant
+ 48, // beta_exp
+
+ 1, // perform_agc_softsplit
+ { 0, // split_min
+ 107, // split_max
+ 51800, // global_split_min
+ 24700 // global_split_max
},
};
@@ -986,55 +982,54 @@ static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
- | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
+ (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
- 712,
- 41,
+ 712, // inv_gain
+ 41, // time_stabiliz
- 0,
- 118,
+ 0, // alpha_level
+ 118, // thlock
- 0,
- 4095,
- 0,
- 0,
+ 0, // wbd_inv
+ 4095, // wbd_ref
+ 0, // wbd_sel
+ 0, // wbd_alpha
- 42598,
- 16384,
- 42598,
- 0,
+ 42598, // agc1_max
+ 16384, // agc1_min
+ 42598, // agc2_max
+ 0, // agc2_min
- 0,
- 137,
- 255,
+ 0, // agc1_pt1
+ 137, // agc1_pt2
+ 255, // agc1_pt3
- 0,
- 255,
+ 0, // agc1_slope1
+ 255, // agc1_slope2
- 0,
- 0,
+ 0, // agc2_pt1
+ 0, // agc2_pt2
- 0,
- 41,
+ 0, // agc2_slope1
+ 41, // agc2_slope2
- 15,
- 25,
+ 15, // alpha_mant
+ 25, // alpha_exp
- 28,
- 48,
+ 28, // beta_mant
+ 48, // beta_exp
- 0,
+ 0, // perform_agc_softsplit
};
static struct dibx000_bandwidth_config stk7700p_pll_config = {
- 60000, 30000,
- 1, 8, 3, 1, 0,
- 0, 0, 1, 1, 0,
- (3 << 14) | (1 << 12) | (524 << 0),
- 60258167,
- 20452225,
- 30000000,
+ 60000, 30000, // internal, sampling
+ 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
+ 0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
+ (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
+ 60258167, // ifreq
+ 20452225, // timf
+ 30000000, // xtal
};
static struct dib7000m_config stk7700p_dib7000m_config = {
@@ -1120,42 +1115,41 @@ static struct dibx000_agc_config dib7070_agc_config = {
BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
- | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-
- 600,
- 10,
-
- 0,
- 118,
-
- 0,
- 3530,
- 1,
- 5,
-
- 65535,
- 0,
-
- 65535,
- 0,
-
- 0,
- 40,
- 183,
- 206,
- 255,
- 72,
- 152,
- 88,
- 90,
-
- 17,
- 27,
- 23,
- 51,
-
- 0,
+ (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
+
+ 600, // inv_gain
+ 10, // time_stabiliz
+
+ 0, // alpha_level
+ 118, // thlock
+
+ 0, // wbd_inv
+ 3530, // wbd_ref
+ 1, // wbd_sel
+ 5, // wbd_alpha
+
+ 65535, // agc1_max
+ 0, // agc1_min
+
+ 65535, // agc2_max
+ 0, // agc2_min
+
+ 0, // agc1_pt1
+ 40, // agc1_pt2
+ 183, // agc1_pt3
+ 206, // agc1_slope1
+ 255, // agc1_slope2
+ 72, // agc2_pt1
+ 152, // agc2_pt2
+ 88, // agc2_slope1
+ 90, // agc2_slope2
+
+ 17, // alpha_mant
+ 27, // alpha_exp
+ 23, // beta_mant
+ 51, // beta_exp
+
+ 0, // perform_agc_softsplit
};
static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
@@ -1282,13 +1276,13 @@ static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
}
static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
- 60000, 15000,
- 1, 20, 3, 1, 0,
- 0, 0, 1, 1, 2,
- (3 << 14) | (1 << 12) | (524 << 0),
- (0 << 25) | 0,
- 20452225,
- 12000000,
+ 60000, 15000, // internal, sampling
+ 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
+ 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
+ (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
+ (0 << 25) | 0, // ifreq = 0.000000 MHz
+ 20452225, // timf
+ 12000000, // xtal_hz
};
static struct dib7000p_config dib7070p_dib7000p_config = {
@@ -1482,12 +1476,12 @@ static struct dib8000_config dib807x_dib8000_config[2] = {
}
};
-static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
+static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff)
{
return dib8000_set_gpio(fe, 5, 0, !onoff);
}
-static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
+static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
return dib8000_set_gpio(fe, 0, 0, onoff);
}
@@ -1500,8 +1494,8 @@ static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
static struct dib0070_config dib807x_dib0070_config[2] = {
{
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
- .reset = dib80xx_tuner_reset,
- .sleep = dib80xx_tuner_sleep,
+ .reset = dib807x_tuner_reset,
+ .sleep = dib807x_tuner_sleep,
.clock_khz = 12000,
.clock_pad_drive = 4,
.vga_filter = 1,
@@ -1514,8 +1508,8 @@ static struct dib0070_config dib807x_dib0070_config[2] = {
.freq_offset_khz_vhf = -100,
}, {
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
- .reset = dib80xx_tuner_reset,
- .sleep = dib80xx_tuner_sleep,
+ .reset = dib807x_tuner_reset,
+ .sleep = dib807x_tuner_sleep,
.clock_khz = 12000,
.clock_pad_drive = 2,
.vga_filter = 1,
@@ -1572,14 +1566,12 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
-static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
- u16 pid, int onoff)
+static int stk807x_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
{
return dib8000_pid_filter(adapter->fe, index, pid, onoff);
}
-static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
- int onoff)
+static int stk807x_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
{
return dib8000_pid_filter_ctrl(adapter->fe, onoff);
}
@@ -1632,7 +1624,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
/* initialize IC 0 */
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80);
+ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80);
adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
&dib807x_dib8000_config[0]);
@@ -1643,7 +1635,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
{
/* initialize IC 1 */
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82);
+ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82);
adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
&dib807x_dib8000_config[1]);
@@ -1651,245 +1643,6 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
return adap->fe == NULL ? -ENODEV : 0;
}
-/* STK8096GP */
-struct dibx000_agc_config dib8090_agc_config[2] = {
- {
- BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
- /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
- * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
- * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
- | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-
- 787,
- 10,
-
- 0,
- 118,
-
- 0,
- 3530,
- 1,
- 5,
-
- 65535,
- 0,
-
- 65535,
- 0,
-
- 0,
- 32,
- 114,
- 143,
- 144,
- 114,
- 227,
- 116,
- 117,
-
- 28,
- 26,
- 31,
- 51,
-
- 0,
- },
- {
- BAND_CBAND,
- /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
- * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
- * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
- | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-
- 787,
- 10,
-
- 0,
- 118,
-
- 0,
- 3530,
- 1,
- 5,
-
- 0,
- 0,
-
- 65535,
- 0,
-
- 0,
- 32,
- 114,
- 143,
- 144,
- 114,
- 227,
- 116,
- 117,
-
- 28,
- 26,
- 31,
- 51,
-
- 0,
- }
-};
-
-static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
- 54000, 13500,
- 1, 18, 3, 1, 0,
- 0, 0, 1, 1, 2,
- (3 << 14) | (1 << 12) | (599 << 0),
- (0 << 25) | 0,
- 20199727,
- 12000000,
-};
-
-static int dib8090_get_adc_power(struct dvb_frontend *fe)
-{
- return dib8000_get_adc_power(fe, 1);
-}
-
-static struct dib8000_config dib809x_dib8000_config = {
- .output_mpeg2_in_188_bytes = 1,
-
- .agc_config_count = 2,
- .agc = dib8090_agc_config,
- .agc_control = dib0090_dcc_freq,
- .pll = &dib8090_pll_config_12mhz,
- .tuner_is_baseband = 1,
-
- .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
- .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
- .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
-
- .hostbus_diversity = 1,
- .div_cfg = 0x31,
- .output_mode = OUTMODE_MPEG2_FIFO,
- .drives = 0x2d98,
- .diversity_delay = 144,
- .refclksel = 3,
-};
-
-static struct dib0090_config dib809x_dib0090_config = {
- .io.pll_bypass = 1,
- .io.pll_range = 1,
- .io.pll_prediv = 1,
- .io.pll_loopdiv = 20,
- .io.adc_clock_ratio = 8,
- .io.pll_int_loop_filt = 0,
- .io.clock_khz = 12000,
- .reset = dib80xx_tuner_reset,
- .sleep = dib80xx_tuner_sleep,
- .clkouttobamse = 1,
- .analog_output = 1,
- .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
- .wbd_vhf_offset = 100,
- .wbd_cband_offset = 450,
- .use_pwm_agc = 1,
- .clkoutdrive = 1,
- .get_adc_power = dib8090_get_adc_power,
- .freq_offset_khz_uhf = 0,
- .freq_offset_khz_vhf = -143,
-};
-
-static int dib8096_set_param_override(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *fep)
-{
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct dib0700_adapter_state *state = adap->priv;
- u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
- u16 offset;
- int ret = 0;
- enum frontend_tune_state tune_state = CT_SHUTDOWN;
- u16 ltgain, rf_gain_limit;
-
- ret = state->set_param_save(fe, fep);
- if (ret < 0)
- return ret;
-
- switch (band) {
- case BAND_VHF:
- offset = 100;
- break;
- case BAND_UHF:
- offset = 550;
- break;
- default:
- offset = 0;
- break;
- }
- offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
- dib8000_set_wbd_ref(fe, offset);
-
-
- if (band == BAND_CBAND) {
- deb_info("tuning in CBAND - soft-AGC startup\n");
- /* TODO specific wbd target for dib0090 - needed for startup ? */
- dib0090_set_tune_state(fe, CT_AGC_START);
- do {
- ret = dib0090_gain_control(fe);
- msleep(ret);
- tune_state = dib0090_get_tune_state(fe);
- if (tune_state == CT_AGC_STEP_0)
- dib8000_set_gpio(fe, 6, 0, 1);
- else if (tune_state == CT_AGC_STEP_1) {
- dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain);
- if (rf_gain_limit == 0)
- dib8000_set_gpio(fe, 6, 0, 0);
- }
- } while (tune_state < CT_AGC_STOP);
- dib0090_pwm_gain_reset(fe);
- dib8000_pwm_agc_reset(fe);
- dib8000_set_tune_state(fe, CT_DEMOD_START);
- } else {
- deb_info("not tuning in CBAND - standard AGC startup\n");
- dib0090_pwm_gain_reset(fe);
- }
-
- return 0;
-}
-
-static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
-{
- struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
-
- if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
- return -ENODEV;
-
- st->set_param_save = adap->fe->ops.tuner_ops.set_params;
- adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
- return 0;
-}
-
-static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
-{
- dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
- msleep(10);
- dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
- dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
- dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-
- dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
- dib0700_ctrl_clock(adap->dev, 72, 1);
-
- msleep(10);
- dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
- msleep(10);
- dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
-
- adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config);
-
- return adap->fe == NULL ? -ENODEV : 0;
-}
/* STK7070PD */
static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
@@ -2176,17 +1929,14 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) },
/* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) },
- { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV73ESE) },
- { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV282E) },
+ { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
+ { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) },
/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
{ USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
{ USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
-/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
- { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
- { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -2488,11 +2238,11 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ NULL },
},
{ "Pinnacle PCTV 73e SE",
- { &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
+ { &dib0700_usb_id_table[57], NULL },
{ NULL },
},
{ "Pinnacle PCTV 282e",
- { &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL },
+ { &dib0700_usb_id_table[58], NULL },
{ NULL },
},
},
@@ -2721,8 +2471,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.pid_filter_count = 32,
- .pid_filter = stk80xx_pid_filter,
- .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+ .pid_filter = stk807x_pid_filter,
+ .pid_filter_ctrl = stk807x_pid_filter_ctrl,
.frontend_attach = stk807x_frontend_attach,
.tuner_attach = dib807x_tuner_attach,
@@ -2760,8 +2510,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.pid_filter_count = 32,
- .pid_filter = stk80xx_pid_filter,
- .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+ .pid_filter = stk807x_pid_filter,
+ .pid_filter_ctrl = stk807x_pid_filter_ctrl,
.frontend_attach = stk807xpvr_frontend_attach0,
.tuner_attach = dib807x_tuner_attach,
@@ -2773,8 +2523,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.pid_filter_count = 32,
- .pid_filter = stk80xx_pid_filter,
- .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+ .pid_filter = stk807x_pid_filter,
+ .pid_filter_ctrl = stk807x_pid_filter_ctrl,
.frontend_attach = stk807xpvr_frontend_attach1,
.tuner_attach = dib807x_tuner_attach,
@@ -2793,37 +2543,6 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = dib0700_rc_keys,
- .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
- .rc_query = dib0700_rc_query
- }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
- .num_adapters = 1,
- .adapter = {
- {
- .caps = DVB_USB_ADAP_HAS_PID_FILTER |
- DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
- .pid_filter_count = 32,
- .pid_filter = stk80xx_pid_filter,
- .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
- .frontend_attach = stk809x_frontend_attach,
- .tuner_attach = dib809x_tuner_attach,
-
- DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-
- .size_of_priv =
- sizeof(struct dib0700_adapter_state),
- },
- },
-
- .num_device_descs = 1,
- .devices = {
- { "DiBcom STK8096GP reference design",
- { &dib0700_usb_id_table[67], NULL },
- { NULL },
- },
- },
-
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dib0700_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
diff --git a/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c b/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c
index 9143b5631e88..da34979b5337 100644
--- a/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -142,13 +142,8 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
} else if ((msg[i].flags & I2C_M_RD) == 0) {
if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
break;
- } else if (msg[i].addr != 0x50) {
- /* 0x50 is the address of the eeprom - we need to protect it
- * from dibusb's bad i2c implementation: reads without
- * writing the offset before are forbidden */
- if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
- break;
- }
+ } else
+ break;
}
mutex_unlock(&d->i2c_mutex);
@@ -248,12 +243,6 @@ static struct dib3000mc_config mod3000p_dib3000p_config = {
int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
{
- if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON &&
- adap->dev->udev->descriptor.idProduct ==
- USB_PID_LITEON_DVB_T_WARM) {
- msleep(1000);
- }
-
if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL ||
(adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) {
if (adap->priv != NULL) {
diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index bc3581d58ced..f1602d4ace6d 100644
--- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -47,7 +47,6 @@
#define USB_VID_MSI_2 0x1462
#define USB_VID_OPERA1 0x695c
#define USB_VID_PINNACLE 0x2304
-#define USB_VID_PCTV 0x2013
#define USB_VID_PIXELVIEW 0x1554
#define USB_VID_TECHNOTREND 0x0b48
#define USB_VID_TERRATEC 0x0ccd
@@ -102,7 +101,6 @@
#define USB_PID_DIBCOM_STK7070PD 0x1ebe
#define USB_PID_DIBCOM_STK807XP 0x1f90
#define USB_PID_DIBCOM_STK807XPVR 0x1f98
-#define USB_PID_DIBCOM_STK8096GP 0x1fa0
#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
#define USB_PID_DIBCOM_STK7770P 0x1e80
#define USB_PID_DPOSH_M9206_COLD 0x9206
@@ -213,7 +211,6 @@
#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
#define USB_PID_PINNACLE_PCTV73A 0x0243
#define USB_PID_PINNACLE_PCTV73ESE 0x0245
-#define USB_PID_PINNACLE_PCTV74E 0x0246
#define USB_PID_PINNACLE_PCTV282E 0x0248
#define USB_PID_PIXELVIEW_SBTVD 0x5010
#define USB_PID_PCTV_200E 0x020e
diff --git a/trunk/drivers/media/dvb/dvb-usb/dw2102.c b/trunk/drivers/media/dvb/dvb-usb/dw2102.c
index 64132c0cf80d..5bb9479d154e 100644
--- a/trunk/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/trunk/drivers/media/dvb/dvb-usb/dw2102.c
@@ -20,11 +20,6 @@
#include "tda1002x.h"
#include "mt312.h"
#include "zl10039.h"
-#include "ds3000.h"
-#include "stv0900.h"
-#include "stv6110.h"
-#include "stb6100.h"
-#include "stb6100_proc.h"
#ifndef USB_PID_DW2102
#define USB_PID_DW2102 0x2102
@@ -42,20 +37,12 @@
#define USB_PID_CINERGY_S 0x0064
#endif
-#ifndef USB_PID_TEVII_S630
-#define USB_PID_TEVII_S630 0xd630
-#endif
-
#ifndef USB_PID_TEVII_S650
#define USB_PID_TEVII_S650 0xd650
#endif
-#ifndef USB_PID_TEVII_S660
-#define USB_PID_TEVII_S660 0xd660
-#endif
-
-#ifndef USB_PID_PROF_1100
-#define USB_PID_PROF_1100 0xb012
+#ifndef USB_PID_TEVII_S630
+#define USB_PID_TEVII_S630 0xd630
#endif
#define DW210X_READ_MSG 0
@@ -68,10 +55,6 @@
#define DW2102_VOLTAGE_CTRL (0x1800)
#define DW2102_RC_QUERY (0x1a00)
-#define err_str "did not find the firmware file. (%s) " \
- "Please see linux/Documentation/dvb/ for more details " \
- "on firmware-problems."
-
struct dvb_usb_rc_keys_table {
struct dvb_usb_rc_key *rc_keys;
int rc_keys_size;
@@ -88,12 +71,6 @@ static int ir_keymap;
module_param_named(keymap, ir_keymap, int, 0644);
MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ...");
-/* demod probe */
-static int demod_probe = 1;
-module_param_named(demod, demod_probe, int, 0644);
-MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
- "4=stv0903+stb6100(or-able)).");
-
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
@@ -206,7 +183,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
switch (num) {
case 2:
/* read si2109 register by number */
- buf6[0] = msg[0].addr << 1;
+ buf6[0] = 0xd0;
buf6[1] = msg[0].len;
buf6[2] = msg[0].buf[0];
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -221,7 +198,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
switch (msg[0].addr) {
case 0x68:
/* write to si2109 register */
- buf6[0] = msg[0].addr << 1;
+ buf6[0] = 0xd0;
buf6[1] = msg[0].len;
memcpy(buf6 + 2, msg[0].buf, msg[0].len);
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
@@ -262,7 +239,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
/* read */
/* first write first register number */
u8 ibuf[msg[1].len + 2], obuf[3];
- obuf[0] = msg[0].addr << 1;
+ obuf[0] = 0xd0;
obuf[1] = msg[0].len;
obuf[2] = msg[0].buf[0];
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -279,7 +256,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
case 0x68: {
/* write to register */
u8 obuf[msg[0].len + 2];
- obuf[0] = msg[0].addr << 1;
+ obuf[0] = 0xd0;
obuf[1] = msg[0].len;
memcpy(obuf + 2, msg[0].buf, msg[0].len);
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -289,7 +266,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
case 0x61: {
/* write to tuner */
u8 obuf[msg[0].len + 2];
- obuf[0] = msg[0].addr << 1;
+ obuf[0] = 0xc2;
obuf[1] = msg[0].len;
memcpy(obuf + 2, msg[0].buf, msg[0].len);
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -324,78 +301,78 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int ret = 0;
- int len, i, j;
+ int len, i;
if (!d)
return -ENODEV;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
- for (j = 0; j < num; j++) {
- switch (msg[j].addr) {
+ switch (num) {
+ case 2: {
+ /* read */
+ /* first write first register number */
+ u8 ibuf[msg[1].len + 2], obuf[3];
+ obuf[0] = 0xaa;
+ obuf[1] = msg[0].len;
+ obuf[2] = msg[0].buf[0];
+ ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
+ obuf, msg[0].len + 2, DW210X_WRITE_MSG);
+ /* second read registers */
+ ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0,
+ ibuf, msg[1].len + 2, DW210X_READ_MSG);
+ memcpy(msg[1].buf, ibuf + 2, msg[1].len);
+
+ break;
+ }
+ case 1:
+ switch (msg[0].addr) {
+ case 0x55: {
+ if (msg[0].buf[0] == 0xf7) {
+ /* firmware */
+ /* Write in small blocks */
+ u8 obuf[19];
+ obuf[0] = 0xaa;
+ obuf[1] = 0x11;
+ obuf[2] = 0xf7;
+ len = msg[0].len - 1;
+ i = 1;
+ do {
+ memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len));
+ ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
+ obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG);
+ i += 16;
+ len -= 16;
+ } while (len > 0);
+ } else {
+ /* write to register */
+ u8 obuf[msg[0].len + 2];
+ obuf[0] = 0xaa;
+ obuf[1] = msg[0].len;
+ memcpy(obuf + 2, msg[0].buf, msg[0].len);
+ ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
+ obuf, msg[0].len + 2, DW210X_WRITE_MSG);
+ }
+ break;
+ }
case(DW2102_RC_QUERY): {
u8 ibuf[2];
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
ibuf, 2, DW210X_READ_MSG);
- memcpy(msg[j].buf, ibuf , 2);
+ memcpy(msg[0].buf, ibuf , 2);
break;
}
case(DW2102_VOLTAGE_CTRL): {
u8 obuf[2];
obuf[0] = 0x30;
- obuf[1] = msg[j].buf[0];
+ obuf[1] = msg[0].buf[0];
ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
obuf, 2, DW210X_WRITE_MSG);
break;
}
- /*case 0x55: cx24116
- case 0x6a: stv0903
- case 0x68: ds3000, stv0903
- case 0x60: ts2020, stv6110, stb6100 */
- default: {
- if (msg[j].flags == I2C_M_RD) {
- /* read registers */
- u8 ibuf[msg[j].len + 2];
- ret = dw210x_op_rw(d->udev, 0xc3,
- (msg[j].addr << 1) + 1, 0,
- ibuf, msg[j].len + 2,
- DW210X_READ_MSG);
- memcpy(msg[j].buf, ibuf + 2, msg[j].len);
- mdelay(10);
- } else if (((msg[j].buf[0] == 0xb0) &&
- (msg[j].addr == 0x68)) ||
- ((msg[j].buf[0] == 0xf7) &&
- (msg[j].addr == 0x55))) {
- /* write firmware */
- u8 obuf[19];
- obuf[0] = msg[j].addr << 1;
- obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
- obuf[2] = msg[j].buf[0];
- len = msg[j].len - 1;
- i = 1;
- do {
- memcpy(obuf + 3, msg[j].buf + i,
- (len > 16 ? 16 : len));
- ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
- obuf, (len > 16 ? 16 : len) + 3,
- DW210X_WRITE_MSG);
- i += 16;
- len -= 16;
- } while (len > 0);
- } else {
- /* write registers */
- u8 obuf[msg[j].len + 2];
- obuf[0] = msg[j].addr << 1;
- obuf[1] = msg[j].len;
- memcpy(obuf + 2, msg[j].buf, msg[j].len);
- ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
- obuf, msg[j].len + 2,
- DW210X_WRITE_MSG);
- }
- break;
- }
}
+ break;
}
mutex_unlock(&d->i2c_mutex);
@@ -465,85 +442,63 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
return num;
}
-static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int ret = 0;
- int len, i, j;
if (!d)
return -ENODEV;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
- for (j = 0; j < num; j++) {
- switch (msg[j].addr) {
+ switch (num) {
+ case 2: { /* read */
+ u8 ibuf[msg[1].len], obuf[3];
+ obuf[0] = msg[1].len;
+ obuf[1] = (msg[0].addr << 1);
+ obuf[2] = msg[0].buf[0];
+
+ ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
+ obuf, 3, DW210X_WRITE_MSG);
+ msleep(5);
+ ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
+ ibuf, msg[1].len, DW210X_READ_MSG);
+ memcpy(msg[1].buf, ibuf, msg[1].len);
+ break;
+ }
+ case 1:
+ switch (msg[0].addr) {
+ case 0x60:
+ case 0x0e: {
+ /* write to zl10313, zl10039 register, */
+ u8 obuf[msg[0].len + 2];
+ obuf[0] = msg[0].len + 1;
+ obuf[1] = (msg[0].addr << 1);
+ memcpy(obuf + 2, msg[0].buf, msg[0].len);
+ ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
+ obuf, msg[0].len + 2, DW210X_WRITE_MSG);
+ break;
+ }
case (DW2102_RC_QUERY): {
u8 ibuf[4];
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
ibuf, 4, DW210X_READ_MSG);
- memcpy(msg[j].buf, ibuf + 1, 2);
+ msg[0].buf[0] = ibuf[3];
break;
}
case (DW2102_VOLTAGE_CTRL): {
u8 obuf[2];
- obuf[0] = 3;
- obuf[1] = msg[j].buf[0];
+ obuf[0] = 0x03;
+ obuf[1] = msg[0].buf[0];
ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
obuf, 2, DW210X_WRITE_MSG);
break;
}
- /*case 0x55: cx24116
- case 0x6a: stv0903
- case 0x68: ds3000, stv0903
- case 0x60: ts2020, stv6110, stb6100
- case 0xa0: eeprom */
- default: {
- if (msg[j].flags == I2C_M_RD) {
- /* read registers */
- u8 ibuf[msg[j].len];
- ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
- ibuf, msg[j].len,
- DW210X_READ_MSG);
- memcpy(msg[j].buf, ibuf, msg[j].len);
- break;
- } else if ((msg[j].buf[0] == 0xb0) &&
- (msg[j].addr == 0x68)) {
- /* write firmware */
- u8 obuf[19];
- obuf[0] = (msg[j].len > 16 ?
- 18 : msg[j].len + 1);
- obuf[1] = msg[j].addr << 1;
- obuf[2] = msg[j].buf[0];
- len = msg[j].len - 1;
- i = 1;
- do {
- memcpy(obuf + 3, msg[j].buf + i,
- (len > 16 ? 16 : len));
- ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
- obuf, (len > 16 ? 16 : len) + 3,
- DW210X_WRITE_MSG);
- i += 16;
- len -= 16;
- } while (len > 0);
- } else {
- /* write registers */
- u8 obuf[msg[j].len + 2];
- obuf[0] = msg[j].len + 1;
- obuf[1] = (msg[j].addr << 1);
- memcpy(obuf + 2, msg[j].buf, msg[j].len);
- ret = dw210x_op_rw(d->udev,
- (num > 1 ? 0x90 : 0x80), 0, 0,
- obuf, msg[j].len + 2,
- DW210X_WRITE_MSG);
- break;
- }
- break;
- }
}
- msleep(3);
+ break;
}
mutex_unlock(&d->i2c_mutex);
@@ -580,8 +535,8 @@ static struct i2c_algorithm dw3101_i2c_algo = {
.functionality = dw210x_i2c_func,
};
-static struct i2c_algorithm s6x0_i2c_algo = {
- .master_xfer = s6x0_i2c_transfer,
+static struct i2c_algorithm s630_i2c_algo = {
+ .master_xfer = s630_i2c_transfer,
.functionality = dw210x_i2c_func,
};
@@ -609,34 +564,25 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
return 0;
};
-static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
{
int i, ret;
- u8 ibuf[] = { 0 }, obuf[] = { 0 };
- u8 eeprom[256], eepromline[16];
- struct i2c_msg msg[] = {
- {
- .addr = 0xa0 >> 1,
- .flags = 0,
- .buf = obuf,
- .len = 1,
- }, {
- .addr = 0xa0 >> 1,
- .flags = I2C_M_RD,
- .buf = ibuf,
- .len = 1,
- }
- };
+ u8 buf[3], eeprom[256], eepromline[16];
for (i = 0; i < 256; i++) {
- obuf[0] = i;
- ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
- if (ret != 2) {
+ buf[0] = 1;
+ buf[1] = 0xa0;
+ buf[2] = i;
+ ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
+ buf, 3, DW210X_WRITE_MSG);
+ ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
+ buf, 1, DW210X_READ_MSG);
+ if (ret < 0) {
err("read eeprom failed.");
return -1;
} else {
- eepromline[i % 16] = ibuf[0];
- eeprom[i] = ibuf[0];
+ eepromline[i % 16] = buf[0];
+ eeprom[i] = buf[0];
}
if ((i % 16) == 15) {
@@ -698,104 +644,19 @@ static struct mt312_config zl313_config = {
.demod_address = 0x0e,
};
-static struct ds3000_config dw2104_ds3000_config = {
- .demod_address = 0x68,
-};
-
-static struct stv0900_config dw2104a_stv0900_config = {
- .demod_address = 0x6a,
- .demod_mode = 0,
- .xtal = 27000000,
- .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
- .diseqc_mode = 2,/* 2/3 PWM */
- .tun1_maddress = 0,/* 0x60 */
- .tun1_adc = 0,/* 2 Vpp */
- .path1_mode = 3,
-};
-
-static struct stb6100_config dw2104a_stb6100_config = {
- .tuner_address = 0x60,
- .refclock = 27000000,
-};
-
-static struct stv0900_config dw2104_stv0900_config = {
- .demod_address = 0x68,
- .demod_mode = 0,
- .xtal = 8000000,
- .clkmode = 3,
- .diseqc_mode = 2,
- .tun1_maddress = 0,
- .tun1_adc = 1,/* 1 Vpp */
- .path1_mode = 3,
-};
-
-static struct stv6110_config dw2104_stv6110_config = {
- .i2c_address = 0x60,
- .mclk = 16000000,
- .clk_div = 1,
-};
-
static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
{
- struct dvb_tuner_ops *tuner_ops = NULL;
-
- if (demod_probe & 4) {
- d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
- &d->dev->i2c_adap, 0);
- if (d->fe != NULL) {
- if (dvb_attach(stb6100_attach, d->fe,
- &dw2104a_stb6100_config,
- &d->dev->i2c_adap)) {
- tuner_ops = &d->fe->ops.tuner_ops;
- tuner_ops->set_frequency = stb6100_set_freq;
- tuner_ops->get_frequency = stb6100_get_freq;
- tuner_ops->set_bandwidth = stb6100_set_bandw;
- tuner_ops->get_bandwidth = stb6100_get_bandw;
- d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached STV0900+STB6100!\n");
- return 0;
- }
- }
- }
-
- if (demod_probe & 2) {
- d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
- &d->dev->i2c_adap, 0);
- if (d->fe != NULL) {
- if (dvb_attach(stv6110_attach, d->fe,
- &dw2104_stv6110_config,
- &d->dev->i2c_adap)) {
- d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached STV0900+STV6110A!\n");
- return 0;
- }
- }
- }
-
- if (demod_probe & 1) {
- d->fe = dvb_attach(cx24116_attach, &dw2104_config,
- &d->dev->i2c_adap);
- if (d->fe != NULL) {
- d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached cx24116!\n");
- return 0;
- }
- }
-
- d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
- &d->dev->i2c_adap);
- if (d->fe != NULL) {
+ if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
+ &d->dev->i2c_adap)) != NULL) {
d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached DS3000!\n");
+ info("Attached cx24116!\n");
return 0;
}
-
return -EIO;
}
static struct dvb_usb_device_properties dw2102_properties;
static struct dvb_usb_device_properties dw2104_properties;
-static struct dvb_usb_device_properties s6x0_properties;
static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
{
@@ -809,17 +670,14 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
return 0;
}
}
-
if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
+ /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
d->fe = dvb_attach(stv0288_attach, &earda_config,
&d->dev->i2c_adap);
if (d->fe != NULL) {
- if (dvb_attach(stb6000_attach, d->fe, 0x61,
- &d->dev->i2c_adap)) {
- d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached stv0288!\n");
- return 0;
- }
+ d->fe->ops.set_voltage = dw210x_set_voltage;
+ info("Attached stv0288!\n");
+ return 0;
}
}
@@ -847,38 +705,15 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
return -EIO;
}
-static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
+static int s630_frontend_attach(struct dvb_usb_adapter *d)
{
d->fe = dvb_attach(mt312_attach, &zl313_config,
- &d->dev->i2c_adap);
- if (d->fe != NULL) {
- if (dvb_attach(zl10039_attach, d->fe, 0x60,
- &d->dev->i2c_adap)) {
- d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached zl100313+zl10039!\n");
- return 0;
- }
- }
-
- d->fe = dvb_attach(stv0288_attach, &earda_config,
- &d->dev->i2c_adap);
- if (d->fe != NULL) {
- if (dvb_attach(stb6000_attach, d->fe, 0x61,
- &d->dev->i2c_adap)) {
- d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached stv0288+stb6000!\n");
- return 0;
- }
- }
-
- d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
- &d->dev->i2c_adap);
+ &d->dev->i2c_adap);
if (d->fe != NULL) {
d->fe->ops.set_voltage = dw210x_set_voltage;
- info("Attached ds3000+ds2020!\n");
+ info("Attached zl10313!\n");
return 0;
}
-
return -EIO;
}
@@ -889,6 +724,14 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
+static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ dvb_attach(stb6000_attach, adap->fe, 0x61,
+ &adap->dev->i2c_adap);
+
+ return 0;
+}
+
static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
{
dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -897,6 +740,14 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
+static int s630_zl10039_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ dvb_attach(zl10039_attach, adap->fe, 0x60,
+ &adap->dev->i2c_adap);
+
+ return 0;
+}
+
static struct dvb_usb_rc_key dw210x_rc_keys[] = {
{ 0xf80a, KEY_Q }, /*power*/
{ 0xf80c, KEY_M }, /*mute*/
@@ -1071,8 +922,6 @@ static struct usb_device_id dw2102_table[] = {
{USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
{USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
{USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
- {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
- {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
{ }
};
@@ -1086,13 +935,15 @@ static int dw2102_load_firmware(struct usb_device *dev,
u8 reset;
u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
const struct firmware *fw;
- const char *fw_2101 = "dvb-usb-dw2101.fw";
+ const char *filename = "dvb-usb-dw2101.fw";
switch (dev->descriptor.idProduct) {
case 0x2101:
- ret = request_firmware(&fw, fw_2101, &dev->dev);
+ ret = request_firmware(&fw, filename, &dev->dev);
if (ret != 0) {
- err(err_str, fw_2101);
+ err("did not find the firmware file. (%s) "
+ "Please see linux/Documentation/dvb/ for more details "
+ "on firmware-problems.", filename);
return ret;
}
break;
@@ -1132,11 +983,6 @@ static int dw2102_load_firmware(struct usb_device *dev,
}
/* init registers */
switch (dev->descriptor.idProduct) {
- case USB_PID_PROF_1100:
- s6x0_properties.rc_key_map = tbs_rc_keys;
- s6x0_properties.rc_key_map_size =
- ARRAY_SIZE(tbs_rc_keys);
- break;
case USB_PID_TEVII_S650:
dw2104_properties.rc_key_map = tevii_rc_keys;
dw2104_properties.rc_key_map_size =
@@ -1175,6 +1021,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
DW210X_READ_MSG);
if (reset16[2] == 0x11) {
dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
+ dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
break;
}
}
@@ -1337,13 +1184,13 @@ static struct dvb_usb_device_properties dw3101_properties = {
}
};
-static struct dvb_usb_device_properties s6x0_properties = {
+static struct dvb_usb_device_properties s630_properties = {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
.usb_ctrl = DEVICE_SPECIFIC,
.firmware = "dvb-usb-s630.fw",
.no_reconnect = 1,
- .i2c_algo = &s6x0_i2c_algo,
+ .i2c_algo = &s630_i2c_algo,
.rc_key_map = tevii_rc_keys,
.rc_key_map_size = ARRAY_SIZE(tevii_rc_keys),
.rc_interval = 150,
@@ -1352,12 +1199,12 @@ static struct dvb_usb_device_properties s6x0_properties = {
.generic_bulk_ctrl_endpoint = 0x81,
.num_adapters = 1,
.download_firmware = dw2102_load_firmware,
- .read_mac_address = s6x0_read_mac_address,
+ .read_mac_address = s630_read_mac_address,
.adapter = {
{
- .frontend_attach = s6x0_frontend_attach,
+ .frontend_attach = s630_frontend_attach,
.streaming_ctrl = NULL,
- .tuner_attach = NULL,
+ .tuner_attach = s630_zl10039_tuner_attach,
.stream = {
.type = USB_BULK,
.count = 8,
@@ -1370,20 +1217,12 @@ static struct dvb_usb_device_properties s6x0_properties = {
},
}
},
- .num_device_descs = 3,
+ .num_device_descs = 1,
.devices = {
{"TeVii S630 USB",
{&dw2102_table[6], NULL},
{NULL},
},
- {"Prof 1100 USB ",
- {&dw2102_table[7], NULL},
- {NULL},
- },
- {"TeVii S660 USB",
- {&dw2102_table[8], NULL},
- {NULL},
- },
}
};
@@ -1396,10 +1235,10 @@ static int dw2102_probe(struct usb_interface *intf,
THIS_MODULE, NULL, adapter_nr) ||
0 == dvb_usb_device_init(intf, &dw3101_properties,
THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, &s6x0_properties,
- THIS_MODULE, NULL, adapter_nr))
+ 0 == dvb_usb_device_init(intf, &s630_properties,
+ THIS_MODULE, NULL, adapter_nr)) {
return 0;
-
+ }
return -ENODEV;
}
@@ -1430,7 +1269,6 @@ module_exit(dw2102_module_exit);
MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
" DVB-C 3101 USB2.0,"
- " TeVii S600, S630, S650, S660 USB2.0,"
- " Prof 1100 USB2.0 devices");
+ " TeVii S600, S630, S650 USB2.0 devices");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/media/dvb/dvb-usb/friio-fe.c b/trunk/drivers/media/dvb/dvb-usb/friio-fe.c
index ebb7b9fd115b..9cbbe42ca44b 100644
--- a/trunk/drivers/media/dvb/dvb-usb/friio-fe.c
+++ b/trunk/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -134,13 +134,11 @@ static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
state->frontend.ops.info.frequency_stepsize);
/* freq -> oscilator frequency conversion. */
- /* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */
+ /* freq: 473,000,000 + n*6,000,000 (no 1/7MHz shift to center freq) */
+ /* add 400[1/7 MHZ] = 57.142857MHz. 57MHz for the IF, */
+ /* 1/7MHz for center freq shift */
f = freq / state->frontend.ops.info.frequency_stepsize;
- /* add 399[1/7 MHZ] = 57MHz for the IF */
- f += 399;
- /* add center frequency shift if necessary */
- if (f % 7 == 0)
- f++;
+ f += 400;
pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
diff --git a/trunk/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/trunk/drivers/media/dvb/dvb-usb/gp8psk-fe.c
index 7a7f1b2b681c..20eadf9318e0 100644
--- a/trunk/drivers/media/dvb/dvb-usb/gp8psk-fe.c
+++ b/trunk/drivers/media/dvb/dvb-usb/gp8psk-fe.c
@@ -146,8 +146,8 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
switch (c->delivery_system) {
case SYS_DVBS:
- /* Allow QPSK and 8PSK (even for DVB-S) */
- if (c->modulation != QPSK && c->modulation != PSK_8) {
+ /* Only QPSK is supported for DVB-S */
+ if (c->modulation != QPSK) {
deb_fe("%s: unsupported modulation selected (%d)\n",
__func__, c->modulation);
return -EOPNOTSUPP;
diff --git a/trunk/drivers/media/dvb/frontends/Kconfig b/trunk/drivers/media/dvb/frontends/Kconfig
index a3b8b697349b..58aac018f109 100644
--- a/trunk/drivers/media/dvb/frontends/Kconfig
+++ b/trunk/drivers/media/dvb/frontends/Kconfig
@@ -526,15 +526,6 @@ config DVB_TUNER_DIB0070
This device is only used inside a SiP called together with a
demodulator for now.
-config DVB_TUNER_DIB0090
- tristate "DiBcom DiB0090 silicon base-band tuner"
- depends on I2C
- default m if DVB_FE_CUSTOMISE
- help
- A driver for the silicon baseband tuner DiB0090 from DiBcom.
- This device is only used inside a SiP called together with a
- demodulator for now.
-
comment "SEC control devices for DVB-S"
depends on DVB_CORE
diff --git a/trunk/drivers/media/dvb/frontends/Makefile b/trunk/drivers/media/dvb/frontends/Makefile
index 47575cc7b699..823482535d11 100644
--- a/trunk/drivers/media/dvb/frontends/Makefile
+++ b/trunk/drivers/media/dvb/frontends/Makefile
@@ -55,7 +55,6 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o
obj-$(CONFIG_DVB_TDA826X) += tda826x.o
obj-$(CONFIG_DVB_TDA8261) += tda8261.o
obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
-obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o
obj-$(CONFIG_DVB_TUA6100) += tua6100.o
obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
diff --git a/trunk/drivers/media/dvb/frontends/au8522_decoder.c b/trunk/drivers/media/dvb/frontends/au8522_decoder.c
index 24268ef2753d..2dc2723b724a 100644
--- a/trunk/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/trunk/drivers/media/dvb/frontends/au8522_decoder.c
@@ -62,7 +62,7 @@ struct au8522_register_config {
The values are as follows from left to right
0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
*/
-static const struct au8522_register_config filter_coef[] = {
+struct au8522_register_config filter_coef[] = {
{AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
{AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
{AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
@@ -104,7 +104,7 @@ static const struct au8522_register_config filter_coef[] = {
0="SIF" 1="ATVRF/ATVRF13"
Note: the "ATVRF/ATVRF13" mode has never been tested
*/
-static const struct au8522_register_config lpfilter_coef[] = {
+struct au8522_register_config lpfilter_coef[] = {
{0x060b, {0x21, 0x0b} },
{0x060c, {0xad, 0xad} },
{0x060d, {0x70, 0xf0} },
diff --git a/trunk/drivers/media/dvb/frontends/dib0070.c b/trunk/drivers/media/dvb/frontends/dib0070.c
index 0d12763603b4..2be17b93e0bd 100644
--- a/trunk/drivers/media/dvb/frontends/dib0070.c
+++ b/trunk/drivers/media/dvb/frontends/dib0070.c
@@ -49,6 +49,21 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
#define DIB0070_P1G 0x03
#define DIB0070S_P1A 0x02
+enum frontend_tune_state {
+ CT_TUNER_START = 10,
+ CT_TUNER_STEP_0,
+ CT_TUNER_STEP_1,
+ CT_TUNER_STEP_2,
+ CT_TUNER_STEP_3,
+ CT_TUNER_STEP_4,
+ CT_TUNER_STEP_5,
+ CT_TUNER_STEP_6,
+ CT_TUNER_STEP_7,
+ CT_TUNER_STOP,
+};
+
+#define FE_CALLBACK_TIME_NEVER 0xffffffff
+
struct dib0070_state {
struct i2c_adapter *i2c;
struct dvb_frontend *fe;
@@ -56,10 +71,10 @@ struct dib0070_state {
u16 wbd_ff_offset;
u8 revision;
- enum frontend_tune_state tune_state;
- u32 current_rf;
+ enum frontend_tune_state tune_state;
+ u32 current_rf;
- /* for the captrim binary search */
+ /* for the captrim binary search */
s8 step;
u16 adc_diff;
@@ -70,7 +85,7 @@ struct dib0070_state {
const struct dib0070_tuning *current_tune_table_index;
const struct dib0070_lna_match *lna_match;
- u8 wbd_gain_current;
+ u8 wbd_gain_current;
u16 wbd_offset_3_3[2];
};
@@ -78,8 +93,8 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
{
u8 b[2];
struct i2c_msg msg[2] = {
- { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 },
- { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 },
+ {.addr = state->cfg->i2c_address,.flags = 0,.buf = ®,.len = 1},
+ {.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2},
};
if (i2c_transfer(state->i2c, msg, 2) != 2) {
printk(KERN_WARNING "DiB0070 I2C read failed\n");
@@ -91,7 +106,7 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
{
u8 b[3] = { reg, val >> 8, val & 0xff };
- struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
+ struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 };
if (i2c_transfer(state->i2c, &msg, 1) != 1) {
printk(KERN_WARNING "DiB0070 I2C write failed\n");
return -EREMOTEIO;
@@ -109,30 +124,30 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
{
- struct dib0070_state *state = fe->tuner_priv;
- u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
-
- if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000)
- tmp |= (0 << 14);
- else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000)
- tmp |= (1 << 14);
- else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000)
- tmp |= (2 << 14);
- else
- tmp |= (3 << 14);
-
- dib0070_write_reg(state, 0x02, tmp);
-
- /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
- if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
- u16 value = dib0070_read_reg(state, 0x17);
-
- dib0070_write_reg(state, 0x17, value & 0xfffc);
- tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
- dib0070_write_reg(state, 0x01, tmp | (60 << 9));
-
- dib0070_write_reg(state, 0x17, value);
- }
+ struct dib0070_state *state = fe->tuner_priv;
+ u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
+
+ if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000)
+ tmp |= (0 << 14);
+ else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000)
+ tmp |= (1 << 14);
+ else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000)
+ tmp |= (2 << 14);
+ else
+ tmp |= (3 << 14);
+
+ dib0070_write_reg(state, 0x02, tmp);
+
+ /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
+ if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
+ u16 value = dib0070_read_reg(state, 0x17);
+
+ dib0070_write_reg(state, 0x17, value & 0xfffc);
+ tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
+ dib0070_write_reg(state, 0x01, tmp | (60 << 9));
+
+ dib0070_write_reg(state, 0x17, value);
+ }
return 0;
}
@@ -145,14 +160,14 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
if (*tune_state == CT_TUNER_STEP_0) {
dib0070_write_reg(state, 0x0f, 0xed10);
- dib0070_write_reg(state, 0x17, 0x0034);
+ dib0070_write_reg(state, 0x17, 0x0034);
dib0070_write_reg(state, 0x18, 0x0032);
state->step = state->captrim = state->fcaptrim = 64;
state->adc_diff = 3000;
ret = 20;
- *tune_state = CT_TUNER_STEP_1;
+ *tune_state = CT_TUNER_STEP_1;
} else if (*tune_state == CT_TUNER_STEP_1) {
state->step /= 2;
dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
@@ -163,7 +178,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
adc = dib0070_read_reg(state, 0x19);
- dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
+ dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024);
if (adc >= 400) {
adc -= 400;
@@ -178,8 +193,6 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
state->adc_diff = adc;
state->fcaptrim = state->captrim;
-
-
}
state->captrim += (step_sign * state->step);
@@ -200,7 +213,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
{
struct dib0070_state *state = fe->tuner_priv;
- u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
+ u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
dprintk("CTRL_LO5: 0x%x", lo5);
return dib0070_write_reg(state, 0x15, lo5);
}
@@ -214,99 +227,99 @@ void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
dib0070_write_reg(state, 0x1a, 0x0000);
} else {
dib0070_write_reg(state, 0x1b, 0x4112);
- if (state->cfg->vga_filter != 0) {
- dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
- dprintk("vga filter register is set to %x", state->cfg->vga_filter);
- } else
- dib0070_write_reg(state, 0x1a, 0x0009);
+ if (state->cfg->vga_filter != 0) {
+ dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
+ dprintk("vga filter register is set to %x", state->cfg->vga_filter);
+ } else
+ dib0070_write_reg(state, 0x1a, 0x0009);
}
}
EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
struct dib0070_tuning {
- u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
- u8 switch_trim;
- u8 vco_band;
- u8 hfdiv;
- u8 vco_multi;
- u8 presc;
- u8 wbdmux;
- u16 tuner_enable;
+ u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
+ u8 switch_trim;
+ u8 vco_band;
+ u8 hfdiv;
+ u8 vco_multi;
+ u8 presc;
+ u8 wbdmux;
+ u16 tuner_enable;
};
struct dib0070_lna_match {
- u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
- u8 lna_band;
+ u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
+ u8 lna_band;
};
static const struct dib0070_tuning dib0070s_tuning_table[] = {
- { 570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */
- { 700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 },
- { 863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 },
- { 1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */
- { 1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
- { 2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
- { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */
+ {570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800}, /* UHF */
+ {700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800},
+ {863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800},
+ {1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND */
+ {1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
+ {2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
+ {0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000}, /* SBAND */
};
static const struct dib0070_tuning dib0070_tuning_table[] = {
- { 115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */
- { 179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */
- { 189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 },
- { 250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 },
- { 569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800 }, /* UHF */
- { 699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800 },
- { 863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800 },
- { 0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */
+ {115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000}, /* FM below 92MHz cannot be tuned */
+ {179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000}, /* VHF */
+ {189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000},
+ {250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000},
+ {569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800}, /* UHF */
+ {699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800},
+ {863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800},
+ {0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND or everything higher than UHF */
};
static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
- { 180000, 0 }, /* VHF */
- { 188000, 1 },
- { 196400, 2 },
- { 250000, 3 },
- { 550000, 0 }, /* UHF */
- { 590000, 1 },
- { 666000, 3 },
- { 864000, 5 },
- { 1500000, 0 }, /* LBAND or everything higher than UHF */
- { 1600000, 1 },
- { 2000000, 3 },
- { 0xffffffff, 7 },
+ {180000, 0}, /* VHF */
+ {188000, 1},
+ {196400, 2},
+ {250000, 3},
+ {550000, 0}, /* UHF */
+ {590000, 1},
+ {666000, 3},
+ {864000, 5},
+ {1500000, 0}, /* LBAND or everything higher than UHF */
+ {1600000, 1},
+ {2000000, 3},
+ {0xffffffff, 7},
};
static const struct dib0070_lna_match dib0070_lna[] = {
- { 180000, 0 }, /* VHF */
- { 188000, 1 },
- { 196400, 2 },
- { 250000, 3 },
- { 550000, 2 }, /* UHF */
- { 650000, 3 },
- { 750000, 5 },
- { 850000, 6 },
- { 864000, 7 },
- { 1500000, 0 }, /* LBAND or everything higher than UHF */
- { 1600000, 1 },
- { 2000000, 3 },
- { 0xffffffff, 7 },
+ {180000, 0}, /* VHF */
+ {188000, 1},
+ {196400, 2},
+ {250000, 3},
+ {550000, 2}, /* UHF */
+ {650000, 3},
+ {750000, 5},
+ {850000, 6},
+ {864000, 7},
+ {1500000, 0}, /* LBAND or everything higher than UHF */
+ {1600000, 1},
+ {2000000, 3},
+ {0xffffffff, 7},
};
-#define LPF 100
+#define LPF 100 // define for the loop filter 100kHz by default 16-07-06
static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
{
- struct dib0070_state *state = fe->tuner_priv;
+ struct dib0070_state *state = fe->tuner_priv;
- const struct dib0070_tuning *tune;
- const struct dib0070_lna_match *lna_match;
+ const struct dib0070_tuning *tune;
+ const struct dib0070_lna_match *lna_match;
- enum frontend_tune_state *tune_state = &state->tune_state;
- int ret = 10; /* 1ms is the default delay most of the time */
+ enum frontend_tune_state *tune_state = &state->tune_state;
+ int ret = 10; /* 1ms is the default delay most of the time */
- u8 band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000);
- u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
+ u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
+ u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
#ifdef CONFIG_SYS_ISDBT
- if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
+ if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
&& (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
|| (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
@@ -315,180 +328,172 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par
&& (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
freq += 850;
#endif
- if (state->current_rf != freq) {
-
- switch (state->revision) {
- case DIB0070S_P1A:
- tune = dib0070s_tuning_table;
- lna_match = dib0070_lna;
- break;
- default:
- tune = dib0070_tuning_table;
- if (state->cfg->flip_chip)
- lna_match = dib0070_lna_flip_chip;
- else
- lna_match = dib0070_lna;
- break;
- }
- while (freq > tune->max_freq) /* find the right one */
- tune++;
- while (freq > lna_match->max_freq) /* find the right one */
- lna_match++;
-
- state->current_tune_table_index = tune;
- state->lna_match = lna_match;
- }
-
- if (*tune_state == CT_TUNER_START) {
- dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
if (state->current_rf != freq) {
- u8 REFDIV;
- u32 FBDiv, Rest, FREF, VCOF_kHz;
- u8 Den;
-
- state->current_rf = freq;
- state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
-
-
- dib0070_write_reg(state, 0x17, 0x30);
-
-
- VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
-
- switch (band) {
- case BAND_VHF:
- REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
- break;
- case BAND_FM:
- REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
- break;
- default:
- REFDIV = (u8) (state->cfg->clock_khz / 10000);
- break;
- }
- FREF = state->cfg->clock_khz / REFDIV;
-
-
switch (state->revision) {
case DIB0070S_P1A:
- FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
- Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
+ tune = dib0070s_tuning_table;
+ lna_match = dib0070_lna;
break;
-
- case DIB0070_P1G:
- case DIB0070_P1F:
default:
- FBDiv = (freq / (FREF / 2));
- Rest = 2 * freq - FBDiv * FREF;
+ tune = dib0070_tuning_table;
+ if (state->cfg->flip_chip)
+ lna_match = dib0070_lna_flip_chip;
+ else
+ lna_match = dib0070_lna;
break;
}
+ while (freq > tune->max_freq) /* find the right one */
+ tune++;
+ while (freq > lna_match->max_freq) /* find the right one */
+ lna_match++;
- if (Rest < LPF)
- Rest = 0;
- else if (Rest < 2 * LPF)
- Rest = 2 * LPF;
- else if (Rest > (FREF - LPF)) {
- Rest = 0;
- FBDiv += 1;
- } else if (Rest > (FREF - 2 * LPF))
- Rest = FREF - 2 * LPF;
- Rest = (Rest * 6528) / (FREF / 10);
-
- Den = 1;
- if (Rest > 0) {
- state->lo4 |= (1 << 14) | (1 << 12);
- Den = 255;
- }
-
-
- dib0070_write_reg(state, 0x11, (u16)FBDiv);
- dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
- dib0070_write_reg(state, 0x13, (u16) Rest);
-
- if (state->revision == DIB0070S_P1A) {
+ state->current_tune_table_index = tune;
+ state->lna_match = lna_match;
+ }
- if (band == BAND_SBAND) {
- dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
- dib0070_write_reg(state, 0x1d, 0xFFFF);
- } else
- dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
+ if (*tune_state == CT_TUNER_START) {
+ dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
+ if (state->current_rf != freq) {
+ u8 REFDIV;
+ u32 FBDiv, Rest, FREF, VCOF_kHz;
+ u8 Den;
+
+ state->current_rf = freq;
+ state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
+
+ dib0070_write_reg(state, 0x17, 0x30);
+
+ VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
+
+ switch (band) {
+ case BAND_VHF:
+ REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
+ break;
+ case BAND_FM:
+ REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
+ break;
+ default:
+ REFDIV = (u8) (state->cfg->clock_khz / 10000);
+ break;
+ }
+ FREF = state->cfg->clock_khz / REFDIV;
+
+ switch (state->revision) {
+ case DIB0070S_P1A:
+ FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
+ Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
+ break;
+
+ case DIB0070_P1G:
+ case DIB0070_P1F:
+ default:
+ FBDiv = (freq / (FREF / 2));
+ Rest = 2 * freq - FBDiv * FREF;
+ break;
+ }
+
+ if (Rest < LPF)
+ Rest = 0;
+ else if (Rest < 2 * LPF)
+ Rest = 2 * LPF;
+ else if (Rest > (FREF - LPF)) {
+ Rest = 0;
+ FBDiv += 1;
+ } else if (Rest > (FREF - 2 * LPF))
+ Rest = FREF - 2 * LPF;
+ Rest = (Rest * 6528) / (FREF / 10);
+
+ Den = 1;
+ if (Rest > 0) {
+ state->lo4 |= (1 << 14) | (1 << 12);
+ Den = 255;
+ }
+
+ dib0070_write_reg(state, 0x11, (u16) FBDiv);
+ dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
+ dib0070_write_reg(state, 0x13, (u16) Rest);
+
+ if (state->revision == DIB0070S_P1A) {
+
+ if (band == BAND_SBAND) {
+ dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
+ dib0070_write_reg(state, 0x1d, 0xFFFF);
+ } else
+ dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
+ }
+
+ dib0070_write_reg(state, 0x20,
+ 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
+
+ dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
+ dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
+ dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
+ dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
+ dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
+ dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
+
+ *tune_state = CT_TUNER_STEP_0;
+ } else { /* we are already tuned to this frequency - the configuration is correct */
+ ret = 50; /* wakeup time */
+ *tune_state = CT_TUNER_STEP_5;
}
+ } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
- dib0070_write_reg(state, 0x20,
- 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
-
- dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
- dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
- dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
- dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
- dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
- dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
-
- *tune_state = CT_TUNER_STEP_0;
- } else { /* we are already tuned to this frequency - the configuration is correct */
- ret = 50; /* wakeup time */
- *tune_state = CT_TUNER_STEP_5;
- }
- } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
+ ret = dib0070_captrim(state, tune_state);
- ret = dib0070_captrim(state, tune_state);
-
- } else if (*tune_state == CT_TUNER_STEP_4) {
- const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
- if (tmp != NULL) {
- while (freq/1000 > tmp->freq) /* find the right one */
- tmp++;
- dib0070_write_reg(state, 0x0f,
- (0 << 15) | (1 << 14) | (3 << 12)
- | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7)
- | (state->current_tune_table_index->wbdmux << 0));
- state->wbd_gain_current = tmp->wbd_gain_val;
- } else {
+ } else if (*tune_state == CT_TUNER_STEP_4) {
+ const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+ if (tmp != NULL) {
+ while (freq / 1000 > tmp->freq) /* find the right one */
+ tmp++;
+ dib0070_write_reg(state, 0x0f,
+ (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state->
+ current_tune_table_index->
+ wbdmux << 0));
+ state->wbd_gain_current = tmp->wbd_gain_val;
+ } else {
dib0070_write_reg(state, 0x0f,
(0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
wbdmux << 0));
- state->wbd_gain_current = 6;
- }
+ state->wbd_gain_current = 6;
+ }
- dib0070_write_reg(state, 0x06, 0x3fff);
+ dib0070_write_reg(state, 0x06, 0x3fff);
dib0070_write_reg(state, 0x07,
(state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
- dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
- dib0070_write_reg(state, 0x0d, 0x0d80);
-
-
- dib0070_write_reg(state, 0x18, 0x07ff);
- dib0070_write_reg(state, 0x17, 0x0033);
+ dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
+ dib0070_write_reg(state, 0x0d, 0x0d80);
+ dib0070_write_reg(state, 0x18, 0x07ff);
+ dib0070_write_reg(state, 0x17, 0x0033);
- *tune_state = CT_TUNER_STEP_5;
- } else if (*tune_state == CT_TUNER_STEP_5) {
- dib0070_set_bandwidth(fe, ch);
- *tune_state = CT_TUNER_STOP;
- } else {
- ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
- }
- return ret;
+ *tune_state = CT_TUNER_STEP_5;
+ } else if (*tune_state == CT_TUNER_STEP_5) {
+ dib0070_set_bandwidth(fe, ch);
+ *tune_state = CT_TUNER_STOP;
+ } else {
+ ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
+ }
+ return ret;
}
-
static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
{
- struct dib0070_state *state = fe->tuner_priv;
- uint32_t ret;
+ struct dib0070_state *state = fe->tuner_priv;
+ uint32_t ret;
- state->tune_state = CT_TUNER_START;
+ state->tune_state = CT_TUNER_START;
- do {
- ret = dib0070_tune_digital(fe, p);
- if (ret != FE_CALLBACK_TIME_NEVER)
- msleep(ret/10);
- else
- break;
- } while (state->tune_state != CT_TUNER_STOP);
+ do {
+ ret = dib0070_tune_digital(fe, p);
+ if (ret != FE_CALLBACK_TIME_NEVER)
+ msleep(ret / 10);
+ else
+ break;
+ } while (state->tune_state != CT_TUNER_STOP);
- return 0;
+ return 0;
}
static int dib0070_wakeup(struct dvb_frontend *fe)
@@ -507,113 +512,92 @@ static int dib0070_sleep(struct dvb_frontend *fe)
return 0;
}
-u8 dib0070_get_rf_output(struct dvb_frontend *fe)
-{
- struct dib0070_state *state = fe->tuner_priv;
- return (dib0070_read_reg(state, 0x07) >> 11) & 0x3;
-}
-EXPORT_SYMBOL(dib0070_get_rf_output);
-
-int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no)
-{
- struct dib0070_state *state = fe->tuner_priv;
- u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff;
- if (no > 3)
- no = 3;
- if (no < 1)
- no = 1;
- return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11));
-}
-EXPORT_SYMBOL(dib0070_set_rf_output);
-
-static const u16 dib0070_p1f_defaults[] =
-
-{
+static const u16 dib0070_p1f_defaults[] = {
7, 0x02,
- 0x0008,
- 0x0000,
- 0x0000,
- 0x0000,
- 0x0000,
- 0x0002,
- 0x0100,
+ 0x0008,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0002,
+ 0x0100,
3, 0x0d,
- 0x0d80,
- 0x0001,
- 0x0000,
+ 0x0d80,
+ 0x0001,
+ 0x0000,
4, 0x11,
- 0x0000,
- 0x0103,
- 0x0000,
- 0x0000,
+ 0x0000,
+ 0x0103,
+ 0x0000,
+ 0x0000,
3, 0x16,
- 0x0004 | 0x0040,
- 0x0030,
- 0x07ff,
+ 0x0004 | 0x0040,
+ 0x0030,
+ 0x07ff,
6, 0x1b,
- 0x4112,
- 0xff00,
- 0xc07f,
- 0x0000,
- 0x0180,
- 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
+ 0x4112,
+ 0xff00,
+ 0xc07f,
+ 0x0000,
+ 0x0180,
+ 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
0,
};
static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
{
- u16 tuner_en = dib0070_read_reg(state, 0x20);
- u16 offset;
-
- dib0070_write_reg(state, 0x18, 0x07ff);
- dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
- dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
- msleep(9);
- offset = dib0070_read_reg(state, 0x19);
- dib0070_write_reg(state, 0x20, tuner_en);
- return offset;
+ u16 tuner_en = dib0070_read_reg(state, 0x20);
+ u16 offset;
+
+ dib0070_write_reg(state, 0x18, 0x07ff);
+ dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
+ dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
+ msleep(9);
+ offset = dib0070_read_reg(state, 0x19);
+ dib0070_write_reg(state, 0x20, tuner_en);
+ return offset;
}
static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
{
- u8 gain;
- for (gain = 6; gain < 8; gain++) {
- state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
- dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]);
- }
+ u8 gain;
+ for (gain = 6; gain < 8; gain++) {
+ state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
+ dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]);
+ }
}
u16 dib0070_wbd_offset(struct dvb_frontend *fe)
{
- struct dib0070_state *state = fe->tuner_priv;
- const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
- u32 freq = fe->dtv_property_cache.frequency/1000;
-
- if (tmp != NULL) {
- while (freq/1000 > tmp->freq) /* find the right one */
- tmp++;
- state->wbd_gain_current = tmp->wbd_gain_val;
+ struct dib0070_state *state = fe->tuner_priv;
+ const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+ u32 freq = fe->dtv_property_cache.frequency / 1000;
+
+ if (tmp != NULL) {
+ while (freq / 1000 > tmp->freq) /* find the right one */
+ tmp++;
+ state->wbd_gain_current = tmp->wbd_gain_val;
} else
- state->wbd_gain_current = 6;
+ state->wbd_gain_current = 6;
- return state->wbd_offset_3_3[state->wbd_gain_current - 6];
+ return state->wbd_offset_3_3[state->wbd_gain_current - 6];
}
+
EXPORT_SYMBOL(dib0070_wbd_offset);
#define pgm_read_word(w) (*w)
static int dib0070_reset(struct dvb_frontend *fe)
{
- struct dib0070_state *state = fe->tuner_priv;
+ struct dib0070_state *state = fe->tuner_priv;
u16 l, r, *n;
HARD_RESET(state);
-
#ifndef FORCE_SBAND_TUNER
if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
@@ -621,7 +605,7 @@ static int dib0070_reset(struct dvb_frontend *fe)
#else
#warning forcing SBAND
#endif
- state->revision = DIB0070S_P1A;
+ state->revision = DIB0070S_P1A;
/* P1F or not */
dprintk("Revision: %x", state->revision);
@@ -636,7 +620,7 @@ static int dib0070_reset(struct dvb_frontend *fe)
while (l) {
r = pgm_read_word(n++);
do {
- dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
+ dib0070_write_reg(state, (u8) r, pgm_read_word(n++));
r++;
} while (--l);
l = pgm_read_word(n++);
@@ -649,7 +633,6 @@ static int dib0070_reset(struct dvb_frontend *fe)
else
r = 2;
-
r |= state->cfg->osc_buffer_state << 3;
dib0070_write_reg(state, 0x10, r);
@@ -660,24 +643,16 @@ static int dib0070_reset(struct dvb_frontend *fe)
dib0070_write_reg(state, 0x02, r | (1 << 5));
}
- if (state->revision == DIB0070S_P1A)
- dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
- else
+ if (state->revision == DIB0070S_P1A)
+ dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
+ else
dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
- dib0070_wbd_offset_calibration(state);
+ dib0070_wbd_offset_calibration(state);
- return 0;
-}
-
-static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
- struct dib0070_state *state = fe->tuner_priv;
-
- *frequency = 1000 * state->current_rf;
- return 0;
+ return 0;
}
static int dib0070_release(struct dvb_frontend *fe)
@@ -689,18 +664,18 @@ static int dib0070_release(struct dvb_frontend *fe)
static const struct dvb_tuner_ops dib0070_ops = {
.info = {
- .name = "DiBcom DiB0070",
- .frequency_min = 45000000,
- .frequency_max = 860000000,
- .frequency_step = 1000,
- },
- .release = dib0070_release,
-
- .init = dib0070_wakeup,
- .sleep = dib0070_sleep,
- .set_params = dib0070_tune,
-
- .get_frequency = dib0070_get_frequency,
+ .name = "DiBcom DiB0070",
+ .frequency_min = 45000000,
+ .frequency_max = 860000000,
+ .frequency_step = 1000,
+ },
+ .release = dib0070_release,
+
+ .init = dib0070_wakeup,
+ .sleep = dib0070_sleep,
+ .set_params = dib0070_tune,
+
+// .get_frequency = dib0070_get_frequency,
// .get_bandwidth = dib0070_get_bandwidth
};
@@ -712,7 +687,7 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
state->cfg = cfg;
state->i2c = i2c;
- state->fe = fe;
+ state->fe = fe;
fe->tuner_priv = state;
if (dib0070_reset(fe) != 0)
@@ -724,11 +699,12 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
fe->tuner_priv = state;
return fe;
-free_mem:
+ free_mem:
kfree(state);
fe->tuner_priv = NULL;
return NULL;
}
+
EXPORT_SYMBOL(dib0070_attach);
MODULE_AUTHOR("Patrick Boettcher ");
diff --git a/trunk/drivers/media/dvb/frontends/dib0070.h b/trunk/drivers/media/dvb/frontends/dib0070.h
index 45c31fae3967..eec9e52ffa75 100644
--- a/trunk/drivers/media/dvb/frontends/dib0070.h
+++ b/trunk/drivers/media/dvb/frontends/dib0070.h
@@ -52,8 +52,6 @@ struct dib0070_config {
extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
extern u16 dib0070_wbd_offset(struct dvb_frontend *);
extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
-extern u8 dib0070_get_rf_output(struct dvb_frontend *fe);
-extern int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no);
#else
static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
{
@@ -64,7 +62,7 @@ static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struc
static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
+ return -ENODEV;
}
static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
diff --git a/trunk/drivers/media/dvb/frontends/dib0090.c b/trunk/drivers/media/dvb/frontends/dib0090.c
deleted file mode 100644
index 614552709a6f..000000000000
--- a/trunk/drivers/media/dvb/frontends/dib0090.c
+++ /dev/null
@@ -1,1522 +0,0 @@
-/*
- * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
- *
- * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * This code is more or less generated from another driver, please
- * excuse some codingstyle oddities.
- *
- */
-
-#include
-#include
-
-#include "dvb_frontend.h"
-
-#include "dib0090.h"
-#include "dibx000_common.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-
-#define dprintk(args...) do { \
- if (debug) { \
- printk(KERN_DEBUG "DiB0090: "); \
- printk(args); \
- printk("\n"); \
- } \
-} while (0)
-
-#define CONFIG_SYS_ISDBT
-#define CONFIG_BAND_CBAND
-#define CONFIG_BAND_VHF
-#define CONFIG_BAND_UHF
-#define CONFIG_DIB0090_USE_PWM_AGC
-
-#define EN_LNA0 0x8000
-#define EN_LNA1 0x4000
-#define EN_LNA2 0x2000
-#define EN_LNA3 0x1000
-#define EN_MIX0 0x0800
-#define EN_MIX1 0x0400
-#define EN_MIX2 0x0200
-#define EN_MIX3 0x0100
-#define EN_IQADC 0x0040
-#define EN_PLL 0x0020
-#define EN_TX 0x0010
-#define EN_BB 0x0008
-#define EN_LO 0x0004
-#define EN_BIAS 0x0001
-
-#define EN_IQANA 0x0002
-#define EN_DIGCLK 0x0080 /* not in the 0x24 reg, only in 0x1b */
-#define EN_CRYSTAL 0x0002
-
-#define EN_UHF 0x22E9
-#define EN_VHF 0x44E9
-#define EN_LBD 0x11E9
-#define EN_SBD 0x44E9
-#define EN_CAB 0x88E9
-
-#define pgm_read_word(w) (*w)
-
-struct dc_calibration;
-
-struct dib0090_tuning {
- u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
- u8 switch_trim;
- u8 lna_tune;
- u8 lna_bias;
- u16 v2i;
- u16 mix;
- u16 load;
- u16 tuner_enable;
-};
-
-struct dib0090_pll {
- u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
- u8 vco_band;
- u8 hfdiv_code;
- u8 hfdiv;
- u8 topresc;
-};
-
-struct dib0090_state {
- struct i2c_adapter *i2c;
- struct dvb_frontend *fe;
- const struct dib0090_config *config;
-
- u8 current_band;
- u16 revision;
- enum frontend_tune_state tune_state;
- u32 current_rf;
-
- u16 wbd_offset;
- s16 wbd_target; /* in dB */
-
- s16 rf_gain_limit; /* take-over-point: where to split between bb and rf gain */
- s16 current_gain; /* keeps the currently programmed gain */
- u8 agc_step; /* new binary search */
-
- u16 gain[2]; /* for channel monitoring */
-
- const u16 *rf_ramp;
- const u16 *bb_ramp;
-
- /* for the software AGC ramps */
- u16 bb_1_def;
- u16 rf_lt_def;
- u16 gain_reg[4];
-
- /* for the captrim/dc-offset search */
- s8 step;
- s16 adc_diff;
- s16 min_adc_diff;
-
- s8 captrim;
- s8 fcaptrim;
-
- const struct dc_calibration *dc;
- u16 bb6, bb7;
-
- const struct dib0090_tuning *current_tune_table_index;
- const struct dib0090_pll *current_pll_table_index;
-
- u8 tuner_is_tuned;
- u8 agc_freeze;
-
- u8 reset;
-};
-
-static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
-{
- u8 b[2];
- struct i2c_msg msg[2] = {
- {.addr = state->config->i2c_address, .flags = 0, .buf = ®, .len = 1},
- {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2},
- };
- if (i2c_transfer(state->i2c, msg, 2) != 2) {
- printk(KERN_WARNING "DiB0090 I2C read failed\n");
- return 0;
- }
- return (b[0] << 8) | b[1];
-}
-
-static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
-{
- u8 b[3] = { reg & 0xff, val >> 8, val & 0xff };
- struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 };
- if (i2c_transfer(state->i2c, &msg, 1) != 1) {
- printk(KERN_WARNING "DiB0090 I2C write failed\n");
- return -EREMOTEIO;
- }
- return 0;
-}
-
-#define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0)
-#define ADC_TARGET -220
-#define GAIN_ALPHA 5
-#define WBD_ALPHA 6
-#define LPF 100
-static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
-{
- do {
- dib0090_write_reg(state, r++, *b++);
- } while (--c);
-}
-
-static u16 dib0090_identify(struct dvb_frontend *fe)
-{
- struct dib0090_state *state = fe->tuner_priv;
- u16 v;
-
- v = dib0090_read_reg(state, 0x1a);
-
-#ifdef FIRMWARE_FIREFLY
- /* pll is not locked locked */
- if (!(v & 0x800))
- dprintk("FE%d : Identification : pll is not yet locked", fe->id);
-#endif
-
- /* without PLL lock info */
- v &= 0x3ff;
- dprintk("P/V: %04x:", v);
-
- if ((v >> 8) & 0xf)
- dprintk("FE%d : Product ID = 0x%x : KROSUS", fe->id, (v >> 8) & 0xf);
- else
- return 0xff;
-
- v &= 0xff;
- if (((v >> 5) & 0x7) == 0x1)
- dprintk("FE%d : MP001 : 9090/8096", fe->id);
- else if (((v >> 5) & 0x7) == 0x4)
- dprintk("FE%d : MP005 : Single Sband", fe->id);
- else if (((v >> 5) & 0x7) == 0x6)
- dprintk("FE%d : MP008 : diversity VHF-UHF-LBAND", fe->id);
- else if (((v >> 5) & 0x7) == 0x7)
- dprintk("FE%d : MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND", fe->id);
- else
- return 0xff;
-
- /* revision only */
- if ((v & 0x1f) == 0x3)
- dprintk("FE%d : P1-D/E/F detected", fe->id);
- else if ((v & 0x1f) == 0x1)
- dprintk("FE%d : P1C detected", fe->id);
- else if ((v & 0x1f) == 0x0) {
-#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
- dprintk("FE%d : P1-A/B detected: using previous driver - support will be removed soon", fe->id);
- dib0090_p1b_register(fe);
-#else
- dprintk("FE%d : P1-A/B detected: driver is deactivated - not available", fe->id);
- return 0xff;
-#endif
- }
-
- return v;
-}
-
-static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
-{
- struct dib0090_state *state = fe->tuner_priv;
-
- HARD_RESET(state);
-
- dib0090_write_reg(state, 0x24, EN_PLL);
- dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
-
- /* adcClkOutRatio=8->7, release reset */
- dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
- if (cfg->clkoutdrive != 0)
- dib0090_write_reg(state, 0x23,
- (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (cfg->clkoutdrive << 5) | (cfg->
- clkouttobamse
- << 4) | (0
- <<
- 2)
- | (0));
- else
- dib0090_write_reg(state, 0x23,
- (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (7 << 5) | (cfg->
- clkouttobamse << 4) | (0
- <<
- 2)
- | (0));
-
- /* enable pll, de-activate reset, ratio: 2/1 = 60MHz */
- dib0090_write_reg(state, 0x21,
- (cfg->io.pll_bypass << 15) | (1 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv));
-
-}
-
-static int dib0090_wakeup(struct dvb_frontend *fe)
-{
- struct dib0090_state *state = fe->tuner_priv;
- if (state->config->sleep)
- state->config->sleep(fe, 0);
- return 0;
-}
-
-static int dib0090_sleep(struct dvb_frontend *fe)
-{
- struct dib0090_state *state = fe->tuner_priv;
- if (state->config->sleep)
- state->config->sleep(fe, 1);
- return 0;
-}
-
-extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
-{
- struct dib0090_state *state = fe->tuner_priv;
- if (fast)
- dib0090_write_reg(state, 0x04, 0);
- else
- dib0090_write_reg(state, 0x04, 1);
-}
-EXPORT_SYMBOL(dib0090_dcc_freq);
-
-static const u16 rf_ramp_pwm_cband[] = {
- 0, /* max RF gain in 10th of dB */
- 0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
- 0, /* ramp_max = maximum X used on the ramp */
- (0 << 10) | 0, /* 0x2c, LNA 1 = 0dB */
- (0 << 10) | 0, /* 0x2d, LNA 1 */
- (0 << 10) | 0, /* 0x2e, LNA 2 = 0dB */
- (0 << 10) | 0, /* 0x2f, LNA 2 */
- (0 << 10) | 0, /* 0x30, LNA 3 = 0dB */
- (0 << 10) | 0, /* 0x31, LNA 3 */
- (0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
- (0 << 10) | 0, /* GAIN_4_2, LNA 4 */
-};
-
-static const u16 rf_ramp_vhf[] = {
- 412, /* max RF gain in 10th of dB */
- 132, 307, 127, /* LNA1, 13.2dB */
- 105, 412, 255, /* LNA2, 10.5dB */
- 50, 50, 127, /* LNA3, 5dB */
- 125, 175, 127, /* LNA4, 12.5dB */
- 0, 0, 127, /* CBAND, 0dB */
-};
-
-static const u16 rf_ramp_uhf[] = {
- 412, /* max RF gain in 10th of dB */
- 132, 307, 127, /* LNA1 : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */
- 105, 412, 255, /* LNA2 : 10.5 dB */
- 50, 50, 127, /* LNA3 : 5.0 dB */
- 125, 175, 127, /* LNA4 : 12.5 dB */
- 0, 0, 127, /* CBAND : 0.0 dB */
-};
-
-static const u16 rf_ramp_cband[] = {
- 332, /* max RF gain in 10th of dB */
- 132, 252, 127, /* LNA1, dB */
- 80, 332, 255, /* LNA2, dB */
- 0, 0, 127, /* LNA3, dB */
- 0, 0, 127, /* LNA4, dB */
- 120, 120, 127, /* LT1 CBAND */
-};
-
-static const u16 rf_ramp_pwm_vhf[] = {
- 404, /* max RF gain in 10th of dB */
- 25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
- 1011, /* ramp_max = maximum X used on the ramp */
- (6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */
- (0 << 10) | 756, /* 0x2d, LNA 1 */
- (16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */
- (0 << 10) | 1011, /* 0x2f, LNA 2 */
- (16 << 10) | 290, /* 0x30, LNA 3 = 5dB */
- (0 << 10) | 417, /* 0x31, LNA 3 */
- (7 << 10) | 0, /* GAIN_4_1, LNA 4 = 12.5dB */
- (0 << 10) | 290, /* GAIN_4_2, LNA 4 */
-};
-
-static const u16 rf_ramp_pwm_uhf[] = {
- 404, /* max RF gain in 10th of dB */
- 25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
- 1011, /* ramp_max = maximum X used on the ramp */
- (6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */
- (0 << 10) | 756, /* 0x2d, LNA 1 */
- (16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */
- (0 << 10) | 1011, /* 0x2f, LNA 2 */
- (16 << 10) | 0, /* 0x30, LNA 3 = 5dB */
- (0 << 10) | 127, /* 0x31, LNA 3 */
- (7 << 10) | 127, /* GAIN_4_1, LNA 4 = 12.5dB */
- (0 << 10) | 417, /* GAIN_4_2, LNA 4 */
-};
-
-static const u16 bb_ramp_boost[] = {
- 550, /* max BB gain in 10th of dB */
- 260, 260, 26, /* BB1, 26dB */
- 290, 550, 29, /* BB2, 29dB */
-};
-
-static const u16 bb_ramp_pwm_normal[] = {
- 500, /* max RF gain in 10th of dB */
- 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */
- 400,
- (2 << 9) | 0, /* 0x35 = 21dB */
- (0 << 9) | 168, /* 0x36 */
- (2 << 9) | 168, /* 0x37 = 29dB */
- (0 << 9) | 400, /* 0x38 */
-};
-
-struct slope {
- int16_t range;
- int16_t slope;
-};
-static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
-{
- u8 i;
- u16 rest;
- u16 ret = 0;
- for (i = 0; i < num; i++) {
- if (val > slopes[i].range)
- rest = slopes[i].range;
- else
- rest = val;
- ret += (rest * slopes[i].slope) / slopes[i].range;
- val -= rest;
- }
- return ret;
-}
-
-static const struct slope dib0090_wbd_slopes[3] = {
- {66, 120}, /* -64,-52: offset - 65 */
- {600, 170}, /* -52,-35: 65 - 665 */
- {170, 250}, /* -45,-10: 665 - 835 */
-};
-
-static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
-{
- wbd &= 0x3ff;
- if (wbd < state->wbd_offset)
- wbd = 0;
- else
- wbd -= state->wbd_offset;
- /* -64dB is the floor */
- return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
-}
-
-static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
-{
- u16 offset = 250;
-
- /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
-
- if (state->current_band == BAND_VHF)
- offset = 650;
-#ifndef FIRMWARE_FIREFLY
- if (state->current_band == BAND_VHF)
- offset = state->config->wbd_vhf_offset;
- if (state->current_band == BAND_CBAND)
- offset = state->config->wbd_cband_offset;
-#endif
-
- state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
- dprintk("wbd-target: %d dB", (u32) state->wbd_target);
-}
-
-static const int gain_reg_addr[4] = {
- 0x08, 0x0a, 0x0f, 0x01
-};
-
-static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
-{
- u16 rf, bb, ref;
- u16 i, v, gain_reg[4] = { 0 }, gain;
- const u16 *g;
-
- if (top_delta < -511)
- top_delta = -511;
- if (top_delta > 511)
- top_delta = 511;
-
- if (force) {
- top_delta *= (1 << WBD_ALPHA);
- gain_delta *= (1 << GAIN_ALPHA);
- }
-
- if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit)) /* overflow */
- state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
- else
- state->rf_gain_limit += top_delta;
-
- if (state->rf_gain_limit < 0) /*underflow */
- state->rf_gain_limit = 0;
-
- /* use gain as a temporary variable and correct current_gain */
- gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
- if (gain_delta >= ((s16) gain - state->current_gain)) /* overflow */
- state->current_gain = gain;
- else
- state->current_gain += gain_delta;
- /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
- if (state->current_gain < 0)
- state->current_gain = 0;
-
- /* now split total gain to rf and bb gain */
- gain = state->current_gain >> GAIN_ALPHA;
-
- /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
- if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
- rf = state->rf_gain_limit >> WBD_ALPHA;
- bb = gain - rf;
- if (bb > state->bb_ramp[0])
- bb = state->bb_ramp[0];
- } else { /* high signal level -> all gains put on RF */
- rf = gain;
- bb = 0;
- }
-
- state->gain[0] = rf;
- state->gain[1] = bb;
-
- /* software ramp */
- /* Start with RF gains */
- g = state->rf_ramp + 1; /* point on RF LNA1 max gain */
- ref = rf;
- for (i = 0; i < 7; i++) { /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
- if (g[0] == 0 || ref < (g[1] - g[0])) /* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */
- v = 0; /* force the gain to write for the current amp to be null */
- else if (ref >= g[1]) /* Gain to set is higher than the high working point of this amp */
- v = g[2]; /* force this amp to be full gain */
- else /* compute the value to set to this amp because we are somewhere in his range */
- v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
-
- if (i == 0) /* LNA 1 reg mapping */
- gain_reg[0] = v;
- else if (i == 1) /* LNA 2 reg mapping */
- gain_reg[0] |= v << 7;
- else if (i == 2) /* LNA 3 reg mapping */
- gain_reg[1] = v;
- else if (i == 3) /* LNA 4 reg mapping */
- gain_reg[1] |= v << 7;
- else if (i == 4) /* CBAND LNA reg mapping */
- gain_reg[2] = v | state->rf_lt_def;
- else if (i == 5) /* BB gain 1 reg mapping */
- gain_reg[3] = v << 3;
- else if (i == 6) /* BB gain 2 reg mapping */
- gain_reg[3] |= v << 8;
-
- g += 3; /* go to next gain bloc */
-
- /* When RF is finished, start with BB */
- if (i == 4) {
- g = state->bb_ramp + 1; /* point on BB gain 1 max gain */
- ref = bb;
- }
- }
- gain_reg[3] |= state->bb_1_def;
- gain_reg[3] |= ((bb % 10) * 100) / 125;
-
-#ifdef DEBUG_AGC
- dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x", rf, bb, rf + bb,
- gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
-#endif
-
- /* Write the amplifier regs */
- for (i = 0; i < 4; i++) {
- v = gain_reg[i];
- if (force || state->gain_reg[i] != v) {
- state->gain_reg[i] = v;
- dib0090_write_reg(state, gain_reg_addr[i], v);
- }
- }
-}
-
-static void dib0090_set_boost(struct dib0090_state *state, int onoff)
-{
- state->bb_1_def &= 0xdfff;
- state->bb_1_def |= onoff << 13;
-}
-
-static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
-{
- state->rf_ramp = cfg;
-}
-
-static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
-{
- state->rf_ramp = cfg;
-
- dib0090_write_reg(state, 0x2a, 0xffff);
-
- dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
-
- dib0090_write_regs(state, 0x2c, cfg + 3, 6);
- dib0090_write_regs(state, 0x3e, cfg + 9, 2);
-}
-
-static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
-{
- state->bb_ramp = cfg;
- dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
-}
-
-static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
-{
- state->bb_ramp = cfg;
-
- dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
-
- dib0090_write_reg(state, 0x33, 0xffff);
- dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33));
- dib0090_write_regs(state, 0x35, cfg + 3, 4);
-}
-
-void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
-{
- struct dib0090_state *state = fe->tuner_priv;
- /* reset the AGC */
-
- if (state->config->use_pwm_agc) {
-#ifdef CONFIG_BAND_SBAND
- if (state->current_band == BAND_SBAND) {
- dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband);
- dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost);
- } else
-#endif
-#ifdef CONFIG_BAND_CBAND
- if (state->current_band == BAND_CBAND) {
- dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
- dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
- } else
-#endif
-#ifdef CONFIG_BAND_VHF
- if (state->current_band == BAND_VHF) {
- dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
- dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
- } else
-#endif
- {
- dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
- dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
- }
-
- if (state->rf_ramp[0] != 0)
- dib0090_write_reg(state, 0x32, (3 << 11));
- else
- dib0090_write_reg(state, 0x32, (0 << 11));
-
- dib0090_write_reg(state, 0x39, (1 << 10));
- }
-}
-EXPORT_SYMBOL(dib0090_pwm_gain_reset);
-
-int dib0090_gain_control(struct dvb_frontend *fe)
-{
- struct dib0090_state *state = fe->tuner_priv;
- enum frontend_tune_state *tune_state = &state->tune_state;
- int ret = 10;
-
- u16 wbd_val = 0;
- u8 apply_gain_immediatly = 1;
- s16 wbd_error = 0, adc_error = 0;
-
- if (*tune_state == CT_AGC_START) {
- state->agc_freeze = 0;
- dib0090_write_reg(state, 0x04, 0x0);
-
-#ifdef CONFIG_BAND_SBAND
- if (state->current_band == BAND_SBAND) {
- dib0090_set_rframp(state, rf_ramp_sband);
- dib0090_set_bbramp(state, bb_ramp_boost);
- } else
-#endif
-#ifdef CONFIG_BAND_VHF
- if (state->current_band == BAND_VHF) {
- dib0090_set_rframp(state, rf_ramp_vhf);
- dib0090_set_bbramp(state, bb_ramp_boost);
- } else
-#endif
-#ifdef CONFIG_BAND_CBAND
- if (state->current_band == BAND_CBAND) {
- dib0090_set_rframp(state, rf_ramp_cband);
- dib0090_set_bbramp(state, bb_ramp_boost);
- } else
-#endif
- {
- dib0090_set_rframp(state, rf_ramp_uhf);
- dib0090_set_bbramp(state, bb_ramp_boost);
- }
-
- dib0090_write_reg(state, 0x32, 0);
- dib0090_write_reg(state, 0x39, 0);
-
- dib0090_wbd_target(state, state->current_rf);
-
- state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
- state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
-
- *tune_state = CT_AGC_STEP_0;
- } else if (!state->agc_freeze) {
- s16 wbd;
-
- int adc;
- wbd_val = dib0090_read_reg(state, 0x1d);
-
- /* read and calc the wbd power */
- wbd = dib0090_wbd_to_db(state, wbd_val);
- wbd_error = state->wbd_target - wbd;
-
- if (*tune_state == CT_AGC_STEP_0) {
- if (wbd_error < 0 && state->rf_gain_limit > 0) {
-#ifdef CONFIG_BAND_CBAND
- /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
- u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
- if (state->current_band == BAND_CBAND && ltg2) {
- ltg2 >>= 1;
- state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */
- }
-#endif
- } else {
- state->agc_step = 0;
- *tune_state = CT_AGC_STEP_1;
- }
- } else {
- /* calc the adc power */
- adc = state->config->get_adc_power(fe);
- adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */
-
- adc_error = (s16) (((s32) ADC_TARGET) - adc);
-#ifdef CONFIG_STANDARD_DAB
- if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
- adc_error += 130;
-#endif
-#ifdef CONFIG_STANDARD_DVBT
- if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
- (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
- adc_error += 60;
-#endif
-#ifdef CONFIG_SYS_ISDBT
- if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
- 0)
- &&
- ((state->fe->dtv_property_cache.layer[0].modulation ==
- QAM_64)
- || (state->fe->dtv_property_cache.layer[0].
- modulation == QAM_16)))
- ||
- ((state->fe->dtv_property_cache.layer[1].segment_count >
- 0)
- &&
- ((state->fe->dtv_property_cache.layer[1].modulation ==
- QAM_64)
- || (state->fe->dtv_property_cache.layer[1].
- modulation == QAM_16)))
- ||
- ((state->fe->dtv_property_cache.layer[2].segment_count >
- 0)
- &&
- ((state->fe->dtv_property_cache.layer[2].modulation ==
- QAM_64)
- || (state->fe->dtv_property_cache.layer[2].
- modulation == QAM_16)))
- )
- )
- adc_error += 60;
-#endif
-
- if (*tune_state == CT_AGC_STEP_1) { /* quickly go to the correct range of the ADC power */
- if (ABS(adc_error) < 50 || state->agc_step++ > 5) {
-
-#ifdef CONFIG_STANDARD_DAB
- if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
- dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63)); /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
- dib0090_write_reg(state, 0x04, 0x0);
- } else
-#endif
- {
- dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
- dib0090_write_reg(state, 0x04, 0x01); /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
- }
-
- *tune_state = CT_AGC_STOP;
- }
- } else {
- /* everything higher than or equal to CT_AGC_STOP means tracking */
- ret = 100; /* 10ms interval */
- apply_gain_immediatly = 0;
- }
- }
-#ifdef DEBUG_AGC
- dprintk
- ("FE: %d, tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
- (u32) fe->id, (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
- (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
-#endif
- }
-
- /* apply gain */
- if (!state->agc_freeze)
- dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
- return ret;
-}
-EXPORT_SYMBOL(dib0090_gain_control);
-
-void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
-{
- struct dib0090_state *state = fe->tuner_priv;
- if (rf)
- *rf = state->gain[0];
- if (bb)
- *bb = state->gain[1];
- if (rf_gain_limit)
- *rf_gain_limit = state->rf_gain_limit;
- if (rflt)
- *rflt = (state->rf_lt_def >> 10) & 0x7;
-}
-EXPORT_SYMBOL(dib0090_get_current_gain);
-
-u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner)
-{
- struct dib0090_state *st = tuner->tuner_priv;
- return st->wbd_offset;
-}
-EXPORT_SYMBOL(dib0090_get_wbd_offset);
-
-static const u16 dib0090_defaults[] = {
-
- 25, 0x01,
- 0x0000,
- 0x99a0,
- 0x6008,
- 0x0000,
- 0x8acb,
- 0x0000,
- 0x0405,
- 0x0000,
- 0x0000,
- 0x0000,
- 0xb802,
- 0x0300,
- 0x2d12,
- 0xbac0,
- 0x7c00,
- 0xdbb9,
- 0x0954,
- 0x0743,
- 0x8000,
- 0x0001,
- 0x0040,
- 0x0100,
- 0x0000,
- 0xe910,
- 0x149e,
-
- 1, 0x1c,
- 0xff2d,
-
- 1, 0x39,
- 0x0000,
-
- 1, 0x1b,
- EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL,
- 2, 0x1e,
- 0x07FF,
- 0x0007,
-
- 1, 0x24,
- EN_UHF | EN_CRYSTAL,
-
- 2, 0x3c,
- 0x3ff,
- 0x111,
- 0
-};
-
-static int dib0090_reset(struct dvb_frontend *fe)
-{
- struct dib0090_state *state = fe->tuner_priv;
- u16 l, r, *n;
-
- dib0090_reset_digital(fe, state->config);
- state->revision = dib0090_identify(fe);
-
- /* Revision definition */
- if (state->revision == 0xff)
- return -EINVAL;
-#ifdef EFUSE
- else if ((state->revision & 0x1f) >= 3) /* Update the efuse : Only available for KROSUS > P1C */
- dib0090_set_EFUSE(state);
-#endif
-
-#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
- if (!(state->revision & 0x1)) /* it is P1B - reset is already done */
- return 0;
-#endif
-
- /* Upload the default values */
- n = (u16 *) dib0090_defaults;
- l = pgm_read_word(n++);
- while (l) {
- r = pgm_read_word(n++);
- do {
- /* DEBUG_TUNER */
- /* dprintk("%d, %d, %d", l, r, pgm_read_word(n)); */
- dib0090_write_reg(state, r, pgm_read_word(n++));
- r++;
- } while (--l);
- l = pgm_read_word(n++);
- }
-
- /* Congigure in function of the crystal */
- if (state->config->io.clock_khz >= 24000)
- l = 1;
- else
- l = 2;
- dib0090_write_reg(state, 0x14, l);
- dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
-
- state->reset = 3; /* enable iq-offset-calibration and wbd-calibration when tuning next time */
-
- return 0;
-}
-
-#define steps(u) (((u) > 15) ? ((u)-16) : (u))
-#define INTERN_WAIT 10
-static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
-{
- int ret = INTERN_WAIT * 10;
-
- switch (*tune_state) {
- case CT_TUNER_STEP_2:
- /* Turns to positive */
- dib0090_write_reg(state, 0x1f, 0x7);
- *tune_state = CT_TUNER_STEP_3;
- break;
-
- case CT_TUNER_STEP_3:
- state->adc_diff = dib0090_read_reg(state, 0x1d);
-
- /* Turns to negative */
- dib0090_write_reg(state, 0x1f, 0x4);
- *tune_state = CT_TUNER_STEP_4;
- break;
-
- case CT_TUNER_STEP_4:
- state->adc_diff -= dib0090_read_reg(state, 0x1d);
- *tune_state = CT_TUNER_STEP_5;
- ret = 0;
- break;
-
- default:
- break;
- }
-
- return ret;
-}
-
-struct dc_calibration {
- uint8_t addr;
- uint8_t offset;
- uint8_t pga:1;
- uint16_t bb1;
- uint8_t i:1;
-};
-
-static const struct dc_calibration dc_table[] = {
- /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
- {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
- {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
- /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
- {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
- {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
- {0},
-};
-
-static void dib0090_set_trim(struct dib0090_state *state)
-{
- u16 *val;
-
- if (state->dc->addr == 0x07)
- val = &state->bb7;
- else
- val = &state->bb6;
-
- *val &= ~(0x1f << state->dc->offset);
- *val |= state->step << state->dc->offset;
-
- dib0090_write_reg(state, state->dc->addr, *val);
-}
-
-static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
-{
- int ret = 0;
-
- switch (*tune_state) {
-
- case CT_TUNER_START:
- /* init */
- dprintk("Internal DC calibration");
-
- /* the LNA is off */
- dib0090_write_reg(state, 0x24, 0x02ed);
-
- /* force vcm2 = 0.8V */
- state->bb6 = 0;
- state->bb7 = 0x040d;
-
- state->dc = dc_table;
-
- *tune_state = CT_TUNER_STEP_0;
-
- /* fall through */
-
- case CT_TUNER_STEP_0:
- dib0090_write_reg(state, 0x01, state->dc->bb1);
- dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
-
- state->step = 0;
-
- state->min_adc_diff = 1023;
-
- *tune_state = CT_TUNER_STEP_1;
- ret = 50;
- break;
-
- case CT_TUNER_STEP_1:
- dib0090_set_trim(state);
-
- *tune_state = CT_TUNER_STEP_2;
- break;
-
- case CT_TUNER_STEP_2:
- case CT_TUNER_STEP_3:
- case CT_TUNER_STEP_4:
- ret = dib0090_get_offset(state, tune_state);
- break;
-
- case CT_TUNER_STEP_5: /* found an offset */
- dprintk("FE%d: IQC read=%d, current=%x", state->fe->id, (u32) state->adc_diff, state->step);
-
- /* first turn for this frequency */
- if (state->step == 0) {
- if (state->dc->pga && state->adc_diff < 0)
- state->step = 0x10;
- if (state->dc->pga == 0 && state->adc_diff > 0)
- state->step = 0x10;
- }
-
- state->adc_diff = ABS(state->adc_diff);
-
- if (state->adc_diff < state->min_adc_diff && steps(state->step) < 15) { /* stop search when the delta to 0 is increasing */
- state->step++;
- state->min_adc_diff = state->adc_diff;
- *tune_state = CT_TUNER_STEP_1;
- } else {
-
- /* the minimum was what we have seen in the step before */
- state->step--;
- dib0090_set_trim(state);
-
- dprintk("FE%d: BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->fe->id, state->dc->addr, state->adc_diff,
- state->step);
-
- state->dc++;
- if (state->dc->addr == 0) /* done */
- *tune_state = CT_TUNER_STEP_6;
- else
- *tune_state = CT_TUNER_STEP_0;
-
- }
- break;
-
- case CT_TUNER_STEP_6:
- dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
- dib0090_write_reg(state, 0x1f, 0x7);
- *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */
- state->reset &= ~0x1;
- default:
- break;
- }
- return ret;
-}
-
-static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
-{
- switch (*tune_state) {
- case CT_TUNER_START:
- /* WBD-mode=log, Bias=2, Gain=6, Testmode=1, en=1, WBDMUX=1 */
- dib0090_write_reg(state, 0x10, 0xdb09 | (1 << 10));
- dib0090_write_reg(state, 0x24, EN_UHF & 0x0fff);
-
- *tune_state = CT_TUNER_STEP_0;
- return 90; /* wait for the WBDMUX to switch and for the ADC to sample */
- case CT_TUNER_STEP_0:
- state->wbd_offset = dib0090_read_reg(state, 0x1d);
- dprintk("WBD calibration offset = %d", state->wbd_offset);
-
- *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */
- state->reset &= ~0x2;
- break;
- default:
- break;
- }
- return 0;
-}
-
-static void dib0090_set_bandwidth(struct dib0090_state *state)
-{
- u16 tmp;
-
- if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
- tmp = (3 << 14);
- else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
- tmp = (2 << 14);
- else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
- tmp = (1 << 14);
- else
- tmp = (0 << 14);
-
- state->bb_1_def &= 0x3fff;
- state->bb_1_def |= tmp;
-
- dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */
-}
-
-static const struct dib0090_pll dib0090_pll_table[] = {
-#ifdef CONFIG_BAND_CBAND
- {56000, 0, 9, 48, 6},
- {70000, 1, 9, 48, 6},
- {87000, 0, 8, 32, 4},
- {105000, 1, 8, 32, 4},
- {115000, 0, 7, 24, 6},
- {140000, 1, 7, 24, 6},
- {170000, 0, 6, 16, 4},
-#endif
-#ifdef CONFIG_BAND_VHF
- {200000, 1, 6, 16, 4},
- {230000, 0, 5, 12, 6},
- {280000, 1, 5, 12, 6},
- {340000, 0, 4, 8, 4},
- {380000, 1, 4, 8, 4},
- {450000, 0, 3, 6, 6},
-#endif
-#ifdef CONFIG_BAND_UHF
- {580000, 1, 3, 6, 6},
- {700000, 0, 2, 4, 4},
- {860000, 1, 2, 4, 4},
-#endif
-#ifdef CONFIG_BAND_LBAND
- {1800000, 1, 0, 2, 4},
-#endif
-#ifdef CONFIG_BAND_SBAND
- {2900000, 0, 14, 1, 4},
-#endif
-};
-
-static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
-
-#ifdef CONFIG_BAND_CBAND
- {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
- {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
- {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
-#endif
-#ifdef CONFIG_BAND_UHF
- {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
- {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
- {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
- {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
- {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
- {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-#endif
-#ifdef CONFIG_BAND_LBAND
- {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
- {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
- {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-#endif
-#ifdef CONFIG_BAND_SBAND
- {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
- {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
-#endif
-};
-
-static const struct dib0090_tuning dib0090_tuning_table[] = {
-
-#ifdef CONFIG_BAND_CBAND
- {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
-#endif
-#ifdef CONFIG_BAND_VHF
- {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
- {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
- {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
-#endif
-#ifdef CONFIG_BAND_UHF
- {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
- {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
- {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
- {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
- {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
- {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-#endif
-#ifdef CONFIG_BAND_LBAND
- {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
- {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
- {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-#endif
-#ifdef CONFIG_BAND_SBAND
- {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
- {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
-#endif
-};
-
-#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */
-static int dib0090_tune(struct dvb_frontend *fe)
-{
- struct dib0090_state *state = fe->tuner_priv;
- const struct dib0090_tuning *tune = state->current_tune_table_index;
- const struct dib0090_pll *pll = state->current_pll_table_index;
- enum frontend_tune_state *tune_state = &state->tune_state;
-
- u32 rf;
- u16 lo4 = 0xe900, lo5, lo6, Den;
- u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
- u16 tmp, adc;
- int8_t step_sign;
- int ret = 10; /* 1ms is the default delay most of the time */
- u8 c, i;
-
- state->current_band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
- rf = fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
- BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->freq_offset_khz_vhf);
- /* in any case we first need to do a reset if needed */
- if (state->reset & 0x1)
- return dib0090_dc_offset_calibration(state, tune_state);
- else if (state->reset & 0x2)
- return dib0090_wbd_calibration(state, tune_state);
-
- /************************* VCO ***************************/
- /* Default values for FG */
- /* from these are needed : */
- /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */
-
-#ifdef CONFIG_SYS_ISDBT
- if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
- rf += 850;
-#endif
-
- if (state->current_rf != rf) {
- state->tuner_is_tuned = 0;
-
- tune = dib0090_tuning_table;
-
- tmp = (state->revision >> 5) & 0x7;
- if (tmp == 0x4 || tmp == 0x7) {
- /* CBAND tuner version for VHF */
- if (state->current_band == BAND_FM || state->current_band == BAND_VHF) {
- /* Force CBAND */
- state->current_band = BAND_CBAND;
- tune = dib0090_tuning_table_fm_vhf_on_cband;
- }
- }
-
- pll = dib0090_pll_table;
- /* Look for the interval */
- while (rf > tune->max_freq)
- tune++;
- while (rf > pll->max_freq)
- pll++;
- state->current_tune_table_index = tune;
- state->current_pll_table_index = pll;
- }
-
- if (*tune_state == CT_TUNER_START) {
-
- if (state->tuner_is_tuned == 0)
- state->current_rf = 0;
-
- if (state->current_rf != rf) {
-
- dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
-
- /* external loop filter, otherwise:
- * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
- * lo6 = 0x0e34 */
- if (pll->vco_band)
- lo5 = 0x049e;
- else if (state->config->analog_output)
- lo5 = 0x041d;
- else
- lo5 = 0x041c;
-
- lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */
-
- if (!state->config->io.pll_int_loop_filt)
- lo6 = 0xff28;
- else
- lo6 = (state->config->io.pll_int_loop_filt << 3);
-
- VCOF_kHz = (pll->hfdiv * rf) * 2;
-
- FREF = state->config->io.clock_khz;
-
- FBDiv = (VCOF_kHz / pll->topresc / FREF);
- Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
-
- if (Rest < LPF)
- Rest = 0;
- else if (Rest < 2 * LPF)
- Rest = 2 * LPF;
- else if (Rest > (FREF - LPF)) {
- Rest = 0;
- FBDiv += 1;
- } else if (Rest > (FREF - 2 * LPF))
- Rest = FREF - 2 * LPF;
- Rest = (Rest * 6528) / (FREF / 10);
-
- Den = 1;
-
- dprintk(" ***** ******* Rest value = %d", Rest);
-
- if (Rest > 0) {
- if (state->config->analog_output)
- lo6 |= (1 << 2) | 2;
- else
- lo6 |= (1 << 2) | 1;
- Den = 255;
- }
-#ifdef CONFIG_BAND_SBAND
- if (state->current_band == BAND_SBAND)
- lo6 &= 0xfffb;
-#endif
-
- dib0090_write_reg(state, 0x15, (u16) FBDiv);
-
- dib0090_write_reg(state, 0x16, (Den << 8) | 1);
-
- dib0090_write_reg(state, 0x17, (u16) Rest);
-
- dib0090_write_reg(state, 0x19, lo5);
-
- dib0090_write_reg(state, 0x1c, lo6);
-
- lo6 = tune->tuner_enable;
- if (state->config->analog_output)
- lo6 = (lo6 & 0xff9f) | 0x2;
-
- dib0090_write_reg(state, 0x24, lo6 | EN_LO
-#ifdef CONFIG_DIB0090_USE_PWM_AGC
- | state->config->use_pwm_agc * EN_CRYSTAL
-#endif
- );
-
- state->current_rf = rf;
-
- /* prepare a complete captrim */
- state->step = state->captrim = state->fcaptrim = 64;
-
- } else { /* we are already tuned to this frequency - the configuration is correct */
-
- /* do a minimal captrim even if the frequency has not changed */
- state->step = 4;
- state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
- }
- state->adc_diff = 3000;
-
- dib0090_write_reg(state, 0x10, 0x2B1);
-
- dib0090_write_reg(state, 0x1e, 0x0032);
-
- ret = 20;
- *tune_state = CT_TUNER_STEP_1;
- } else if (*tune_state == CT_TUNER_STEP_0) {
- /* nothing */
- } else if (*tune_state == CT_TUNER_STEP_1) {
- state->step /= 2;
- dib0090_write_reg(state, 0x18, lo4 | state->captrim);
- *tune_state = CT_TUNER_STEP_2;
- } else if (*tune_state == CT_TUNER_STEP_2) {
-
- adc = dib0090_read_reg(state, 0x1d);
- dprintk("FE %d CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) fe->id, (u32) state->captrim, (u32) adc,
- (u32) (adc) * (u32) 1800 / (u32) 1024);
-
- if (adc >= 400) {
- adc -= 400;
- step_sign = -1;
- } else {
- adc = 400 - adc;
- step_sign = 1;
- }
-
- if (adc < state->adc_diff) {
- dprintk("FE %d CAPTRIM=%d is closer to target (%d/%d)", (u32) fe->id, (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
- state->adc_diff = adc;
- state->fcaptrim = state->captrim;
-
- }
-
- state->captrim += step_sign * state->step;
- if (state->step >= 1)
- *tune_state = CT_TUNER_STEP_1;
- else
- *tune_state = CT_TUNER_STEP_3;
-
- ret = 15;
- } else if (*tune_state == CT_TUNER_STEP_3) {
- /*write the final cptrim config */
- dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
-
-#ifdef CONFIG_TUNER_DIB0090_CAPTRIM_MEMORY
- state->memory[state->memory_index].cap = state->fcaptrim;
-#endif
-
- *tune_state = CT_TUNER_STEP_4;
- } else if (*tune_state == CT_TUNER_STEP_4) {
- dib0090_write_reg(state, 0x1e, 0x07ff);
-
- dprintk("FE %d Final Captrim: %d", (u32) fe->id, (u32) state->fcaptrim);
- dprintk("FE %d HFDIV code: %d", (u32) fe->id, (u32) pll->hfdiv_code);
- dprintk("FE %d VCO = %d", (u32) fe->id, (u32) pll->vco_band);
- dprintk("FE %d VCOF in kHz: %d ((%d*%d) << 1))", (u32) fe->id, (u32) ((pll->hfdiv * rf) * 2), (u32) pll->hfdiv, (u32) rf);
- dprintk("FE %d REFDIV: %d, FREF: %d", (u32) fe->id, (u32) 1, (u32) state->config->io.clock_khz);
- dprintk("FE %d FBDIV: %d, Rest: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
- dprintk("FE %d Num: %d, Den: %d, SD: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x17),
- (u32) (dib0090_read_reg(state, 0x16) >> 8), (u32) dib0090_read_reg(state, 0x1c) & 0x3);
-
- c = 4;
- i = 3;
-#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
- if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND)) {
- c = 2;
- i = 2;
- }
-#endif
- dib0090_write_reg(state, 0x10, (c << 13) | (i << 11) | (WBD
-#ifdef CONFIG_DIB0090_USE_PWM_AGC
- | (state->config->use_pwm_agc << 1)
-#endif
- ));
- dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | (tune->lna_bias << 0));
- dib0090_write_reg(state, 0x0c, tune->v2i);
- dib0090_write_reg(state, 0x0d, tune->mix);
- dib0090_write_reg(state, 0x0e, tune->load);
-
- *tune_state = CT_TUNER_STEP_5;
- } else if (*tune_state == CT_TUNER_STEP_5) {
-
- /* initialize the lt gain register */
- state->rf_lt_def = 0x7c00;
- dib0090_write_reg(state, 0x0f, state->rf_lt_def);
-
- dib0090_set_bandwidth(state);
- state->tuner_is_tuned = 1;
- *tune_state = CT_TUNER_STOP;
- } else
- ret = FE_CALLBACK_TIME_NEVER;
- return ret;
-}
-
-static int dib0090_release(struct dvb_frontend *fe)
-{
- kfree(fe->tuner_priv);
- fe->tuner_priv = NULL;
- return 0;
-}
-
-enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
-{
- struct dib0090_state *state = fe->tuner_priv;
-
- return state->tune_state;
-}
-EXPORT_SYMBOL(dib0090_get_tune_state);
-
-int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
-{
- struct dib0090_state *state = fe->tuner_priv;
-
- state->tune_state = tune_state;
- return 0;
-}
-EXPORT_SYMBOL(dib0090_set_tune_state);
-
-static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
-{
- struct dib0090_state *state = fe->tuner_priv;
-
- *frequency = 1000 * state->current_rf;
- return 0;
-}
-
-static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
-{
- struct dib0090_state *state = fe->tuner_priv;
- uint32_t ret;
-
- state->tune_state = CT_TUNER_START;
-
- do {
- ret = dib0090_tune(fe);
- if (ret != FE_CALLBACK_TIME_NEVER)
- msleep(ret / 10);
- else
- break;
- } while (state->tune_state != CT_TUNER_STOP);
-
- return 0;
-}
-
-static const struct dvb_tuner_ops dib0090_ops = {
- .info = {
- .name = "DiBcom DiB0090",
- .frequency_min = 45000000,
- .frequency_max = 860000000,
- .frequency_step = 1000,
- },
- .release = dib0090_release,
-
- .init = dib0090_wakeup,
- .sleep = dib0090_sleep,
- .set_params = dib0090_set_params,
- .get_frequency = dib0090_get_frequency,
-};
-
-struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
-{
- struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
- if (st == NULL)
- return NULL;
-
- st->config = config;
- st->i2c = i2c;
- st->fe = fe;
- fe->tuner_priv = st;
-
- if (dib0090_reset(fe) != 0)
- goto free_mem;
-
- printk(KERN_INFO "DiB0090: successfully identified\n");
- memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
-
- return fe;
- free_mem:
- kfree(st);
- fe->tuner_priv = NULL;
- return NULL;
-}
-EXPORT_SYMBOL(dib0090_register);
-
-MODULE_AUTHOR("Patrick Boettcher ");
-MODULE_AUTHOR("Olivier Grenie ");
-MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
-MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/media/dvb/frontends/dib0090.h b/trunk/drivers/media/dvb/frontends/dib0090.h
deleted file mode 100644
index aa7711e88776..000000000000
--- a/trunk/drivers/media/dvb/frontends/dib0090.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
- *
- * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- */
-#ifndef DIB0090_H
-#define DIB0090_H
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-#define DEFAULT_DIB0090_I2C_ADDRESS 0x60
-
-struct dib0090_io_config {
- u32 clock_khz;
-
- u8 pll_bypass:1;
- u8 pll_range:1;
- u8 pll_prediv:6;
- u8 pll_loopdiv:6;
-
- u8 adc_clock_ratio; /* valid is 8, 7 ,6 */
- u16 pll_int_loop_filt;
-};
-
-struct dib0090_config {
- struct dib0090_io_config io;
- int (*reset) (struct dvb_frontend *, int);
- int (*sleep) (struct dvb_frontend *, int);
-
- /* offset in kHz */
- int freq_offset_khz_uhf;
- int freq_offset_khz_vhf;
-
- int (*get_adc_power) (struct dvb_frontend *);
-
- u8 clkouttobamse:1; /* activate or deactivate clock output */
- u8 analog_output;
-
- u8 i2c_address;
- /* add drives and other things if necessary */
- u16 wbd_vhf_offset;
- u16 wbd_cband_offset;
- u8 use_pwm_agc;
- u8 clkoutdrive;
-};
-
-#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE))
-extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
-extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
-extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe);
-extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner);
-extern int dib0090_gain_control(struct dvb_frontend *fe);
-extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe);
-extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
-extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt);
-#else
-static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-
-static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-
-static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-
-static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-
-static inline int dib0090_gain_control(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return CT_DONE;
-}
-
-static inline int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-#endif
-
-#endif
diff --git a/trunk/drivers/media/dvb/frontends/dib8000.c b/trunk/drivers/media/dvb/frontends/dib8000.c
index 6f6fa29d9ea4..898400d331a3 100644
--- a/trunk/drivers/media/dvb/frontends/dib8000.c
+++ b/trunk/drivers/media/dvb/frontends/dib8000.c
@@ -28,6 +28,18 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
+enum frontend_tune_state {
+ CT_AGC_START = 20,
+ CT_AGC_STEP_0,
+ CT_AGC_STEP_1,
+ CT_AGC_STEP_2,
+ CT_AGC_STEP_3,
+ CT_AGC_STEP_4,
+ CT_AGC_STOP,
+
+ CT_DEMOD_START = 30,
+};
+
#define FE_STATUS_TUNE_FAILED 0
struct i2c_device {
@@ -121,104 +133,104 @@ static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
return dib8000_i2c_write16(&state->i2c, reg, val);
}
-static const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
+const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
(769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
(920 << 5) | 0x09
};
-static const int16_t coeff_2k_sb_1seg[8] = {
+const int16_t coeff_2k_sb_1seg[8] = {
(692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
};
-static const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
+const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
(832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
(-931 << 5) | 0x0f
};
-static const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
+const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
(622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
(982 << 5) | 0x0c
};
-static const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
+const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
(699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
(-720 << 5) | 0x0d
};
-static const int16_t coeff_2k_sb_3seg[8] = {
+const int16_t coeff_2k_sb_3seg[8] = {
(664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
(-610 << 5) | 0x0a
};
-static const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
+const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
(-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
(-922 << 5) | 0x0d
};
-static const int16_t coeff_4k_sb_1seg[8] = {
+const int16_t coeff_4k_sb_1seg[8] = {
(638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
(-655 << 5) | 0x0a
};
-static const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
+const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
(-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
(-958 << 5) | 0x13
};
-static const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
+const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
(-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
(-568 << 5) | 0x0f
};
-static const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
+const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
(-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
(-848 << 5) | 0x13
};
-static const int16_t coeff_4k_sb_3seg[8] = {
+const int16_t coeff_4k_sb_3seg[8] = {
(612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
(-869 << 5) | 0x13
};
-static const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
+const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
(-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
(-598 << 5) | 0x10
};
-static const int16_t coeff_8k_sb_1seg[8] = {
+const int16_t coeff_8k_sb_1seg[8] = {
(673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
(585 << 5) | 0x0f
};
-static const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
+const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
(863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
(0 << 5) | 0x14
};
-static const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
+const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
(-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
(-877 << 5) | 0x15
};
-static const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
+const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
(-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
(-921 << 5) | 0x14
};
-static const int16_t coeff_8k_sb_3seg[8] = {
+const int16_t coeff_8k_sb_3seg[8] = {
(514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
(690 << 5) | 0x14
};
-static const int16_t ana_fe_coeff_3seg[24] = {
+const int16_t ana_fe_coeff_3seg[24] = {
81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
};
-static const int16_t ana_fe_coeff_1seg[24] = {
+const int16_t ana_fe_coeff_1seg[24] = {
249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
};
-static const int16_t ana_fe_coeff_13seg[24] = {
+const int16_t ana_fe_coeff_13seg[24] = {
396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
};
@@ -840,14 +852,6 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
return 0;
}
-void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
-{
- struct dib8000_state *state = fe->demodulator_priv;
- dib8000_set_adc_state(state, DIBX000_ADC_ON);
- dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
-}
-EXPORT_SYMBOL(dib8000_pwm_agc_reset);
-
static int dib8000_agc_soft_split(struct dib8000_state *state)
{
u16 agc, split_offset;
@@ -935,32 +939,6 @@ static int dib8000_agc_startup(struct dvb_frontend *fe)
}
-static const int32_t lut_1000ln_mant[] =
-{
- 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
-};
-
-int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode)
-{
- struct dib8000_state *state = fe->demodulator_priv;
- uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0;
- int32_t val;
-
- val = dib8000_read32(state, 384);
- /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */
- if (mode) {
- tmp_val = val;
- while (tmp_val >>= 1)
- exp++;
- mant = (val * 1000 / (1<timf = dib8000_read32(state, 435);
@@ -1423,9 +1401,10 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
}
break;
}
+ }
+ if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
for (i = 0; i < 8; i++)
dib8000_write_word(state, 343 + i, ncoeff[i]);
- }
// P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
dib8000_write_word(state, 351,
@@ -1875,24 +1854,6 @@ static int dib8000_sleep(struct dvb_frontend *fe)
}
}
-enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
-{
- struct dib8000_state *state = fe->demodulator_priv;
- return state->tune_state;
-}
-EXPORT_SYMBOL(dib8000_get_tune_state);
-
-int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
-{
- struct dib8000_state *state = fe->demodulator_priv;
- state->tune_state = tune_state;
- return 0;
-}
-EXPORT_SYMBOL(dib8000_set_tune_state);
-
-
-
-
static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
{
struct dib8000_state *state = fe->demodulator_priv;
@@ -2082,31 +2043,29 @@ static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
*stat = 0;
- if ((lock >> 13) & 1)
+ if ((lock >> 14) & 1) // AGC
*stat |= FE_HAS_SIGNAL;
- if ((lock >> 8) & 1) /* Equal */
+ if ((lock >> 8) & 1) // Equal
*stat |= FE_HAS_CARRIER;
- if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */
+ if ((lock >> 3) & 1) // TMCC_SYNC
*stat |= FE_HAS_SYNC;
- if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */
+ if ((lock >> 5) & 7) // FEC MPEG
*stat |= FE_HAS_LOCK;
- if ((lock >> 12) & 1) {
- lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
- if (lock & 0x01)
- *stat |= FE_HAS_VITERBI;
+ lock = dib8000_read_word(state, 554); // Viterbi Layer A
+ if (lock & 0x01)
+ *stat |= FE_HAS_VITERBI;
- lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
- if (lock & 0x01)
- *stat |= FE_HAS_VITERBI;
+ lock = dib8000_read_word(state, 555); // Viterbi Layer B
+ if (lock & 0x01)
+ *stat |= FE_HAS_VITERBI;
- lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
- if (lock & 0x01)
- *stat |= FE_HAS_VITERBI;
- }
+ lock = dib8000_read_word(state, 556); // Viterbi Layer C
+ if (lock & 0x01)
+ *stat |= FE_HAS_VITERBI;
return 0;
}
diff --git a/trunk/drivers/media/dvb/frontends/dib8000.h b/trunk/drivers/media/dvb/frontends/dib8000.h
index d99619ae983c..8c89482b738a 100644
--- a/trunk/drivers/media/dvb/frontends/dib8000.h
+++ b/trunk/drivers/media/dvb/frontends/dib8000.h
@@ -46,10 +46,6 @@ extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
-extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
-extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
-extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
-extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
#else
static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
{
@@ -63,53 +59,35 @@ static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe
return NULL;
}
-static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
+int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return CT_SHUTDOWN,
-}
-static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
#endif
#endif
diff --git a/trunk/drivers/media/dvb/frontends/dibx000_common.c b/trunk/drivers/media/dvb/frontends/dibx000_common.c
index e6f3d73db9d3..4efca30d2127 100644
--- a/trunk/drivers/media/dvb/frontends/dibx000_common.c
+++ b/trunk/drivers/media/dvb/frontends/dibx000_common.c
@@ -6,7 +6,7 @@ static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0)
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0)
static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
{
@@ -25,7 +25,7 @@ static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
enum dibx000_i2c_interface intf)
{
if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
- dprintk("selecting interface: %d", intf);
+ dprintk("selecting interface: %d\n", intf);
mst->selected_interface = intf;
return dibx000_write_word(mst, mst->base_reg + 4, intf);
}
@@ -171,17 +171,8 @@ void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
{
i2c_del_adapter(&mst->gated_tuner_i2c_adap);
}
-EXPORT_SYMBOL(dibx000_exit_i2c_master);
-
-
-u32 systime()
-{
- struct timespec t;
- t = current_kernel_time();
- return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
-}
-EXPORT_SYMBOL(systime);
+EXPORT_SYMBOL(dibx000_exit_i2c_master);
MODULE_AUTHOR("Patrick Boettcher ");
MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
diff --git a/trunk/drivers/media/dvb/frontends/dibx000_common.h b/trunk/drivers/media/dvb/frontends/dibx000_common.h
index 4f5d141a308d..5be10eca07c0 100644
--- a/trunk/drivers/media/dvb/frontends/dibx000_common.h
+++ b/trunk/drivers/media/dvb/frontends/dibx000_common.h
@@ -36,17 +36,13 @@ extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
-extern u32 systime(void);
-
#define BAND_LBAND 0x01
#define BAND_UHF 0x02
#define BAND_VHF 0x04
#define BAND_SBAND 0x08
-#define BAND_FM 0x10
-#define BAND_CBAND 0x20
+#define BAND_FM 0x10
-#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \
- (freq_kHz) <= 115000 ? BAND_FM : \
+#define BAND_OF_FREQUENCY(freq_kHz) ( (freq_kHz) <= 115000 ? BAND_FM : \
(freq_kHz) <= 250000 ? BAND_VHF : \
(freq_kHz) <= 863000 ? BAND_UHF : \
(freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND )
@@ -153,67 +149,4 @@ enum dibx000_adc_states {
#define OUTMODE_MPEG2_FIFO 5
#define OUTMODE_ANALOG_ADC 6
-enum frontend_tune_state {
- CT_TUNER_START = 10,
- CT_TUNER_STEP_0,
- CT_TUNER_STEP_1,
- CT_TUNER_STEP_2,
- CT_TUNER_STEP_3,
- CT_TUNER_STEP_4,
- CT_TUNER_STEP_5,
- CT_TUNER_STEP_6,
- CT_TUNER_STEP_7,
- CT_TUNER_STOP,
-
- CT_AGC_START = 20,
- CT_AGC_STEP_0,
- CT_AGC_STEP_1,
- CT_AGC_STEP_2,
- CT_AGC_STEP_3,
- CT_AGC_STEP_4,
- CT_AGC_STOP,
-
- CT_DEMOD_START = 30,
- CT_DEMOD_STEP_1,
- CT_DEMOD_STEP_2,
- CT_DEMOD_STEP_3,
- CT_DEMOD_STEP_4,
- CT_DEMOD_STEP_5,
- CT_DEMOD_STEP_6,
- CT_DEMOD_STEP_7,
- CT_DEMOD_STEP_8,
- CT_DEMOD_STEP_9,
- CT_DEMOD_STEP_10,
- CT_DEMOD_SEARCH_NEXT = 41,
- CT_DEMOD_STEP_LOCKED,
- CT_DEMOD_STOP,
-
- CT_DONE = 100,
- CT_SHUTDOWN,
-
-};
-
-struct dvb_frontend_parametersContext {
-#define CHANNEL_STATUS_PARAMETERS_UNKNOWN 0x01
-#define CHANNEL_STATUS_PARAMETERS_SET 0x02
- u8 status;
- u32 tune_time_estimation[2];
- s32 tps_available;
- u16 tps[9];
-};
-
-#define FE_STATUS_TUNE_FAILED 0
-#define FE_STATUS_TUNE_TIMED_OUT -1
-#define FE_STATUS_TUNE_TIME_TOO_SHORT -2
-#define FE_STATUS_TUNE_PENDING -3
-#define FE_STATUS_STD_SUCCESS -4
-#define FE_STATUS_FFT_SUCCESS -5
-#define FE_STATUS_DEMOD_SUCCESS -6
-#define FE_STATUS_LOCKED -7
-#define FE_STATUS_DATA_LOCKED -8
-
-#define FE_CALLBACK_TIME_NEVER 0xffffffff
-
-#define ABS(x) ((x < 0) ? (-x) : (x))
-
#endif
diff --git a/trunk/drivers/media/dvb/frontends/lgs8gxx.c b/trunk/drivers/media/dvb/frontends/lgs8gxx.c
index dee53960e7e8..eabcadc425d5 100644
--- a/trunk/drivers/media/dvb/frontends/lgs8gxx.c
+++ b/trunk/drivers/media/dvb/frontends/lgs8gxx.c
@@ -199,7 +199,7 @@ static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/)
val = freq;
if (freq != 0) {
- val <<= 32;
+ val *= (u64)1 << 32;
if (if_clk != 0)
do_div(val, if_clk);
v32 = val & 0xFFFFFFFF;
@@ -246,7 +246,7 @@ static int lgs8gxx_get_afc_phase(struct lgs8gxx_state *priv)
val = v32;
val *= priv->config->if_clk_freq;
- val >>= 32;
+ val /= (u64)1 << 32;
dprintk("AFC = %u kHz\n", (u32)val);
return 0;
}
diff --git a/trunk/drivers/media/dvb/frontends/lnbp21.c b/trunk/drivers/media/dvb/frontends/lnbp21.c
index b181bf023ada..71f607fe8fc7 100644
--- a/trunk/drivers/media/dvb/frontends/lnbp21.c
+++ b/trunk/drivers/media/dvb/frontends/lnbp21.c
@@ -1,7 +1,7 @@
/*
* lnbp21.c - driver for lnb supply and control ic lnbp21
*
- * Copyright (C) 2006, 2009 Oliver Endriss
+ * Copyright (C) 2006 Oliver Endriss
* Copyright (C) 2009 Igor M. Liplianin
*
* This program is free software; you can redistribute it and/or
@@ -91,31 +91,6 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
}
-static int lnbp21_set_tone(struct dvb_frontend *fe,
- fe_sec_tone_mode_t tone)
-{
- struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
- struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
- .buf = &lnbp21->config,
- .len = sizeof(lnbp21->config) };
-
- switch (tone) {
- case SEC_TONE_OFF:
- lnbp21->config &= ~LNBP21_TEN;
- break;
- case SEC_TONE_ON:
- lnbp21->config |= LNBP21_TEN;
- break;
- default:
- return -EINVAL;
- };
-
- lnbp21->config |= lnbp21->override_or;
- lnbp21->config &= lnbp21->override_and;
-
- return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
-}
-
static void lnbp21_release(struct dvb_frontend *fe)
{
/* LNBP power off */
@@ -158,7 +133,6 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
/* override frontend ops */
fe->ops.set_voltage = lnbp21_set_voltage;
fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
- fe->ops.set_tone = lnbp21_set_tone;
printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr);
return fe;
diff --git a/trunk/drivers/media/dvb/frontends/stv0900_core.c b/trunk/drivers/media/dvb/frontends/stv0900_core.c
index 8762c86044a5..df49ea0983bc 100644
--- a/trunk/drivers/media/dvb/frontends/stv0900_core.c
+++ b/trunk/drivers/media/dvb/frontends/stv0900_core.c
@@ -1451,8 +1451,6 @@ static int stv0900_status(struct stv0900_internal *intp,
{
enum fe_stv0900_search_state demod_state;
int locked = FALSE;
- u8 tsbitrate0_val, tsbitrate1_val;
- s32 bitrate;
demod_state = stv0900_get_bits(intp, HEADER_MODE);
switch (demod_state) {
@@ -1475,17 +1473,6 @@ static int stv0900_status(struct stv0900_internal *intp,
dprintk("%s: locked = %d\n", __func__, locked);
- if (stvdebug) {
- /* Print TS bitrate */
- tsbitrate0_val = stv0900_read_reg(intp, TSBITRATE0);
- tsbitrate1_val = stv0900_read_reg(intp, TSBITRATE1);
- /* Formula Bit rate = Mclk * px_tsfifo_bitrate / 16384 */
- bitrate = (stv0900_get_mclk_freq(intp, intp->quartz)/1000000)
- * (tsbitrate1_val << 8 | tsbitrate0_val);
- bitrate /= 16384;
- dprintk("TS bitrate = %d Mbit/sec \n", bitrate);
- };
-
return locked;
}
diff --git a/trunk/drivers/media/dvb/frontends/stv090x.c b/trunk/drivers/media/dvb/frontends/stv090x.c
index 1573466a5c74..48edd542242e 100644
--- a/trunk/drivers/media/dvb/frontends/stv090x.c
+++ b/trunk/drivers/media/dvb/frontends/stv090x.c
@@ -3597,8 +3597,7 @@ static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma
reg = STV090x_READ_DEMOD(state, DISTXCTL);
- STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD,
- (state->config->diseqc_envelope_mode) ? 4 : 2);
+ STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 2);
STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
goto err;
@@ -3650,10 +3649,10 @@ static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t
reg = STV090x_READ_DEMOD(state, DISTXCTL);
if (burst == SEC_MINI_A) {
- mode = (state->config->diseqc_envelope_mode) ? 5 : 3;
+ mode = 3;
value = 0x00;
} else {
- mode = (state->config->diseqc_envelope_mode) ? 4 : 2;
+ mode = 2;
value = 0xFF;
}
diff --git a/trunk/drivers/media/dvb/frontends/stv090x.h b/trunk/drivers/media/dvb/frontends/stv090x.h
index b133807663ea..e968c98bb70f 100644
--- a/trunk/drivers/media/dvb/frontends/stv090x.h
+++ b/trunk/drivers/media/dvb/frontends/stv090x.h
@@ -75,8 +75,6 @@ struct stv090x_config {
enum stv090x_i2crpt repeater_level;
- bool diseqc_envelope_mode;
-
int (*tuner_init) (struct dvb_frontend *fe);
int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
diff --git a/trunk/drivers/media/dvb/siano/smsdvb.c b/trunk/drivers/media/dvb/siano/smsdvb.c
index 68bf9fbd8fed..266033ae2784 100644
--- a/trunk/drivers/media/dvb/siano/smsdvb.c
+++ b/trunk/drivers/media/dvb/siano/smsdvb.c
@@ -662,7 +662,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
return rc;
}
-static int __init smsdvb_module_init(void)
+int smsdvb_module_init(void)
{
int rc;
@@ -676,7 +676,7 @@ static int __init smsdvb_module_init(void)
return rc;
}
-static void __exit smsdvb_module_exit(void)
+void smsdvb_module_exit(void)
{
smscore_unregister_hotplug(smsdvb_hotplug);
diff --git a/trunk/drivers/media/dvb/siano/smssdio.c b/trunk/drivers/media/dvb/siano/smssdio.c
index 195244a3e69b..24206cbda264 100644
--- a/trunk/drivers/media/dvb/siano/smssdio.c
+++ b/trunk/drivers/media/dvb/siano/smssdio.c
@@ -48,7 +48,7 @@
#define SMSSDIO_INT 0x04
#define SMSSDIO_BLOCK_SIZE 128
-static const struct sdio_device_id smssdio_ids[] __devinitconst = {
+static const struct sdio_device_id smssdio_ids[] = {
{SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
.driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
{SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
@@ -222,7 +222,7 @@ static void smssdio_interrupt(struct sdio_func *func)
smscore_onresponse(smsdev->coredev, cb);
}
-static int __devinit smssdio_probe(struct sdio_func *func,
+static int smssdio_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
int ret;
@@ -338,7 +338,7 @@ static struct sdio_driver smssdio_driver = {
/* Module functions */
/*******************************************************************/
-static int __init smssdio_module_init(void)
+int smssdio_module_init(void)
{
int ret = 0;
@@ -350,7 +350,7 @@ static int __init smssdio_module_init(void)
return ret;
}
-static void __exit smssdio_module_exit(void)
+void smssdio_module_exit(void)
{
sdio_unregister_driver(&smssdio_driver);
}
diff --git a/trunk/drivers/media/dvb/siano/smsusb.c b/trunk/drivers/media/dvb/siano/smsusb.c
index 5eac27287d9c..8f88a586b0dd 100644
--- a/trunk/drivers/media/dvb/siano/smsusb.c
+++ b/trunk/drivers/media/dvb/siano/smsusb.c
@@ -390,7 +390,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
return rc;
}
-static int __devinit smsusb_probe(struct usb_interface *intf,
+static int smsusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
@@ -484,7 +484,7 @@ static int smsusb_resume(struct usb_interface *intf)
return 0;
}
-static const struct usb_device_id smsusb_id_table[] __devinitconst = {
+struct usb_device_id smsusb_id_table[] = {
{ USB_DEVICE(0x187f, 0x0010),
.driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
{ USB_DEVICE(0x187f, 0x0100),
@@ -533,18 +533,8 @@ static const struct usb_device_id smsusb_id_table[] __devinitconst = {
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ USB_DEVICE(0x2040, 0xb910),
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0xb980),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0xb990),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ USB_DEVICE(0x2040, 0xc000),
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0xc010),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0xc080),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0xc090),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ } /* Terminating entry */
};
@@ -560,7 +550,7 @@ static struct usb_driver smsusb_driver = {
.resume = smsusb_resume,
};
-static int __init smsusb_module_init(void)
+int smsusb_module_init(void)
{
int rc = usb_register(&smsusb_driver);
if (rc)
@@ -571,7 +561,7 @@ static int __init smsusb_module_init(void)
return rc;
}
-static void __exit smsusb_module_exit(void)
+void smsusb_module_exit(void)
{
/* Regular USB Cleanup */
usb_deregister(&smsusb_driver);
diff --git a/trunk/drivers/media/dvb/ttpci/budget-ci.c b/trunk/drivers/media/dvb/ttpci/budget-ci.c
index 9782e0593733..7d193ebc0aea 100644
--- a/trunk/drivers/media/dvb/ttpci/budget-ci.c
+++ b/trunk/drivers/media/dvb/ttpci/budget-ci.c
@@ -190,13 +190,12 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
struct saa7146_dev *saa = budget_ci->budget.dev;
struct input_dev *input_dev = budget_ci->ir.dev;
int error;
- struct ir_scancode_table *ir_codes;
-
budget_ci->ir.dev = input_dev = input_allocate_device();
if (!input_dev) {
printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
- return -ENOMEM;
+ error = -ENOMEM;
+ goto out1;
}
snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
@@ -218,11 +217,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
}
input_dev->dev.parent = &saa->pci->dev;
- if (rc5_device < 0)
- budget_ci->ir.rc5_device = IR_DEVICE_ANY;
- else
- budget_ci->ir.rc5_device = rc5_device;
-
/* Select keymap and address */
switch (budget_ci->budget.dev->pci->subsystem_device) {
case 0x100c:
@@ -230,34 +224,53 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
case 0x1011:
case 0x1012:
/* The hauppauge keymap is a superset of these remotes */
- ir_codes = &ir_codes_hauppauge_new_table;
+ error = ir_input_init(input_dev, &budget_ci->ir.state,
+ IR_TYPE_RC5, &ir_codes_hauppauge_new_table);
+ if (error < 0)
+ goto out2;
if (rc5_device < 0)
budget_ci->ir.rc5_device = 0x1f;
+ else
+ budget_ci->ir.rc5_device = rc5_device;
break;
case 0x1010:
case 0x1017:
case 0x101a:
/* for the Technotrend 1500 bundled remote */
- ir_codes = &ir_codes_tt_1500_table;
+ error = ir_input_init(input_dev, &budget_ci->ir.state,
+ IR_TYPE_RC5, &ir_codes_tt_1500_table);
+ if (error < 0)
+ goto out2;
+
+ if (rc5_device < 0)
+ budget_ci->ir.rc5_device = IR_DEVICE_ANY;
+ else
+ budget_ci->ir.rc5_device = rc5_device;
break;
default:
/* unknown remote */
- ir_codes = &ir_codes_budget_ci_old_table;
+ error = ir_input_init(input_dev, &budget_ci->ir.state,
+ IR_TYPE_RC5, &ir_codes_budget_ci_old_table);
+ if (error < 0)
+ goto out2;
+
+ if (rc5_device < 0)
+ budget_ci->ir.rc5_device = IR_DEVICE_ANY;
+ else
+ budget_ci->ir.rc5_device = rc5_device;
break;
}
- ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5);
-
/* initialise the key-up timeout handler */
init_timer(&budget_ci->ir.timer_keyup);
budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
budget_ci->ir.last_raw = 0xffff; /* An impossible value */
- error = ir_input_register(input_dev, ir_codes);
+ error = input_register_device(input_dev);
if (error) {
printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
- return error;
+ goto out2;
}
/* note: these must be after input_register_device */
@@ -271,6 +284,12 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
return 0;
+
+out2:
+ ir_input_free(input_dev);
+ input_free_device(input_dev);
+out1:
+ return error;
}
static void msp430_ir_deinit(struct budget_ci *budget_ci)
@@ -285,7 +304,8 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
del_timer_sync(&dev->timer);
ir_input_nokey(dev, &budget_ci->ir.state);
- ir_input_unregister(dev);
+ ir_input_free(dev);
+ input_unregister_device(dev);
}
static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
diff --git a/trunk/drivers/media/radio/Kconfig b/trunk/drivers/media/radio/Kconfig
index 3f40f375981b..4c2b8a246772 100644
--- a/trunk/drivers/media/radio/Kconfig
+++ b/trunk/drivers/media/radio/Kconfig
@@ -215,10 +215,13 @@ config RADIO_MIROPCM20
module will be called radio-miropcm20.
config RADIO_SF16FMI
- tristate "SF16-FMI/SF16-FMP Radio"
+ tristate "SF16FMI Radio"
depends on ISA && VIDEO_V4L2
---help---
- Choose Y here if you have one of these FM radio cards.
+ Choose Y here if you have one of these FM radio cards. If you
+ compile the driver into the kernel and your card is not PnP one, you
+ have to add "sf16fm=" to the kernel command line (I/O address is
+ 0x284 or 0x384).
In order to control your radio card, you will need to use programs
that are compatible with the Video For Linux API. Information on
diff --git a/trunk/drivers/media/radio/radio-aimslab.c b/trunk/drivers/media/radio/radio-aimslab.c
index 5bf4985daede..35edee009ba8 100644
--- a/trunk/drivers/media/radio/radio-aimslab.c
+++ b/trunk/drivers/media/radio/radio-aimslab.c
@@ -268,8 +268,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct rtrack *rt = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
rt_setfreq(rt, f->frequency);
return 0;
}
@@ -279,8 +277,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct rtrack *rt = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = rt->curfreq;
return 0;
diff --git a/trunk/drivers/media/radio/radio-aztech.c b/trunk/drivers/media/radio/radio-aztech.c
index c22311393624..8daf809eb01a 100644
--- a/trunk/drivers/media/radio/radio-aztech.c
+++ b/trunk/drivers/media/radio/radio-aztech.c
@@ -254,8 +254,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct aztech *az = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
az_setfreq(az, f->frequency);
return 0;
}
@@ -265,8 +263,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct aztech *az = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = az->curfreq;
return 0;
diff --git a/trunk/drivers/media/radio/radio-gemtek-pci.c b/trunk/drivers/media/radio/radio-gemtek-pci.c
index 000f4d34087c..c6cf11661868 100644
--- a/trunk/drivers/media/radio/radio-gemtek-pci.c
+++ b/trunk/drivers/media/radio/radio-gemtek-pci.c
@@ -240,8 +240,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct gemtek_pci *card = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
if (f->frequency < GEMTEK_PCI_RANGE_LOW ||
f->frequency > GEMTEK_PCI_RANGE_HIGH)
return -EINVAL;
@@ -255,8 +253,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct gemtek_pci *card = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = card->current_frequency;
return 0;
diff --git a/trunk/drivers/media/radio/radio-maestro.c b/trunk/drivers/media/radio/radio-maestro.c
index f8213b7c8ddc..64d737c35acf 100644
--- a/trunk/drivers/media/radio/radio-maestro.c
+++ b/trunk/drivers/media/radio/radio-maestro.c
@@ -200,8 +200,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct maestro *dev = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
return -EINVAL;
mutex_lock(&dev->lock);
@@ -215,8 +213,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct maestro *dev = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
mutex_lock(&dev->lock);
f->frequency = BITS2FREQ(radio_bits_get(dev));
diff --git a/trunk/drivers/media/radio/radio-maxiradio.c b/trunk/drivers/media/radio/radio-maxiradio.c
index 44b4dbedb322..3da51fe8fb93 100644
--- a/trunk/drivers/media/radio/radio-maxiradio.c
+++ b/trunk/drivers/media/radio/radio-maxiradio.c
@@ -262,8 +262,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct maxiradio *dev = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) {
dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
f->frequency / 16000,
@@ -287,8 +285,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct maxiradio *dev = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = dev->freq;
diff --git a/trunk/drivers/media/radio/radio-mr800.c b/trunk/drivers/media/radio/radio-mr800.c
index 02a9cefc9a00..949f60513d9e 100644
--- a/trunk/drivers/media/radio/radio-mr800.c
+++ b/trunk/drivers/media/radio/radio-mr800.c
@@ -374,8 +374,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct amradio_device *radio = file->private_data;
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
return amradio_setfreq(radio, f->frequency);
}
@@ -385,8 +383,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct amradio_device *radio = file->private_data;
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = radio->curfreq;
diff --git a/trunk/drivers/media/radio/radio-rtrack2.c b/trunk/drivers/media/radio/radio-rtrack2.c
index a79296aac9a9..9cb193fa6e33 100644
--- a/trunk/drivers/media/radio/radio-rtrack2.c
+++ b/trunk/drivers/media/radio/radio-rtrack2.c
@@ -167,8 +167,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct rtrack2 *rt = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
rt_setfreq(rt, f->frequency);
return 0;
}
@@ -178,8 +176,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct rtrack2 *rt = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = rt->curfreq;
return 0;
diff --git a/trunk/drivers/media/radio/radio-sf16fmi.c b/trunk/drivers/media/radio/radio-sf16fmi.c
index 985359d18aa5..49c4aab95dab 100644
--- a/trunk/drivers/media/radio/radio-sf16fmi.c
+++ b/trunk/drivers/media/radio/radio-sf16fmi.c
@@ -1,4 +1,4 @@
-/* SF16-FMI and SF16-FMP radio driver for Linux radio support
+/* SF16FMI radio driver for Linux radio support
* heavily based on rtrack driver...
* (c) 1997 M. Kirkwood
* (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz
@@ -11,7 +11,7 @@
*
* Frequency control is done digitally -- ie out(port,encodefreq(95.8));
* No volume control - only mute/unmute - you have to use line volume
- * control on SB-part of SF16-FMI/SF16-FMP
+ * control on SB-part of SF16FMI
*
* Converted to V4L2 API by Mauro Carvalho Chehab
*/
@@ -30,14 +30,14 @@
#include
MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
-MODULE_DESCRIPTION("A driver for the SF16-FMI and SF16-FMP radio.");
+MODULE_DESCRIPTION("A driver for the SF16MI radio.");
MODULE_LICENSE("GPL");
static int io = -1;
static int radio_nr = -1;
module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the SF16-FMI or SF16-FMP card (0x284 or 0x384)");
+MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
module_param(radio_nr, int, 0);
#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
@@ -47,14 +47,13 @@ struct fmi
struct v4l2_device v4l2_dev;
struct video_device vdev;
int io;
- bool mute;
+ int curvol; /* 1 or 0 */
unsigned long curfreq; /* freq in kHz */
struct mutex lock;
};
static struct fmi fmi_card;
static struct pnp_dev *dev;
-bool pnp_attached;
/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
/* It is only useful to give freq in interval of 800 (=0.05Mhz),
@@ -106,7 +105,7 @@ static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq)
outbits(8, 0xC0, fmi->io);
msleep(143); /* was schedule_timeout(HZ/7) */
mutex_unlock(&fmi->lock);
- if (!fmi->mute)
+ if (fmi->curvol)
fmi_unmute(fmi);
return 0;
}
@@ -117,7 +116,7 @@ static inline int fmi_getsigstr(struct fmi *fmi)
int res;
mutex_lock(&fmi->lock);
- val = fmi->mute ? 0x00 : 0x08; /* mute/unmute */
+ val = fmi->curvol ? 0x08 : 0x00; /* unmute/mute */
outb(val, fmi->io);
outb(val | 0x10, fmi->io);
msleep(143); /* was schedule_timeout(HZ/7) */
@@ -169,8 +168,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct fmi *fmi = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
if (f->frequency < RSF16_MINFREQ ||
f->frequency > RSF16_MAXFREQ)
return -EINVAL;
@@ -185,8 +182,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct fmi *fmi = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = fmi->curfreq;
return 0;
@@ -209,7 +204,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = fmi->mute;
+ ctrl->value = fmi->curvol;
return 0;
}
return -EINVAL;
@@ -226,7 +221,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
fmi_mute(fmi);
else
fmi_unmute(fmi);
- fmi->mute = ctrl->value;
+ fmi->curvol = ctrl->value;
return 0;
}
return -EINVAL;
@@ -321,54 +316,26 @@ static int __init fmi_init(void)
{
struct fmi *fmi = &fmi_card;
struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
- int res, i;
- int probe_ports[] = { 0, 0x284, 0x384 };
-
- if (io < 0) {
- for (i = 0; i < ARRAY_SIZE(probe_ports); i++) {
- io = probe_ports[i];
- if (io == 0) {
- io = isapnp_fmi_probe();
- if (io < 0)
- continue;
- pnp_attached = 1;
- }
- if (!request_region(io, 2, "radio-sf16fmi")) {
- if (pnp_attached)
- pnp_device_detach(dev);
- io = -1;
- continue;
- }
- if (pnp_attached ||
- ((inb(io) & 0xf9) == 0xf9 && (inb(io) & 0x4) == 0))
- break;
- release_region(io, 2);
- io = -1;
- }
- } else {
- if (!request_region(io, 2, "radio-sf16fmi")) {
- printk(KERN_ERR "radio-sf16fmi: port %#x already in use\n", io);
- return -EBUSY;
- }
- if (inb(io) == 0xff) {
- printk(KERN_ERR "radio-sf16fmi: card not present at %#x\n", io);
- release_region(io, 2);
- return -ENODEV;
- }
- }
- if (io < 0) {
- printk(KERN_ERR "radio-sf16fmi: no cards found\n");
- return -ENODEV;
- }
+ int res;
+ if (io < 0)
+ io = isapnp_fmi_probe();
strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
fmi->io = io;
+ if (fmi->io < 0) {
+ v4l2_err(v4l2_dev, "No PnP card found.\n");
+ return fmi->io;
+ }
+ if (!request_region(io, 2, "radio-sf16fmi")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io);
+ pnp_device_detach(dev);
+ return -EBUSY;
+ }
res = v4l2_device_register(NULL, v4l2_dev);
if (res < 0) {
release_region(fmi->io, 2);
- if (pnp_attached)
- pnp_device_detach(dev);
+ pnp_device_detach(dev);
v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
return res;
}
@@ -385,8 +352,7 @@ static int __init fmi_init(void)
if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(v4l2_dev);
release_region(fmi->io, 2);
- if (pnp_attached)
- pnp_device_detach(dev);
+ pnp_device_detach(dev);
return -EINVAL;
}
@@ -403,7 +369,7 @@ static void __exit fmi_exit(void)
video_unregister_device(&fmi->vdev);
v4l2_device_unregister(&fmi->v4l2_dev);
release_region(fmi->io, 2);
- if (dev && pnp_attached)
+ if (dev)
pnp_device_detach(dev);
}
diff --git a/trunk/drivers/media/radio/radio-sf16fmr2.c b/trunk/drivers/media/radio/radio-sf16fmr2.c
index 52c7bbb32b8b..a11414f648d4 100644
--- a/trunk/drivers/media/radio/radio-sf16fmr2.c
+++ b/trunk/drivers/media/radio/radio-sf16fmr2.c
@@ -251,8 +251,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct fmr2 *fmr2 = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
if (f->frequency < RSF16_MINFREQ ||
f->frequency > RSF16_MAXFREQ)
return -EINVAL;
@@ -274,8 +272,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct fmr2 *fmr2 = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = fmr2->curfreq;
return 0;
diff --git a/trunk/drivers/media/radio/radio-tea5764.c b/trunk/drivers/media/radio/radio-tea5764.c
index 8e718bfcdad3..3cd76dddb6aa 100644
--- a/trunk/drivers/media/radio/radio-tea5764.c
+++ b/trunk/drivers/media/radio/radio-tea5764.c
@@ -314,7 +314,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
if (v->index > 0)
return -EINVAL;
- memset(v, 0, sizeof(*v));
+ memset(v, 0, sizeof(v));
strcpy(v->name, "FM");
v->type = V4L2_TUNER_RADIO;
tea5764_i2c_read(radio);
@@ -349,7 +349,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct tea5764_device *radio = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+ if (f->tuner != 0)
return -EINVAL;
if (f->frequency == 0) {
/* We special case this as a power down control. */
@@ -370,10 +370,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
struct tea5764_device *radio = video_drvdata(file);
struct tea5764_regs *r = &radio->regs;
- if (f->tuner != 0)
- return -EINVAL;
tea5764_i2c_read(radio);
- memset(f, 0, sizeof(*f));
+ memset(f, 0, sizeof(f));
f->type = V4L2_TUNER_RADIO;
if (r->tnctrl & TEA5764_TNCTRL_PUPD0)
f->frequency = (tea5764_get_freq(radio) * 2) / 125;
@@ -460,8 +458,12 @@ static int vidioc_s_audio(struct file *file, void *priv,
static int tea5764_open(struct file *file)
{
/* Currently we support only one device */
+ int minor = video_devdata(file)->minor;
struct tea5764_device *radio = video_drvdata(file);
+ if (radio->videodev->minor != minor)
+ return -ENODEV;
+
mutex_lock(&radio->mutex);
/* Only exclusive access */
if (radio->users) {
diff --git a/trunk/drivers/media/radio/radio-terratec.c b/trunk/drivers/media/radio/radio-terratec.c
index fc1c860fd438..699db9acaaf7 100644
--- a/trunk/drivers/media/radio/radio-terratec.c
+++ b/trunk/drivers/media/radio/radio-terratec.c
@@ -240,8 +240,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct terratec *tt = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
tt_setfreq(tt, f->frequency);
return 0;
}
@@ -251,8 +249,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct terratec *tt = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = tt->curfreq;
return 0;
diff --git a/trunk/drivers/media/radio/radio-trust.c b/trunk/drivers/media/radio/radio-trust.c
index 9d6dcf8af5b0..6f9ecc359356 100644
--- a/trunk/drivers/media/radio/radio-trust.c
+++ b/trunk/drivers/media/radio/radio-trust.c
@@ -239,8 +239,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct trust *tr = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
tr_setfreq(tr, f->frequency);
return 0;
}
@@ -250,8 +248,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct trust *tr = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = tr->curfreq;
return 0;
diff --git a/trunk/drivers/media/radio/radio-typhoon.c b/trunk/drivers/media/radio/radio-typhoon.c
index 03439282dfce..3a98f1399495 100644
--- a/trunk/drivers/media/radio/radio-typhoon.c
+++ b/trunk/drivers/media/radio/radio-typhoon.c
@@ -207,8 +207,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct typhoon *dev = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = dev->curfreq;
return 0;
@@ -219,8 +217,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct typhoon *dev = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
dev->curfreq = f->frequency;
typhoon_setfreq(dev, dev->curfreq);
return 0;
diff --git a/trunk/drivers/media/radio/radio-zoltrix.c b/trunk/drivers/media/radio/radio-zoltrix.c
index f31eab99c943..80e98b6422fe 100644
--- a/trunk/drivers/media/radio/radio-zoltrix.c
+++ b/trunk/drivers/media/radio/radio-zoltrix.c
@@ -266,8 +266,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
{
struct zoltrix *zol = video_drvdata(file);
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
if (zol_setfreq(zol, f->frequency) != 0)
return -EINVAL;
return 0;
@@ -278,8 +276,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct zoltrix *zol = video_drvdata(file);
- if (f->tuner != 0)
- return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = zol->curfreq;
return 0;
diff --git a/trunk/drivers/media/radio/si470x/radio-si470x-common.c b/trunk/drivers/media/radio/si470x/radio-si470x-common.c
index 4da0f150c6e2..f33315f2c543 100644
--- a/trunk/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/trunk/drivers/media/radio/si470x/radio-si470x-common.c
@@ -425,104 +425,6 @@ int si470x_rds_on(struct si470x_device *radio)
-/**************************************************************************
- * File Operations Interface
- **************************************************************************/
-
-/*
- * si470x_fops_read - read RDS data
- */
-static ssize_t si470x_fops_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct si470x_device *radio = video_drvdata(file);
- int retval = 0;
- unsigned int block_count = 0;
-
- /* switch on rds reception */
- if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
- si470x_rds_on(radio);
-
- /* block if no new data available */
- while (radio->wr_index == radio->rd_index) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EWOULDBLOCK;
- goto done;
- }
- if (wait_event_interruptible(radio->read_queue,
- radio->wr_index != radio->rd_index) < 0) {
- retval = -EINTR;
- goto done;
- }
- }
-
- /* calculate block count from byte count */
- count /= 3;
-
- /* copy RDS block out of internal buffer and to user buffer */
- mutex_lock(&radio->lock);
- while (block_count < count) {
- if (radio->rd_index == radio->wr_index)
- break;
-
- /* always transfer rds complete blocks */
- if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
- /* retval = -EFAULT; */
- break;
-
- /* increment and wrap read pointer */
- radio->rd_index += 3;
- if (radio->rd_index >= radio->buf_size)
- radio->rd_index = 0;
-
- /* increment counters */
- block_count++;
- buf += 3;
- retval += 3;
- }
- mutex_unlock(&radio->lock);
-
-done:
- return retval;
-}
-
-
-/*
- * si470x_fops_poll - poll RDS data
- */
-static unsigned int si470x_fops_poll(struct file *file,
- struct poll_table_struct *pts)
-{
- struct si470x_device *radio = video_drvdata(file);
- int retval = 0;
-
- /* switch on rds reception */
- if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
- si470x_rds_on(radio);
-
- poll_wait(file, &radio->read_queue, pts);
-
- if (radio->rd_index != radio->wr_index)
- retval = POLLIN | POLLRDNORM;
-
- return retval;
-}
-
-
-/*
- * si470x_fops - file operations interface
- */
-static const struct v4l2_file_operations si470x_fops = {
- .owner = THIS_MODULE,
- .read = si470x_fops_read,
- .poll = si470x_fops_poll,
- .ioctl = video_ioctl2,
- .open = si470x_fops_open,
- .release = si470x_fops_release,
-};
-
-
-
/**************************************************************************
* Video4Linux Interface
**************************************************************************/
diff --git a/trunk/drivers/media/radio/si470x/radio-si470x-i2c.c b/trunk/drivers/media/radio/si470x/radio-si470x-i2c.c
index 5466015346a1..2d53b6a9409b 100644
--- a/trunk/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/trunk/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -22,17 +22,22 @@
*/
+/*
+ * ToDo:
+ * - RDS support
+ */
+
+
/* driver definitions */
#define DRIVER_AUTHOR "Joonyoung Shim ";
-#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 1)
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 0)
#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
#define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers"
-#define DRIVER_VERSION "1.0.1"
+#define DRIVER_VERSION "1.0.0"
/* kernel includes */
#include
#include
-#include
#include "radio-si470x.h"
@@ -57,20 +62,6 @@ static int radio_nr = -1;
module_param(radio_nr, int, 0444);
MODULE_PARM_DESC(radio_nr, "Radio Nr");
-/* RDS buffer blocks */
-static unsigned int rds_buf = 100;
-module_param(rds_buf, uint, 0444);
-MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
-
-/* RDS maximum block errors */
-static unsigned short max_rds_errors = 1;
-/* 0 means 0 errors requiring correction */
-/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */
-/* 2 means 3-5 errors requiring correction */
-/* 3 means 6+ errors or errors in checkword, correction not possible */
-module_param(max_rds_errors, ushort, 0644);
-MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
-
/**************************************************************************
@@ -182,7 +173,7 @@ int si470x_disconnect_check(struct si470x_device *radio)
/*
* si470x_fops_open - file open
*/
-int si470x_fops_open(struct file *file)
+static int si470x_fops_open(struct file *file)
{
struct si470x_device *radio = video_drvdata(file);
int retval = 0;
@@ -190,21 +181,12 @@ int si470x_fops_open(struct file *file)
mutex_lock(&radio->lock);
radio->users++;
- if (radio->users == 1) {
+ if (radio->users == 1)
/* start radio */
retval = si470x_start(radio);
- if (retval < 0)
- goto done;
-
- /* enable RDS interrupt */
- radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN;
- radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2;
- radio->registers[SYSCONFIG1] |= 0x1 << 2;
- retval = si470x_set_register(radio, SYSCONFIG1);
- }
-done:
mutex_unlock(&radio->lock);
+
return retval;
}
@@ -212,7 +194,7 @@ int si470x_fops_open(struct file *file)
/*
* si470x_fops_release - file release
*/
-int si470x_fops_release(struct file *file)
+static int si470x_fops_release(struct file *file)
{
struct si470x_device *radio = video_drvdata(file);
int retval = 0;
@@ -233,6 +215,17 @@ int si470x_fops_release(struct file *file)
}
+/*
+ * si470x_fops - file operations interface
+ */
+const struct v4l2_file_operations si470x_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = video_ioctl2,
+ .open = si470x_fops_open,
+ .release = si470x_fops_release,
+};
+
+
/**************************************************************************
* Video4Linux Interface
@@ -259,105 +252,6 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
* I2C Interface
**************************************************************************/
-/*
- * si470x_i2c_interrupt_work - rds processing function
- */
-static void si470x_i2c_interrupt_work(struct work_struct *work)
-{
- struct si470x_device *radio = container_of(work,
- struct si470x_device, radio_work);
- unsigned char regnr;
- unsigned char blocknum;
- unsigned short bler; /* rds block errors */
- unsigned short rds;
- unsigned char tmpbuf[3];
- int retval = 0;
-
- /* safety checks */
- if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
- return;
-
- /* Update RDS registers */
- for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) {
- retval = si470x_get_register(radio, STATUSRSSI + regnr);
- if (retval < 0)
- return;
- }
-
- /* get rds blocks */
- if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0)
- /* No RDS group ready, better luck next time */
- return;
-
- for (blocknum = 0; blocknum < 4; blocknum++) {
- switch (blocknum) {
- default:
- bler = (radio->registers[STATUSRSSI] &
- STATUSRSSI_BLERA) >> 9;
- rds = radio->registers[RDSA];
- break;
- case 1:
- bler = (radio->registers[READCHAN] &
- READCHAN_BLERB) >> 14;
- rds = radio->registers[RDSB];
- break;
- case 2:
- bler = (radio->registers[READCHAN] &
- READCHAN_BLERC) >> 12;
- rds = radio->registers[RDSC];
- break;
- case 3:
- bler = (radio->registers[READCHAN] &
- READCHAN_BLERD) >> 10;
- rds = radio->registers[RDSD];
- break;
- };
-
- /* Fill the V4L2 RDS buffer */
- put_unaligned_le16(rds, &tmpbuf);
- tmpbuf[2] = blocknum; /* offset name */
- tmpbuf[2] |= blocknum << 3; /* received offset */
- if (bler > max_rds_errors)
- tmpbuf[2] |= 0x80; /* uncorrectable errors */
- else if (bler > 0)
- tmpbuf[2] |= 0x40; /* corrected error(s) */
-
- /* copy RDS block to internal buffer */
- memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
- radio->wr_index += 3;
-
- /* wrap write pointer */
- if (radio->wr_index >= radio->buf_size)
- radio->wr_index = 0;
-
- /* check for overflow */
- if (radio->wr_index == radio->rd_index) {
- /* increment and wrap read pointer */
- radio->rd_index += 3;
- if (radio->rd_index >= radio->buf_size)
- radio->rd_index = 0;
- }
- }
-
- if (radio->wr_index != radio->rd_index)
- wake_up_interruptible(&radio->read_queue);
-}
-
-
-/*
- * si470x_i2c_interrupt - interrupt handler
- */
-static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
-{
- struct si470x_device *radio = dev_id;
-
- if (!work_pending(&radio->radio_work))
- schedule_work(&radio->radio_work);
-
- return IRQ_HANDLED;
-}
-
-
/*
* si470x_i2c_probe - probe for the device
*/
@@ -374,8 +268,6 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
retval = -ENOMEM;
goto err_initial;
}
-
- INIT_WORK(&radio->radio_work, si470x_i2c_interrupt_work);
radio->users = 0;
radio->client = client;
mutex_init(&radio->lock);
@@ -427,26 +319,6 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
/* set initial frequency */
si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
- /* rds buffer allocation */
- radio->buf_size = rds_buf * 3;
- radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
- if (!radio->buffer) {
- retval = -EIO;
- goto err_video;
- }
-
- /* rds buffer configuration */
- radio->wr_index = 0;
- radio->rd_index = 0;
- init_waitqueue_head(&radio->read_queue);
-
- retval = request_irq(client->irq, si470x_i2c_interrupt,
- IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
- if (retval) {
- dev_err(&client->dev, "Failed to register interrupt\n");
- goto err_rds;
- }
-
/* register video device */
retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
radio_nr);
@@ -458,9 +330,6 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
return 0;
err_all:
- free_irq(client->irq, radio);
-err_rds:
- kfree(radio->buffer);
err_video:
video_device_release(radio->videodev);
err_radio:
@@ -477,8 +346,6 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
{
struct si470x_device *radio = i2c_get_clientdata(client);
- free_irq(client->irq, radio);
- cancel_work_sync(&radio->radio_work);
video_unregister_device(radio->videodev);
kfree(radio);
i2c_set_clientdata(client, NULL);
@@ -487,44 +354,6 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
}
-#ifdef CONFIG_PM
-/*
- * si470x_i2c_suspend - suspend the device
- */
-static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
-{
- struct si470x_device *radio = i2c_get_clientdata(client);
-
- /* power down */
- radio->registers[POWERCFG] |= POWERCFG_DISABLE;
- if (si470x_set_register(radio, POWERCFG) < 0)
- return -EIO;
-
- return 0;
-}
-
-
-/*
- * si470x_i2c_resume - resume the device
- */
-static int si470x_i2c_resume(struct i2c_client *client)
-{
- struct si470x_device *radio = i2c_get_clientdata(client);
-
- /* power up : need 110ms */
- radio->registers[POWERCFG] |= POWERCFG_ENABLE;
- if (si470x_set_register(radio, POWERCFG) < 0)
- return -EIO;
- msleep(110);
-
- return 0;
-}
-#else
-#define si470x_i2c_suspend NULL
-#define si470x_i2c_resume NULL
-#endif
-
-
/*
* si470x_i2c_driver - i2c driver interface
*/
@@ -535,8 +364,6 @@ static struct i2c_driver si470x_i2c_driver = {
},
.probe = si470x_i2c_probe,
.remove = __devexit_p(si470x_i2c_remove),
- .suspend = si470x_i2c_suspend,
- .resume = si470x_i2c_resume,
.id_table = si470x_i2c_id,
};
diff --git a/trunk/drivers/media/radio/si470x/radio-si470x-usb.c b/trunk/drivers/media/radio/si470x/radio-si470x-usb.c
index a96e1b9dd646..f2d0e1ddb301 100644
--- a/trunk/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/trunk/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -508,10 +508,90 @@ static void si470x_int_in_callback(struct urb *urb)
* File Operations Interface
**************************************************************************/
+/*
+ * si470x_fops_read - read RDS data
+ */
+static ssize_t si470x_fops_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct si470x_device *radio = video_drvdata(file);
+ int retval = 0;
+ unsigned int block_count = 0;
+
+ /* switch on rds reception */
+ if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
+ si470x_rds_on(radio);
+
+ /* block if no new data available */
+ while (radio->wr_index == radio->rd_index) {
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EWOULDBLOCK;
+ goto done;
+ }
+ if (wait_event_interruptible(radio->read_queue,
+ radio->wr_index != radio->rd_index) < 0) {
+ retval = -EINTR;
+ goto done;
+ }
+ }
+
+ /* calculate block count from byte count */
+ count /= 3;
+
+ /* copy RDS block out of internal buffer and to user buffer */
+ mutex_lock(&radio->lock);
+ while (block_count < count) {
+ if (radio->rd_index == radio->wr_index)
+ break;
+
+ /* always transfer rds complete blocks */
+ if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
+ /* retval = -EFAULT; */
+ break;
+
+ /* increment and wrap read pointer */
+ radio->rd_index += 3;
+ if (radio->rd_index >= radio->buf_size)
+ radio->rd_index = 0;
+
+ /* increment counters */
+ block_count++;
+ buf += 3;
+ retval += 3;
+ }
+ mutex_unlock(&radio->lock);
+
+done:
+ return retval;
+}
+
+
+/*
+ * si470x_fops_poll - poll RDS data
+ */
+static unsigned int si470x_fops_poll(struct file *file,
+ struct poll_table_struct *pts)
+{
+ struct si470x_device *radio = video_drvdata(file);
+ int retval = 0;
+
+ /* switch on rds reception */
+ if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
+ si470x_rds_on(radio);
+
+ poll_wait(file, &radio->read_queue, pts);
+
+ if (radio->rd_index != radio->wr_index)
+ retval = POLLIN | POLLRDNORM;
+
+ return retval;
+}
+
+
/*
* si470x_fops_open - file open
*/
-int si470x_fops_open(struct file *file)
+static int si470x_fops_open(struct file *file)
{
struct si470x_device *radio = video_drvdata(file);
int retval;
@@ -565,7 +645,7 @@ int si470x_fops_open(struct file *file)
/*
* si470x_fops_release - file release
*/
-int si470x_fops_release(struct file *file)
+static int si470x_fops_release(struct file *file)
{
struct si470x_device *radio = video_drvdata(file);
int retval = 0;
@@ -608,6 +688,19 @@ int si470x_fops_release(struct file *file)
}
+/*
+ * si470x_fops - file operations interface
+ */
+const struct v4l2_file_operations si470x_fops = {
+ .owner = THIS_MODULE,
+ .read = si470x_fops_read,
+ .poll = si470x_fops_poll,
+ .ioctl = video_ioctl2,
+ .open = si470x_fops_open,
+ .release = si470x_fops_release,
+};
+
+
/**************************************************************************
* Video4Linux Interface
diff --git a/trunk/drivers/media/radio/si470x/radio-si470x.h b/trunk/drivers/media/radio/si470x/radio-si470x.h
index 3cd0a29cd6e7..d0af194d194c 100644
--- a/trunk/drivers/media/radio/si470x/radio-si470x.h
+++ b/trunk/drivers/media/radio/si470x/radio-si470x.h
@@ -29,7 +29,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -182,7 +181,6 @@ struct si470x_device {
#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE)
struct i2c_client *client;
- struct work_struct radio_work;
#endif
};
@@ -214,6 +212,7 @@ struct si470x_device {
/**************************************************************************
* Common Functions
**************************************************************************/
+extern const struct v4l2_file_operations si470x_fops;
extern struct video_device si470x_viddev_template;
int si470x_get_register(struct si470x_device *radio, int regnr);
int si470x_set_register(struct si470x_device *radio, int regnr);
@@ -222,7 +221,5 @@ int si470x_set_freq(struct si470x_device *radio, unsigned int freq);
int si470x_start(struct si470x_device *radio);
int si470x_stop(struct si470x_device *radio);
int si470x_rds_on(struct si470x_device *radio);
-int si470x_fops_open(struct file *file);
-int si470x_fops_release(struct file *file);
int si470x_vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *capability);
diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig
index 2f83be766d9f..9dc74c93bf24 100644
--- a/trunk/drivers/media/video/Kconfig
+++ b/trunk/drivers/media/video/Kconfig
@@ -37,6 +37,10 @@ config VIDEO_BTCX
depends on PCI
tristate
+config VIDEO_IR
+ tristate
+ depends on INPUT
+
config VIDEO_TVEEPROM
tristate
depends on I2C
@@ -836,12 +840,6 @@ config SOC_CAMERA_MT9T031
help
This driver supports MT9T031 cameras from Micron.
-config SOC_CAMERA_MT9T112
- tristate "mt9t112 support"
- depends on SOC_CAMERA && I2C
- help
- This driver supports MT9T112 cameras from Aptina.
-
config SOC_CAMERA_MT9V022
tristate "mt9v022 support"
depends on SOC_CAMERA && I2C
diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile
index 2af68ee84122..7a2dcc34111c 100644
--- a/trunk/drivers/media/video/Makefile
+++ b/trunk/drivers/media/video/Makefile
@@ -75,7 +75,6 @@ obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
-obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o
obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
@@ -150,7 +149,7 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885/
obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
-obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o
+obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
# soc-camera host drivers have to be linked after camera drivers
obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
diff --git a/trunk/drivers/media/video/arv.c b/trunk/drivers/media/video/arv.c
index a356d6bd3131..d137bac84511 100644
--- a/trunk/drivers/media/video/arv.c
+++ b/trunk/drivers/media/video/arv.c
@@ -767,6 +767,7 @@ static struct video_device ar_template = {
.name = "Colour AR VGA",
.fops = &ar_fops,
.release = ar_release,
+ .minor = -1,
};
#define ALIGN4(x) ((((int)(x)) & 0x3) == 0)
@@ -859,8 +860,8 @@ static int __init ar_init(void)
goto out_dev;
}
- printk("%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
- video_device_node_name(ar->vdev), M32R_IRQ_INT3, freq);
+ printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
+ ar->vdev->num, M32R_IRQ_INT3, freq);
return 0;
diff --git a/trunk/drivers/media/video/au0828/au0828-video.c b/trunk/drivers/media/video/au0828/au0828-video.c
index dc67bc40f36f..1485aee18d58 100644
--- a/trunk/drivers/media/video/au0828/au0828-video.c
+++ b/trunk/drivers/media/video/au0828/au0828-video.c
@@ -40,6 +40,7 @@
#include "au0828.h"
#include "au0828-reg.h"
+static LIST_HEAD(au0828_devlist);
static DEFINE_MUTEX(au0828_sysfs_lock);
#define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1)
@@ -692,8 +693,10 @@ void au0828_analog_unregister(struct au0828_dev *dev)
dprintk(1, "au0828_release_resources called\n");
mutex_lock(&au0828_sysfs_lock);
- if (dev->vdev)
+ if (dev->vdev) {
+ list_del(&dev->au0828list);
video_unregister_device(dev->vdev);
+ }
if (dev->vbi_dev)
video_unregister_device(dev->vbi_dev);
@@ -734,15 +737,29 @@ static void res_free(struct au0828_fh *fh)
static int au0828_v4l2_open(struct file *filp)
{
+ int minor = video_devdata(filp)->minor;
int ret = 0;
- struct au0828_dev *dev = video_drvdata(filp);
+ struct au0828_dev *h, *dev = NULL;
struct au0828_fh *fh;
- int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
+ int type = 0;
+ struct list_head *list;
+
+ list_for_each(list, &au0828_devlist) {
+ h = list_entry(list, struct au0828_dev, au0828list);
+ if (h->vdev->minor == minor) {
+ dev = h;
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ }
#ifdef VBI_IS_WORKING
- if (video_devdata(filp)->vfl_type == VFL_TYPE_GRABBER)
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ if (h->vbi_dev->minor == minor) {
+ dev = h;
+ type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ }
#endif
+ }
+
+ if (NULL == dev)
+ return -ENODEV;
fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
if (NULL == fh) {
@@ -1570,6 +1587,7 @@ static const struct video_device au0828_video_template = {
.fops = &au0828_v4l_fops,
.release = video_device_release,
.ioctl_ops = &video_ioctl_ops,
+ .minor = -1,
.tvnorms = V4L2_STD_NTSC_M,
.current_norm = V4L2_STD_NTSC_M,
};
@@ -1658,23 +1676,25 @@ int au0828_analog_register(struct au0828_dev *dev,
strcpy(dev->vbi_dev->name, "au0828a vbi");
#endif
+ list_add_tail(&dev->au0828list, &au0828_devlist);
+
/* Register the v4l2 device */
- video_set_drvdata(dev->vdev, dev);
retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1);
if (retval != 0) {
dprintk(1, "unable to register video device (error = %d).\n",
retval);
+ list_del(&dev->au0828list);
video_device_release(dev->vdev);
return -ENODEV;
}
#ifdef VBI_IS_WORKING
/* Register the vbi device */
- video_set_drvdata(dev->vbi_dev, dev);
retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1);
if (retval != 0) {
dprintk(1, "unable to register vbi device (error = %d).\n",
retval);
+ list_del(&dev->au0828list);
video_device_release(dev->vbi_dev);
video_device_release(dev->vdev);
return -ENODEV;
diff --git a/trunk/drivers/media/video/au0828/au0828.h b/trunk/drivers/media/video/au0828/au0828.h
index 207f32dec6a6..b977915efbd0 100644
--- a/trunk/drivers/media/video/au0828/au0828.h
+++ b/trunk/drivers/media/video/au0828/au0828.h
@@ -192,6 +192,7 @@ struct au0828_dev {
struct au0828_dvb dvb;
/* Analog */
+ struct list_head au0828list;
struct v4l2_device v4l2_dev;
int users;
unsigned int stream_on:1; /* Locks streams */
diff --git a/trunk/drivers/media/video/bt8xx/bttv-driver.c b/trunk/drivers/media/video/bt8xx/bttv-driver.c
index 3182a406bdd1..a6724019c66f 100644
--- a/trunk/drivers/media/video/bt8xx/bttv-driver.c
+++ b/trunk/drivers/media/video/bt8xx/bttv-driver.c
@@ -3206,24 +3206,24 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
static int bttv_open(struct file *file)
{
- struct video_device *vdev = video_devdata(file);
+ int minor = video_devdata(file)->minor;
struct bttv *btv = video_drvdata(file);
struct bttv_fh *fh;
enum v4l2_buf_type type = 0;
- dprintk(KERN_DEBUG "bttv: open dev=%s\n", video_device_node_name(vdev));
+ dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
- if (vdev->vfl_type == VFL_TYPE_GRABBER) {
+ lock_kernel();
+ if (btv->video_dev->minor == minor) {
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- } else if (vdev->vfl_type == VFL_TYPE_VBI) {
+ } else if (btv->vbi_dev->minor == minor) {
type = V4L2_BUF_TYPE_VBI_CAPTURE;
} else {
WARN_ON(1);
+ unlock_kernel();
return -ENODEV;
}
- lock_kernel();
-
dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n",
btv->c.nr,v4l2_type_names[type]);
@@ -3397,6 +3397,7 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = {
static struct video_device bttv_video_template = {
.fops = &bttv_fops,
+ .minor = -1,
.ioctl_ops = &bttv_ioctl_ops,
.tvnorms = BTTV_NORMS,
.current_norm = V4L2_STD_PAL,
@@ -3407,13 +3408,18 @@ static struct video_device bttv_video_template = {
static int radio_open(struct file *file)
{
- struct video_device *vdev = video_devdata(file);
+ int minor = video_devdata(file)->minor;
struct bttv *btv = video_drvdata(file);
struct bttv_fh *fh;
- dprintk("bttv: open dev=%s\n", video_device_node_name(vdev));
+ dprintk("bttv: open minor=%d\n",minor);
lock_kernel();
+ WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor);
+ if (!btv->radio_dev || btv->radio_dev->minor != minor) {
+ unlock_kernel();
+ return -ENODEV;
+ }
dprintk("bttv%d: open called (radio)\n",btv->c.nr);
@@ -3634,6 +3640,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
static struct video_device radio_template = {
.fops = &radio_fops,
+ .minor = -1,
.ioctl_ops = &radio_ioctl_ops,
};
@@ -4201,21 +4208,21 @@ static struct video_device *vdev_init(struct bttv *btv,
static void bttv_unregister_video(struct bttv *btv)
{
if (btv->video_dev) {
- if (video_is_registered(btv->video_dev))
+ if (-1 != btv->video_dev->minor)
video_unregister_device(btv->video_dev);
else
video_device_release(btv->video_dev);
btv->video_dev = NULL;
}
if (btv->vbi_dev) {
- if (video_is_registered(btv->vbi_dev))
+ if (-1 != btv->vbi_dev->minor)
video_unregister_device(btv->vbi_dev);
else
video_device_release(btv->vbi_dev);
btv->vbi_dev = NULL;
}
if (btv->radio_dev) {
- if (video_is_registered(btv->radio_dev))
+ if (-1 != btv->radio_dev->minor)
video_unregister_device(btv->radio_dev);
else
video_device_release(btv->radio_dev);
@@ -4237,8 +4244,8 @@ static int __devinit bttv_register_video(struct bttv *btv)
if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER,
video_nr[btv->c.nr]) < 0)
goto err;
- printk(KERN_INFO "bttv%d: registered device %s\n",
- btv->c.nr, video_device_node_name(btv->video_dev));
+ printk(KERN_INFO "bttv%d: registered device video%d\n",
+ btv->c.nr, btv->video_dev->num);
if (device_create_file(&btv->video_dev->dev,
&dev_attr_card)<0) {
printk(KERN_ERR "bttv%d: device_create_file 'card' "
@@ -4254,8 +4261,8 @@ static int __devinit bttv_register_video(struct bttv *btv)
if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI,
vbi_nr[btv->c.nr]) < 0)
goto err;
- printk(KERN_INFO "bttv%d: registered device %s\n",
- btv->c.nr, video_device_node_name(btv->vbi_dev));
+ printk(KERN_INFO "bttv%d: registered device vbi%d\n",
+ btv->c.nr, btv->vbi_dev->num);
if (!btv->has_radio)
return 0;
@@ -4266,8 +4273,8 @@ static int __devinit bttv_register_video(struct bttv *btv)
if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,
radio_nr[btv->c.nr]) < 0)
goto err;
- printk(KERN_INFO "bttv%d: registered device %s\n",
- btv->c.nr, video_device_node_name(btv->radio_dev));
+ printk(KERN_INFO "bttv%d: registered device radio%d\n",
+ btv->c.nr, btv->radio_dev->num);
/* all done */
return 0;
diff --git a/trunk/drivers/media/video/bt8xx/bttv-i2c.c b/trunk/drivers/media/video/bt8xx/bttv-i2c.c
index 63aa31a041e8..beda363418b0 100644
--- a/trunk/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/trunk/drivers/media/video/bt8xx/bttv-i2c.c
@@ -40,7 +40,7 @@ static int i2c_debug;
static int i2c_hw;
static int i2c_scan;
module_param(i2c_debug, int, 0644);
-MODULE_PARM_DESC(i2c_debug, "configure i2c debug level");
+MODULE_PARM_DESC(i2c_hw,"configure i2c debug level");
module_param(i2c_hw, int, 0444);
MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, "
"instead of software bitbang");
@@ -400,7 +400,7 @@ int __devinit init_bttv_i2c(struct bttv *btv)
That's why we probe 0x1a (~0x34) first. CB
*/
const unsigned short addr_list[] = {
- 0x1a, 0x18, 0x4b, 0x64, 0x30, 0x71,
+ 0x1a, 0x18, 0x4b, 0x64, 0x30,
I2C_CLIENT_END
};
diff --git a/trunk/drivers/media/video/bt8xx/bttv-input.c b/trunk/drivers/media/video/bt8xx/bttv-input.c
index 277a092e1214..84a957e52c4b 100644
--- a/trunk/drivers/media/video/bt8xx/bttv-input.c
+++ b/trunk/drivers/media/video/bt8xx/bttv-input.c
@@ -368,7 +368,7 @@ int bttv_input_init(struct bttv *btv)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(btv->c.pci));
- err = ir_input_init(input_dev, &ir->ir, ir_type);
+ err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
if (err < 0)
goto err_out_free;
@@ -389,7 +389,7 @@ int bttv_input_init(struct bttv *btv)
bttv_ir_start(btv, ir);
/* all done */
- err = ir_input_register(btv->remote->dev, ir_codes);
+ err = input_register_device(btv->remote->dev);
if (err)
goto err_out_stop;
@@ -403,6 +403,8 @@ int bttv_input_init(struct bttv *btv)
bttv_ir_stop(btv);
btv->remote = NULL;
err_out_free:
+ ir_input_free(input_dev);
+ input_free_device(input_dev);
kfree(ir);
return err;
}
@@ -413,7 +415,8 @@ void bttv_input_fini(struct bttv *btv)
return;
bttv_ir_stop(btv);
- ir_input_unregister(btv->remote->dev);
+ ir_input_free(btv->remote->dev);
+ input_unregister_device(btv->remote->dev);
kfree(btv->remote);
btv->remote = NULL;
}
diff --git a/trunk/drivers/media/video/c-qcam.c b/trunk/drivers/media/video/c-qcam.c
index e2cbebab959b..85cf1778827a 100644
--- a/trunk/drivers/media/video/c-qcam.c
+++ b/trunk/drivers/media/video/c-qcam.c
@@ -809,8 +809,8 @@ static int init_cqcam(struct parport *port)
return -ENODEV;
}
- printk(KERN_INFO "%s: Colour QuickCam found on %s\n",
- video_device_node_name(&qcam->vdev), qcam->pport->name);
+ printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
+ qcam->vdev.num, qcam->pport->name);
qcams[num_cams++] = qcam;
diff --git a/trunk/drivers/media/video/cafe_ccic.c b/trunk/drivers/media/video/cafe_ccic.c
index 7bb9c1ec7819..10230cb3d210 100644
--- a/trunk/drivers/media/video/cafe_ccic.c
+++ b/trunk/drivers/media/video/cafe_ccic.c
@@ -1723,6 +1723,7 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
static struct video_device cafe_v4l_template = {
.name = "cafe",
+ .minor = -1, /* Get one dynamically */
.tvnorms = V4L2_STD_NTSC_M,
.current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */
diff --git a/trunk/drivers/media/video/cpia.c b/trunk/drivers/media/video/cpia.c
index 551ddf216a4b..2377313c041a 100644
--- a/trunk/drivers/media/video/cpia.c
+++ b/trunk/drivers/media/video/cpia.c
@@ -32,7 +32,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -245,67 +244,72 @@ static void rvfree(void *mem, unsigned long size)
#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *cpia_proc_root=NULL;
-static int cpia_proc_show(struct seq_file *m, void *v)
+static int cpia_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
{
- struct cam_data *cam = m->private;
- int tmp;
+ char *out = page;
+ int len, tmp;
+ struct cam_data *cam = data;
char tmpstr[29];
- seq_printf(m, "read-only\n-----------------------\n");
- seq_printf(m, "V4L Driver version: %d.%d.%d\n",
+ /* IMPORTANT: This output MUST be kept under PAGE_SIZE
+ * or we need to get more sophisticated. */
+
+ out += sprintf(out, "read-only\n-----------------------\n");
+ out += sprintf(out, "V4L Driver version: %d.%d.%d\n",
CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
- seq_printf(m, "CPIA Version: %d.%02d (%d.%d)\n",
+ out += sprintf(out, "CPIA Version: %d.%02d (%d.%d)\n",
cam->params.version.firmwareVersion,
cam->params.version.firmwareRevision,
cam->params.version.vcVersion,
cam->params.version.vcRevision);
- seq_printf(m, "CPIA PnP-ID: %04x:%04x:%04x\n",
+ out += sprintf(out, "CPIA PnP-ID: %04x:%04x:%04x\n",
cam->params.pnpID.vendor, cam->params.pnpID.product,
cam->params.pnpID.deviceRevision);
- seq_printf(m, "VP-Version: %d.%d %04x\n",
+ out += sprintf(out, "VP-Version: %d.%d %04x\n",
cam->params.vpVersion.vpVersion,
cam->params.vpVersion.vpRevision,
cam->params.vpVersion.cameraHeadID);
- seq_printf(m, "system_state: %#04x\n",
+ out += sprintf(out, "system_state: %#04x\n",
cam->params.status.systemState);
- seq_printf(m, "grab_state: %#04x\n",
+ out += sprintf(out, "grab_state: %#04x\n",
cam->params.status.grabState);
- seq_printf(m, "stream_state: %#04x\n",
+ out += sprintf(out, "stream_state: %#04x\n",
cam->params.status.streamState);
- seq_printf(m, "fatal_error: %#04x\n",
+ out += sprintf(out, "fatal_error: %#04x\n",
cam->params.status.fatalError);
- seq_printf(m, "cmd_error: %#04x\n",
+ out += sprintf(out, "cmd_error: %#04x\n",
cam->params.status.cmdError);
- seq_printf(m, "debug_flags: %#04x\n",
+ out += sprintf(out, "debug_flags: %#04x\n",
cam->params.status.debugFlags);
- seq_printf(m, "vp_status: %#04x\n",
+ out += sprintf(out, "vp_status: %#04x\n",
cam->params.status.vpStatus);
- seq_printf(m, "error_code: %#04x\n",
+ out += sprintf(out, "error_code: %#04x\n",
cam->params.status.errorCode);
/* QX3 specific entries */
if (cam->params.qx3.qx3_detected) {
- seq_printf(m, "button: %4d\n",
+ out += sprintf(out, "button: %4d\n",
cam->params.qx3.button);
- seq_printf(m, "cradled: %4d\n",
+ out += sprintf(out, "cradled: %4d\n",
cam->params.qx3.cradled);
}
- seq_printf(m, "video_size: %s\n",
+ out += sprintf(out, "video_size: %s\n",
cam->params.format.videoSize == VIDEOSIZE_CIF ?
"CIF " : "QCIF");
- seq_printf(m, "roi: (%3d, %3d) to (%3d, %3d)\n",
+ out += sprintf(out, "roi: (%3d, %3d) to (%3d, %3d)\n",
cam->params.roi.colStart*8,
cam->params.roi.rowStart*4,
cam->params.roi.colEnd*8,
cam->params.roi.rowEnd*4);
- seq_printf(m, "actual_fps: %3d\n", cam->fps);
- seq_printf(m, "transfer_rate: %4dkB/s\n",
+ out += sprintf(out, "actual_fps: %3d\n", cam->fps);
+ out += sprintf(out, "transfer_rate: %4dkB/s\n",
cam->transfer_rate);
- seq_printf(m, "\nread-write\n");
- seq_printf(m, "----------------------- current min"
+ out += sprintf(out, "\nread-write\n");
+ out += sprintf(out, "----------------------- current min"
" max default comment\n");
- seq_printf(m, "brightness: %8d %8d %8d %8d\n",
+ out += sprintf(out, "brightness: %8d %8d %8d %8d\n",
cam->params.colourParams.brightness, 0, 100, 50);
if (cam->params.version.firmwareVersion == 1 &&
cam->params.version.firmwareRevision == 2)
@@ -314,26 +318,26 @@ static int cpia_proc_show(struct seq_file *m, void *v)
else
tmp = 96;
- seq_printf(m, "contrast: %8d %8d %8d %8d"
+ out += sprintf(out, "contrast: %8d %8d %8d %8d"
" steps of 8\n",
cam->params.colourParams.contrast, 0, tmp, 48);
- seq_printf(m, "saturation: %8d %8d %8d %8d\n",
+ out += sprintf(out, "saturation: %8d %8d %8d %8d\n",
cam->params.colourParams.saturation, 0, 100, 50);
tmp = (25000+5000*cam->params.sensorFps.baserate)/
(1<params.sensorFps.divisor);
- seq_printf(m, "sensor_fps: %4d.%03d %8d %8d %8d\n",
+ out += sprintf(out, "sensor_fps: %4d.%03d %8d %8d %8d\n",
tmp/1000, tmp%1000, 3, 30, 15);
- seq_printf(m, "stream_start_line: %8d %8d %8d %8d\n",
+ out += sprintf(out, "stream_start_line: %8d %8d %8d %8d\n",
2*cam->params.streamStartLine, 0,
cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144,
cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120);
- seq_printf(m, "sub_sample: %8s %8s %8s %8s\n",
+ out += sprintf(out, "sub_sample: %8s %8s %8s %8s\n",
cam->params.format.subSample == SUBSAMPLE_420 ?
"420" : "422", "420", "422", "422");
- seq_printf(m, "yuv_order: %8s %8s %8s %8s\n",
+ out += sprintf(out, "yuv_order: %8s %8s %8s %8s\n",
cam->params.format.yuvOrder == YUVORDER_YUYV ?
"YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV");
- seq_printf(m, "ecp_timing: %8s %8s %8s %8s\n",
+ out += sprintf(out, "ecp_timing: %8s %8s %8s %8s\n",
cam->params.ecpTiming ? "slow" : "normal", "slow",
"normal", "normal");
@@ -342,13 +346,13 @@ static int cpia_proc_show(struct seq_file *m, void *v)
} else {
sprintf(tmpstr, "manual");
}
- seq_printf(m, "color_balance_mode: %8s %8s %8s"
+ out += sprintf(out, "color_balance_mode: %8s %8s %8s"
" %8s\n", tmpstr, "manual", "auto", "auto");
- seq_printf(m, "red_gain: %8d %8d %8d %8d\n",
+ out += sprintf(out, "red_gain: %8d %8d %8d %8d\n",
cam->params.colourBalance.redGain, 0, 212, 32);
- seq_printf(m, "green_gain: %8d %8d %8d %8d\n",
+ out += sprintf(out, "green_gain: %8d %8d %8d %8d\n",
cam->params.colourBalance.greenGain, 0, 212, 6);
- seq_printf(m, "blue_gain: %8d %8d %8d %8d\n",
+ out += sprintf(out, "blue_gain: %8d %8d %8d %8d\n",
cam->params.colourBalance.blueGain, 0, 212, 92);
if (cam->params.version.firmwareVersion == 1 &&
@@ -359,10 +363,10 @@ static int cpia_proc_show(struct seq_file *m, void *v)
sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2);
if (cam->params.exposure.gainMode == 0)
- seq_printf(m, "max_gain: unknown %28s"
+ out += sprintf(out, "max_gain: unknown %28s"
" powers of 2\n", tmpstr);
else
- seq_printf(m, "max_gain: %8d %28s"
+ out += sprintf(out, "max_gain: %8d %28s"
" 1,2,4 or 8 \n",
1<<(cam->params.exposure.gainMode-1), tmpstr);
@@ -378,12 +382,12 @@ static int cpia_proc_show(struct seq_file *m, void *v)
sprintf(tmpstr, "unknown");
break;
}
- seq_printf(m, "exposure_mode: %8s %8s %8s"
+ out += sprintf(out, "exposure_mode: %8s %8s %8s"
" %8s\n", tmpstr, "manual", "auto", "auto");
- seq_printf(m, "centre_weight: %8s %8s %8s %8s\n",
+ out += sprintf(out, "centre_weight: %8s %8s %8s %8s\n",
(2-cam->params.exposure.centreWeight) ? "on" : "off",
"off", "on", "on");
- seq_printf(m, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n",
+ out += sprintf(out, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n",
1<params.exposure.gain, 1, 1);
if (cam->params.version.firmwareVersion == 1 &&
cam->params.version.firmwareRevision == 2)
@@ -392,7 +396,7 @@ static int cpia_proc_show(struct seq_file *m, void *v)
else
tmp = 510;
- seq_printf(m, "fine_exp: %8d %8d %8d %8d\n",
+ out += sprintf(out, "fine_exp: %8d %8d %8d %8d\n",
cam->params.exposure.fineExp*2, 0, tmp, 0);
if (cam->params.version.firmwareVersion == 1 &&
cam->params.version.firmwareRevision == 2)
@@ -401,122 +405,127 @@ static int cpia_proc_show(struct seq_file *m, void *v)
else
tmp = MAX_EXP;
- seq_printf(m, "coarse_exp: %8d %8d %8d"
+ out += sprintf(out, "coarse_exp: %8d %8d %8d"
" %8d\n", cam->params.exposure.coarseExpLo+
256*cam->params.exposure.coarseExpHi, 0, tmp, 185);
- seq_printf(m, "red_comp: %8d %8d %8d %8d\n",
+ out += sprintf(out, "red_comp: %8d %8d %8d %8d\n",
cam->params.exposure.redComp, COMP_RED, 255, COMP_RED);
- seq_printf(m, "green1_comp: %8d %8d %8d %8d\n",
+ out += sprintf(out, "green1_comp: %8d %8d %8d %8d\n",
cam->params.exposure.green1Comp, COMP_GREEN1, 255,
COMP_GREEN1);
- seq_printf(m, "green2_comp: %8d %8d %8d %8d\n",
+ out += sprintf(out, "green2_comp: %8d %8d %8d %8d\n",
cam->params.exposure.green2Comp, COMP_GREEN2, 255,
COMP_GREEN2);
- seq_printf(m, "blue_comp: %8d %8d %8d %8d\n",
+ out += sprintf(out, "blue_comp: %8d %8d %8d %8d\n",
cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE);
- seq_printf(m, "apcor_gain1: %#8x %#8x %#8x %#8x\n",
+ out += sprintf(out, "apcor_gain1: %#8x %#8x %#8x %#8x\n",
cam->params.apcor.gain1, 0, 0xff, 0x1c);
- seq_printf(m, "apcor_gain2: %#8x %#8x %#8x %#8x\n",
+ out += sprintf(out, "apcor_gain2: %#8x %#8x %#8x %#8x\n",
cam->params.apcor.gain2, 0, 0xff, 0x1a);
- seq_printf(m, "apcor_gain4: %#8x %#8x %#8x %#8x\n",
+ out += sprintf(out, "apcor_gain4: %#8x %#8x %#8x %#8x\n",
cam->params.apcor.gain4, 0, 0xff, 0x2d);
- seq_printf(m, "apcor_gain8: %#8x %#8x %#8x %#8x\n",
+ out += sprintf(out, "apcor_gain8: %#8x %#8x %#8x %#8x\n",
cam->params.apcor.gain8, 0, 0xff, 0x2a);
- seq_printf(m, "vl_offset_gain1: %8d %8d %8d %8d\n",
+ out += sprintf(out, "vl_offset_gain1: %8d %8d %8d %8d\n",
cam->params.vlOffset.gain1, 0, 255, 24);
- seq_printf(m, "vl_offset_gain2: %8d %8d %8d %8d\n",
+ out += sprintf(out, "vl_offset_gain2: %8d %8d %8d %8d\n",
cam->params.vlOffset.gain2, 0, 255, 28);
- seq_printf(m, "vl_offset_gain4: %8d %8d %8d %8d\n",
+ out += sprintf(out, "vl_offset_gain4: %8d %8d %8d %8d\n",
cam->params.vlOffset.gain4, 0, 255, 30);
- seq_printf(m, "vl_offset_gain8: %8d %8d %8d %8d\n",
+ out += sprintf(out, "vl_offset_gain8: %8d %8d %8d %8d\n",
cam->params.vlOffset.gain8, 0, 255, 30);
- seq_printf(m, "flicker_control: %8s %8s %8s %8s\n",
+ out += sprintf(out, "flicker_control: %8s %8s %8s %8s\n",
cam->params.flickerControl.flickerMode ? "on" : "off",
"off", "on", "off");
- seq_printf(m, "mains_frequency: %8d %8d %8d %8d"
+ out += sprintf(out, "mains_frequency: %8d %8d %8d %8d"
" only 50/60\n",
cam->mainsFreq ? 60 : 50, 50, 60, 50);
if(cam->params.flickerControl.allowableOverExposure < 0)
- seq_printf(m, "allowable_overexposure: %4dauto auto %8d auto\n",
+ out += sprintf(out, "allowable_overexposure: %4dauto auto %8d auto\n",
-cam->params.flickerControl.allowableOverExposure,
255);
else
- seq_printf(m, "allowable_overexposure: %8d auto %8d auto\n",
+ out += sprintf(out, "allowable_overexposure: %8d auto %8d auto\n",
cam->params.flickerControl.allowableOverExposure,
255);
- seq_printf(m, "compression_mode: ");
+ out += sprintf(out, "compression_mode: ");
switch(cam->params.compression.mode) {
case CPIA_COMPRESSION_NONE:
- seq_printf(m, "%8s", "none");
+ out += sprintf(out, "%8s", "none");
break;
case CPIA_COMPRESSION_AUTO:
- seq_printf(m, "%8s", "auto");
+ out += sprintf(out, "%8s", "auto");
break;
case CPIA_COMPRESSION_MANUAL:
- seq_printf(m, "%8s", "manual");
+ out += sprintf(out, "%8s", "manual");
break;
default:
- seq_printf(m, "%8s", "unknown");
+ out += sprintf(out, "%8s", "unknown");
break;
}
- seq_printf(m, " none,auto,manual auto\n");
- seq_printf(m, "decimation_enable: %8s %8s %8s %8s\n",
+ out += sprintf(out, " none,auto,manual auto\n");
+ out += sprintf(out, "decimation_enable: %8s %8s %8s %8s\n",
cam->params.compression.decimation ==
DECIMATION_ENAB ? "on":"off", "off", "on",
"off");
- seq_printf(m, "compression_target: %9s %9s %9s %9s\n",
+ out += sprintf(out, "compression_target: %9s %9s %9s %9s\n",
cam->params.compressionTarget.frTargeting ==
CPIA_COMPRESSION_TARGET_FRAMERATE ?
"framerate":"quality",
"framerate", "quality", "quality");
- seq_printf(m, "target_framerate: %8d %8d %8d %8d\n",
+ out += sprintf(out, "target_framerate: %8d %8d %8d %8d\n",
cam->params.compressionTarget.targetFR, 1, 30, 15);
- seq_printf(m, "target_quality: %8d %8d %8d %8d\n",
+ out += sprintf(out, "target_quality: %8d %8d %8d %8d\n",
cam->params.compressionTarget.targetQ, 1, 64, 5);
- seq_printf(m, "y_threshold: %8d %8d %8d %8d\n",
+ out += sprintf(out, "y_threshold: %8d %8d %8d %8d\n",
cam->params.yuvThreshold.yThreshold, 0, 31, 6);
- seq_printf(m, "uv_threshold: %8d %8d %8d %8d\n",
+ out += sprintf(out, "uv_threshold: %8d %8d %8d %8d\n",
cam->params.yuvThreshold.uvThreshold, 0, 31, 6);
- seq_printf(m, "hysteresis: %8d %8d %8d %8d\n",
+ out += sprintf(out, "hysteresis: %8d %8d %8d %8d\n",
cam->params.compressionParams.hysteresis, 0, 255, 3);
- seq_printf(m, "threshold_max: %8d %8d %8d %8d\n",
+ out += sprintf(out, "threshold_max: %8d %8d %8d %8d\n",
cam->params.compressionParams.threshMax, 0, 255, 11);
- seq_printf(m, "small_step: %8d %8d %8d %8d\n",
+ out += sprintf(out, "small_step: %8d %8d %8d %8d\n",
cam->params.compressionParams.smallStep, 0, 255, 1);
- seq_printf(m, "large_step: %8d %8d %8d %8d\n",
+ out += sprintf(out, "large_step: %8d %8d %8d %8d\n",
cam->params.compressionParams.largeStep, 0, 255, 3);
- seq_printf(m, "decimation_hysteresis: %8d %8d %8d %8d\n",
+ out += sprintf(out, "decimation_hysteresis: %8d %8d %8d %8d\n",
cam->params.compressionParams.decimationHysteresis,
0, 255, 2);
- seq_printf(m, "fr_diff_step_thresh: %8d %8d %8d %8d\n",
+ out += sprintf(out, "fr_diff_step_thresh: %8d %8d %8d %8d\n",
cam->params.compressionParams.frDiffStepThresh,
0, 255, 5);
- seq_printf(m, "q_diff_step_thresh: %8d %8d %8d %8d\n",
+ out += sprintf(out, "q_diff_step_thresh: %8d %8d %8d %8d\n",
cam->params.compressionParams.qDiffStepThresh,
0, 255, 3);
- seq_printf(m, "decimation_thresh_mod: %8d %8d %8d %8d\n",
+ out += sprintf(out, "decimation_thresh_mod: %8d %8d %8d %8d\n",
cam->params.compressionParams.decimationThreshMod,
0, 255, 2);
/* QX3 specific entries */
if (cam->params.qx3.qx3_detected) {
- seq_printf(m, "toplight: %8s %8s %8s %8s\n",
+ out += sprintf(out, "toplight: %8s %8s %8s %8s\n",
cam->params.qx3.toplight ? "on" : "off",
"off", "on", "off");
- seq_printf(m, "bottomlight: %8s %8s %8s %8s\n",
+ out += sprintf(out, "bottomlight: %8s %8s %8s %8s\n",
cam->params.qx3.bottomlight ? "on" : "off",
"off", "on", "off");
}
- return 0;
-}
+ len = out - page;
+ len -= off;
+ if (len < count) {
+ *eof = 1;
+ if (len <= 0) return 0;
+ } else
+ len = count;
-static int cpia_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, cpia_proc_show, PDE(inode)->data);
+ *start = page + off;
+ return len;
}
-static int match(char *checkstr, char **buffer, size_t *count,
+
+static int match(char *checkstr, char **buffer, unsigned long *count,
int *find_colon, int *err)
{
int ret, colon_found = 1;
@@ -542,7 +551,7 @@ static int match(char *checkstr, char **buffer, size_t *count,
return ret;
}
-static unsigned long int value(char **buffer, size_t *count, int *err)
+static unsigned long int value(char **buffer, unsigned long *count, int *err)
{
char *p;
unsigned long int ret;
@@ -556,10 +565,10 @@ static unsigned long int value(char **buffer, size_t *count, int *err)
return ret;
}
-static ssize_t cpia_proc_write(struct file *file, const char __user *buf,
- size_t count, loff_t *pos)
+static int cpia_write_proc(struct file *file, const char __user *buf,
+ unsigned long count, void *data)
{
- struct cam_data *cam = PDE(file->f_path.dentry->d_inode)->data;
+ struct cam_data *cam = data;
struct cam_params new_params;
char *page, *buffer;
int retval, find_colon;
@@ -573,7 +582,7 @@ static ssize_t cpia_proc_write(struct file *file, const char __user *buf,
* from the comx driver
*/
if (count > PAGE_SIZE) {
- printk(KERN_ERR "count is %zu > %d!!!\n", count, (int)PAGE_SIZE);
+ printk(KERN_ERR "count is %lu > %d!!!\n", count, (int)PAGE_SIZE);
return -ENOSPC;
}
@@ -1331,28 +1340,23 @@ static ssize_t cpia_proc_write(struct file *file, const char __user *buf,
return retval;
}
-static const struct file_operations cpia_proc_fops = {
- .owner = THIS_MODULE,
- .open = cpia_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = cpia_proc_write,
-};
-
static void create_proc_cpia_cam(struct cam_data *cam)
{
+ char name[5 + 1 + 10 + 1];
struct proc_dir_entry *ent;
if (!cpia_proc_root || !cam)
return;
- ent = proc_create_data(video_device_node_name(&cam->vdev),
- S_IRUGO|S_IWUSR, cpia_proc_root,
- &cpia_proc_fops, cam);
+ snprintf(name, sizeof(name), "video%d", cam->vdev.num);
+
+ ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root);
if (!ent)
return;
+ ent->data = cam;
+ ent->read_proc = cpia_read_proc;
+ ent->write_proc = cpia_write_proc;
/*
size of the proc entry is 3736 bytes for the standard webcam;
the extra features of the QX3 microscope add 189 bytes.
@@ -1364,10 +1368,13 @@ static void create_proc_cpia_cam(struct cam_data *cam)
static void destroy_proc_cpia_cam(struct cam_data *cam)
{
+ char name[5 + 1 + 10 + 1];
+
if (!cam || !cam->proc_entry)
return;
- remove_proc_entry(video_device_node_name(&cam->vdev), cpia_proc_root);
+ snprintf(name, sizeof(name), "video%d", cam->vdev.num);
+ remove_proc_entry(name, cpia_proc_root);
cam->proc_entry = NULL;
}
@@ -3992,7 +3999,7 @@ void cpia_unregister_camera(struct cam_data *cam)
}
#ifdef CONFIG_PROC_FS
- DBG("destroying /proc/cpia/%s\n", video_device_node_name(&cam->vdev));
+ DBG("destroying /proc/cpia/video%d\n", cam->vdev.num);
destroy_proc_cpia_cam(cam);
#endif
if (!cam->open_count) {
diff --git a/trunk/drivers/media/video/cpia2/cpia2_v4l.c b/trunk/drivers/media/video/cpia2/cpia2_v4l.c
index 6f91415eb7b4..0b4a8f309cfa 100644
--- a/trunk/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/trunk/drivers/media/video/cpia2/cpia2_v4l.c
@@ -38,12 +38,17 @@
#include
#include
#include
-#include
#include
#include "cpia2.h"
#include "cpia2dev.h"
+
+//#define _CPIA2_DEBUG_
+
+#define MAKE_STRING_1(x) #x
+#define MAKE_STRING(x) MAKE_STRING_1(x)
+
static int video_nr = -1;
module_param(video_nr, int, 0);
MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");
@@ -55,26 +60,26 @@ MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)
static int num_buffers = 3;
module_param(num_buffers, int, 0);
MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-"
- __stringify(VIDEO_MAX_FRAME) ", default 3)");
+ MAKE_STRING(VIDEO_MAX_FRAME) ", default 3)");
static int alternate = DEFAULT_ALT;
module_param(alternate, int, 0);
-MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-"
- __stringify(USBIF_ISO_6) ", default "
- __stringify(DEFAULT_ALT) ")");
+MODULE_PARM_DESC(alternate, "USB Alternate (" MAKE_STRING(USBIF_ISO_1) "-"
+ MAKE_STRING(USBIF_ISO_6) ", default "
+ MAKE_STRING(DEFAULT_ALT) ")");
static int flicker_freq = 60;
module_param(flicker_freq, int, 0);
-MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" __stringify(50) "or"
- __stringify(60) ", default "
- __stringify(60) ")");
+MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" MAKE_STRING(50) "or"
+ MAKE_STRING(60) ", default "
+ MAKE_STRING(60) ")");
static int flicker_mode = NEVER_FLICKER;
module_param(flicker_mode, int, 0);
MODULE_PARM_DESC(flicker_mode,
- "Flicker supression (" __stringify(NEVER_FLICKER) "or"
- __stringify(ANTI_FLICKER_ON) ", default "
- __stringify(NEVER_FLICKER) ")");
+ "Flicker supression (" MAKE_STRING(NEVER_FLICKER) "or"
+ MAKE_STRING(ANTI_FLICKER_ON) ", default "
+ MAKE_STRING(NEVER_FLICKER) ")");
MODULE_AUTHOR("Steve Miller (STMicroelectronics) ");
MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");
@@ -1921,6 +1926,7 @@ static const struct v4l2_file_operations fops_template = {
static struct video_device cpia2_template = {
/* I could not find any place for the old .initialize initializer?? */
.name= "CPiA2 Camera",
+ .minor= -1,
.fops= &fops_template,
.release= video_device_release,
};
@@ -1961,9 +1967,9 @@ void cpia2_unregister_camera(struct camera_data *cam)
if (!cam->open_count) {
video_unregister_device(cam->vdev);
} else {
- LOG("%s removed while open, deferring "
- "video_unregister_device\n",
- video_device_node_name(cam->vdev));
+ LOG("/dev/video%d removed while open, "
+ "deferring video_unregister_device\n",
+ cam->vdev->num);
}
}
diff --git a/trunk/drivers/media/video/cx18/cx18-fileops.c b/trunk/drivers/media/video/cx18/cx18-fileops.c
index c0885c69fd89..4e278db31cc9 100644
--- a/trunk/drivers/media/video/cx18/cx18-fileops.c
+++ b/trunk/drivers/media/video/cx18/cx18-fileops.c
@@ -758,8 +758,8 @@ int cx18_v4l2_open(struct file *filp)
mutex_lock(&cx->serialize_lock);
if (cx18_init_on_first_open(cx)) {
- CX18_ERR("Failed to initialize on %s\n",
- video_device_node_name(video_dev));
+ CX18_ERR("Failed to initialize on minor %d\n",
+ video_dev->minor);
mutex_unlock(&cx->serialize_lock);
return -ENXIO;
}
diff --git a/trunk/drivers/media/video/cx18/cx18-streams.c b/trunk/drivers/media/video/cx18/cx18-streams.c
index 987a9308d938..c398651dd74c 100644
--- a/trunk/drivers/media/video/cx18/cx18-streams.c
+++ b/trunk/drivers/media/video/cx18/cx18-streams.c
@@ -219,7 +219,6 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
{
struct cx18_stream *s = &cx->streams[type];
int vfl_type = cx18_stream_info[type].vfl_type;
- const char *name;
int num, ret;
/* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
@@ -259,30 +258,31 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
s->video_dev = NULL;
return ret;
}
-
- name = video_device_node_name(s->video_dev);
+ num = s->video_dev->num;
switch (vfl_type) {
case VFL_TYPE_GRABBER:
- CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n",
- name, s->name, cx->stream_buffers[type],
+ CX18_INFO("Registered device video%d for %s "
+ "(%d x %d.%02d kB)\n",
+ num, s->name, cx->stream_buffers[type],
cx->stream_buf_size[type] / 1024,
(cx->stream_buf_size[type] * 100 / 1024) % 100);
break;
case VFL_TYPE_RADIO:
- CX18_INFO("Registered device %s for %s\n", name, s->name);
+ CX18_INFO("Registered device radio%d for %s\n",
+ num, s->name);
break;
case VFL_TYPE_VBI:
if (cx->stream_buffers[type])
- CX18_INFO("Registered device %s for %s "
+ CX18_INFO("Registered device vbi%d for %s "
"(%d x %d bytes)\n",
- name, s->name, cx->stream_buffers[type],
+ num, s->name, cx->stream_buffers[type],
cx->stream_buf_size[type]);
else
- CX18_INFO("Registered device %s for %s\n",
- name, s->name);
+ CX18_INFO("Registered device vbi%d for %s\n",
+ num, s->name);
break;
}
diff --git a/trunk/drivers/media/video/cx231xx/cx231xx-cards.c b/trunk/drivers/media/video/cx231xx/cx231xx-cards.c
index a54908235009..319c459459e0 100644
--- a/trunk/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/trunk/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -68,19 +68,19 @@ struct cx231xx_board cx231xx_boards[] = {
.type = CX231XX_VMUX_TELEVISION,
.vmux = CX231XX_VIN_3_1,
.amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
+ .gpio = 0,
}, {
.type = CX231XX_VMUX_COMPOSITE1,
.vmux = CX231XX_VIN_2_1,
.amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
+ .gpio = 0,
}, {
.type = CX231XX_VMUX_SVIDEO,
.vmux = CX231XX_VIN_1_1 |
(CX231XX_VIN_1_2 << 8) |
CX25840_SVIDEO_ON,
.amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
+ .gpio = 0,
}
},
},
@@ -107,19 +107,19 @@ struct cx231xx_board cx231xx_boards[] = {
.type = CX231XX_VMUX_TELEVISION,
.vmux = CX231XX_VIN_3_1,
.amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
+ .gpio = 0,
}, {
.type = CX231XX_VMUX_COMPOSITE1,
.vmux = CX231XX_VIN_2_1,
.amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
+ .gpio = 0,
}, {
.type = CX231XX_VMUX_SVIDEO,
.vmux = CX231XX_VIN_1_1 |
(CX231XX_VIN_1_2 << 8) |
CX25840_SVIDEO_ON,
.amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
+ .gpio = 0,
}
},
},
@@ -147,19 +147,19 @@ struct cx231xx_board cx231xx_boards[] = {
.type = CX231XX_VMUX_TELEVISION,
.vmux = CX231XX_VIN_3_1,
.amux = CX231XX_AMUX_VIDEO,
- .gpio = NULL,
+ .gpio = 0,
}, {
.type = CX231XX_VMUX_COMPOSITE1,
.vmux = CX231XX_VIN_2_1,
.amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
+ .gpio = 0,
}, {
.type = CX231XX_VMUX_SVIDEO,
.vmux = CX231XX_VIN_1_1 |
(CX231XX_VIN_1_2 << 8) |
CX25840_SVIDEO_ON,
.amux = CX231XX_AMUX_LINE_IN,
- .gpio = NULL,
+ .gpio = 0,
}
},
},
@@ -856,9 +856,8 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
if (dev->users) {
cx231xx_warn
- ("device %s is open! Deregistration and memory "
- "deallocation are deferred on close.\n",
- video_device_node_name(dev->vdev));
+ ("device /dev/video%d is open! Deregistration and memory "
+ "deallocation are deferred on close.\n", dev->vdev->num);
dev->state |= DEV_MISCONFIGURED;
cx231xx_uninit_isoc(dev);
diff --git a/trunk/drivers/media/video/cx231xx/cx231xx-core.c b/trunk/drivers/media/video/cx231xx/cx231xx-core.c
index 4a60dfbc347d..0d333e679f70 100644
--- a/trunk/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/trunk/drivers/media/video/cx231xx/cx231xx-core.c
@@ -66,6 +66,32 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
static LIST_HEAD(cx231xx_devlist);
static DEFINE_MUTEX(cx231xx_devlist_mutex);
+struct cx231xx *cx231xx_get_device(int minor,
+ enum v4l2_buf_type *fh_type, int *has_radio)
+{
+ struct cx231xx *h, *dev = NULL;
+
+ *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ *has_radio = 0;
+
+ mutex_lock(&cx231xx_devlist_mutex);
+ list_for_each_entry(h, &cx231xx_devlist, devlist) {
+ if (h->vdev->minor == minor)
+ dev = h;
+ if (h->vbi_dev->minor == minor) {
+ dev = h;
+ *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ }
+ if (h->radio_dev && h->radio_dev->minor == minor) {
+ dev = h;
+ *has_radio = 1;
+ }
+ }
+ mutex_unlock(&cx231xx_devlist_mutex);
+
+ return dev;
+}
+
/*
* cx231xx_realease_resources()
* unregisters the v4l2,i2c and usb devices
diff --git a/trunk/drivers/media/video/cx231xx/cx231xx-input.c b/trunk/drivers/media/video/cx231xx/cx231xx-input.c
index 15826f98b688..cd135f01b9c1 100644
--- a/trunk/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/trunk/drivers/media/video/cx231xx/cx231xx-input.c
@@ -197,7 +197,8 @@ int cx231xx_ir_init(struct cx231xx *dev)
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys));
- err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
+ err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
+ dev->board.ir_codes);
if (err < 0)
goto err_out_free;
@@ -216,7 +217,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
cx231xx_ir_start(ir);
/* all done */
- err = ir_input_register(ir->input, dev->board.ir_codes);
+ err = input_register_device(ir->input);
if (err)
goto err_out_stop;
@@ -225,6 +226,8 @@ int cx231xx_ir_init(struct cx231xx *dev)
cx231xx_ir_stop(ir);
dev->ir = NULL;
err_out_free:
+ ir_input_free(input_dev);
+ input_free_device(input_dev);
kfree(ir);
return err;
}
@@ -238,7 +241,8 @@ int cx231xx_ir_fini(struct cx231xx *dev)
return 0;
cx231xx_ir_stop(ir);
- ir_input_unregister(ir->input);
+ ir_input_free(ir->input);
+ input_unregister_device(ir->input);
kfree(ir);
/* done */
diff --git a/trunk/drivers/media/video/cx231xx/cx231xx-video.c b/trunk/drivers/media/video/cx231xx/cx231xx-video.c
index d4f546f11d74..d095aa0d6d19 100644
--- a/trunk/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/trunk/drivers/media/video/cx231xx/cx231xx-video.c
@@ -1916,29 +1916,20 @@ static int radio_queryctrl(struct file *file, void *priv,
*/
static int cx231xx_v4l2_open(struct file *filp)
{
+ int minor = video_devdata(filp)->minor;
int errCode = 0, radio = 0;
- struct video_device *vdev = video_devdata(filp);
- struct cx231xx *dev = video_drvdata(filp);
+ struct cx231xx *dev = NULL;
struct cx231xx_fh *fh;
enum v4l2_buf_type fh_type = 0;
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
- }
+ dev = cx231xx_get_device(minor, &fh_type, &radio);
+ if (NULL == dev)
+ return -ENODEV;
mutex_lock(&dev->lock);
- cx231xx_videodbg("open dev=%s type=%s users=%d\n",
- video_device_node_name(vdev), v4l2_type_names[fh_type],
- dev->users);
+ cx231xx_videodbg("open minor=%d type=%s users=%d\n",
+ minor, v4l2_type_names[fh_type], dev->users);
#if 0
errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
@@ -2029,25 +2020,25 @@ void cx231xx_release_analog_resources(struct cx231xx *dev)
/*FIXME: I2C IR should be disconnected */
if (dev->radio_dev) {
- if (video_is_registered(dev->radio_dev))
+ if (-1 != dev->radio_dev->minor)
video_unregister_device(dev->radio_dev);
else
video_device_release(dev->radio_dev);
dev->radio_dev = NULL;
}
if (dev->vbi_dev) {
- cx231xx_info("V4L2 device %s deregistered\n",
- video_device_node_name(dev->vbi_dev));
- if (video_is_registered(dev->vbi_dev))
+ cx231xx_info("V4L2 device /dev/vbi%d deregistered\n",
+ dev->vbi_dev->num);
+ if (-1 != dev->vbi_dev->minor)
video_unregister_device(dev->vbi_dev);
else
video_device_release(dev->vbi_dev);
dev->vbi_dev = NULL;
}
if (dev->vdev) {
- cx231xx_info("V4L2 device %s deregistered\n",
- video_device_node_name(dev->vdev));
- if (video_is_registered(dev->vdev))
+ cx231xx_info("V4L2 device /dev/video%d deregistered\n",
+ dev->vdev->num);
+ if (-1 != dev->vdev->minor)
video_unregister_device(dev->vdev);
else
video_device_release(dev->vdev);
@@ -2277,6 +2268,7 @@ static const struct video_device cx231xx_video_template = {
.fops = &cx231xx_v4l_fops,
.release = video_device_release,
.ioctl_ops = &video_ioctl_ops,
+ .minor = -1,
.tvnorms = V4L2_STD_ALL,
.current_norm = V4L2_STD_PAL,
};
@@ -2311,6 +2303,7 @@ static struct video_device cx231xx_radio_template = {
.name = "cx231xx-radio",
.fops = &radio_fops,
.ioctl_ops = &radio_ioctl_ops,
+ .minor = -1,
};
/******************************** usb interface ******************************/
@@ -2326,13 +2319,13 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,
return NULL;
*vfd = *template;
+ vfd->minor = -1;
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
- video_set_drvdata(vfd, dev);
return vfd;
}
@@ -2381,8 +2374,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
return ret;
}
- cx231xx_info("%s/0: registered device %s [v4l2]\n",
- dev->name, video_device_node_name(dev->vdev));
+ cx231xx_info("%s/0: registered device video%d [v4l2]\n",
+ dev->name, dev->vdev->num);
/* Initialize VBI template */
memcpy(&cx231xx_vbi_template, &cx231xx_video_template,
@@ -2400,8 +2393,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
return ret;
}
- cx231xx_info("%s/0: registered device %s\n",
- dev->name, video_device_node_name(dev->vbi_dev));
+ cx231xx_info("%s/0: registered device vbi%d\n",
+ dev->name, dev->vbi_dev->num);
if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) {
dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template,
@@ -2416,13 +2409,12 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
cx231xx_errdev("can't register radio device\n");
return ret;
}
- cx231xx_info("Registered radio device as %s\n",
- video_device_node_name(dev->radio_dev));
+ cx231xx_info("Registered radio device as /dev/radio%d\n",
+ dev->radio_dev->num);
}
- cx231xx_info("V4L2 device registered as %s and %s\n",
- video_device_node_name(dev->vdev),
- video_device_node_name(dev->vbi_dev));
+ cx231xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
+ dev->vdev->num, dev->vbi_dev->num);
return 0;
}
diff --git a/trunk/drivers/media/video/cx231xx/cx231xx.h b/trunk/drivers/media/video/cx231xx/cx231xx.h
index 17d4d1a800ce..64e2ddd3c401 100644
--- a/trunk/drivers/media/video/cx231xx/cx231xx.h
+++ b/trunk/drivers/media/video/cx231xx/cx231xx.h
@@ -689,6 +689,8 @@ void cx231xx_release_analog_resources(struct cx231xx *dev);
int cx231xx_register_analog_devices(struct cx231xx *dev);
void cx231xx_remove_from_devlist(struct cx231xx *dev);
void cx231xx_add_into_devlist(struct cx231xx *dev);
+struct cx231xx *cx231xx_get_device(int minor,
+ enum v4l2_buf_type *fh_type, int *has_radio);
void cx231xx_init_extension(struct cx231xx *dev);
void cx231xx_close_extension(struct cx231xx *dev);
diff --git a/trunk/drivers/media/video/cx23885/cimax2.c b/trunk/drivers/media/video/cx23885/cimax2.c
index d4a9d2c5947c..c04222ffb286 100644
--- a/trunk/drivers/media/video/cx23885/cimax2.c
+++ b/trunk/drivers/media/video/cx23885/cimax2.c
@@ -53,8 +53,6 @@
#define NETUP_CI_CTL 0x04
#define NETUP_CI_RD 1
-#define NETUP_IRQ_DETAM 0x1
-#define NETUP_IRQ_IRQAM 0x4
static unsigned int ci_dbg;
module_param(ci_dbg, int, 0644);
@@ -75,9 +73,6 @@ struct netup_ci_state {
int status;
struct work_struct work;
void *priv;
- u8 current_irq_mode;
- int current_ci_flag;
- unsigned long next_status_checked_time;
};
@@ -174,26 +169,24 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
if (0 != slot)
return -EINVAL;
- if (state->current_ci_flag != flag) {
- ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &store, 1);
- if (ret != 0)
- return ret;
+ ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &store, 1);
+ if (ret != 0)
+ return ret;
- store &= ~0x0c;
- store |= flag;
+ store &= ~0x0c;
+ store |= flag;
- ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &store, 1);
- if (ret != 0)
- return ret;
- };
- state->current_ci_flag = flag;
+ ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &store, 1);
+ if (ret != 0)
+ return ret;
mutex_lock(&dev->gpio_lock);
/* write addr */
cx_write(MC417_OEN, NETUP_EN_ALL);
+ msleep(2);
cx_write(MC417_RWD, NETUP_CTRL_OFF |
NETUP_ADLO | (0xff & addr));
cx_clear(MC417_RWD, NETUP_ADLO);
@@ -203,6 +196,7 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
if (read) { /* data in */
cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
+ msleep(2);
} else /* data out */
cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
@@ -219,8 +213,8 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
if (mem < 0)
return -EREMOTEIO;
- ci_dbg_print("%s: %s: chipaddr=[0x%x] addr=[0x%02x], %s=%x\n", __func__,
- (read) ? "read" : "write", state->ci_i2c_addr, addr,
+ ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__,
+ (read) ? "read" : "write", addr,
(flag == NETUP_CI_CTL) ? "ctl" : "mem",
(read) ? mem : data);
@@ -289,39 +283,14 @@ int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
return 0;
}
-int netup_ci_set_irq(struct dvb_ca_en50221 *en50221, u8 irq_mode)
-{
- struct netup_ci_state *state = en50221->data;
- int ret;
-
- if (irq_mode == state->current_irq_mode)
- return 0;
-
- ci_dbg_print("%s: chipaddr=[0x%x] setting ci IRQ to [0x%x] \n",
- __func__, state->ci_i2c_addr, irq_mode);
- ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0x1b, &irq_mode, 1);
-
- if (ret != 0)
- return ret;
-
- state->current_irq_mode = irq_mode;
-
- return 0;
-}
-
int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
{
struct netup_ci_state *state = en50221->data;
- u8 buf;
+ u8 buf = 0x60;
if (0 != slot)
return -EINVAL;
- netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &buf, 1);
- buf |= 0x60;
-
return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
0, &buf, 1);
}
@@ -334,35 +303,21 @@ static void netup_read_ci_status(struct work_struct *work)
u8 buf[33];
int ret;
- /* CAM module IRQ processing. fast operation */
- dvb_ca_en50221_frda_irq(&state->ca, 0);
+ ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &buf[0], 33);
- /* CAM module INSERT/REMOVE processing. slow operation because of i2c
- * transfers */
- if (time_after(jiffies, state->next_status_checked_time)
- || !state->status) {
- ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
- 0, &buf[0], 33);
-
- state->next_status_checked_time = jiffies
- + msecs_to_jiffies(1000);
-
- if (ret != 0)
- return;
-
- ci_dbg_print("%s: Slot Status Addr=[0x%04x], "
- "Reg=[0x%02x], data=%02x, "
- "TS config = %02x\n", __func__,
- state->ci_i2c_addr, 0, buf[0],
- buf[0]);
+ if (ret != 0)
+ return;
+ ci_dbg_print("%s: Slot Status Addr=[0x%04x], Reg=[0x%02x], data=%02x, "
+ "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0],
+ buf[32]);
- if (buf[0] & 1)
- state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
- DVB_CA_EN50221_POLL_CAM_READY;
- else
- state->status = 0;
- };
+ if (buf[0] & 1)
+ state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
+ DVB_CA_EN50221_POLL_CAM_READY;
+ else
+ state->status = 0;
}
/* CI irq handler */
@@ -392,9 +347,6 @@ int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open
if (0 != slot)
return -EINVAL;
- netup_ci_set_irq(en50221, open ? (NETUP_IRQ_DETAM | NETUP_IRQ_IRQAM)
- : NETUP_IRQ_DETAM);
-
return state->status;
}
@@ -429,8 +381,8 @@ int netup_ci_init(struct cx23885_tsport *port)
0x01, /* power on (use it like store place) */
0x00, /* RFU */
0x00, /* int status read only */
- NETUP_IRQ_IRQAM | NETUP_IRQ_DETAM, /* DETAM, IRQAM unmasked */
- 0x05, /* EXTINT=active-high, INT=push-pull */
+ 0x01, /* all int unmasked */
+ 0x04, /* int config */
0x00, /* USCG1 */
0x04, /* ack active low */
0x00, /* LOCK = 0 */
@@ -470,7 +422,6 @@ int netup_ci_init(struct cx23885_tsport *port)
state->ca.poll_slot_status = netup_poll_ci_slot_status;
state->ca.data = state;
state->priv = port;
- state->current_irq_mode = NETUP_IRQ_IRQAM | NETUP_IRQ_DETAM;
ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
0, &cimax_init[0], 34);
diff --git a/trunk/drivers/media/video/cx23885/cx23885-417.c b/trunk/drivers/media/video/cx23885/cx23885-417.c
index 88c0d2481118..0eed852c61e9 100644
--- a/trunk/drivers/media/video/cx23885/cx23885-417.c
+++ b/trunk/drivers/media/video/cx23885/cx23885-417.c
@@ -1568,11 +1568,28 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int mpeg_open(struct file *file)
{
- struct cx23885_dev *dev = video_drvdata(file);
+ int minor = video_devdata(file)->minor;
+ struct cx23885_dev *h, *dev = NULL;
+ struct list_head *list;
struct cx23885_fh *fh;
dprintk(2, "%s()\n", __func__);
+ lock_kernel();
+ list_for_each(list, &cx23885_devlist) {
+ h = list_entry(list, struct cx23885_dev, devlist);
+ if (h->v4l_device &&
+ h->v4l_device->minor == minor) {
+ dev = h;
+ break;
+ }
+ }
+
+ if (dev == NULL) {
+ unlock_kernel();
+ return -ENODEV;
+ }
+
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
if (NULL == fh) {
@@ -1580,8 +1597,6 @@ static int mpeg_open(struct file *file)
return -ENOMEM;
}
- lock_kernel();
-
file->private_data = fh;
fh->dev = dev;
@@ -1721,6 +1736,7 @@ static struct video_device cx23885_mpeg_template = {
.name = "cx23885",
.fops = &mpeg_fops,
.ioctl_ops = &mpeg_ioctl_ops,
+ .minor = -1,
.tvnorms = CX23885_NORMS,
.current_norm = V4L2_STD_NTSC_M,
};
@@ -1730,7 +1746,7 @@ void cx23885_417_unregister(struct cx23885_dev *dev)
dprintk(1, "%s()\n", __func__);
if (dev->v4l_device) {
- if (video_is_registered(dev->v4l_device))
+ if (-1 != dev->v4l_device->minor)
video_unregister_device(dev->v4l_device);
else
video_device_release(dev->v4l_device);
@@ -1787,7 +1803,6 @@ int cx23885_417_register(struct cx23885_dev *dev)
/* Allocate and initialize V4L video device */
dev->v4l_device = cx23885_video_dev_alloc(tsport,
dev->pci, &cx23885_mpeg_template, "mpeg");
- video_set_drvdata(dev->v4l_device, dev);
err = video_register_device(dev->v4l_device,
VFL_TYPE_GRABBER, -1);
if (err < 0) {
@@ -1795,8 +1810,8 @@ int cx23885_417_register(struct cx23885_dev *dev)
return err;
}
- printk(KERN_INFO "%s: registered device %s [mpeg]\n",
- dev->name, video_device_node_name(dev->v4l_device));
+ printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
+ dev->name, dev->v4l_device->num);
return 0;
}
diff --git a/trunk/drivers/media/video/cx23885/cx23885-core.c b/trunk/drivers/media/video/cx23885/cx23885-core.c
index 0dde57e96d30..04b12d27bc13 100644
--- a/trunk/drivers/media/video/cx23885/cx23885-core.c
+++ b/trunk/drivers/media/video/cx23885/cx23885-core.c
@@ -55,6 +55,9 @@ MODULE_PARM_DESC(card, "card type");
static unsigned int cx23885_devcount;
+static DEFINE_MUTEX(devlist);
+LIST_HEAD(cx23885_devlist);
+
#define NO_SYNC_LINE (-1U)
/* FIXME, these allocations will change when
@@ -782,6 +785,10 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
dev->nr = cx23885_devcount++;
sprintf(dev->name, "cx23885[%d]", dev->nr);
+ mutex_lock(&devlist);
+ list_add_tail(&dev->devlist, &cx23885_devlist);
+ mutex_unlock(&devlist);
+
/* Configure the internal memory */
if (dev->pci->device == 0x8880) {
/* Could be 887 or 888, assume a default */
@@ -2001,6 +2008,10 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
/* unregister stuff */
free_irq(pci_dev->irq, dev);
+ mutex_lock(&devlist);
+ list_del(&dev->devlist);
+ mutex_unlock(&devlist);
+
cx23885_dev_unregister(dev);
v4l2_device_unregister(v4l2_dev);
kfree(dev);
diff --git a/trunk/drivers/media/video/cx23885/cx23885-input.c b/trunk/drivers/media/video/cx23885/cx23885-input.c
index 768eec92ccf9..469e083dd5f8 100644
--- a/trunk/drivers/media/video/cx23885/cx23885-input.c
+++ b/trunk/drivers/media/video/cx23885/cx23885-input.c
@@ -377,7 +377,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
cx23885_boards[dev->board].name);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci));
- ret = ir_input_init(input_dev, &ir->ir, ir_type);
+ ret = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
if (ret < 0)
goto err_out_free;
@@ -397,7 +397,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
dev->ir_input = ir;
cx23885_input_ir_start(dev);
- ret = ir_input_register(ir->dev, ir_codes);
+ ret = input_register_device(ir->dev);
if (ret)
goto err_out_stop;
@@ -407,6 +407,8 @@ int cx23885_input_init(struct cx23885_dev *dev)
cx23885_input_ir_stop(dev);
dev->ir_input = NULL;
err_out_free:
+ ir_input_free(input_dev);
+ input_free_device(input_dev);
kfree(ir);
return ret;
}
@@ -418,7 +420,8 @@ void cx23885_input_fini(struct cx23885_dev *dev)
if (dev->ir_input == NULL)
return;
- ir_input_unregister(dev->ir_input->dev);
+ ir_input_free(dev->ir_input->dev);
+ input_unregister_device(dev->ir_input->dev);
kfree(dev->ir_input);
dev->ir_input = NULL;
}
diff --git a/trunk/drivers/media/video/cx23885/cx23885-video.c b/trunk/drivers/media/video/cx23885/cx23885-video.c
index 8934d61cf660..8b372b4f0de2 100644
--- a/trunk/drivers/media/video/cx23885/cx23885-video.c
+++ b/trunk/drivers/media/video/cx23885/cx23885-video.c
@@ -318,11 +318,11 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
if (NULL == vfd)
return NULL;
*vfd = *template;
+ vfd->minor = -1;
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
dev->name, type, cx23885_boards[dev->board].name);
- video_set_drvdata(vfd, dev);
return vfd;
}
@@ -716,34 +716,46 @@ static int get_resource(struct cx23885_fh *fh)
static int video_open(struct file *file)
{
- struct video_device *vdev = video_devdata(file);
- struct cx23885_dev *dev = video_drvdata(file);
+ int minor = video_devdata(file)->minor;
+ struct cx23885_dev *h, *dev = NULL;
struct cx23885_fh *fh;
+ struct list_head *list;
enum v4l2_buf_type type = 0;
int radio = 0;
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
+ lock_kernel();
+ list_for_each(list, &cx23885_devlist) {
+ h = list_entry(list, struct cx23885_dev, devlist);
+ if (h->video_dev &&
+ h->video_dev->minor == minor) {
+ dev = h;
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ }
+ if (h->vbi_dev &&
+ h->vbi_dev->minor == minor) {
+ dev = h;
+ type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ }
+ if (h->radio_dev &&
+ h->radio_dev->minor == minor) {
+ radio = 1;
+ dev = h;
+ }
+ }
+ if (NULL == dev) {
+ unlock_kernel();
+ return -ENODEV;
}
- dprintk(1, "open dev=%s radio=%d type=%s\n",
- video_device_node_name(vdev), radio, v4l2_type_names[type]);
+ dprintk(1, "open minor=%d radio=%d type=%s\n",
+ minor, radio, v4l2_type_names[type]);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
+ if (NULL == fh) {
+ unlock_kernel();
return -ENOMEM;
-
- lock_kernel();
-
+ }
file->private_data = fh;
fh->dev = dev;
fh->radio = radio;
@@ -1429,6 +1441,7 @@ static struct video_device cx23885_vbi_template;
static struct video_device cx23885_video_template = {
.name = "cx23885-video",
.fops = &video_fops,
+ .minor = -1,
.ioctl_ops = &video_ioctl_ops,
.tvnorms = CX23885_NORMS,
.current_norm = V4L2_STD_NTSC_M,
@@ -1448,7 +1461,7 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
cx_clear(PCI_INT_MSK, 1);
if (dev->video_dev) {
- if (video_is_registered(dev->video_dev))
+ if (-1 != dev->video_dev->minor)
video_unregister_device(dev->video_dev);
else
video_device_release(dev->video_dev);
@@ -1519,8 +1532,8 @@ int cx23885_video_register(struct cx23885_dev *dev)
dev->name);
goto fail_unreg;
}
- printk(KERN_INFO "%s/0: registered device %s [v4l2]\n",
- dev->name, video_device_node_name(dev->video_dev));
+ printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n",
+ dev->name, dev->video_dev->num);
/* initial device configuration */
mutex_lock(&dev->lock);
cx23885_set_tvnorm(dev, dev->tvnorm);
diff --git a/trunk/drivers/media/video/cx23885/cx23885.h b/trunk/drivers/media/video/cx23885/cx23885.h
index 08b3f6b136a0..fa744764dc8b 100644
--- a/trunk/drivers/media/video/cx23885/cx23885.h
+++ b/trunk/drivers/media/video/cx23885/cx23885.h
@@ -303,6 +303,7 @@ struct cx23885_tsport {
};
struct cx23885_dev {
+ struct list_head devlist;
atomic_t refcount;
struct v4l2_device v4l2_dev;
@@ -398,6 +399,8 @@ static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev)
extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw);
+extern struct list_head cx23885_devlist;
+
#define SRAM_CH01 0 /* Video A */
#define SRAM_CH02 1 /* VBI A */
#define SRAM_CH03 2 /* Video B */
diff --git a/trunk/drivers/media/video/cx88/cx88-blackbird.c b/trunk/drivers/media/video/cx88/cx88-blackbird.c
index 6fe30e6c4262..fbdc1cde56a6 100644
--- a/trunk/drivers/media/video/cx88/cx88-blackbird.c
+++ b/trunk/drivers/media/video/cx88/cx88-blackbird.c
@@ -1048,15 +1048,21 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id)
static int mpeg_open(struct file *file)
{
- struct video_device *vdev = video_devdata(file);
- struct cx8802_dev *dev = video_drvdata(file);
+ int minor = video_devdata(file)->minor;
+ struct cx8802_dev *dev = NULL;
struct cx8802_fh *fh;
struct cx8802_driver *drv = NULL;
int err;
+ lock_kernel();
+ dev = cx8802_get_device(minor);
+
dprintk( 1, "%s\n", __func__);
- lock_kernel();
+ if (dev == NULL) {
+ unlock_kernel();
+ return -ENODEV;
+ }
/* Make sure we can acquire the hardware */
drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
@@ -1075,7 +1081,7 @@ static int mpeg_open(struct file *file)
unlock_kernel();
return -EINVAL;
}
- dprintk(1, "open dev=%s\n", video_device_node_name(vdev));
+ dprintk(1,"open minor=%d\n",minor);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh),GFP_KERNEL);
@@ -1123,6 +1129,10 @@ static int mpeg_release(struct file *file)
kfree(fh);
/* Make sure we release the hardware */
+ dev = cx8802_get_device(video_devdata(file)->minor);
+ if (dev == NULL)
+ return -ENODEV;
+
drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
if (drv)
drv->request_release(drv);
@@ -1210,6 +1220,7 @@ static struct video_device cx8802_mpeg_template = {
.name = "cx8802",
.fops = &mpeg_fops,
.ioctl_ops = &mpeg_ioctl_ops,
+ .minor = -1,
.tvnorms = CX88_NORMS,
.current_norm = V4L2_STD_NTSC_M,
};
@@ -1265,7 +1276,7 @@ static int cx8802_blackbird_advise_release(struct cx8802_driver *drv)
static void blackbird_unregister_video(struct cx8802_dev *dev)
{
if (dev->mpeg_dev) {
- if (video_is_registered(dev->mpeg_dev))
+ if (-1 != dev->mpeg_dev->minor)
video_unregister_device(dev->mpeg_dev);
else
video_device_release(dev->mpeg_dev);
@@ -1279,15 +1290,14 @@ static int blackbird_register_video(struct cx8802_dev *dev)
dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci,
&cx8802_mpeg_template,"mpeg");
- video_set_drvdata(dev->mpeg_dev, dev);
err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1);
if (err < 0) {
printk(KERN_INFO "%s/2: can't register mpeg device\n",
dev->core->name);
return err;
}
- printk(KERN_INFO "%s/2: registered device %s [mpeg]\n",
- dev->core->name, video_device_node_name(dev->mpeg_dev));
+ printk(KERN_INFO "%s/2: registered device video%d [mpeg]\n",
+ dev->core->name, dev->mpeg_dev->num);
return 0;
}
diff --git a/trunk/drivers/media/video/cx88/cx88-input.c b/trunk/drivers/media/video/cx88/cx88-input.c
index f9fda18b410c..92b8cdf9fb81 100644
--- a/trunk/drivers/media/video/cx88/cx88-input.c
+++ b/trunk/drivers/media/video/cx88/cx88-input.c
@@ -360,7 +360,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
- err = ir_input_init(input_dev, &ir->ir, ir_type);
+ err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
if (err < 0)
goto err_out_free;
@@ -383,7 +383,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
cx88_ir_start(core, ir);
/* all done */
- err = ir_input_register(ir->input, ir_codes);
+ err = input_register_device(ir->input);
if (err)
goto err_out_stop;
@@ -393,6 +393,8 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
cx88_ir_stop(core, ir);
core->ir = NULL;
err_out_free:
+ ir_input_free(input_dev);
+ input_free_device(input_dev);
kfree(ir);
return err;
}
@@ -406,7 +408,8 @@ int cx88_ir_fini(struct cx88_core *core)
return 0;
cx88_ir_stop(core, ir);
- ir_input_unregister(ir->input);
+ ir_input_free(ir->input);
+ input_unregister_device(ir->input);
kfree(ir);
/* done */
diff --git a/trunk/drivers/media/video/cx88/cx88-mpeg.c b/trunk/drivers/media/video/cx88/cx88-mpeg.c
index bb5104893411..de9ff0fc741f 100644
--- a/trunk/drivers/media/video/cx88/cx88-mpeg.c
+++ b/trunk/drivers/media/video/cx88/cx88-mpeg.c
@@ -580,6 +580,21 @@ static int cx8802_resume_common(struct pci_dev *pci_dev)
return 0;
}
+#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \
+ defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE)
+struct cx8802_dev *cx8802_get_device(int minor)
+{
+ struct cx8802_dev *dev;
+
+ list_for_each_entry(dev, &cx8802_devlist, devlist)
+ if (dev->mpeg_dev && dev->mpeg_dev->minor == minor)
+ return dev;
+
+ return NULL;
+}
+EXPORT_SYMBOL(cx8802_get_device);
+#endif
+
struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype)
{
struct cx8802_driver *d;
diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c
index 48c450f4a85a..d7e8fcee559c 100644
--- a/trunk/drivers/media/video/cx88/cx88-video.c
+++ b/trunk/drivers/media/video/cx88/cx88-video.c
@@ -75,6 +75,10 @@ MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
#define dprintk(level,fmt, arg...) if (video_debug >= level) \
printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
+/* ------------------------------------------------------------------ */
+
+static LIST_HEAD(cx8800_devlist);
+
/* ------------------------------------------------------------------- */
/* static data */
@@ -749,31 +753,38 @@ static int get_ressource(struct cx8800_fh *fh)
static int video_open(struct file *file)
{
- struct video_device *vdev = video_devdata(file);
- struct cx8800_dev *dev = video_drvdata(file);
+ int minor = video_devdata(file)->minor;
+ struct cx8800_dev *h,*dev = NULL;
struct cx88_core *core;
struct cx8800_fh *fh;
enum v4l2_buf_type type = 0;
int radio = 0;
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
- }
-
lock_kernel();
+ list_for_each_entry(h, &cx8800_devlist, devlist) {
+ if (h->video_dev->minor == minor) {
+ dev = h;
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ }
+ if (h->vbi_dev->minor == minor) {
+ dev = h;
+ type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ }
+ if (h->radio_dev &&
+ h->radio_dev->minor == minor) {
+ radio = 1;
+ dev = h;
+ }
+ }
+ if (NULL == dev) {
+ unlock_kernel();
+ return -ENODEV;
+ }
core = dev->core;
- dprintk(1, "open dev=%s radio=%d type=%s\n",
- video_device_node_name(vdev), radio, v4l2_type_names[type]);
+ dprintk(1,"open minor=%d radio=%d type=%s\n",
+ minor,radio,v4l2_type_names[type]);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh),GFP_KERNEL);
@@ -1722,6 +1733,7 @@ static struct video_device cx8800_vbi_template;
static struct video_device cx8800_video_template = {
.name = "cx8800-video",
.fops = &video_fops,
+ .minor = -1,
.ioctl_ops = &video_ioctl_ops,
.tvnorms = CX88_NORMS,
.current_norm = V4L2_STD_NTSC_M,
@@ -1757,6 +1769,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
static struct video_device cx8800_radio_template = {
.name = "cx8800-radio",
.fops = &radio_fops,
+ .minor = -1,
.ioctl_ops = &radio_ioctl_ops,
};
@@ -1765,21 +1778,21 @@ static struct video_device cx8800_radio_template = {
static void cx8800_unregister_video(struct cx8800_dev *dev)
{
if (dev->radio_dev) {
- if (video_is_registered(dev->radio_dev))
+ if (-1 != dev->radio_dev->minor)
video_unregister_device(dev->radio_dev);
else
video_device_release(dev->radio_dev);
dev->radio_dev = NULL;
}
if (dev->vbi_dev) {
- if (video_is_registered(dev->vbi_dev))
+ if (-1 != dev->vbi_dev->minor)
video_unregister_device(dev->vbi_dev);
else
video_device_release(dev->vbi_dev);
dev->vbi_dev = NULL;
}
if (dev->video_dev) {
- if (video_is_registered(dev->video_dev))
+ if (-1 != dev->video_dev->minor)
video_unregister_device(dev->video_dev);
else
video_device_release(dev->video_dev);
@@ -1896,7 +1909,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
/* register v4l devices */
dev->video_dev = cx88_vdev_init(core,dev->pci,
&cx8800_video_template,"video");
- video_set_drvdata(dev->video_dev, dev);
err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
video_nr[core->nr]);
if (err < 0) {
@@ -1904,11 +1916,10 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
core->name);
goto fail_unreg;
}
- printk(KERN_INFO "%s/0: registered device %s [v4l2]\n",
- core->name, video_device_node_name(dev->video_dev));
+ printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n",
+ core->name, dev->video_dev->num);
dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi");
- video_set_drvdata(dev->vbi_dev, dev);
err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
vbi_nr[core->nr]);
if (err < 0) {
@@ -1916,13 +1927,12 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
core->name);
goto fail_unreg;
}
- printk(KERN_INFO "%s/0: registered device %s\n",
- core->name, video_device_node_name(dev->vbi_dev));
+ printk(KERN_INFO "%s/0: registered device vbi%d\n",
+ core->name, dev->vbi_dev->num);
if (core->board.radio.type == CX88_RADIO) {
dev->radio_dev = cx88_vdev_init(core,dev->pci,
&cx8800_radio_template,"radio");
- video_set_drvdata(dev->radio_dev, dev);
err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
radio_nr[core->nr]);
if (err < 0) {
@@ -1930,11 +1940,12 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
core->name);
goto fail_unreg;
}
- printk(KERN_INFO "%s/0: registered device %s\n",
- core->name, video_device_node_name(dev->radio_dev));
+ printk(KERN_INFO "%s/0: registered device radio%d\n",
+ core->name, dev->radio_dev->num);
}
/* everything worked */
+ list_add_tail(&dev->devlist,&cx8800_devlist);
pci_set_drvdata(pci_dev,dev);
/* initial device configuration */
@@ -1990,6 +2001,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
/* free memory */
btcx_riscmem_free(dev->pci,&dev->vidq.stopper);
+ list_del(&dev->devlist);
cx88_core_put(core,dev->pci);
kfree(dev);
}
diff --git a/trunk/drivers/media/video/cx88/cx88.h b/trunk/drivers/media/video/cx88/cx88.h
index b1499bf604ea..e1c521710103 100644
--- a/trunk/drivers/media/video/cx88/cx88.h
+++ b/trunk/drivers/media/video/cx88/cx88.h
@@ -423,6 +423,7 @@ struct cx8800_suspend_state {
struct cx8800_dev {
struct cx88_core *core;
+ struct list_head devlist;
spinlock_t slock;
/* various device info */
@@ -669,6 +670,7 @@ int cx88_audio_thread(void *data);
int cx8802_register_driver(struct cx8802_driver *drv);
int cx8802_unregister_driver(struct cx8802_driver *drv);
+struct cx8802_dev *cx8802_get_device(int minor);
struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
/* ----------------------------------------------------------- */
diff --git a/trunk/drivers/media/video/davinci/vpfe_capture.c b/trunk/drivers/media/video/davinci/vpfe_capture.c
index de22bc9faf21..c3916a42668e 100644
--- a/trunk/drivers/media/video/davinci/vpfe_capture.c
+++ b/trunk/drivers/media/video/davinci/vpfe_capture.c
@@ -70,6 +70,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1966,6 +1967,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
vfd->release = video_device_release;
vfd->fops = &vpfe_fops;
vfd->ioctl_ops = &vpfe_ioctl_ops;
+ vfd->minor = -1;
vfd->tvnorms = 0;
vfd->current_norm = V4L2_STD_PAL;
vfd->v4l2_dev = &vpfe_dev->v4l2_dev;
@@ -2069,7 +2071,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
probe_out_v4l2_unregister:
v4l2_device_unregister(&vpfe_dev->v4l2_dev);
probe_out_video_release:
- if (!video_is_registered(vpfe_dev->video_dev))
+ if (vpfe_dev->video_dev->minor == -1)
video_device_release(vpfe_dev->video_dev);
probe_out_release_irq:
free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
@@ -2089,7 +2091,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
/*
* vpfe_remove : It un-register device from V4L2 driver
*/
-static int __devexit vpfe_remove(struct platform_device *pdev)
+static int vpfe_remove(struct platform_device *pdev)
{
struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
struct resource *res;
diff --git a/trunk/drivers/media/video/davinci/vpif.c b/trunk/drivers/media/video/davinci/vpif.c
index 1f532e31cd49..3b8eac31ecae 100644
--- a/trunk/drivers/media/video/davinci/vpif.c
+++ b/trunk/drivers/media/video/davinci/vpif.c
@@ -266,7 +266,7 @@ static int __init vpif_probe(struct platform_device *pdev)
return status;
}
-static int __devexit vpif_remove(struct platform_device *pdev)
+static int vpif_remove(struct platform_device *pdev)
{
iounmap(vpif_base);
release_mem_region(res->start, res_len);
diff --git a/trunk/drivers/media/video/davinci/vpif_display.c b/trunk/drivers/media/video/davinci/vpif_display.c
index dfddef7228dd..d14cfb200ed0 100644
--- a/trunk/drivers/media/video/davinci/vpif_display.c
+++ b/trunk/drivers/media/video/davinci/vpif_display.c
@@ -1347,6 +1347,7 @@ static const struct v4l2_file_operations vpif_fops = {
static struct video_device vpif_video_template = {
.name = "vpif",
.fops = &vpif_fops,
+ .minor = -1,
.ioctl_ops = &vpif_ioctl_ops,
.tvnorms = DM646X_V4L2_STD,
.current_norm = V4L2_STD_625_50,
diff --git a/trunk/drivers/media/video/davinci/vpss.c b/trunk/drivers/media/video/davinci/vpss.c
index 7ee72ecd3d81..453236bd7559 100644
--- a/trunk/drivers/media/video/davinci/vpss.c
+++ b/trunk/drivers/media/video/davinci/vpss.c
@@ -268,7 +268,7 @@ static int __init vpss_probe(struct platform_device *pdev)
return status;
}
-static int __devexit vpss_remove(struct platform_device *pdev)
+static int vpss_remove(struct platform_device *pdev)
{
iounmap(oper_cfg.vpss_bl_regs_base);
release_mem_region(oper_cfg.r1->start, oper_cfg.len1);
diff --git a/trunk/drivers/media/video/em28xx/em28xx-cards.c b/trunk/drivers/media/video/em28xx/em28xx-cards.c
index 25100001ffff..82da205047be 100644
--- a/trunk/drivers/media/video/em28xx/em28xx-cards.c
+++ b/trunk/drivers/media/video/em28xx/em28xx-cards.c
@@ -2285,7 +2285,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
break;
case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
- dev->init_data.ir_codes = &ir_codes_rc5_hauppauge_new_table;
+ dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
dev->init_data.get_key = em28xx_get_key_em_haup;
dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
break;
@@ -2653,6 +2653,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
INIT_LIST_HEAD(&dev->vbiq.active);
INIT_LIST_HEAD(&dev->vbiq.queued);
+
if (dev->board.has_msp34xx) {
/* Send a reset to other chips via gpio */
errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
@@ -2922,9 +2923,9 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
if (dev->users) {
em28xx_warn
- ("device %s is open! Deregistration and memory "
+ ("device /dev/video%d is open! Deregistration and memory "
"deallocation are deferred on close.\n",
- video_device_node_name(dev->vdev));
+ dev->vdev->num);
dev->state |= DEV_MISCONFIGURED;
em28xx_uninit_isoc(dev);
diff --git a/trunk/drivers/media/video/em28xx/em28xx-core.c b/trunk/drivers/media/video/em28xx/em28xx-core.c
index b311d4514bdf..3f86d36dff2b 100644
--- a/trunk/drivers/media/video/em28xx/em28xx-core.c
+++ b/trunk/drivers/media/video/em28xx/em28xx-core.c
@@ -216,7 +216,7 @@ int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val)
* sets only some bits (specified by bitmask) of a register, by first reading
* the actual value
*/
-int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
u8 bitmask)
{
int oldval;
@@ -1136,6 +1136,34 @@ void em28xx_wake_i2c(struct em28xx *dev)
static LIST_HEAD(em28xx_devlist);
static DEFINE_MUTEX(em28xx_devlist_mutex);
+struct em28xx *em28xx_get_device(int minor,
+ enum v4l2_buf_type *fh_type,
+ int *has_radio)
+{
+ struct em28xx *h, *dev = NULL;
+
+ *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ *has_radio = 0;
+
+ mutex_lock(&em28xx_devlist_mutex);
+ list_for_each_entry(h, &em28xx_devlist, devlist) {
+ if (h->vdev->minor == minor)
+ dev = h;
+ if (h->vbi_dev && h->vbi_dev->minor == minor) {
+ dev = h;
+ *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ }
+ if (h->radio_dev &&
+ h->radio_dev->minor == minor) {
+ dev = h;
+ *has_radio = 1;
+ }
+ }
+ mutex_unlock(&em28xx_devlist_mutex);
+
+ return dev;
+}
+
/*
* em28xx_realease_resources()
* unregisters the v4l2,i2c and usb devices
diff --git a/trunk/drivers/media/video/em28xx/em28xx-input.c b/trunk/drivers/media/video/em28xx/em28xx-input.c
index af0d935c29be..d96ec7c09dca 100644
--- a/trunk/drivers/media/video/em28xx/em28xx-input.c
+++ b/trunk/drivers/media/video/em28xx/em28xx-input.c
@@ -112,13 +112,10 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
{
unsigned char buf[2];
- u16 code;
- int size;
+ unsigned char code;
/* poll IR chip */
- size = i2c_master_recv(ir->c, buf, sizeof(buf));
-
- if (size != 2)
+ if (2 != i2c_master_recv(ir->c, buf, 2))
return -EIO;
/* Does eliminate repeated parity code */
@@ -127,30 +124,16 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
ir->old = buf[1];
- /*
- * Rearranges bits to the right order.
- * The bit order were determined experimentally by using
- * The original Hauppauge Grey IR and another RC5 that uses addr=0x08
- * The RC5 code has 14 bits, but we've experimentally determined
- * the meaning for only 11 bits.
- * So, the code translation is not complete. Yet, it is enough to
- * work with the provided RC5 IR.
- */
- code =
- ((buf[0] & 0x01) ? 0x0020 : 0) | /* 0010 0000 */
- ((buf[0] & 0x02) ? 0x0010 : 0) | /* 0001 0000 */
- ((buf[0] & 0x04) ? 0x0008 : 0) | /* 0000 1000 */
- ((buf[0] & 0x08) ? 0x0004 : 0) | /* 0000 0100 */
- ((buf[0] & 0x10) ? 0x0002 : 0) | /* 0000 0010 */
- ((buf[0] & 0x20) ? 0x0001 : 0) | /* 0000 0001 */
- ((buf[1] & 0x08) ? 0x1000 : 0) | /* 0001 0000 */
- ((buf[1] & 0x10) ? 0x0800 : 0) | /* 0000 1000 */
- ((buf[1] & 0x20) ? 0x0400 : 0) | /* 0000 0100 */
- ((buf[1] & 0x40) ? 0x0200 : 0) | /* 0000 0010 */
- ((buf[1] & 0x80) ? 0x0100 : 0); /* 0000 0001 */
-
- i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x%02x)\n",
- code, buf[1], buf[0]);
+ /* Rearranges bits to the right order */
+ code = ((buf[0]&0x01)<<5) | /* 0010 0000 */
+ ((buf[0]&0x02)<<3) | /* 0001 0000 */
+ ((buf[0]&0x04)<<1) | /* 0000 1000 */
+ ((buf[0]&0x08)>>1) | /* 0000 0100 */
+ ((buf[0]&0x10)>>3) | /* 0000 0010 */
+ ((buf[0]&0x20)>>5); /* 0000 0001 */
+
+ i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",
+ code, buf[0]);
/* return key */
*ir_key = code;
@@ -354,28 +337,19 @@ int em28xx_ir_init(struct em28xx *dev)
goto err_out_free;
ir->input = input_dev;
- ir_config = EM2874_IR_RC5;
-
- /* Adjust xclk based o IR table for RC5/NEC tables */
- if (dev->board.ir_codes->ir_type == IR_TYPE_RC5) {
- dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
- ir->full_code = 1;
- } else if (dev->board.ir_codes->ir_type == IR_TYPE_NEC) {
- dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
- ir_config = EM2874_IR_NEC;
- ir->full_code = 1;
- }
- em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
- EM28XX_XCLK_IR_RC5_MODE);
/* Setup the proper handler based on the chip */
switch (dev->chip_id) {
case CHIP_ID_EM2860:
case CHIP_ID_EM2883:
+ if (dev->model == EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950)
+ ir->full_code = 1;
ir->get_key = default_polling_getkey;
break;
case CHIP_ID_EM2874:
ir->get_key = em2874_polling_getkey;
+ /* For now we only support RC5, so enable it */
+ ir_config = EM2874_IR_RC5;
em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1);
break;
default:
@@ -393,7 +367,8 @@ int em28xx_ir_init(struct em28xx *dev)
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys));
- err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
+ err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
+ dev->board.ir_codes);
if (err < 0)
goto err_out_free;
@@ -412,7 +387,7 @@ int em28xx_ir_init(struct em28xx *dev)
em28xx_ir_start(ir);
/* all done */
- err = ir_input_register(ir->input, dev->board.ir_codes);
+ err = input_register_device(ir->input);
if (err)
goto err_out_stop;
@@ -421,6 +396,8 @@ int em28xx_ir_init(struct em28xx *dev)
em28xx_ir_stop(ir);
dev->ir = NULL;
err_out_free:
+ ir_input_free(input_dev);
+ input_free_device(input_dev);
kfree(ir);
return err;
}
@@ -434,7 +411,8 @@ int em28xx_ir_fini(struct em28xx *dev)
return 0;
em28xx_ir_stop(ir);
- ir_input_unregister(ir->input);
+ ir_input_free(ir->input);
+ input_unregister_device(ir->input);
kfree(ir);
/* done */
diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c
index 849b18c94037..7ad65370f274 100644
--- a/trunk/drivers/media/video/em28xx/em28xx-video.c
+++ b/trunk/drivers/media/video/em28xx/em28xx-video.c
@@ -2081,30 +2081,22 @@ static int radio_queryctrl(struct file *file, void *priv,
*/
static int em28xx_v4l2_open(struct file *filp)
{
- int errCode = 0, radio = 0;
- struct video_device *vdev = video_devdata(filp);
- struct em28xx *dev = video_drvdata(filp);
- enum v4l2_buf_type fh_type = 0;
+ int minor = video_devdata(filp)->minor;
+ int errCode = 0, radio;
+ struct em28xx *dev;
+ enum v4l2_buf_type fh_type;
struct em28xx_fh *fh;
enum v4l2_field field;
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
- }
+ dev = em28xx_get_device(minor, &fh_type, &radio);
+
+ if (NULL == dev)
+ return -ENODEV;
mutex_lock(&dev->lock);
- em28xx_videodbg("open dev=%s type=%s users=%d\n",
- video_device_node_name(vdev), v4l2_type_names[fh_type],
- dev->users);
+ em28xx_videodbg("open minor=%d type=%s users=%d\n",
+ minor, v4l2_type_names[fh_type], dev->users);
fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
@@ -2168,25 +2160,25 @@ void em28xx_release_analog_resources(struct em28xx *dev)
/*FIXME: I2C IR should be disconnected */
if (dev->radio_dev) {
- if (video_is_registered(dev->radio_dev))
+ if (-1 != dev->radio_dev->minor)
video_unregister_device(dev->radio_dev);
else
video_device_release(dev->radio_dev);
dev->radio_dev = NULL;
}
if (dev->vbi_dev) {
- em28xx_info("V4L2 device %s deregistered\n",
- video_device_node_name(dev->vbi_dev));
- if (video_is_registered(dev->vbi_dev))
+ em28xx_info("V4L2 device /dev/vbi%d deregistered\n",
+ dev->vbi_dev->num);
+ if (-1 != dev->vbi_dev->minor)
video_unregister_device(dev->vbi_dev);
else
video_device_release(dev->vbi_dev);
dev->vbi_dev = NULL;
}
if (dev->vdev) {
- em28xx_info("V4L2 device %s deregistered\n",
- video_device_node_name(dev->vdev));
- if (video_is_registered(dev->vdev))
+ em28xx_info("V4L2 device /dev/video%d deregistered\n",
+ dev->vdev->num);
+ if (-1 != dev->vdev->minor)
video_unregister_device(dev->vdev);
else
video_device_release(dev->vdev);
@@ -2405,6 +2397,8 @@ static const struct video_device em28xx_video_template = {
.release = video_device_release,
.ioctl_ops = &video_ioctl_ops,
+ .minor = -1,
+
.tvnorms = V4L2_STD_ALL,
.current_norm = V4L2_STD_PAL,
};
@@ -2439,6 +2433,7 @@ static struct video_device em28xx_radio_template = {
.name = "em28xx-radio",
.fops = &radio_fops,
.ioctl_ops = &radio_ioctl_ops,
+ .minor = -1,
};
/******************************** usb interface ******************************/
@@ -2456,6 +2451,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
return NULL;
*vfd = *template;
+ vfd->minor = -1;
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
vfd->debug = video_debug;
@@ -2463,7 +2459,6 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
snprintf(vfd->name, sizeof(vfd->name), "%s %s",
dev->name, type_name);
- video_set_drvdata(vfd, dev);
return vfd;
}
@@ -2545,16 +2540,16 @@ int em28xx_register_analog_devices(struct em28xx *dev)
em28xx_errdev("can't register radio device\n");
return ret;
}
- em28xx_info("Registered radio device as %s\n",
- video_device_node_name(dev->radio_dev));
+ em28xx_info("Registered radio device as /dev/radio%d\n",
+ dev->radio_dev->num);
}
- em28xx_info("V4L2 video device registered as %s\n",
- video_device_node_name(dev->vdev));
+ em28xx_info("V4L2 video device registered as /dev/video%d\n",
+ dev->vdev->num);
if (dev->vbi_dev)
- em28xx_info("V4L2 VBI device registered as %s\n",
- video_device_node_name(dev->vbi_dev));
+ em28xx_info("V4L2 VBI device registered as /dev/vbi%d\n",
+ dev->vbi_dev->num);
return 0;
}
diff --git a/trunk/drivers/media/video/em28xx/em28xx.h b/trunk/drivers/media/video/em28xx/em28xx.h
index 80d9b4fa1b97..441df644ddbe 100644
--- a/trunk/drivers/media/video/em28xx/em28xx.h
+++ b/trunk/drivers/media/video/em28xx/em28xx.h
@@ -643,8 +643,6 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
int len);
int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val);
-int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
- u8 bitmask);
int em28xx_read_ac97(struct em28xx *dev, u8 reg);
int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val);
@@ -668,6 +666,9 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
void em28xx_wake_i2c(struct em28xx *dev);
void em28xx_remove_from_devlist(struct em28xx *dev);
void em28xx_add_into_devlist(struct em28xx *dev);
+struct em28xx *em28xx_get_device(int minor,
+ enum v4l2_buf_type *fh_type,
+ int *has_radio);
int em28xx_register_extension(struct em28xx_ops *dev);
void em28xx_unregister_extension(struct em28xx_ops *dev);
void em28xx_init_extension(struct em28xx *dev);
diff --git a/trunk/drivers/media/video/et61x251/et61x251_core.c b/trunk/drivers/media/video/et61x251/et61x251_core.c
index e6c23d509862..88987a57cf7b 100644
--- a/trunk/drivers/media/video/et61x251/et61x251_core.c
+++ b/trunk/drivers/media/video/et61x251/et61x251_core.c
@@ -587,8 +587,8 @@ static int et61x251_stream_interrupt(struct et61x251_device* cam)
else if (cam->stream != STREAM_OFF) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "URB timeout reached. The camera is misconfigured. To "
- "use it, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use it, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -EIO;
}
@@ -1195,8 +1195,7 @@ static void et61x251_release_resources(struct kref *kref)
cam = container_of(kref, struct et61x251_device, kref);
- DBG(2, "V4L2 device %s deregistered",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num);
video_set_drvdata(cam->v4ldev, NULL);
video_unregister_device(cam->v4ldev);
usb_put_dev(cam->usbdev);
@@ -1237,8 +1236,8 @@ static int et61x251_open(struct file *filp)
}
if (cam->users) {
- DBG(2, "Device %s is already in use",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "Device /dev/video%d is already in use",
+ cam->v4ldev->num);
DBG(3, "Simultaneous opens are not supported");
if ((filp->f_flags & O_NONBLOCK) ||
(filp->f_flags & O_NDELAY)) {
@@ -1281,8 +1280,7 @@ static int et61x251_open(struct file *filp)
cam->frame_count = 0;
et61x251_empty_framequeues(cam);
- DBG(3, "Video device %s is open",
- video_device_node_name(cam->v4ldev));
+ DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num);
out:
mutex_unlock(&cam->open_mutex);
@@ -1306,8 +1304,7 @@ static int et61x251_release(struct file *filp)
cam->users--;
wake_up_interruptible_nr(&cam->wait_open, 1);
- DBG(3, "Video device %s closed",
- video_device_node_name(cam->v4ldev));
+ DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num);
kref_put(&cam->kref, et61x251_release_resources);
@@ -1849,8 +1846,8 @@ et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg)
if (err) { /* atomic, no rollback in ioctl() */
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -EIO;
}
@@ -1862,8 +1859,8 @@ et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg)
nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -ENOMEM;
}
@@ -2072,8 +2069,8 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
if (err) { /* atomic, no rollback in ioctl() */
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -EIO;
}
@@ -2084,8 +2081,8 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -ENOMEM;
}
@@ -2133,7 +2130,7 @@ et61x251_vidioc_s_jpegcomp(struct et61x251_device* cam, void __user * arg)
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
"problems. To use the camera, close and open "
- "%s again.", video_device_node_name(cam->v4ldev));
+ "/dev/video%d again.", cam->v4ldev->num);
return -EIO;
}
@@ -2587,6 +2584,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
cam->v4ldev->fops = &et61x251_fops;
+ cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
cam->v4ldev->parent = &udev->dev;
video_set_drvdata(cam->v4ldev, cam);
@@ -2605,8 +2603,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
goto fail;
}
- DBG(2, "V4L2 device registered as %s",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num);
cam->module_param.force_munmap = force_munmap[dev_nr];
cam->module_param.frame_timeout = frame_timeout[dev_nr];
@@ -2657,9 +2654,9 @@ static void et61x251_usb_disconnect(struct usb_interface* intf)
DBG(2, "Disconnecting %s...", cam->v4ldev->name);
if (cam->users) {
- DBG(2, "Device %s is open! Deregistration and memory "
- "deallocation are deferred.",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "Device /dev/video%d is open! Deregistration and "
+ "memory deallocation are deferred.",
+ cam->v4ldev->num);
cam->state |= DEV_MISCONFIGURED;
et61x251_stop_transfer(cam);
cam->state |= DEV_DISCONNECTED;
diff --git a/trunk/drivers/media/video/gspca/conex.c b/trunk/drivers/media/video/gspca/conex.c
index c98b5d69c438..2f0b8d621e00 100644
--- a/trunk/drivers/media/video/gspca/conex.c
+++ b/trunk/drivers/media/video/gspca/conex.c
@@ -1046,14 +1046,14 @@ static struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-static const struct usb_device_id device_table[] __devinitconst = {
+static __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0572, 0x0041)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff --git a/trunk/drivers/media/video/gspca/etoms.c b/trunk/drivers/media/video/gspca/etoms.c
index fdf4c0ec5e7a..9de86419ae1e 100644
--- a/trunk/drivers/media/video/gspca/etoms.c
+++ b/trunk/drivers/media/video/gspca/etoms.c
@@ -864,7 +864,7 @@ static struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-static const struct usb_device_id device_table[] __devinitconst = {
+static __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
#if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
@@ -875,7 +875,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff --git a/trunk/drivers/media/video/gspca/gl860/gl860-mi1320.c b/trunk/drivers/media/video/gspca/gl860/gl860-mi1320.c
index c276a7debdec..1355e526ee84 100644
--- a/trunk/drivers/media/video/gspca/gl860/gl860-mi1320.c
+++ b/trunk/drivers/media/video/gspca/gl860/gl860-mi1320.c
@@ -345,7 +345,7 @@ static int mi1320_configure_alt(struct gspca_dev *gspca_dev)
return 0;
}
-static int mi1320_camera_settings(struct gspca_dev *gspca_dev)
+int mi1320_camera_settings(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
diff --git a/trunk/drivers/media/video/gspca/gl860/gl860-mi2020.c b/trunk/drivers/media/video/gspca/gl860/gl860-mi2020.c
index 7c31b4f2abea..80cb3f1b36f7 100644
--- a/trunk/drivers/media/video/gspca/gl860/gl860-mi2020.c
+++ b/trunk/drivers/media/video/gspca/gl860/gl860-mi2020.c
@@ -769,7 +769,7 @@ static int mi2020_configure_alt(struct gspca_dev *gspca_dev)
return 0;
}
-static int mi2020_camera_settings(struct gspca_dev *gspca_dev)
+int mi2020_camera_settings(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
diff --git a/trunk/drivers/media/video/gspca/gl860/gl860.c b/trunk/drivers/media/video/gspca/gl860/gl860.c
index 4878c8f66543..a695e0ae13c2 100644
--- a/trunk/drivers/media/video/gspca/gl860/gl860.c
+++ b/trunk/drivers/media/video/gspca/gl860/gl860.c
@@ -40,7 +40,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
static void sd_callback(struct gspca_dev *gspca_dev);
static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
- u16 vendor_id, u16 product_id);
+ s32 vendor_id, s32 product_id);
/*============================ driver options ==============================*/
@@ -326,11 +326,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- u16 vendor_id, product_id;
+ s32 vendor_id, product_id;
/* Get USB VendorID and ProductID */
- vendor_id = id->idVendor;
- product_id = id->idProduct;
+ vendor_id = le16_to_cpu(id->idVendor);
+ product_id = le16_to_cpu(id->idProduct);
sd->nbRightUp = 1;
sd->nbIm = -1;
@@ -534,8 +534,8 @@ static int sd_probe(struct usb_interface *intf,
gspca_dev = usb_get_intfdata(intf);
PDEBUG(D_PROBE,
- "Camera is now controlling video device %s",
- video_device_node_name(&gspca_dev->vdev));
+ "Camera is now controlling video device /dev/video%d",
+ gspca_dev->vdev.minor);
}
return ret;
@@ -673,7 +673,7 @@ void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len)
}
static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
- u16 vendor_id, u16 product_id)
+ s32 vendor_id, s32 product_id)
{
struct sd *sd = (struct sd *) gspca_dev;
u8 probe, nb26, nb96, nOV, ntry;
diff --git a/trunk/drivers/media/video/gspca/gspca.c b/trunk/drivers/media/video/gspca/gspca.c
index e930a67d526b..4076f8e5a6fc 100644
--- a/trunk/drivers/media/video/gspca/gspca.c
+++ b/trunk/drivers/media/video/gspca/gspca.c
@@ -304,6 +304,7 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
j = gspca_dev->fr_queue[i];
gspca_dev->cur_frame = &gspca_dev->frame[j];
}
+ return;
}
EXPORT_SYMBOL(gspca_frame_add);
@@ -320,7 +321,7 @@ static int gspca_is_compressed(__u32 format)
return 0;
}
-static void *rvmalloc(long size)
+static void *rvmalloc(unsigned long size)
{
void *mem;
unsigned long adr;
@@ -328,7 +329,7 @@ static void *rvmalloc(long size)
mem = vmalloc_32(size);
if (mem != NULL) {
adr = (unsigned long) mem;
- while (size > 0) {
+ while ((long) size > 0) {
SetPageReserved(vmalloc_to_page((void *) adr));
adr += PAGE_SIZE;
size -= PAGE_SIZE;
@@ -767,7 +768,6 @@ static int vidioc_g_register(struct file *file, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
if (gspca_dev->present)
ret = gspca_dev->sd_desc->get_register(gspca_dev, reg);
else
@@ -791,7 +791,6 @@ static int vidioc_s_register(struct file *file, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
if (gspca_dev->present)
ret = gspca_dev->sd_desc->set_register(gspca_dev, reg);
else
@@ -813,7 +812,6 @@ static int vidioc_g_chip_ident(struct file *file, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
if (gspca_dev->present)
ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);
else
@@ -985,40 +983,11 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
return -EINVAL;
}
-static int vidioc_enum_frameintervals(struct file *filp, void *priv,
- struct v4l2_frmivalenum *fival)
-{
- struct gspca_dev *gspca_dev = priv;
- int mode = wxh_to_mode(gspca_dev, fival->width, fival->height);
- __u32 i;
-
- if (gspca_dev->cam.mode_framerates == NULL ||
- gspca_dev->cam.mode_framerates[mode].nrates == 0)
- return -EINVAL;
-
- if (fival->pixel_format !=
- gspca_dev->cam.cam_mode[mode].pixelformat)
- return -EINVAL;
-
- for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) {
- if (fival->index == i) {
- fival->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fival->discrete.numerator = 1;
- fival->discrete.denominator =
- gspca_dev->cam.mode_framerates[mode].rates[i];
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
static void gspca_release(struct video_device *vfd)
{
struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
- PDEBUG(D_PROBE, "%s released",
- video_device_node_name(&gspca_dev->vdev));
+ PDEBUG(D_PROBE, "/dev/video%d released", gspca_dev->vdev.num);
kfree(gspca_dev->usb_buf);
kfree(gspca_dev);
@@ -1084,7 +1053,6 @@ static int dev_close(struct file *file)
if (gspca_dev->capt_file == file) {
if (gspca_dev->streaming) {
mutex_lock(&gspca_dev->usb_lock);
- gspca_dev->usb_err = 0;
gspca_stream_off(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
@@ -1175,14 +1143,12 @@ static int vidioc_queryctrl(struct file *file, void *priv,
continue;
ctrls = &gspca_dev->sd_desc->ctrls[i];
}
- if (ctrls == NULL)
- return -EINVAL;
} else {
ctrls = get_ctrl(gspca_dev, id);
- if (ctrls == NULL)
- return -EINVAL;
i = ctrls - gspca_dev->sd_desc->ctrls;
}
+ if (ctrls == NULL)
+ return -EINVAL;
memcpy(q_ctrl, ctrls, sizeof *q_ctrl);
if (gspca_dev->ctrl_inac & (1 << i))
q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
@@ -1206,7 +1172,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
if (gspca_dev->present)
ret = ctrls->set(gspca_dev, ctrl->value);
else
@@ -1228,7 +1193,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
if (gspca_dev->present)
ret = ctrls->get(gspca_dev, &ctrl->value);
else
@@ -1343,7 +1307,6 @@ static int vidioc_reqbufs(struct file *file, void *priv,
/* stop streaming */
if (gspca_dev->streaming) {
mutex_lock(&gspca_dev->usb_lock);
- gspca_dev->usb_err = 0;
gspca_stream_off(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
@@ -1435,7 +1398,6 @@ static int vidioc_streamoff(struct file *file, void *priv,
ret = -ERESTARTSYS;
goto out;
}
- gspca_dev->usb_err = 0;
gspca_stream_off(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
@@ -1461,7 +1423,6 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
if (gspca_dev->present)
ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
else
@@ -1480,7 +1441,6 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
if (gspca_dev->present)
ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
else
@@ -1501,7 +1461,6 @@ static int vidioc_g_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
if (gspca_dev->present)
ret = gspca_dev->sd_desc->get_streamparm(gspca_dev,
parm);
@@ -1531,7 +1490,6 @@ static int vidioc_s_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- gspca_dev->usb_err = 0;
if (gspca_dev->present)
ret = gspca_dev->sd_desc->set_streamparm(gspca_dev,
parm);
@@ -1655,7 +1613,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
size -= PAGE_SIZE;
}
- vma->vm_ops = &gspca_vm_ops;
+ vma->vm_ops = (struct vm_operations_struct *) &gspca_vm_ops;
vma->vm_private_data = frame;
gspca_vm_open(vma);
ret = 0;
@@ -1703,7 +1661,6 @@ static int frame_wait(struct gspca_dev *gspca_dev,
if (gspca_dev->sd_desc->dq_callback) {
mutex_lock(&gspca_dev->usb_lock);
- gspca_dev->usb_err = 0;
if (gspca_dev->present)
gspca_dev->sd_desc->dq_callback(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
@@ -2016,7 +1973,6 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
.vidioc_g_parm = vidioc_g_parm,
.vidioc_s_parm = vidioc_s_parm,
.vidioc_enum_framesizes = vidioc_enum_framesizes,
- .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
@@ -2032,6 +1988,7 @@ static struct video_device gspca_template = {
.fops = &dev_fops,
.ioctl_ops = &dev_ioctl_ops,
.release = gspca_release,
+ .minor = -1,
};
/*
@@ -2090,6 +2047,9 @@ int gspca_dev_probe(struct usb_interface *intf,
if (ret < 0)
goto out;
ret = sd_desc->init(gspca_dev);
+ if (ret < 0)
+ goto out;
+ ret = gspca_set_alt0(gspca_dev);
if (ret < 0)
goto out;
gspca_set_default_mode(gspca_dev);
@@ -2113,7 +2073,7 @@ int gspca_dev_probe(struct usb_interface *intf,
}
usb_set_intfdata(intf, gspca_dev);
- PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev));
+ PDEBUG(D_PROBE, "/dev/video%d created", gspca_dev->vdev.num);
return 0;
out:
kfree(gspca_dev->usb_buf);
@@ -2132,8 +2092,7 @@ void gspca_disconnect(struct usb_interface *intf)
{
struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
- PDEBUG(D_PROBE, "%s disconnect",
- video_device_node_name(&gspca_dev->vdev));
+ PDEBUG(D_PROBE, "/dev/video%d disconnect", gspca_dev->vdev.num);
mutex_lock(&gspca_dev->usb_lock);
gspca_dev->present = 0;
diff --git a/trunk/drivers/media/video/gspca/gspca.h b/trunk/drivers/media/video/gspca/gspca.h
index 59c7941da999..181617355ec3 100644
--- a/trunk/drivers/media/video/gspca/gspca.h
+++ b/trunk/drivers/media/video/gspca/gspca.h
@@ -45,20 +45,11 @@ extern int gspca_debug;
/* image transfers */
#define MAX_NURBS 4 /* max number of URBs */
-
-/* used to list framerates supported by a camera mode (resolution) */
-struct framerates {
- int *rates;
- int nrates;
-};
-
/* device information - set at probe time */
struct cam {
int bulk_size; /* buffer size when image transfer by bulk */
const struct v4l2_pix_format *cam_mode; /* size nmodes */
char nmodes;
- const struct framerates *mode_framerates; /* must have size nmode,
- * just like cam_mode */
__u8 bulk_nurbs; /* number of URBs in bulk mode
* - cannot be > MAX_NURBS
* - when 0 and bulk_size != 0 means
@@ -180,7 +171,6 @@ struct gspca_dev {
struct mutex usb_lock; /* usb exchange protection */
struct mutex read_lock; /* read protection */
struct mutex queue_lock; /* ISOC queue protection */
- int usb_err; /* USB error - protected by usb_lock */
#ifdef CONFIG_PM
char frozen; /* suspend - resume */
#endif
diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_core.c b/trunk/drivers/media/video/gspca/m5602/m5602_core.c
index 4294c75e3b11..844fc1d886d1 100644
--- a/trunk/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/trunk/drivers/media/video/gspca/m5602/m5602_core.c
@@ -81,7 +81,7 @@ int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data)
return (err < 0) ? err : 0;
}
-static int m5602_wait_for_i2c(struct sd *sd)
+int m5602_wait_for_i2c(struct sd *sd)
{
int err;
u8 data;
@@ -388,7 +388,7 @@ static int m5602_probe(struct usb_interface *intf,
THIS_MODULE);
}
-static void m5602_disconnect(struct usb_interface *intf)
+void m5602_disconnect(struct usb_interface *intf)
{
struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
struct sd *sd = (struct sd *) gspca_dev;
diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c b/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 923cdd5f7a6b..c2739d6605a1 100644
--- a/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/trunk/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -439,7 +439,7 @@ int ov9650_start(struct sd *sd)
err = m5602_write_bridge(sd, res_init_ov9650[i][1],
res_init_ov9650[i][2]);
else if (res_init_ov9650[i][0] == SENSOR) {
- data = res_init_ov9650[i][2];
+ u8 data = res_init_ov9650[i][2];
err = m5602_write_sensor(sd,
res_init_ov9650[i][1], &data, 1);
}
diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index aa2f3c7e2cb5..a27afeb6f39b 100644
--- a/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/trunk/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -525,10 +525,7 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
if (err < 0)
return err;
- if (val)
- data &= 0xfe;
- else
- data |= 0x01;
+ data = (data & 0xfe) | !val;
err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
return err;
}
@@ -573,10 +570,7 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
if (err < 0)
return err;
- if (val)
- data &= 0xfe;
- else
- data |= 0x01;
+ data = (data & 0xfe) | !val;
err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
return err;
}
diff --git a/trunk/drivers/media/video/gspca/mr97310a.c b/trunk/drivers/media/video/gspca/mr97310a.c
index 9154870e07d2..126d968dd9e0 100644
--- a/trunk/drivers/media/video/gspca/mr97310a.c
+++ b/trunk/drivers/media/video/gspca/mr97310a.c
@@ -67,7 +67,7 @@ MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
MODULE_LICENSE("GPL");
/* global parameters */
-static int force_sensor_type = -1;
+int force_sensor_type = -1;
module_param(force_sensor_type, int, 0644);
MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
diff --git a/trunk/drivers/media/video/gspca/ov519.c b/trunk/drivers/media/video/gspca/ov519.c
index b4f965731244..ad9ec339981d 100644
--- a/trunk/drivers/media/video/gspca/ov519.c
+++ b/trunk/drivers/media/video/gspca/ov519.c
@@ -1982,7 +1982,7 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
{
int ret;
- *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
+ *((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
@@ -2021,9 +2021,9 @@ static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
if (rc < 0)
return rc;
- do {
+ do
rc = reg_r(sd, R511_I2C_CTL);
- } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
+ while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
if (rc < 0)
return rc;
@@ -2055,9 +2055,9 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
if (rc < 0)
return rc;
- do {
+ do
rc = reg_r(sd, R511_I2C_CTL);
- } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
+ while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
if (rc < 0)
return rc;
@@ -2081,9 +2081,9 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
if (rc < 0)
return rc;
- do {
+ do
rc = reg_r(sd, R511_I2C_CTL);
- } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
+ while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
if (rc < 0)
return rc;
diff --git a/trunk/drivers/media/video/gspca/pac7302.c b/trunk/drivers/media/video/gspca/pac7302.c
index de0b66c4b56e..74acceea8094 100644
--- a/trunk/drivers/media/video/gspca/pac7302.c
+++ b/trunk/drivers/media/video/gspca/pac7302.c
@@ -90,9 +90,6 @@ struct sd {
unsigned char autogain;
__u8 hflip;
__u8 vflip;
- u8 flags;
-#define FL_HFLIP 0x01 /* mirrored by default */
-#define FL_VFLIP 0x02 /* vertical flipped by default */
u8 sof_read;
u8 autogain_ignore_frames;
@@ -555,7 +552,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->autogain = AUTOGAIN_DEF;
sd->hflip = HFLIP_DEF;
sd->vflip = VFLIP_DEF;
- sd->flags = id->driver_info;
return 0;
}
@@ -712,17 +708,10 @@ static int sethvflip(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int ret;
- u8 data, hflip, vflip;
-
- hflip = sd->hflip;
- if (sd->flags & FL_HFLIP)
- hflip = !hflip;
- vflip = sd->vflip;
- if (sd->flags & FL_VFLIP)
- vflip = !vflip;
+ __u8 data;
ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
- data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
+ data = (sd->hflip ? 0x08 : 0x00) | (sd->vflip ? 0x04 : 0x00);
if (0 <= ret)
ret = reg_w(gspca_dev, 0x21, data);
/* load registers to sensor (Bit 0, auto clear) */
@@ -1229,15 +1218,15 @@ static struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-static const struct usb_device_id device_table[] __devinitconst = {
+static __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x06f8, 0x3009)},
{USB_DEVICE(0x093a, 0x2620)},
{USB_DEVICE(0x093a, 0x2621)},
- {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
- {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
+ {USB_DEVICE(0x093a, 0x2622)},
+ {USB_DEVICE(0x093a, 0x2624)},
{USB_DEVICE(0x093a, 0x2626)},
{USB_DEVICE(0x093a, 0x2628)},
- {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
+ {USB_DEVICE(0x093a, 0x2629)},
{USB_DEVICE(0x093a, 0x262a)},
{USB_DEVICE(0x093a, 0x262c)},
{}
@@ -1245,7 +1234,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff --git a/trunk/drivers/media/video/gspca/pac7311.c b/trunk/drivers/media/video/gspca/pac7311.c
index 42cfcdfd8f4f..e5697a6345e8 100644
--- a/trunk/drivers/media/video/gspca/pac7311.c
+++ b/trunk/drivers/media/video/gspca/pac7311.c
@@ -863,7 +863,7 @@ static struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-static const struct usb_device_id device_table[] __devinitconst = {
+static __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x2600)},
{USB_DEVICE(0x093a, 0x2601)},
{USB_DEVICE(0x093a, 0x2603)},
@@ -875,7 +875,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff --git a/trunk/drivers/media/video/gspca/sn9c20x.c b/trunk/drivers/media/video/gspca/sn9c20x.c
index 4cff8035614f..b1944a7cbb0f 100644
--- a/trunk/drivers/media/video/gspca/sn9c20x.c
+++ b/trunk/drivers/media/video/gspca/sn9c20x.c
@@ -1158,7 +1158,7 @@ static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
return i2c_w(gspca_dev, row);
}
-static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
+int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
u8 row[8];
@@ -1183,7 +1183,7 @@ static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
return 0;
}
-static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
+int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
u8 row[8];
@@ -1476,9 +1476,8 @@ static int sn9c20x_input_init(struct gspca_dev *gspca_dev)
if (input_register_device(sd->input_dev))
return -EINVAL;
- sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%s-%s",
- gspca_dev->dev->bus->bus_name,
- gspca_dev->dev->devpath);
+ sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%d",
+ gspca_dev->vdev.minor);
if (IS_ERR(sd->input_task))
return -EINVAL;
@@ -2175,7 +2174,8 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
}
#define HW_WIN(mode, hstart, vstart) \
-((const u8 []){hstart, 0, vstart, 0, \
+((const u8 []){hstart & 0xff, hstart >> 8, \
+vstart & 0xff, vstart >> 8, \
(mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
(mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
diff --git a/trunk/drivers/media/video/gspca/sonixb.c b/trunk/drivers/media/video/gspca/sonixb.c
index ddff2b5ee5c2..5be95bc65138 100644
--- a/trunk/drivers/media/video/gspca/sonixb.c
+++ b/trunk/drivers/media/video/gspca/sonixb.c
@@ -1226,7 +1226,7 @@ static const struct sd_desc sd_desc = {
.driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
-static const struct usb_device_id device_table[] __devinitconst = {
+static __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */
{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
@@ -1257,7 +1257,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff --git a/trunk/drivers/media/video/gspca/spca506.c b/trunk/drivers/media/video/gspca/spca506.c
index 39257e4e074f..ab28cc23e415 100644
--- a/trunk/drivers/media/video/gspca/spca506.c
+++ b/trunk/drivers/media/video/gspca/spca506.c
@@ -685,7 +685,7 @@ static struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-static const struct usb_device_id device_table[] __devinitconst = {
+static __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x06e1, 0xa190)},
/*fixme: may be IntelPCCameraPro BRIDGE_SPCA505
{USB_DEVICE(0x0733, 0x0430)}, */
@@ -696,7 +696,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff --git a/trunk/drivers/media/video/gspca/stk014.c b/trunk/drivers/media/video/gspca/stk014.c
index 2e2935532d99..8e23320d7ab7 100644
--- a/trunk/drivers/media/video/gspca/stk014.c
+++ b/trunk/drivers/media/video/gspca/stk014.c
@@ -126,14 +126,12 @@ static const struct v4l2_pix_format vga_mode[] = {
};
/* -- read a register -- */
-static u8 reg_r(struct gspca_dev *gspca_dev,
+static int reg_r(struct gspca_dev *gspca_dev,
__u16 index)
{
struct usb_device *dev = gspca_dev->dev;
int ret;
- if (gspca_dev->usb_err < 0)
- return 0;
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0x00,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -143,21 +141,18 @@ static u8 reg_r(struct gspca_dev *gspca_dev,
500);
if (ret < 0) {
PDEBUG(D_ERR, "reg_r err %d", ret);
- gspca_dev->usb_err = ret;
- return 0;
+ return ret;
}
return gspca_dev->usb_buf[0];
}
/* -- write a register -- */
-static void reg_w(struct gspca_dev *gspca_dev,
+static int reg_w(struct gspca_dev *gspca_dev,
__u16 index, __u16 value)
{
struct usb_device *dev = gspca_dev->dev;
int ret;
- if (gspca_dev->usb_err < 0)
- return;
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0x01,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -166,14 +161,13 @@ static void reg_w(struct gspca_dev *gspca_dev,
NULL,
0,
500);
- if (ret < 0) {
+ if (ret < 0)
PDEBUG(D_ERR, "reg_w err %d", ret);
- gspca_dev->usb_err = ret;
- }
+ return ret;
}
/* -- get a bulk value (4 bytes) -- */
-static void rcv_val(struct gspca_dev *gspca_dev,
+static int rcv_val(struct gspca_dev *gspca_dev,
int ads)
{
struct usb_device *dev = gspca_dev->dev;
@@ -188,22 +182,17 @@ static void rcv_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x63a, 0);
reg_w(gspca_dev, 0x63b, 0);
reg_w(gspca_dev, 0x630, 5);
- if (gspca_dev->usb_err < 0)
- return;
ret = usb_bulk_msg(dev,
usb_rcvbulkpipe(dev, 0x05),
gspca_dev->usb_buf,
4, /* length */
&alen,
500); /* timeout in milliseconds */
- if (ret < 0) {
- PDEBUG(D_ERR, "rcv_val err %d", ret);
- gspca_dev->usb_err = ret;
- }
+ return ret;
}
/* -- send a bulk value -- */
-static void snd_val(struct gspca_dev *gspca_dev,
+static int snd_val(struct gspca_dev *gspca_dev,
int ads,
unsigned int val)
{
@@ -212,9 +201,16 @@ static void snd_val(struct gspca_dev *gspca_dev,
__u8 seq = 0;
if (ads == 0x003f08) {
- reg_r(gspca_dev, 0x0704);
- seq = reg_r(gspca_dev, 0x0705);
- reg_r(gspca_dev, 0x0650);
+ ret = reg_r(gspca_dev, 0x0704);
+ if (ret < 0)
+ goto ko;
+ ret = reg_r(gspca_dev, 0x0705);
+ if (ret < 0)
+ goto ko;
+ seq = ret; /* keep the sequence number */
+ ret = reg_r(gspca_dev, 0x0650);
+ if (ret < 0)
+ goto ko;
reg_w(gspca_dev, 0x654, seq);
} else {
reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
@@ -227,8 +223,6 @@ static void snd_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x65a, 0);
reg_w(gspca_dev, 0x65b, 0);
reg_w(gspca_dev, 0x650, 5);
- if (gspca_dev->usb_err < 0)
- return;
gspca_dev->usb_buf[0] = val >> 24;
gspca_dev->usb_buf[1] = val >> 16;
gspca_dev->usb_buf[2] = val >> 8;
@@ -239,23 +233,24 @@ static void snd_val(struct gspca_dev *gspca_dev,
4,
&alen,
500); /* timeout in milliseconds */
- if (ret < 0) {
- PDEBUG(D_ERR, "snd_val err %d", ret);
- gspca_dev->usb_err = ret;
- } else {
- if (ads == 0x003f08) {
- seq += 4;
- seq &= 0x3f;
- reg_w(gspca_dev, 0x705, seq);
- }
+ if (ret < 0)
+ goto ko;
+ if (ads == 0x003f08) {
+ seq += 4;
+ seq &= 0x3f;
+ reg_w(gspca_dev, 0x705, seq);
}
+ return ret;
+ko:
+ PDEBUG(D_ERR, "snd_val err %d", ret);
+ return ret;
}
/* set a camera parameter */
-static void set_par(struct gspca_dev *gspca_dev,
+static int set_par(struct gspca_dev *gspca_dev,
int parval)
{
- snd_val(gspca_dev, 0x003f08, parval);
+ return snd_val(gspca_dev, 0x003f08, parval);
}
static void setbrightness(struct gspca_dev *gspca_dev)
@@ -316,18 +311,18 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- u8 ret;
+ int ret;
/* check if the device responds */
usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
ret = reg_r(gspca_dev, 0x0740);
- if (gspca_dev->usb_err >= 0) {
- if (ret != 0xff) {
- PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret);
- gspca_dev->usb_err = -EIO;
- }
+ if (ret < 0)
+ return ret;
+ if (ret != 0xff) {
+ PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret);
+ return -1;
}
- return gspca_dev->usb_err;
+ return 0;
}
/* -- start the camera -- */
@@ -362,12 +357,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
if (ret < 0) {
PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed",
gspca_dev->iface, gspca_dev->alt);
- gspca_dev->usb_err = ret;
goto out;
}
- reg_r(gspca_dev, 0x0630);
+ ret = reg_r(gspca_dev, 0x0630);
+ if (ret < 0)
+ goto out;
rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
- reg_r(gspca_dev, 0x0650);
+ ret = reg_r(gspca_dev, 0x0650);
+ if (ret < 0)
+ goto out;
snd_val(gspca_dev, 0x000020, 0xffffffff);
reg_w(gspca_dev, 0x0620, 0);
reg_w(gspca_dev, 0x0630, 0);
@@ -386,11 +384,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* start the video flow */
set_par(gspca_dev, 0x01000000);
set_par(gspca_dev, 0x01000000);
- if (gspca_dev->usb_err >= 0)
- PDEBUG(D_STREAM, "camera started alt: 0x%02x",
- gspca_dev->alt);
+ PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
+ return 0;
out:
- return gspca_dev->usb_err;
+ PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret);
+ return ret;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -458,7 +456,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
sd->brightness = val;
if (gspca_dev->streaming)
setbrightness(gspca_dev);
- return gspca_dev->usb_err;
+ return 0;
}
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -476,7 +474,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
sd->contrast = val;
if (gspca_dev->streaming)
setcontrast(gspca_dev);
- return gspca_dev->usb_err;
+ return 0;
}
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -494,7 +492,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
sd->colors = val;
if (gspca_dev->streaming)
setcolors(gspca_dev);
- return gspca_dev->usb_err;
+ return 0;
}
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@@ -512,7 +510,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
sd->lightfreq = val;
if (gspca_dev->streaming)
setfreq(gspca_dev);
- return gspca_dev->usb_err;
+ return 0;
}
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
@@ -554,7 +552,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev,
sd->quality = jcomp->quality;
if (gspca_dev->streaming)
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
- return gspca_dev->usb_err;
+ return 0;
}
static int sd_get_jcomp(struct gspca_dev *gspca_dev,
diff --git a/trunk/drivers/media/video/gspca/sunplus.c b/trunk/drivers/media/video/gspca/sunplus.c
index 716df6b15fc5..72bf3b4f0a31 100644
--- a/trunk/drivers/media/video/gspca/sunplus.c
+++ b/trunk/drivers/media/video/gspca/sunplus.c
@@ -460,17 +460,13 @@ static void reg_r(struct gspca_dev *gspca_dev,
u16 index,
u16 len)
{
- int ret;
-
#ifdef GSPCA_DEBUG
if (len > USB_BUF_SZ) {
err("reg_r: buffer overflow");
return;
}
#endif
- if (gspca_dev->usb_err < 0)
- return;
- ret = usb_control_msg(gspca_dev->dev,
+ usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -478,10 +474,6 @@ static void reg_r(struct gspca_dev *gspca_dev,
index,
len ? gspca_dev->usb_buf : NULL, len,
500);
- if (ret < 0) {
- PDEBUG(D_ERR, "reg_r err %d", ret);
- gspca_dev->usb_err = ret;
- }
}
/* write one byte */
@@ -491,55 +483,40 @@ static void reg_w_1(struct gspca_dev *gspca_dev,
u16 index,
u16 byte)
{
- int ret;
-
- if (gspca_dev->usb_err < 0)
- return;
gspca_dev->usb_buf[0] = byte;
- ret = usb_control_msg(gspca_dev->dev,
+ usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index,
gspca_dev->usb_buf, 1,
500);
- if (ret < 0) {
- PDEBUG(D_ERR, "reg_w_1 err %d", ret);
- gspca_dev->usb_err = ret;
- }
}
/* write req / index / value */
-static void reg_w_riv(struct gspca_dev *gspca_dev,
+static int reg_w_riv(struct usb_device *dev,
u8 req, u16 index, u16 value)
{
- struct usb_device *dev = gspca_dev->dev;
int ret;
- if (gspca_dev->usb_err < 0)
- return;
ret = usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500);
- if (ret < 0) {
- PDEBUG(D_ERR, "reg_w_riv err %d", ret);
- gspca_dev->usb_err = ret;
- return;
- }
- PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x",
- req, index, value);
+ PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
+ req, index, value, ret);
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg write: error %d", ret);
+ return ret;
}
/* read 1 byte */
-static u8 reg_r_1(struct gspca_dev *gspca_dev,
+static int reg_r_1(struct gspca_dev *gspca_dev,
u16 value) /* wValue */
{
int ret;
- if (gspca_dev->usb_err < 0)
- return 0;
ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
0x20, /* request */
@@ -550,22 +527,19 @@ static u8 reg_r_1(struct gspca_dev *gspca_dev,
500); /* timeout */
if (ret < 0) {
PDEBUG(D_ERR, "reg_r_1 err %d", ret);
- gspca_dev->usb_err = ret;
return 0;
}
return gspca_dev->usb_buf[0];
}
-/* read 1 or 2 bytes */
-static u16 reg_r_12(struct gspca_dev *gspca_dev,
+/* read 1 or 2 bytes - returns < 0 if error */
+static int reg_r_12(struct gspca_dev *gspca_dev,
u8 req, /* bRequest */
u16 index, /* wIndex */
u16 length) /* wLength (1 or 2 only) */
{
int ret;
- if (gspca_dev->usb_err < 0)
- return 0;
gspca_dev->usb_buf[1] = 0;
ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -576,44 +550,62 @@ static u16 reg_r_12(struct gspca_dev *gspca_dev,
gspca_dev->usb_buf, length,
500);
if (ret < 0) {
- PDEBUG(D_ERR, "reg_r_12 err %d", ret);
- gspca_dev->usb_err = ret;
- return 0;
+ PDEBUG(D_ERR, "reg_read err %d", ret);
+ return -1;
}
return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
}
-static void write_vector(struct gspca_dev *gspca_dev,
+static int write_vector(struct gspca_dev *gspca_dev,
const struct cmd *data, int ncmds)
{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret;
+
while (--ncmds >= 0) {
- reg_w_riv(gspca_dev, data->req, data->idx, data->val);
+ ret = reg_w_riv(dev, data->req, data->idx, data->val);
+ if (ret < 0) {
+ PDEBUG(D_ERR,
+ "Register write failed for 0x%02x, 0x%04x, 0x%04x",
+ data->req, data->val, data->idx);
+ return ret;
+ }
data++;
}
+ return 0;
}
-static void setup_qtable(struct gspca_dev *gspca_dev,
- const u8 qtable[2][64])
+static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
+ const u8 qtable[2][64])
{
- int i;
+ struct usb_device *dev = gspca_dev->dev;
+ int i, err;
/* loop over y components */
- for (i = 0; i < 64; i++)
- reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
+ for (i = 0; i < 64; i++) {
+ err = reg_w_riv(dev, 0x00, 0x2800 + i, qtable[0][i]);
+ if (err < 0)
+ return err;
+ }
/* loop over c components */
- for (i = 0; i < 64; i++)
- reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
+ for (i = 0; i < 64; i++) {
+ err = reg_w_riv(dev, 0x00, 0x2840 + i, qtable[1][i]);
+ if (err < 0)
+ return err;
+ }
+ return 0;
}
static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
u8 req, u16 idx, u16 val)
{
- u16 notdone;
+ struct usb_device *dev = gspca_dev->dev;
+ int notdone;
- reg_w_riv(gspca_dev, req, idx, val);
+ reg_w_riv(dev, req, idx, val);
notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
- reg_w_riv(gspca_dev, req, idx, val);
+ reg_w_riv(dev, req, idx, val);
PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
@@ -624,22 +616,23 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
u8 req,
- u16 idx, u16 val, u16 endcode, u8 count)
+ u16 idx, u16 val, u8 stat, u8 count)
{
- u16 status;
+ struct usb_device *dev = gspca_dev->dev;
+ int status;
+ u8 endcode;
- reg_w_riv(gspca_dev, req, idx, val);
+ reg_w_riv(dev, req, idx, val);
status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
- if (gspca_dev->usb_err < 0)
- return;
- PDEBUG(D_FRAM, "Status 0x%04x Need 0x%04x", status, endcode);
+ endcode = stat;
+ PDEBUG(D_FRAM, "Status 0x%x Need 0x%04x", status, stat);
if (!count)
return;
count = 200;
while (--count > 0) {
msleep(10);
/* gsmart mini2 write a each wait setting 1 ms is enough */
-/* reg_w_riv(gspca_dev, req, idx, val); */
+/* reg_w_riv(dev, req, idx, val); */
status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
if (status == endcode) {
PDEBUG(D_FRAM, "status 0x%04x after wait %d",
@@ -649,7 +642,7 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
}
}
-static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
+static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
{
int count = 10;
@@ -659,6 +652,7 @@ static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
break;
msleep(10);
}
+ return gspca_dev->usb_buf[0];
}
static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
@@ -692,26 +686,28 @@ static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
u8 Size;
+ int rc;
Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
switch (sd->bridge) {
case BRIDGE_SPCA533:
- reg_w_riv(gspca_dev, 0x31, 0, 0);
+ reg_w_riv(dev, 0x31, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
- spca504B_PollingDataReady(gspca_dev);
+ rc = spca504B_PollingDataReady(gspca_dev);
spca50x_GetFirmware(gspca_dev);
reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */
reg_r(gspca_dev, 0x24, 8, 1);
reg_w_1(gspca_dev, 0x25, 0, 4, Size);
reg_r(gspca_dev, 0x25, 4, 1); /* size */
- spca504B_PollingDataReady(gspca_dev);
+ rc = spca504B_PollingDataReady(gspca_dev);
/* Init the cam width height with some values get on init ? */
- reg_w_riv(gspca_dev, 0x31, 0, 0x04);
+ reg_w_riv(dev, 0x31, 0, 0x04);
spca504B_WaitCmdStatus(gspca_dev);
- spca504B_PollingDataReady(gspca_dev);
+ rc = spca504B_PollingDataReady(gspca_dev);
break;
default:
/* case BRIDGE_SPCA504B: */
@@ -720,7 +716,7 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
reg_r(gspca_dev, 0x25, 4, 1); /* size */
reg_w_1(gspca_dev, 0x27, 0, 0, 6);
reg_r(gspca_dev, 0x27, 0, 1); /* type */
- spca504B_PollingDataReady(gspca_dev);
+ rc = spca504B_PollingDataReady(gspca_dev);
break;
case BRIDGE_SPCA504:
Size += 3;
@@ -737,8 +733,8 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
break;
case BRIDGE_SPCA504C:
/* capture mode */
- reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
- reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
+ reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
+ reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
break;
}
}
@@ -766,33 +762,37 @@ static void spca504B_setQtable(struct gspca_dev *gspca_dev)
static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
u16 reg;
reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
- reg_w_riv(gspca_dev, 0x00, reg, sd->brightness);
+ reg_w_riv(dev, 0x00, reg, sd->brightness);
}
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
u16 reg;
reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
- reg_w_riv(gspca_dev, 0x00, reg, sd->contrast);
+ reg_w_riv(dev, 0x00, reg, sd->contrast);
}
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
u16 reg;
reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
- reg_w_riv(gspca_dev, 0x00, reg, sd->colors);
+ reg_w_riv(dev, 0x00, reg, sd->colors);
}
static void init_ctl_reg(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
int pollreg = 1;
setbrightness(gspca_dev);
@@ -807,14 +807,14 @@ static void init_ctl_reg(struct gspca_dev *gspca_dev)
default:
/* case BRIDGE_SPCA533: */
/* case BRIDGE_SPCA504B: */
- reg_w_riv(gspca_dev, 0, 0x00, 0x21ad); /* hue */
- reg_w_riv(gspca_dev, 0, 0x01, 0x21ac); /* sat/hue */
- reg_w_riv(gspca_dev, 0, 0x00, 0x21a3); /* gamma */
+ reg_w_riv(dev, 0, 0x00, 0x21ad); /* hue */
+ reg_w_riv(dev, 0, 0x01, 0x21ac); /* sat/hue */
+ reg_w_riv(dev, 0, 0x00, 0x21a3); /* gamma */
break;
case BRIDGE_SPCA536:
- reg_w_riv(gspca_dev, 0, 0x40, 0x20f5);
- reg_w_riv(gspca_dev, 0, 0x01, 0x20f4);
- reg_w_riv(gspca_dev, 0, 0x00, 0x2089);
+ reg_w_riv(dev, 0, 0x40, 0x20f5);
+ reg_w_riv(dev, 0, 0x01, 0x20f4);
+ reg_w_riv(dev, 0, 0x00, 0x2089);
break;
}
if (pollreg)
@@ -881,17 +881,18 @@ static int sd_config(struct gspca_dev *gspca_dev,
static int sd_init(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int i;
+ struct usb_device *dev = gspca_dev->dev;
+ int i, err_code;
u8 info[6];
switch (sd->bridge) {
case BRIDGE_SPCA504B:
- reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
- reg_w_riv(gspca_dev, 0, 0x01, 0x2306);
- reg_w_riv(gspca_dev, 0, 0x00, 0x0d04);
- reg_w_riv(gspca_dev, 0, 0x00, 0x2000);
- reg_w_riv(gspca_dev, 0, 0x13, 0x2301);
- reg_w_riv(gspca_dev, 0, 0x00, 0x2306);
+ reg_w_riv(dev, 0x1d, 0x00, 0);
+ reg_w_riv(dev, 0, 0x01, 0x2306);
+ reg_w_riv(dev, 0, 0x00, 0x0d04);
+ reg_w_riv(dev, 0, 0x00, 0x2000);
+ reg_w_riv(dev, 0, 0x13, 0x2301);
+ reg_w_riv(dev, 0, 0x00, 0x2306);
/* fall thru */
case BRIDGE_SPCA533:
spca504B_PollingDataReady(gspca_dev);
@@ -903,13 +904,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
reg_w_1(gspca_dev, 0x24, 0, 0, 0);
reg_r(gspca_dev, 0x24, 0, 1);
spca504B_PollingDataReady(gspca_dev);
- reg_w_riv(gspca_dev, 0x34, 0, 0);
+ reg_w_riv(dev, 0x34, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
break;
case BRIDGE_SPCA504C: /* pccam600 */
PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
- reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
- reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001); /* reset */
+ reg_w_riv(dev, 0xe0, 0x0000, 0x0000);
+ reg_w_riv(dev, 0xe0, 0x0000, 0x0001); /* reset */
spca504_wait_status(gspca_dev);
if (sd->subtype == LogitechClickSmart420)
write_vector(gspca_dev,
@@ -918,7 +919,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
else
write_vector(gspca_dev, spca504_pccam600_open_data,
ARRAY_SIZE(spca504_pccam600_open_data));
- setup_qtable(gspca_dev, qtable_creative_pccam);
+ err_code = spca50x_setup_qtable(gspca_dev,
+ qtable_creative_pccam);
+ if (err_code < 0) {
+ PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
+ return err_code;
+ }
break;
default:
/* case BRIDGE_SPCA504: */
@@ -952,24 +958,29 @@ static int sd_init(struct gspca_dev *gspca_dev)
6, 0, 0x86, 1); */
/* spca504A_acknowledged_command (gspca_dev, 0x24,
0, 0, 0x9D, 1); */
- reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
- /* L92 sno1t.txt */
- reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
+ reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
+ reg_w_riv(dev, 0x00, 0x2310, 0x05);
spca504A_acknowledged_command(gspca_dev, 0x01,
0x0f, 0, 0xff, 0);
}
/* setup qtable */
- reg_w_riv(gspca_dev, 0, 0x2000, 0);
- reg_w_riv(gspca_dev, 0, 0x2883, 1);
- setup_qtable(gspca_dev, qtable_spca504_default);
+ reg_w_riv(dev, 0, 0x2000, 0);
+ reg_w_riv(dev, 0, 0x2883, 1);
+ err_code = spca50x_setup_qtable(gspca_dev,
+ qtable_spca504_default);
+ if (err_code < 0) {
+ PDEBUG(D_ERR, "spca50x_setup_qtable failed");
+ return err_code;
+ }
break;
}
- return gspca_dev->usb_err;
+ return 0;
}
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
int enable;
int i;
u8 info[6];
@@ -994,13 +1005,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
case MegapixV4:
case LogitechClickSmart820:
case MegaImageVI:
- reg_w_riv(gspca_dev, 0xf0, 0, 0);
+ reg_w_riv(dev, 0xf0, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
reg_r(gspca_dev, 0xf0, 4, 0);
spca504B_WaitCmdStatus(gspca_dev);
break;
default:
- reg_w_riv(gspca_dev, 0x31, 0, 0x04);
+ reg_w_riv(dev, 0x31, 0, 0x04);
spca504B_WaitCmdStatus(gspca_dev);
spca504B_PollingDataReady(gspca_dev);
break;
@@ -1037,9 +1048,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
}
spca504B_SetSizeType(gspca_dev);
- reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
- /* L92 sno1t.txt */
- reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
+ reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
+ reg_w_riv(dev, 0x00, 0x2310, 0x05);
break;
case BRIDGE_SPCA504C:
if (sd->subtype == LogitechClickSmart420) {
@@ -1051,37 +1061,36 @@ static int sd_start(struct gspca_dev *gspca_dev)
ARRAY_SIZE(spca504_pccam600_init_data));
}
enable = (sd->autogain ? 0x04 : 0x01);
- reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
- /* auto exposure */
- reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
- /* auto whiteness */
+ reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */
+ reg_w_riv(dev, 0xb0, 0x0000, enable); /* auto whiteness */
/* set default exposure compensation and whiteness balance */
- reg_w_riv(gspca_dev, 0x30, 0x0001, 800); /* ~ 20 fps */
- reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
+ reg_w_riv(dev, 0x30, 0x0001, 800); /* ~ 20 fps */
+ reg_w_riv(dev, 0x30, 0x0002, 1600);
spca504B_SetSizeType(gspca_dev);
break;
}
init_ctl_reg(gspca_dev);
- return gspca_dev->usb_err;
+ return 0;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
switch (sd->bridge) {
default:
/* case BRIDGE_SPCA533: */
/* case BRIDGE_SPCA536: */
/* case BRIDGE_SPCA504B: */
- reg_w_riv(gspca_dev, 0x31, 0, 0);
+ reg_w_riv(dev, 0x31, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
spca504B_PollingDataReady(gspca_dev);
break;
case BRIDGE_SPCA504:
case BRIDGE_SPCA504C:
- reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
+ reg_w_riv(dev, 0x00, 0x2000, 0x0000);
if (sd->subtype == AiptekMiniPenCam13) {
/* spca504a aiptek */
@@ -1093,7 +1102,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
0x0f, 0x00, 0xff, 1);
} else {
spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
- reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
+ reg_w_riv(dev, 0x01, 0x000f, 0x0000);
}
break;
}
@@ -1207,7 +1216,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
sd->brightness = val;
if (gspca_dev->streaming)
setbrightness(gspca_dev);
- return gspca_dev->usb_err;
+ return 0;
}
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1225,7 +1234,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
sd->contrast = val;
if (gspca_dev->streaming)
setcontrast(gspca_dev);
- return gspca_dev->usb_err;
+ return 0;
}
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1243,7 +1252,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
sd->colors = val;
if (gspca_dev->streaming)
setcolors(gspca_dev);
- return gspca_dev->usb_err;
+ return 0;
}
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1283,7 +1292,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev,
sd->quality = jcomp->quality;
if (gspca_dev->streaming)
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
- return gspca_dev->usb_err;
+ return 0;
}
static int sd_get_jcomp(struct gspca_dev *gspca_dev,
diff --git a/trunk/drivers/media/video/gspca/zc3xx.c b/trunk/drivers/media/video/gspca/zc3xx.c
index 1a800fc1c00e..69e5dc4fc9de 100644
--- a/trunk/drivers/media/video/gspca/zc3xx.c
+++ b/trunk/drivers/media/video/gspca/zc3xx.c
@@ -5345,6 +5345,9 @@ static const struct usb_action tas5130cxx_InitialScale[] = { /* 320x240 */
{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
+ {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
+
{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -5361,27 +5364,27 @@ static const struct usb_action tas5130cxx_InitialScale[] = { /* 320x240 */
{0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x70, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x95, ZC3XX_R18D_YTARGET},
{0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
{0xa0, 0x00, 0x01ad},
{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
- {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
{}
};
static const struct usb_action tas5130cxx_Initial[] = { /* 640x480 */
{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x40, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
{0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT},
{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
{0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING},
{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
+ {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -5397,15 +5400,13 @@ static const struct usb_action tas5130cxx_Initial[] = { /* 640x480 */
{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x70, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x95, ZC3XX_R18D_YTARGET},
{0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
{0xa0, 0x00, 0x01ad},
{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
- {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
{}
};
static const struct usb_action tas5130cxx_50HZ[] = {
@@ -6423,11 +6424,11 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
if (retword != 0)
return 0x0e; /* PAS202BCB */
- start_2wr_probe(dev, 0x02); /* TAS5130C */
+ start_2wr_probe(dev, 0x02); /* ?? */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
retword = i2c_read(gspca_dev, 0x01);
if (retword != 0)
- return 0x02; /* TAS5130C */
+ return 0x02; /* ?? */
ov_check:
reg_r(gspca_dev, 0x0010); /* ?? */
reg_r(gspca_dev, 0x0010);
@@ -6504,8 +6505,6 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_r(gspca_dev, 0x0010);
/* value 0x4001 is meaningless */
if (retword != 0x4001) {
- if ((retword & 0xff00) == 0x6400)
- return 0x02; /* TAS5130C */
for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
if (chipset_revision_sensor[i].revision == retword) {
sd->chip_revision = retword;
@@ -6516,7 +6515,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
}
}
- reg_w(dev, 0x01, 0x0000); /* check PB0330 */
+ reg_w(dev, 0x01, 0x0000); /* check ?? */
reg_w(dev, 0x01, 0x0001);
reg_w(dev, 0xdd, 0x008b);
reg_w(dev, 0x0a, 0x0010);
@@ -6525,7 +6524,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
retword = i2c_read(gspca_dev, 0x00);
if (retword != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
- return 0x0a; /* PB0330 */
+ return 0x0a; /* ?? */
}
reg_w(dev, 0x01, 0x0000);
@@ -6674,10 +6673,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Find Sensor HV7131B");
sd->sensor = SENSOR_HV7131B;
break;
- case 0x02:
- PDEBUG(D_PROBE, "Sensor TAS5130C");
- sd->sensor = SENSOR_TAS5130CXX;
- break;
case 0x04:
PDEBUG(D_PROBE, "Find Sensor CS2102");
sd->sensor = SENSOR_CS2102;
@@ -6871,14 +6866,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
case SENSOR_GC0305:
case SENSOR_OV7620:
case SENSOR_PO2030:
- case SENSOR_TAS5130CXX:
case SENSOR_TAS5130C_VF0250:
/* msleep(100); * ?? */
reg_r(gspca_dev, 0x0002); /* --> 0x40 */
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae);
- if (sd->sensor == SENSOR_TAS5130CXX)
- break;
reg_w(dev, 0x0d, 0x003a);
reg_w(dev, 0x02, 0x003b);
reg_w(dev, 0x00, 0x0038);
@@ -6895,7 +6887,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
break;
case SENSOR_PAS202B:
case SENSOR_GC0305:
- case SENSOR_TAS5130CXX:
reg_r(gspca_dev, 0x0008);
/* fall thru */
case SENSOR_PO2030:
@@ -6937,7 +6928,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(dev, 0x40, 0x0117);
break;
case SENSOR_GC0305:
- case SENSOR_TAS5130CXX:
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae);
/* fall thru */
@@ -7230,7 +7220,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106},
{USB_DEVICE(0x0ac8, 0x301b)},
{USB_DEVICE(0x0ac8, 0x303b)},
- {USB_DEVICE(0x0ac8, 0x305b)},
+ {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
{USB_DEVICE(0x0ac8, 0x307b)},
{USB_DEVICE(0x10fd, 0x0128)},
{USB_DEVICE(0x10fd, 0x804d)},
diff --git a/trunk/drivers/media/video/hdpvr/hdpvr-core.c b/trunk/drivers/media/video/hdpvr/hdpvr-core.c
index 51f393d03a46..1c9bc94c905c 100644
--- a/trunk/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/trunk/drivers/media/video/hdpvr/hdpvr-core.c
@@ -145,7 +145,7 @@ static int device_authorization(struct hdpvr_device *dev)
#ifdef HDPVR_DEBUG
else {
hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf,
- 5*buf_size+1, 0);
+ sizeof(print_buf), 0);
v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"Status request returned, len %d: %s\n",
ret, print_buf);
@@ -168,13 +168,13 @@ static int device_authorization(struct hdpvr_device *dev)
response = dev->usbc_buf+38;
#ifdef HDPVR_DEBUG
- hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0);
+ hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n",
print_buf);
#endif
challenge(response);
#ifdef HDPVR_DEBUG
- hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0);
+ hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n",
print_buf);
#endif
@@ -376,8 +376,8 @@ static int hdpvr_probe(struct usb_interface *interface,
usb_set_intfdata(interface, dev);
/* let the user know what node this device is now attached to */
- v4l2_info(&dev->v4l2_dev, "device now attached to %s\n",
- video_device_node_name(dev->video_dev));
+ v4l2_info(&dev->v4l2_dev, "device now attached to /dev/video%d\n",
+ dev->video_dev->minor);
return 0;
error:
@@ -391,10 +391,13 @@ static int hdpvr_probe(struct usb_interface *interface,
static void hdpvr_disconnect(struct usb_interface *interface)
{
struct hdpvr_device *dev;
+ int minor;
dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
+ minor = dev->video_dev->minor;
+
/* prevent more I/O from starting and stop any ongoing */
mutex_lock(&dev->io_mutex);
dev->status = STATUS_DISCONNECTED;
@@ -422,8 +425,7 @@ static void hdpvr_disconnect(struct usb_interface *interface)
atomic_dec(&dev_nr);
- v4l2_info(&dev->v4l2_dev, "device %s disconnected\n",
- video_device_node_name(dev->video_dev));
+ v4l2_info(&dev->v4l2_dev, "device /dev/video%d disconnected\n", minor);
v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev->usbc_buf);
diff --git a/trunk/drivers/media/video/hdpvr/hdpvr-video.c b/trunk/drivers/media/video/hdpvr/hdpvr-video.c
index fdd782039e9d..b5439cabb381 100644
--- a/trunk/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/trunk/drivers/media/video/hdpvr/hdpvr-video.c
@@ -523,7 +523,7 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
mutex_lock(&dev->io_mutex);
- if (!video_is_registered(dev->video_dev)) {
+ if (video_is_unregistered(dev->video_dev)) {
mutex_unlock(&dev->io_mutex);
return -EIO;
}
diff --git a/trunk/drivers/media/video/ir-kbd-i2c.c b/trunk/drivers/media/video/ir-kbd-i2c.c
index b86e35386cee..64360d26b32d 100644
--- a/trunk/drivers/media/video/ir-kbd-i2c.c
+++ b/trunk/drivers/media/video/ir-kbd-i2c.c
@@ -353,7 +353,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
ir_type = IR_TYPE_RC5;
ir_codes = &ir_codes_fusionhdtv_mce_table;
break;
- case 0x0b:
case 0x47:
case 0x71:
if (adap->id == I2C_HW_B_CX2388x ||
@@ -423,7 +422,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
/* Make sure we are all setup before going on */
if (!name || !ir->get_key || !ir_type || !ir_codes) {
- dprintk(1, ": Unsupported device at address 0x%02x\n",
+ dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n",
addr);
err = -ENODEV;
goto err_out_free;
@@ -438,7 +437,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_name(&client->dev));
/* init + register input device */
- err = ir_input_init(input_dev, &ir->ir, ir_type);
+ err = ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
if (err < 0)
goto err_out_free;
@@ -446,7 +445,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
input_dev->name = ir->name;
input_dev->phys = ir->phys;
- err = ir_input_register(ir->input, ir->ir_codes);
+ err = input_register_device(ir->input);
if (err)
goto err_out_free;
@@ -460,6 +459,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
return 0;
err_out_free:
+ ir_input_free(input_dev);
+ input_free_device(input_dev);
kfree(ir);
return err;
}
@@ -472,7 +473,8 @@ static int ir_remove(struct i2c_client *client)
cancel_delayed_work_sync(&ir->work);
/* unregister device */
- ir_input_unregister(ir->input);
+ ir_input_free(ir->input);
+ input_unregister_device(ir->input);
/* free memory */
kfree(ir);
diff --git a/trunk/drivers/media/video/ivtv/ivtv-fileops.c b/trunk/drivers/media/video/ivtv/ivtv-fileops.c
index babcabd73c08..e707ef3086b2 100644
--- a/trunk/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/trunk/drivers/media/video/ivtv/ivtv-fileops.c
@@ -985,8 +985,8 @@ int ivtv_v4l2_open(struct file *filp)
mutex_lock(&itv->serialize_lock);
if (ivtv_init_on_first_open(itv)) {
- IVTV_ERR("Failed to initialize on device %s\n",
- video_device_node_name(vdev));
+ IVTV_ERR("Failed to initialize on minor %d\n",
+ vdev->minor);
mutex_unlock(&itv->serialize_lock);
return -ENXIO;
}
diff --git a/trunk/drivers/media/video/ivtv/ivtv-streams.c b/trunk/drivers/media/video/ivtv/ivtv-streams.c
index e12c6022373e..67699e3f2aaa 100644
--- a/trunk/drivers/media/video/ivtv/ivtv-streams.c
+++ b/trunk/drivers/media/video/ivtv/ivtv-streams.c
@@ -245,7 +245,6 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
{
struct ivtv_stream *s = &itv->streams[type];
int vfl_type = ivtv_stream_info[type].vfl_type;
- const char *name;
int num;
if (s->vdev == NULL)
@@ -269,24 +268,24 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
s->vdev = NULL;
return -ENOMEM;
}
- name = video_device_node_name(s->vdev);
+ num = s->vdev->num;
switch (vfl_type) {
case VFL_TYPE_GRABBER:
- IVTV_INFO("Registered device %s for %s (%d kB)\n",
- name, s->name, itv->options.kilobytes[type]);
+ IVTV_INFO("Registered device video%d for %s (%d kB)\n",
+ num, s->name, itv->options.kilobytes[type]);
break;
case VFL_TYPE_RADIO:
- IVTV_INFO("Registered device %s for %s\n",
- name, s->name);
+ IVTV_INFO("Registered device radio%d for %s\n",
+ num, s->name);
break;
case VFL_TYPE_VBI:
if (itv->options.kilobytes[type])
- IVTV_INFO("Registered device %s for %s (%d kB)\n",
- name, s->name, itv->options.kilobytes[type]);
+ IVTV_INFO("Registered device vbi%d for %s (%d kB)\n",
+ num, s->name, itv->options.kilobytes[type]);
else
- IVTV_INFO("Registered device %s for %s\n",
- name, s->name);
+ IVTV_INFO("Registered device vbi%d for %s\n",
+ num, s->name);
break;
}
return 0;
diff --git a/trunk/drivers/media/video/meye.c b/trunk/drivers/media/video/meye.c
index 6ffa64cd1c6d..01e1eefcf1eb 100644
--- a/trunk/drivers/media/video/meye.c
+++ b/trunk/drivers/media/video/meye.c
@@ -1681,6 +1681,7 @@ static struct video_device meye_template = {
.fops = &meye_fops,
.ioctl_ops = &meye_ioctl_ops,
.release = video_device_release,
+ .minor = -1,
};
#ifdef CONFIG_PM
diff --git a/trunk/drivers/media/video/mt9m001.c b/trunk/drivers/media/video/mt9m001.c
index b62c0bd3f8ea..45388d2ce2fd 100644
--- a/trunk/drivers/media/video/mt9m001.c
+++ b/trunk/drivers/media/video/mt9m001.c
@@ -17,11 +17,9 @@
#include
#include
-/*
- * mt9m001 i2c address 0x5d
+/* mt9m001 i2c address 0x5d
* The platform has to define ctruct i2c_board_info objects and link to them
- * from struct soc_camera_link
- */
+ * from struct soc_camera_link */
/* mt9m001 selected register addresses */
#define MT9M001_CHIP_VERSION 0x00
@@ -48,50 +46,42 @@
#define MT9M001_COLUMN_SKIP 20
#define MT9M001_ROW_SKIP 12
-/* MT9M001 has only one fixed colorspace per pixelcode */
-struct mt9m001_datafmt {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-/* Find a data format by a pixel code in an array */
-static const struct mt9m001_datafmt *mt9m001_find_datafmt(
- enum v4l2_mbus_pixelcode code, const struct mt9m001_datafmt *fmt,
- int n)
-{
- int i;
- for (i = 0; i < n; i++)
- if (fmt[i].code == code)
- return fmt + i;
-
- return NULL;
-}
-
-static const struct mt9m001_datafmt mt9m001_colour_fmts[] = {
- /*
- * Order important: first natively supported,
- * second supported with a GPIO extender
- */
- {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
+static const struct soc_camera_data_format mt9m001_colour_formats[] = {
+ /* Order important: first natively supported,
+ * second supported with a GPIO extender */
+ {
+ .name = "Bayer (sRGB) 10 bit",
+ .depth = 10,
+ .fourcc = V4L2_PIX_FMT_SBGGR16,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }, {
+ .name = "Bayer (sRGB) 8 bit",
+ .depth = 8,
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }
};
-static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
+static const struct soc_camera_data_format mt9m001_monochrome_formats[] = {
/* Order important - see above */
- {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG},
+ {
+ .name = "Monochrome 10 bit",
+ .depth = 10,
+ .fourcc = V4L2_PIX_FMT_Y16,
+ }, {
+ .name = "Monochrome 8 bit",
+ .depth = 8,
+ .fourcc = V4L2_PIX_FMT_GREY,
+ },
};
struct mt9m001 {
struct v4l2_subdev subdev;
struct v4l2_rect rect; /* Sensor window */
- const struct mt9m001_datafmt *fmt;
- const struct mt9m001_datafmt *fmts;
- int num_fmts;
+ __u32 fourcc;
int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
unsigned int gain;
unsigned int exposure;
- unsigned short y_skip_top; /* Lines to skip at the top */
unsigned char autoexposure;
};
@@ -214,7 +204,8 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
const u16 hblank = 9, vblank = 25;
unsigned int total_h;
- if (mt9m001->fmts == mt9m001_colour_fmts)
+ if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 ||
+ mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16)
/*
* Bayer format - even number of rows for simplicity,
* but let the user play with the top row.
@@ -231,17 +222,15 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
soc_camera_limit_side(&rect.top, &rect.height,
MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
- total_h = rect.height + mt9m001->y_skip_top + vblank;
+ total_h = rect.height + icd->y_skip_top + vblank;
/* Blanking and start values - default... */
ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
if (!ret)
ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank);
- /*
- * The caller provides a supported format, as verified per
- * call to icd->try_fmt()
- */
+ /* The caller provides a supported format, as verified per
+ * call to icd->try_fmt() */
if (!ret)
ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
if (!ret)
@@ -250,7 +239,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1);
if (!ret)
ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
- rect.height + mt9m001->y_skip_top - 1);
+ rect.height + icd->y_skip_top - 1);
if (!ret && mt9m001->autoexposure) {
ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h);
if (!ret) {
@@ -294,32 +283,32 @@ static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int mt9m001_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9m001_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct mt9m001 *mt9m001 = to_mt9m001(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- mf->width = mt9m001->rect.width;
- mf->height = mt9m001->rect.height;
- mf->code = mt9m001->fmt->code;
- mf->colorspace = mt9m001->fmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
+ pix->width = mt9m001->rect.width;
+ pix->height = mt9m001->rect.height;
+ pix->pixelformat = mt9m001->fourcc;
+ pix->field = V4L2_FIELD_NONE;
+ pix->colorspace = V4L2_COLORSPACE_SRGB;
return 0;
}
-static int mt9m001_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct mt9m001 *mt9m001 = to_mt9m001(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_crop a = {
.c = {
.left = mt9m001->rect.left,
.top = mt9m001->rect.top,
- .width = mf->width,
- .height = mf->height,
+ .width = pix->width,
+ .height = pix->height,
},
};
int ret;
@@ -327,39 +316,28 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd,
/* No support for scaling so far, just crop. TODO: use skipping */
ret = mt9m001_s_crop(sd, &a);
if (!ret) {
- mf->width = mt9m001->rect.width;
- mf->height = mt9m001->rect.height;
- mt9m001->fmt = mt9m001_find_datafmt(mf->code,
- mt9m001->fmts, mt9m001->num_fmts);
- mf->colorspace = mt9m001->fmt->colorspace;
+ pix->width = mt9m001->rect.width;
+ pix->height = mt9m001->rect.height;
+ mt9m001->fourcc = pix->pixelformat;
}
return ret;
}
-static int mt9m001_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
- struct mt9m001 *mt9m001 = to_mt9m001(client);
- const struct mt9m001_datafmt *fmt;
+ struct soc_camera_device *icd = client->dev.platform_data;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH,
+ v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH,
MT9M001_MAX_WIDTH, 1,
- &mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top,
- MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0);
-
- if (mt9m001->fmts == mt9m001_colour_fmts)
- mf->height = ALIGN(mf->height - 1, 2);
+ &pix->height, MT9M001_MIN_HEIGHT + icd->y_skip_top,
+ MT9M001_MAX_HEIGHT + icd->y_skip_top, 0, 0);
- fmt = mt9m001_find_datafmt(mf->code, mt9m001->fmts,
- mt9m001->num_fmts);
- if (!fmt) {
- fmt = mt9m001->fmt;
- mf->code = fmt->code;
- }
-
- mf->colorspace = fmt->colorspace;
+ if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
+ pix->pixelformat == V4L2_PIX_FMT_SBGGR16)
+ pix->height = ALIGN(pix->height - 1, 2);
return 0;
}
@@ -574,7 +552,7 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
if (ctrl->value) {
const u16 vblank = 25;
unsigned int total_h = mt9m001->rect.height +
- mt9m001->y_skip_top + vblank;
+ icd->y_skip_top + vblank;
if (reg_write(client, MT9M001_SHUTTER_WIDTH,
total_h) < 0)
return -EIO;
@@ -590,10 +568,8 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
return 0;
}
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
static int mt9m001_video_probe(struct soc_camera_device *icd,
struct i2c_client *client)
{
@@ -603,10 +579,8 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
unsigned long flags;
int ret;
- /*
- * We must have a parent by now. And it cannot be a wrong one.
- * So this entire test is completely redundant.
- */
+ /* We must have a parent by now. And it cannot be a wrong one.
+ * So this entire test is completely redundant. */
if (!icd->dev.parent ||
to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
return -ENODEV;
@@ -623,11 +597,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
case 0x8411:
case 0x8421:
mt9m001->model = V4L2_IDENT_MT9M001C12ST;
- mt9m001->fmts = mt9m001_colour_fmts;
+ icd->formats = mt9m001_colour_formats;
break;
case 0x8431:
mt9m001->model = V4L2_IDENT_MT9M001C12STM;
- mt9m001->fmts = mt9m001_monochrome_fmts;
+ icd->formats = mt9m001_monochrome_formats;
break;
default:
dev_err(&client->dev,
@@ -635,7 +609,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
return -ENODEV;
}
- mt9m001->num_fmts = 0;
+ icd->num_formats = 0;
/*
* This is a 10bit sensor, so by default we only allow 10bit.
@@ -648,14 +622,14 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
flags = SOCAM_DATAWIDTH_10;
if (flags & SOCAM_DATAWIDTH_10)
- mt9m001->num_fmts++;
+ icd->num_formats++;
else
- mt9m001->fmts++;
+ icd->formats++;
if (flags & SOCAM_DATAWIDTH_8)
- mt9m001->num_fmts++;
+ icd->num_formats++;
- mt9m001->fmt = &mt9m001->fmts[0];
+ mt9m001->fourcc = icd->formats->fourcc;
dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
data == 0x8431 ? "C12STM" : "C12ST");
@@ -681,16 +655,6 @@ static void mt9m001_video_remove(struct soc_camera_device *icd)
icl->free_bus(icl);
}
-static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
-{
- struct i2c_client *client = sd->priv;
- struct mt9m001 *mt9m001 = to_mt9m001(client);
-
- *lines = mt9m001->y_skip_top;
-
- return 0;
-}
-
static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
.g_ctrl = mt9m001_g_ctrl,
.s_ctrl = mt9m001_s_ctrl,
@@ -701,38 +665,19 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
#endif
};
-static int mt9m001_enum_fmt(struct v4l2_subdev *sd, int index,
- enum v4l2_mbus_pixelcode *code)
-{
- struct i2c_client *client = sd->priv;
- struct mt9m001 *mt9m001 = to_mt9m001(client);
-
- if ((unsigned int)index >= mt9m001->num_fmts)
- return -EINVAL;
-
- *code = mt9m001->fmts[index].code;
- return 0;
-}
-
static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
.s_stream = mt9m001_s_stream,
- .s_mbus_fmt = mt9m001_s_fmt,
- .g_mbus_fmt = mt9m001_g_fmt,
- .try_mbus_fmt = mt9m001_try_fmt,
+ .s_fmt = mt9m001_s_fmt,
+ .g_fmt = mt9m001_g_fmt,
+ .try_fmt = mt9m001_try_fmt,
.s_crop = mt9m001_s_crop,
.g_crop = mt9m001_g_crop,
.cropcap = mt9m001_cropcap,
- .enum_mbus_fmt = mt9m001_enum_fmt,
-};
-
-static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
- .g_skip_top_lines = mt9m001_g_skip_top_lines,
};
static struct v4l2_subdev_ops mt9m001_subdev_ops = {
.core = &mt9m001_subdev_core_ops,
.video = &mt9m001_subdev_video_ops,
- .sensor = &mt9m001_subdev_sensor_ops,
};
static int mt9m001_probe(struct i2c_client *client,
@@ -769,17 +714,15 @@ static int mt9m001_probe(struct i2c_client *client,
/* Second stage probe - when a capture adapter is there */
icd->ops = &mt9m001_ops;
+ icd->y_skip_top = 0;
- mt9m001->y_skip_top = 0;
mt9m001->rect.left = MT9M001_COLUMN_SKIP;
mt9m001->rect.top = MT9M001_ROW_SKIP;
mt9m001->rect.width = MT9M001_MAX_WIDTH;
mt9m001->rect.height = MT9M001_MAX_HEIGHT;
- /*
- * Simulated autoexposure. If enabled, we calculate shutter width
- * ourselves in the driver based on vertical blanking and frame width
- */
+ /* Simulated autoexposure. If enabled, we calculate shutter width
+ * ourselves in the driver based on vertical blanking and frame width */
mt9m001->autoexposure = 1;
ret = mt9m001_video_probe(icd, client);
diff --git a/trunk/drivers/media/video/mt9m111.c b/trunk/drivers/media/video/mt9m111.c
index d35f536f9fc3..90da699601ea 100644
--- a/trunk/drivers/media/video/mt9m111.c
+++ b/trunk/drivers/media/video/mt9m111.c
@@ -123,34 +123,23 @@
#define MT9M111_MAX_HEIGHT 1024
#define MT9M111_MAX_WIDTH 1280
-/* MT9M111 has only one fixed colorspace per pixelcode */
-struct mt9m111_datafmt {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-/* Find a data format by a pixel code in an array */
-static const struct mt9m111_datafmt *mt9m111_find_datafmt(
- enum v4l2_mbus_pixelcode code, const struct mt9m111_datafmt *fmt,
- int n)
-{
- int i;
- for (i = 0; i < n; i++)
- if (fmt[i].code == code)
- return fmt + i;
-
- return NULL;
-}
-
-static const struct mt9m111_datafmt mt9m111_colour_fmts[] = {
- {V4L2_MBUS_FMT_YUYV8_2X8_LE, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_YVYU8_2X8_LE, V4L2_COLORSPACE_JPEG},
- {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_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
+#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
+ { .name = _name, .depth = _depth, .fourcc = _fourcc, \
+ .colorspace = _colorspace }
+#define RGB_FMT(_name, _depth, _fourcc) \
+ COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB)
+#define JPG_FMT(_name, _depth, _fourcc) \
+ COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+
+static const struct soc_camera_data_format mt9m111_colour_formats[] = {
+ JPG_FMT("CbYCrY 16 bit", 16, V4L2_PIX_FMT_UYVY),
+ JPG_FMT("CrYCbY 16 bit", 16, V4L2_PIX_FMT_VYUY),
+ JPG_FMT("YCbYCr 16 bit", 16, V4L2_PIX_FMT_YUYV),
+ JPG_FMT("YCrYCb 16 bit", 16, V4L2_PIX_FMT_YVYU),
+ RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565),
+ RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555),
+ RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16),
+ RGB_FMT("Bayer (sRGB) 8 bit", 8, V4L2_PIX_FMT_SBGGR8),
};
enum mt9m111_context {
@@ -163,7 +152,7 @@ struct mt9m111 {
int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
enum mt9m111_context context;
struct v4l2_rect rect;
- const struct mt9m111_datafmt *fmt;
+ u32 pixfmt;
unsigned int gain;
unsigned char autoexposure;
unsigned char datawidth;
@@ -269,8 +258,8 @@ static int mt9m111_setup_rect(struct i2c_client *client,
int width = rect->width;
int height = rect->height;
- if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
- mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE)
+ if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
+ mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)
is_raw_format = 1;
else
is_raw_format = 0;
@@ -318,8 +307,7 @@ static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt)
static int mt9m111_setfmt_bayer8(struct i2c_client *client)
{
- return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER |
- MT9M111_OUTFMT_RGB);
+ return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER);
}
static int mt9m111_setfmt_bayer10(struct i2c_client *client)
@@ -413,8 +401,8 @@ static int mt9m111_make_rect(struct i2c_client *client,
{
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) {
+ if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
+ mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) {
/* Bayer format - even size lengths */
rect->width = ALIGN(rect->width, 2);
rect->height = ALIGN(rect->height, 2);
@@ -472,139 +460,120 @@ static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int mt9m111_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9m111_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct mt9m111 *mt9m111 = to_mt9m111(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- mf->width = mt9m111->rect.width;
- mf->height = mt9m111->rect.height;
- mf->code = mt9m111->fmt->code;
- mf->field = V4L2_FIELD_NONE;
+ pix->width = mt9m111->rect.width;
+ pix->height = mt9m111->rect.height;
+ pix->pixelformat = mt9m111->pixfmt;
+ pix->field = V4L2_FIELD_NONE;
+ pix->colorspace = V4L2_COLORSPACE_SRGB;
return 0;
}
-static int mt9m111_set_pixfmt(struct i2c_client *client,
- enum v4l2_mbus_pixelcode code)
+static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt)
{
struct mt9m111 *mt9m111 = to_mt9m111(client);
int ret;
- switch (code) {
- case V4L2_MBUS_FMT_SBGGR8_1X8:
+ switch (pixfmt) {
+ case V4L2_PIX_FMT_SBGGR8:
ret = mt9m111_setfmt_bayer8(client);
break;
- case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE:
+ case V4L2_PIX_FMT_SBGGR16:
ret = mt9m111_setfmt_bayer10(client);
break;
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
+ case V4L2_PIX_FMT_RGB555:
ret = mt9m111_setfmt_rgb555(client);
break;
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
+ case V4L2_PIX_FMT_RGB565:
ret = mt9m111_setfmt_rgb565(client);
break;
- case V4L2_MBUS_FMT_YUYV8_2X8_BE:
+ case V4L2_PIX_FMT_UYVY:
mt9m111->swap_yuv_y_chromas = 0;
mt9m111->swap_yuv_cb_cr = 0;
ret = mt9m111_setfmt_yuv(client);
break;
- case V4L2_MBUS_FMT_YVYU8_2X8_BE:
+ case V4L2_PIX_FMT_VYUY:
mt9m111->swap_yuv_y_chromas = 0;
mt9m111->swap_yuv_cb_cr = 1;
ret = mt9m111_setfmt_yuv(client);
break;
- case V4L2_MBUS_FMT_YUYV8_2X8_LE:
+ case V4L2_PIX_FMT_YUYV:
mt9m111->swap_yuv_y_chromas = 1;
mt9m111->swap_yuv_cb_cr = 0;
ret = mt9m111_setfmt_yuv(client);
break;
- case V4L2_MBUS_FMT_YVYU8_2X8_LE:
+ case V4L2_PIX_FMT_YVYU:
mt9m111->swap_yuv_y_chromas = 1;
mt9m111->swap_yuv_cb_cr = 1;
ret = mt9m111_setfmt_yuv(client);
break;
default:
dev_err(&client->dev, "Pixel format not handled : %x\n",
- code);
+ pixfmt);
ret = -EINVAL;
}
+ if (!ret)
+ mt9m111->pixfmt = pixfmt;
+
return ret;
}
-static int mt9m111_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
- const struct mt9m111_datafmt *fmt;
struct mt9m111 *mt9m111 = to_mt9m111(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_rect rect = {
.left = mt9m111->rect.left,
.top = mt9m111->rect.top,
- .width = mf->width,
- .height = mf->height,
+ .width = pix->width,
+ .height = pix->height,
};
int ret;
- fmt = mt9m111_find_datafmt(mf->code, mt9m111_colour_fmts,
- ARRAY_SIZE(mt9m111_colour_fmts));
- if (!fmt)
- return -EINVAL;
-
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);
+ "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__,
+ pix->pixelformat, rect.left, rect.top, rect.width, rect.height);
ret = mt9m111_make_rect(client, &rect);
if (!ret)
- ret = mt9m111_set_pixfmt(client, mf->code);
- if (!ret) {
- mt9m111->rect = rect;
- mt9m111->fmt = fmt;
- mf->colorspace = fmt->colorspace;
- }
-
+ ret = mt9m111_set_pixfmt(client, pix->pixelformat);
+ if (!ret)
+ mt9m111->rect = rect;
return ret;
}
-static int mt9m111_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
- struct i2c_client *client = sd->priv;
- struct mt9m111 *mt9m111 = to_mt9m111(client);
- 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) {
- fmt = mt9m111->fmt;
- mf->code = fmt->code;
- }
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ bool bayer = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
+ pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
/*
* With Bayer format enforce even side lengths, but let the user play
* with the starting pixel
*/
- if (mf->height > MT9M111_MAX_HEIGHT)
- mf->height = MT9M111_MAX_HEIGHT;
- else if (mf->height < 2)
- mf->height = 2;
+ if (pix->height > MT9M111_MAX_HEIGHT)
+ pix->height = MT9M111_MAX_HEIGHT;
+ else if (pix->height < 2)
+ pix->height = 2;
else if (bayer)
- mf->height = ALIGN(mf->height, 2);
+ pix->height = ALIGN(pix->height, 2);
- if (mf->width > MT9M111_MAX_WIDTH)
- mf->width = MT9M111_MAX_WIDTH;
- else if (mf->width < 2)
- mf->width = 2;
+ if (pix->width > MT9M111_MAX_WIDTH)
+ pix->width = MT9M111_MAX_WIDTH;
+ else if (pix->width < 2)
+ pix->width = 2;
else if (bayer)
- mf->width = ALIGN(mf->width, 2);
-
- mf->colorspace = fmt->colorspace;
+ pix->width = ALIGN(pix->width, 2);
return 0;
}
@@ -894,7 +863,7 @@ static int mt9m111_restore_state(struct i2c_client *client)
struct mt9m111 *mt9m111 = to_mt9m111(client);
mt9m111_set_context(client, mt9m111->context);
- mt9m111_set_pixfmt(client, mt9m111->fmt->code);
+ mt9m111_set_pixfmt(client, mt9m111->pixfmt);
mt9m111_setup_rect(client, &mt9m111->rect);
mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
@@ -983,6 +952,9 @@ static int mt9m111_video_probe(struct soc_camera_device *icd,
goto ei2c;
}
+ icd->formats = mt9m111_colour_formats;
+ icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats);
+
dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data);
ei2c:
@@ -999,24 +971,13 @@ static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
#endif
};
-static int mt9m111_enum_fmt(struct v4l2_subdev *sd, int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if ((unsigned int)index >= ARRAY_SIZE(mt9m111_colour_fmts))
- return -EINVAL;
-
- *code = mt9m111_colour_fmts[index].code;
- return 0;
-}
-
static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
- .s_mbus_fmt = mt9m111_s_fmt,
- .g_mbus_fmt = mt9m111_g_fmt,
- .try_mbus_fmt = mt9m111_try_fmt,
+ .s_fmt = mt9m111_s_fmt,
+ .g_fmt = mt9m111_g_fmt,
+ .try_fmt = mt9m111_try_fmt,
.s_crop = mt9m111_s_crop,
.g_crop = mt9m111_g_crop,
.cropcap = mt9m111_cropcap,
- .enum_mbus_fmt = mt9m111_enum_fmt,
};
static struct v4l2_subdev_ops mt9m111_subdev_ops = {
@@ -1058,12 +1019,12 @@ static int mt9m111_probe(struct i2c_client *client,
/* Second stage probe - when a capture adapter is there */
icd->ops = &mt9m111_ops;
+ icd->y_skip_top = 0;
mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
mt9m111->rect.top = MT9M111_MIN_DARK_ROWS;
mt9m111->rect.width = MT9M111_MAX_WIDTH;
mt9m111->rect.height = MT9M111_MAX_HEIGHT;
- mt9m111->fmt = &mt9m111_colour_fmts[0];
ret = mt9m111_video_probe(icd, client);
if (ret) {
diff --git a/trunk/drivers/media/video/mt9t031.c b/trunk/drivers/media/video/mt9t031.c
index a9061bff79b2..6966f644977e 100644
--- a/trunk/drivers/media/video/mt9t031.c
+++ b/trunk/drivers/media/video/mt9t031.c
@@ -17,11 +17,9 @@
#include
#include
-/*
- * mt9t031 i2c address 0x5d
+/* mt9t031 i2c address 0x5d
* The platform has to define i2c_board_info and link to it from
- * struct soc_camera_link
- */
+ * struct soc_camera_link */
/* mt9t031 selected register addresses */
#define MT9T031_CHIP_VERSION 0x00
@@ -60,6 +58,15 @@
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | \
SOCAM_MASTER | SOCAM_DATAWIDTH_10)
+static const struct soc_camera_data_format mt9t031_colour_formats[] = {
+ {
+ .name = "Bayer (sRGB) 10 bit",
+ .depth = 10,
+ .fourcc = V4L2_PIX_FMT_SGRBG10,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }
+};
+
struct mt9t031 {
struct v4l2_subdev subdev;
struct v4l2_rect rect; /* Sensor window */
@@ -67,7 +74,6 @@ struct mt9t031 {
u16 xskip;
u16 yskip;
unsigned int gain;
- unsigned short y_skip_top; /* Lines to skip at the top */
unsigned int exposure;
unsigned char autoexposure;
};
@@ -201,71 +207,6 @@ static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
}
-enum {
- MT9T031_CTRL_VFLIP,
- MT9T031_CTRL_HFLIP,
- MT9T031_CTRL_GAIN,
- MT9T031_CTRL_EXPOSURE,
- MT9T031_CTRL_EXPOSURE_AUTO,
-};
-
-static const struct v4l2_queryctrl mt9t031_controls[] = {
- [MT9T031_CTRL_VFLIP] = {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Flip Vertically",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- [MT9T031_CTRL_HFLIP] = {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Flip Horizontally",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- [MT9T031_CTRL_GAIN] = {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = 64,
- .flags = V4L2_CTRL_FLAG_SLIDER,
- },
- [MT9T031_CTRL_EXPOSURE] = {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = 1,
- .maximum = 255,
- .step = 1,
- .default_value = 255,
- .flags = V4L2_CTRL_FLAG_SLIDER,
- },
- [MT9T031_CTRL_EXPOSURE_AUTO] = {
- .id = V4L2_CID_EXPOSURE_AUTO,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Automatic Exposure",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- }
-};
-
-static struct soc_camera_ops mt9t031_ops = {
- .set_bus_param = mt9t031_set_bus_param,
- .query_bus_param = mt9t031_query_bus_param,
- .controls = mt9t031_controls,
- .num_controls = ARRAY_SIZE(mt9t031_controls),
-};
-
/* target must be _even_ */
static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
{
@@ -285,9 +226,10 @@ static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
}
/* rect is the sensor rectangle, the caller guarantees parameter validity */
-static int mt9t031_set_params(struct i2c_client *client,
+static int mt9t031_set_params(struct soc_camera_device *icd,
struct v4l2_rect *rect, u16 xskip, u16 yskip)
{
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
struct mt9t031 *mt9t031 = to_mt9t031(client);
int ret;
u16 xbin, ybin;
@@ -349,10 +291,8 @@ static int mt9t031_set_params(struct i2c_client *client,
dev_dbg(&client->dev, "new physical left %u, top %u\n",
rect->left, rect->top);
- /*
- * The caller provides a supported format, as guaranteed by
- * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap()
- */
+ /* The caller provides a supported format, as guaranteed by
+ * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
if (ret >= 0)
ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
if (ret >= 0)
@@ -361,14 +301,15 @@ static int mt9t031_set_params(struct i2c_client *client,
ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1);
if (ret >= 0)
ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
- rect->height + mt9t031->y_skip_top - 1);
+ rect->height + icd->y_skip_top - 1);
if (ret >= 0 && mt9t031->autoexposure) {
- unsigned int total_h = rect->height + mt9t031->y_skip_top + vblank;
+ unsigned int total_h = rect->height + icd->y_skip_top + vblank;
ret = set_shutter(client, total_h);
if (ret >= 0) {
const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
const struct v4l2_queryctrl *qctrl =
- &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
+ soc_camera_find_qctrl(icd->ops,
+ V4L2_CID_EXPOSURE);
mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
(qctrl->maximum - qctrl->minimum)) /
shutter_max + qctrl->minimum;
@@ -393,6 +334,7 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
struct v4l2_rect rect = a->c;
struct i2c_client *client = sd->priv;
struct mt9t031 *mt9t031 = to_mt9t031(client);
+ struct soc_camera_device *icd = client->dev.platform_data;
rect.width = ALIGN(rect.width, 2);
rect.height = ALIGN(rect.height, 2);
@@ -403,7 +345,7 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
soc_camera_limit_side(&rect.top, &rect.height,
MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT);
- return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip);
+ return mt9t031_set_params(icd, &rect, mt9t031->xskip, mt9t031->yskip);
}
static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
@@ -431,26 +373,27 @@ static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int mt9t031_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9t031_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct mt9t031 *mt9t031 = to_mt9t031(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- mf->width = mt9t031->rect.width / mt9t031->xskip;
- mf->height = mt9t031->rect.height / mt9t031->yskip;
- mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
- mf->colorspace = V4L2_COLORSPACE_SRGB;
- mf->field = V4L2_FIELD_NONE;
+ pix->width = mt9t031->rect.width / mt9t031->xskip;
+ pix->height = mt9t031->rect.height / mt9t031->yskip;
+ pix->pixelformat = V4L2_PIX_FMT_SGRBG10;
+ pix->field = V4L2_FIELD_NONE;
+ pix->colorspace = V4L2_COLORSPACE_SRGB;
return 0;
}
-static int mt9t031_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct mt9t031 *mt9t031 = to_mt9t031(client);
+ struct soc_camera_device *icd = client->dev.platform_data;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
u16 xskip, yskip;
struct v4l2_rect rect = mt9t031->rect;
@@ -458,29 +401,24 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd,
* try_fmt has put width and height within limits.
* S_FMT: use binning and skipping for scaling
*/
- xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH);
- yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT);
-
- mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
- mf->colorspace = V4L2_COLORSPACE_SRGB;
+ xskip = mt9t031_skip(&rect.width, pix->width, MT9T031_MAX_WIDTH);
+ yskip = mt9t031_skip(&rect.height, pix->height, MT9T031_MAX_HEIGHT);
/* mt9t031_set_params() doesn't change width and height */
- return mt9t031_set_params(client, &rect, xskip, yskip);
+ return mt9t031_set_params(icd, &rect, xskip, yskip);
}
/*
* If a user window larger than sensor window is requested, we'll increase the
* sensor window.
*/
-static int mt9t031_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
- v4l_bound_align_image(
- &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1,
- &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
- mf->colorspace = V4L2_COLORSPACE_SRGB;
+ v4l_bound_align_image(
+ &pix->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1,
+ &pix->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0);
return 0;
}
@@ -541,6 +479,59 @@ static int mt9t031_s_register(struct v4l2_subdev *sd,
}
#endif
+static const struct v4l2_queryctrl mt9t031_controls[] = {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flip Vertically",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flip Horizontally",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 64,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
+ }, {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Exposure",
+ .minimum = 1,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 255,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
+ }, {
+ .id = V4L2_CID_EXPOSURE_AUTO,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Automatic Exposure",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ }
+};
+
+static struct soc_camera_ops mt9t031_ops = {
+ .set_bus_param = mt9t031_set_bus_param,
+ .query_bus_param = mt9t031_query_bus_param,
+ .controls = mt9t031_controls,
+ .num_controls = ARRAY_SIZE(mt9t031_controls),
+};
+
static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct i2c_client *client = sd->priv;
@@ -577,9 +568,15 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct i2c_client *client = sd->priv;
struct mt9t031 *mt9t031 = to_mt9t031(client);
+ struct soc_camera_device *icd = client->dev.platform_data;
const struct v4l2_queryctrl *qctrl;
int data;
+ qctrl = soc_camera_find_qctrl(&mt9t031_ops, ctrl->id);
+
+ if (!qctrl)
+ return -EINVAL;
+
switch (ctrl->id) {
case V4L2_CID_VFLIP:
if (ctrl->value)
@@ -598,7 +595,6 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
return -EIO;
break;
case V4L2_CID_GAIN:
- qctrl = &mt9t031_controls[MT9T031_CTRL_GAIN];
if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
return -EINVAL;
/* See Datasheet Table 7, Gain settings. */
@@ -638,7 +634,6 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
mt9t031->gain = ctrl->value;
break;
case V4L2_CID_EXPOSURE:
- qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
/* mt9t031 has maximum == default */
if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
return -EINVAL;
@@ -662,11 +657,11 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
const u16 vblank = MT9T031_VERTICAL_BLANK;
const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
unsigned int total_h = mt9t031->rect.height +
- mt9t031->y_skip_top + vblank;
+ icd->y_skip_top + vblank;
if (set_shutter(client, total_h) < 0)
return -EIO;
- qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
+ qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
(qctrl->maximum - qctrl->minimum)) /
shutter_max + qctrl->minimum;
@@ -674,18 +669,15 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
} else
mt9t031->autoexposure = 0;
break;
- default:
- return -EINVAL;
}
return 0;
}
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
static int mt9t031_video_probe(struct i2c_client *client)
{
+ struct soc_camera_device *icd = client->dev.platform_data;
struct mt9t031 *mt9t031 = to_mt9t031(client);
s32 data;
int ret;
@@ -700,6 +692,8 @@ static int mt9t031_video_probe(struct i2c_client *client)
switch (data) {
case 0x1621:
mt9t031->model = V4L2_IDENT_MT9T031;
+ icd->formats = mt9t031_colour_formats;
+ icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats);
break;
default:
dev_err(&client->dev,
@@ -720,16 +714,6 @@ static int mt9t031_video_probe(struct i2c_client *client)
return ret;
}
-static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
-{
- struct i2c_client *client = sd->priv;
- struct mt9t031 *mt9t031 = to_mt9t031(client);
-
- *lines = mt9t031->y_skip_top;
-
- return 0;
-}
-
static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
.g_ctrl = mt9t031_g_ctrl,
.s_ctrl = mt9t031_s_ctrl,
@@ -740,35 +724,19 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
#endif
};
-static int mt9t031_enum_fmt(struct v4l2_subdev *sd, int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index)
- return -EINVAL;
-
- *code = V4L2_MBUS_FMT_SBGGR10_1X10;
- return 0;
-}
-
static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
.s_stream = mt9t031_s_stream,
- .s_mbus_fmt = mt9t031_s_fmt,
- .g_mbus_fmt = mt9t031_g_fmt,
- .try_mbus_fmt = mt9t031_try_fmt,
+ .s_fmt = mt9t031_s_fmt,
+ .g_fmt = mt9t031_g_fmt,
+ .try_fmt = mt9t031_try_fmt,
.s_crop = mt9t031_s_crop,
.g_crop = mt9t031_g_crop,
.cropcap = mt9t031_cropcap,
- .enum_mbus_fmt = mt9t031_enum_fmt,
-};
-
-static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
- .g_skip_top_lines = mt9t031_g_skip_top_lines,
};
static struct v4l2_subdev_ops mt9t031_subdev_ops = {
.core = &mt9t031_subdev_core_ops,
.video = &mt9t031_subdev_video_ops,
- .sensor = &mt9t031_subdev_sensor_ops,
};
static int mt9t031_probe(struct i2c_client *client,
@@ -777,16 +745,18 @@ static int mt9t031_probe(struct i2c_client *client,
struct mt9t031 *mt9t031;
struct soc_camera_device *icd = client->dev.platform_data;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct soc_camera_link *icl;
int ret;
- if (icd) {
- struct soc_camera_link *icl = to_soc_camera_link(icd);
- if (!icl) {
- dev_err(&client->dev, "MT9T031 driver needs platform data\n");
- return -EINVAL;
- }
+ if (!icd) {
+ dev_err(&client->dev, "MT9T031: missing soc-camera data!\n");
+ return -EINVAL;
+ }
- icd->ops = &mt9t031_ops;
+ icl = to_soc_camera_link(icd);
+ if (!icl) {
+ dev_err(&client->dev, "MT9T031 driver needs platform data\n");
+ return -EINVAL;
}
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
@@ -801,16 +771,17 @@ static int mt9t031_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
- mt9t031->y_skip_top = 0;
+ /* Second stage probe - when a capture adapter is there */
+ icd->ops = &mt9t031_ops;
+ icd->y_skip_top = 0;
+
mt9t031->rect.left = MT9T031_COLUMN_SKIP;
mt9t031->rect.top = MT9T031_ROW_SKIP;
mt9t031->rect.width = MT9T031_MAX_WIDTH;
mt9t031->rect.height = MT9T031_MAX_HEIGHT;
- /*
- * Simulated autoexposure. If enabled, we calculate shutter width
- * ourselves in the driver based on vertical blanking and frame width
- */
+ /* Simulated autoexposure. If enabled, we calculate shutter width
+ * ourselves in the driver based on vertical blanking and frame width */
mt9t031->autoexposure = 1;
mt9t031->xskip = 1;
@@ -823,8 +794,7 @@ static int mt9t031_probe(struct i2c_client *client,
mt9t031_disable(client);
if (ret) {
- if (icd)
- icd->ops = NULL;
+ icd->ops = NULL;
i2c_set_clientdata(client, NULL);
kfree(mt9t031);
}
@@ -837,8 +807,7 @@ static int mt9t031_remove(struct i2c_client *client)
struct mt9t031 *mt9t031 = to_mt9t031(client);
struct soc_camera_device *icd = client->dev.platform_data;
- if (icd)
- icd->ops = NULL;
+ icd->ops = NULL;
i2c_set_clientdata(client, NULL);
client->driver = NULL;
kfree(mt9t031);
diff --git a/trunk/drivers/media/video/mt9t112.c b/trunk/drivers/media/video/mt9t112.c
deleted file mode 100644
index fc4dd6045720..000000000000
--- a/trunk/drivers/media/video/mt9t112.c
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- * mt9t112 Camera Driver
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Kuninori Morimoto
- *
- * Based on ov772x driver, mt9m111 driver,
- *
- * Copyright (C) 2008 Kuninori Morimoto
- * Copyright (C) 2008, Robert Jarzmik
- * Copyright 2006-7 Jonathan Corbet
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-/* you can check PLL/clock info */
-/* #define EXT_CLOCK 24000000 */
-
-/************************************************************************
-
-
- macro
-
-
-************************************************************************/
-/*
- * frame size
- */
-#define MAX_WIDTH 2048
-#define MAX_HEIGHT 1536
-
-#define VGA_WIDTH 640
-#define VGA_HEIGHT 480
-
-/*
- * macro of read/write
- */
-#define ECHECKER(ret, x) \
- do { \
- (ret) = (x); \
- if ((ret) < 0) \
- return (ret); \
- } while (0)
-
-#define mt9t112_reg_write(ret, client, a, b) \
- ECHECKER(ret, __mt9t112_reg_write(client, a, b))
-#define mt9t112_mcu_write(ret, client, a, b) \
- ECHECKER(ret, __mt9t112_mcu_write(client, a, b))
-
-#define mt9t112_reg_mask_set(ret, client, a, b, c) \
- ECHECKER(ret, __mt9t112_reg_mask_set(client, a, b, c))
-#define mt9t112_mcu_mask_set(ret, client, a, b, c) \
- ECHECKER(ret, __mt9t112_mcu_mask_set(client, a, b, c))
-
-#define mt9t112_reg_read(ret, client, a) \
- ECHECKER(ret, __mt9t112_reg_read(client, a))
-
-/*
- * Logical address
- */
-#define _VAR(id, offset, base) (base | (id & 0x1f) << 10 | (offset & 0x3ff))
-#define VAR(id, offset) _VAR(id, offset, 0x0000)
-#define VAR8(id, offset) _VAR(id, offset, 0x8000)
-
-/************************************************************************
-
-
- struct
-
-
-************************************************************************/
-struct mt9t112_frame_size {
- u16 width;
- u16 height;
-};
-
-struct mt9t112_format {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
- u16 fmt;
- u16 order;
-};
-
-struct mt9t112_priv {
- struct v4l2_subdev subdev;
- struct mt9t112_camera_info *info;
- struct i2c_client *client;
- struct soc_camera_device icd;
- struct mt9t112_frame_size frame;
- const struct mt9t112_format *format;
- int model;
- u32 flags;
-/* for flags */
-#define INIT_DONE (1<<0)
-};
-
-/************************************************************************
-
-
- supported format
-
-
-************************************************************************/
-
-static const struct mt9t112_format mt9t112_cfmts[] = {
- {
- .code = V4L2_MBUS_FMT_YUYV8_2X8_BE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .fmt = 1,
- .order = 0,
- }, {
- .code = V4L2_MBUS_FMT_YVYU8_2X8_BE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .fmt = 1,
- .order = 1,
- }, {
- .code = V4L2_MBUS_FMT_YUYV8_2X8_LE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .fmt = 1,
- .order = 2,
- }, {
- .code = V4L2_MBUS_FMT_YVYU8_2X8_LE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .fmt = 1,
- .order = 3,
- }, {
- .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .fmt = 8,
- .order = 2,
- }, {
- .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .fmt = 4,
- .order = 2,
- },
-};
-
-/************************************************************************
-
-
- general function
-
-
-************************************************************************/
-static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client),
- struct mt9t112_priv,
- subdev);
-}
-
-static int __mt9t112_reg_read(const struct i2c_client *client, u16 command)
-{
- struct i2c_msg msg[2];
- u8 buf[2];
- int ret;
-
- command = swab16(command);
-
- msg[0].addr = client->addr;
- msg[0].flags = 0;
- msg[0].len = 2;
- msg[0].buf = (u8 *)&command;
-
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].len = 2;
- msg[1].buf = buf;
-
- /*
- * if return value of this function is < 0,
- * it mean error.
- * else, under 16bit is valid data.
- */
- ret = i2c_transfer(client->adapter, msg, 2);
- if (ret < 0)
- return ret;
-
- memcpy(&ret, buf, 2);
- return swab16(ret);
-}
-
-static int __mt9t112_reg_write(const struct i2c_client *client,
- u16 command, u16 data)
-{
- struct i2c_msg msg;
- u8 buf[4];
- int ret;
-
- command = swab16(command);
- data = swab16(data);
-
- memcpy(buf + 0, &command, 2);
- memcpy(buf + 2, &data, 2);
-
- msg.addr = client->addr;
- msg.flags = 0;
- msg.len = 4;
- msg.buf = buf;
-
- /*
- * i2c_transfer return message length,
- * but this function should return 0 if correct case
- */
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret >= 0)
- ret = 0;
-
- return ret;
-}
-
-static int __mt9t112_reg_mask_set(const struct i2c_client *client,
- u16 command,
- u16 mask,
- u16 set)
-{
- int val = __mt9t112_reg_read(client, command);
- if (val < 0)
- return val;
-
- val &= ~mask;
- val |= set & mask;
-
- return __mt9t112_reg_write(client, command, val);
-}
-
-/* mcu access */
-static int __mt9t112_mcu_read(const struct i2c_client *client, u16 command)
-{
- int ret;
-
- ret = __mt9t112_reg_write(client, 0x098E, command);
- if (ret < 0)
- return ret;
-
- return __mt9t112_reg_read(client, 0x0990);
-}
-
-static int __mt9t112_mcu_write(const struct i2c_client *client,
- u16 command, u16 data)
-{
- int ret;
-
- ret = __mt9t112_reg_write(client, 0x098E, command);
- if (ret < 0)
- return ret;
-
- return __mt9t112_reg_write(client, 0x0990, data);
-}
-
-static int __mt9t112_mcu_mask_set(const struct i2c_client *client,
- u16 command,
- u16 mask,
- u16 set)
-{
- int val = __mt9t112_mcu_read(client, command);
- if (val < 0)
- return val;
-
- val &= ~mask;
- val |= set & mask;
-
- return __mt9t112_mcu_write(client, command, val);
-}
-
-static int mt9t112_reset(const struct i2c_client *client)
-{
- int ret;
-
- mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001);
- msleep(1);
- mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000);
-
- return ret;
-}
-
-#ifndef EXT_CLOCK
-#define CLOCK_INFO(a, b)
-#else
-#define CLOCK_INFO(a, b) mt9t112_clock_info(a, b)
-static int mt9t112_clock_info(const struct i2c_client *client, u32 ext)
-{
- int m, n, p1, p2, p3, p4, p5, p6, p7;
- u32 vco, clk;
- char *enable;
-
- ext /= 1000; /* kbyte order */
-
- mt9t112_reg_read(n, client, 0x0012);
- p1 = n & 0x000f;
- n = n >> 4;
- p2 = n & 0x000f;
- n = n >> 4;
- p3 = n & 0x000f;
-
- mt9t112_reg_read(n, client, 0x002a);
- p4 = n & 0x000f;
- n = n >> 4;
- p5 = n & 0x000f;
- n = n >> 4;
- p6 = n & 0x000f;
-
- mt9t112_reg_read(n, client, 0x002c);
- p7 = n & 0x000f;
-
- mt9t112_reg_read(n, client, 0x0010);
- m = n & 0x00ff;
- n = (n >> 8) & 0x003f;
-
- enable = ((6000 > ext) || (54000 < ext)) ? "X" : "";
- dev_info(&client->dev, "EXTCLK : %10u K %s\n", ext, enable);
-
- vco = 2 * m * ext / (n+1);
- enable = ((384000 > vco) || (768000 < vco)) ? "X" : "";
- dev_info(&client->dev, "VCO : %10u K %s\n", vco, enable);
-
- clk = vco / (p1+1) / (p2+1);
- enable = (96000 < clk) ? "X" : "";
- dev_info(&client->dev, "PIXCLK : %10u K %s\n", clk, enable);
-
- clk = vco / (p3+1);
- enable = (768000 < clk) ? "X" : "";
- dev_info(&client->dev, "MIPICLK : %10u K %s\n", clk, enable);
-
- clk = vco / (p6+1);
- enable = (96000 < clk) ? "X" : "";
- dev_info(&client->dev, "MCU CLK : %10u K %s\n", clk, enable);
-
- clk = vco / (p5+1);
- enable = (54000 < clk) ? "X" : "";
- dev_info(&client->dev, "SOC CLK : %10u K %s\n", clk, enable);
-
- clk = vco / (p4+1);
- enable = (70000 < clk) ? "X" : "";
- dev_info(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable);
-
- clk = vco / (p7+1);
- dev_info(&client->dev, "External sensor : %10u K\n", clk);
-
- clk = ext / (n+1);
- enable = ((2000 > clk) || (24000 < clk)) ? "X" : "";
- dev_info(&client->dev, "PFD : %10u K %s\n", clk, enable);
-
- return 0;
-}
-#endif
-
-static void mt9t112_frame_check(u32 *width, u32 *height)
-{
- if (*width > MAX_WIDTH)
- *width = MAX_WIDTH;
-
- if (*height > MAX_HEIGHT)
- *height = MAX_HEIGHT;
-}
-
-static int mt9t112_set_a_frame_size(const struct i2c_client *client,
- u16 width,
- u16 height)
-{
- int ret;
- u16 wstart = (MAX_WIDTH - width) / 2;
- u16 hstart = (MAX_HEIGHT - height) / 2;
-
- /* (Context A) Image Width/Height */
- mt9t112_mcu_write(ret, client, VAR(26, 0), width);
- mt9t112_mcu_write(ret, client, VAR(26, 2), height);
-
- /* (Context A) Output Width/Height */
- mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width);
- mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height);
-
- /* (Context A) Start Row/Column */
- mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart);
- mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart);
-
- /* (Context A) End Row/Column */
- mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart);
- mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width + wstart);
-
- mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
-
- return ret;
-}
-
-static int mt9t112_set_pll_dividers(const struct i2c_client *client,
- u8 m, u8 n,
- u8 p1, u8 p2, u8 p3,
- u8 p4, u8 p5, u8 p6,
- u8 p7)
-{
- int ret;
- u16 val;
-
- /* N/M */
- val = (n << 8) |
- (m << 0);
- mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val);
-
- /* P1/P2/P3 */
- val = ((p3 & 0x0F) << 8) |
- ((p2 & 0x0F) << 4) |
- ((p1 & 0x0F) << 0);
- mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val);
-
- /* P4/P5/P6 */
- val = (0x7 << 12) |
- ((p6 & 0x0F) << 8) |
- ((p5 & 0x0F) << 4) |
- ((p4 & 0x0F) << 0);
- mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val);
-
- /* P7 */
- val = (0x1 << 12) |
- ((p7 & 0x0F) << 0);
- mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val);
-
- return ret;
-}
-
-static int mt9t112_init_pll(const struct i2c_client *client)
-{
- struct mt9t112_priv *priv = to_mt9t112(client);
- int data, i, ret;
-
- mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001);
-
- /* PLL control: BYPASS PLL = 8517 */
- mt9t112_reg_write(ret, client, 0x0014, 0x2145);
-
- /* Replace these registers when new timing parameters are generated */
- mt9t112_set_pll_dividers(client,
- priv->info->divider.m,
- priv->info->divider.n,
- priv->info->divider.p1,
- priv->info->divider.p2,
- priv->info->divider.p3,
- priv->info->divider.p4,
- priv->info->divider.p5,
- priv->info->divider.p6,
- priv->info->divider.p7);
-
- /*
- * TEST_BYPASS on
- * PLL_ENABLE on
- * SEL_LOCK_DET on
- * TEST_BYPASS off
- */
- mt9t112_reg_write(ret, client, 0x0014, 0x2525);
- mt9t112_reg_write(ret, client, 0x0014, 0x2527);
- mt9t112_reg_write(ret, client, 0x0014, 0x3427);
- mt9t112_reg_write(ret, client, 0x0014, 0x3027);
-
- mdelay(10);
-
- /*
- * PLL_BYPASS off
- * Reference clock count
- * I2C Master Clock Divider
- */
- mt9t112_reg_write(ret, client, 0x0014, 0x3046);
- mt9t112_reg_write(ret, client, 0x0022, 0x0190);
- mt9t112_reg_write(ret, client, 0x3B84, 0x0212);
-
- /* External sensor clock is PLL bypass */
- mt9t112_reg_write(ret, client, 0x002E, 0x0500);
-
- mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002);
- mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004);
-
- /* MCU disabled */
- mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004);
-
- /* out of standby */
- mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0);
-
- mdelay(50);
-
- /*
- * Standby Workaround
- * Disable Secondary I2C Pads
- */
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
- mt9t112_reg_write(ret, client, 0x0614, 0x0001);
- mdelay(1);
-
- /* poll to verify out of standby. Must Poll this bit */
- for (i = 0; i < 100; i++) {
- mt9t112_reg_read(data, client, 0x0018);
- if (0x4000 & data)
- break;
-
- mdelay(10);
- }
-
- return ret;
-}
-
-static int mt9t112_init_setting(const struct i2c_client *client)
-{
-
- int ret;
-
- /* Adaptive Output Clock (A) */
- mt9t112_mcu_mask_set(ret, client, VAR(26, 160), 0x0040, 0x0000);
-
- /* Read Mode (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 12), 0x0024);
-
- /* Fine Correction (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 15), 0x00CC);
-
- /* Fine IT Min (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 17), 0x01f1);
-
- /* Fine IT Max Margin (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 19), 0x00fF);
-
- /* Base Frame Lines (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 29), 0x032D);
-
- /* Min Line Length (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 31), 0x073a);
-
- /* Line Length (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 37), 0x07d0);
-
- /* Adaptive Output Clock (B) */
- mt9t112_mcu_mask_set(ret, client, VAR(27, 160), 0x0040, 0x0000);
-
- /* Row Start (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 74), 0x004);
-
- /* Column Start (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 76), 0x004);
-
- /* Row End (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 78), 0x60B);
-
- /* Column End (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 80), 0x80B);
-
- /* Fine Correction (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 87), 0x008C);
-
- /* Fine IT Min (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 89), 0x01F1);
-
- /* Fine IT Max Margin (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 91), 0x00FF);
-
- /* Base Frame Lines (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 101), 0x0668);
-
- /* Min Line Length (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 103), 0x0AF0);
-
- /* Line Length (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0);
-
- /*
- * Flicker Dectection registers
- * This section should be replaced whenever new Timing file is generated
- * All the following registers need to be replaced
- * Following registers are generated from Register Wizard but user can
- * modify them. For detail see auto flicker detection tuning
- */
-
- /* FD_FDPERIOD_SELECT */
- mt9t112_mcu_write(ret, client, VAR8(8, 5), 0x01);
-
- /* PRI_B_CONFIG_FD_ALGO_RUN */
- mt9t112_mcu_write(ret, client, VAR(27, 17), 0x0003);
-
- /* PRI_A_CONFIG_FD_ALGO_RUN */
- mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003);
-
- /*
- * AFD range detection tuning registers
- */
-
- /* search_f1_50 */
- mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25);
-
- /* search_f2_50 */
- mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28);
-
- /* search_f1_60 */
- mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C);
-
- /* search_f2_60 */
- mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F);
-
- /* period_50Hz (A) */
- mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA);
-
- /* secret register by aptina */
- /* period_50Hz (A MSB) */
- mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00);
-
- /* period_60Hz (A) */
- mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B);
-
- /* secret register by aptina */
- /* period_60Hz (A MSB) */
- mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00);
-
- /* period_50Hz (B) */
- mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82);
-
- /* secret register by aptina */
- /* period_50Hz (B) MSB */
- mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00);
-
- /* period_60Hz (B) */
- mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D);
-
- /* secret register by aptina */
- /* period_60Hz (B) MSB */
- mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00);
-
- /* FD Mode */
- mt9t112_mcu_write(ret, client, VAR8(8, 2), 0x10);
-
- /* Stat_min */
- mt9t112_mcu_write(ret, client, VAR8(8, 9), 0x02);
-
- /* Stat_max */
- mt9t112_mcu_write(ret, client, VAR8(8, 10), 0x03);
-
- /* Min_amplitude */
- mt9t112_mcu_write(ret, client, VAR8(8, 12), 0x0A);
-
- /* RX FIFO Watermark (A) */
- mt9t112_mcu_write(ret, client, VAR(18, 70), 0x0014);
-
- /* RX FIFO Watermark (B) */
- mt9t112_mcu_write(ret, client, VAR(18, 142), 0x0014);
-
- /* MCLK: 16MHz
- * PCLK: 73MHz
- * CorePixCLK: 36.5 MHz
- */
- mt9t112_mcu_write(ret, client, VAR8(18, 0x0044), 133);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x0045), 110);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x008c), 130);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x008d), 108);
-
- mt9t112_mcu_write(ret, client, VAR8(18, 0x00A5), 27);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x00a6), 30);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x00a7), 32);
- mt9t112_mcu_write(ret, client, VAR8(18, 0x00a8), 35);
-
- return ret;
-}
-
-static int mt9t112_auto_focus_setting(const struct i2c_client *client)
-{
- int ret;
-
- mt9t112_mcu_write(ret, client, VAR(12, 13), 0x000F);
- mt9t112_mcu_write(ret, client, VAR(12, 23), 0x0F0F);
- mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
-
- mt9t112_reg_write(ret, client, 0x0614, 0x0000);
-
- mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x05);
- mt9t112_mcu_write(ret, client, VAR8(12, 2), 0x02);
- mt9t112_mcu_write(ret, client, VAR(12, 3), 0x0002);
- mt9t112_mcu_write(ret, client, VAR(17, 3), 0x8001);
- mt9t112_mcu_write(ret, client, VAR(17, 11), 0x0025);
- mt9t112_mcu_write(ret, client, VAR(17, 13), 0x0193);
- mt9t112_mcu_write(ret, client, VAR8(17, 33), 0x18);
- mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x05);
-
- return ret;
-}
-
-static int mt9t112_auto_focus_trigger(const struct i2c_client *client)
-{
- int ret;
-
- mt9t112_mcu_write(ret, client, VAR8(12, 25), 0x01);
-
- return ret;
-}
-
-static int mt9t112_init_camera(const struct i2c_client *client)
-{
- int ret;
-
- ECHECKER(ret, mt9t112_reset(client));
-
- ECHECKER(ret, mt9t112_init_pll(client));
-
- ECHECKER(ret, mt9t112_init_setting(client));
-
- ECHECKER(ret, mt9t112_auto_focus_setting(client));
-
- mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0);
-
- /* Analog setting B */
- mt9t112_reg_write(ret, client, 0x3084, 0x2409);
- mt9t112_reg_write(ret, client, 0x3092, 0x0A49);
- mt9t112_reg_write(ret, client, 0x3094, 0x4949);
- mt9t112_reg_write(ret, client, 0x3096, 0x4950);
-
- /*
- * Disable adaptive clock
- * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR
- * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR
- */
- mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E);
- mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E);
-
- /* Configure STatus in Status_before_length Format and enable header */
- /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */
- mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4);
-
- /* Enable JPEG in context B */
- /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */
- mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01);
-
- /* Disable Dac_TXLO */
- mt9t112_reg_write(ret, client, 0x316C, 0x350F);
-
- /* Set max slew rates */
- mt9t112_reg_write(ret, client, 0x1E, 0x777);
-
- return ret;
-}
-
-/************************************************************************
-
-
- soc_camera_ops
-
-
-************************************************************************/
-static int mt9t112_set_bus_param(struct soc_camera_device *icd,
- unsigned long flags)
-{
- return 0;
-}
-
-static unsigned long mt9t112_query_bus_param(struct soc_camera_device *icd)
-{
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
- struct mt9t112_priv *priv = to_mt9t112(client);
- struct soc_camera_link *icl = to_soc_camera_link(icd);
- unsigned long flags = SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH |
- SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH;
-
- flags |= (priv->info->flags & MT9T112_FLAG_PCLK_RISING_EDGE) ?
- SOCAM_PCLK_SAMPLE_RISING : SOCAM_PCLK_SAMPLE_FALLING;
-
- if (priv->info->flags & MT9T112_FLAG_DATAWIDTH_8)
- flags |= SOCAM_DATAWIDTH_8;
- else
- flags |= SOCAM_DATAWIDTH_10;
-
- return soc_camera_apply_sensor_flags(icl, flags);
-}
-
-static struct soc_camera_ops mt9t112_ops = {
- .set_bus_param = mt9t112_set_bus_param,
- .query_bus_param = mt9t112_query_bus_param,
-};
-
-/************************************************************************
-
-
- v4l2_subdev_core_ops
-
-
-************************************************************************/
-static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = sd->priv;
- struct mt9t112_priv *priv = to_mt9t112(client);
-
- id->ident = priv->model;
- id->revision = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9t112_g_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = sd->priv;
- int ret;
-
- reg->size = 2;
- mt9t112_reg_read(ret, client, reg->reg);
-
- reg->val = (__u64)ret;
-
- return 0;
-}
-
-static int mt9t112_s_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = sd->priv;
- int ret;
-
- mt9t112_reg_write(ret, client, reg->reg, reg->val);
-
- return ret;
-}
-#endif
-
-static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
- .g_chip_ident = mt9t112_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = mt9t112_g_register,
- .s_register = mt9t112_s_register,
-#endif
-};
-
-
-/************************************************************************
-
-
- v4l2_subdev_video_ops
-
-
-************************************************************************/
-static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct i2c_client *client = sd->priv;
- struct mt9t112_priv *priv = to_mt9t112(client);
- int ret = 0;
-
- if (!enable) {
- /* FIXME
- *
- * If user selected large output size,
- * and used it long time,
- * mt9t112 camera will be very warm.
- *
- * But current driver can not stop mt9t112 camera.
- * So, set small size here to solve this problem.
- */
- mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT);
- return ret;
- }
-
- if (!(priv->flags & INIT_DONE)) {
- u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE &
- priv->info->flags) ? 0x0001 : 0x0000;
-
- ECHECKER(ret, mt9t112_init_camera(client));
-
- /* Invert PCLK (Data sampled on falling edge of pixclk) */
- mt9t112_reg_write(ret, client, 0x3C20, param);
-
- mdelay(5);
-
- priv->flags |= INIT_DONE;
- }
-
- mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt);
- mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order);
- mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
-
- mt9t112_set_a_frame_size(client,
- priv->frame.width,
- priv->frame.height);
-
- ECHECKER(ret, mt9t112_auto_focus_trigger(client));
-
- dev_dbg(&client->dev, "format : %d\n", priv->format->code);
- dev_dbg(&client->dev, "size : %d x %d\n",
- priv->frame.width,
- priv->frame.height);
-
- CLOCK_INFO(client, EXT_CLOCK);
-
- return ret;
-}
-
-static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
- enum v4l2_mbus_pixelcode code)
-{
- struct mt9t112_priv *priv = to_mt9t112(client);
- int i;
-
- priv->format = NULL;
-
- /*
- * frame size check
- */
- mt9t112_frame_check(&width, &height);
-
- /*
- * get color format
- */
- for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++)
- if (mt9t112_cfmts[i].code == code)
- break;
-
- if (i == ARRAY_SIZE(mt9t112_cfmts))
- return -EINVAL;
-
- priv->frame.width = (u16)width;
- priv->frame.height = (u16)height;
-
- priv->format = mt9t112_cfmts + i;
-
- return 0;
-}
-
-static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = VGA_WIDTH;
- a->bounds.height = VGA_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- a->c.left = 0;
- a->c.top = 0;
- a->c.width = VGA_WIDTH;
- a->c.height = VGA_HEIGHT;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = sd->priv;
- struct v4l2_rect *rect = &a->c;
-
- return mt9t112_set_params(client, rect->width, rect->height,
- V4L2_MBUS_FMT_YUYV8_2X8_BE);
-}
-
-static int mt9t112_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = sd->priv;
- struct mt9t112_priv *priv = to_mt9t112(client);
-
- if (!priv->format) {
- int ret = mt9t112_set_params(client, VGA_WIDTH, VGA_HEIGHT,
- V4L2_MBUS_FMT_YUYV8_2X8_BE);
- if (ret < 0)
- return ret;
- }
-
- mf->width = priv->frame.width;
- mf->height = priv->frame.height;
- /* TODO: set colorspace */
- mf->code = priv->format->code;
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int mt9t112_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = sd->priv;
-
- /* TODO: set colorspace */
- return mt9t112_set_params(client, mf->width, mf->height, mf->code);
-}
-
-static int mt9t112_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- mt9t112_frame_check(&mf->width, &mf->height);
-
- /* TODO: set colorspace */
- mf->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int mt9t112_enum_fmt(struct v4l2_subdev *sd, int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if ((unsigned int)index >= ARRAY_SIZE(mt9t112_cfmts))
- return -EINVAL;
-
- *code = mt9t112_cfmts[index].code;
- return 0;
-}
-
-static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
- .s_stream = mt9t112_s_stream,
- .g_mbus_fmt = mt9t112_g_fmt,
- .s_mbus_fmt = mt9t112_s_fmt,
- .try_mbus_fmt = mt9t112_try_fmt,
- .cropcap = mt9t112_cropcap,
- .g_crop = mt9t112_g_crop,
- .s_crop = mt9t112_s_crop,
- .enum_mbus_fmt = mt9t112_enum_fmt,
-};
-
-/************************************************************************
-
-
- i2c driver
-
-
-************************************************************************/
-static struct v4l2_subdev_ops mt9t112_subdev_ops = {
- .core = &mt9t112_subdev_core_ops,
- .video = &mt9t112_subdev_video_ops,
-};
-
-static int mt9t112_camera_probe(struct soc_camera_device *icd,
- struct i2c_client *client)
-{
- struct mt9t112_priv *priv = to_mt9t112(client);
- const char *devname;
- int chipid;
-
- /*
- * We must have a parent by now. And it cannot be a wrong one.
- * So this entire test is completely redundant.
- */
- if (!icd->dev.parent ||
- to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
- return -ENODEV;
-
- /*
- * check and show chip ID
- */
- mt9t112_reg_read(chipid, client, 0x0000);
-
- switch (chipid) {
- case 0x2680:
- devname = "mt9t111";
- priv->model = V4L2_IDENT_MT9T111;
- break;
- case 0x2682:
- devname = "mt9t112";
- priv->model = V4L2_IDENT_MT9T112;
- break;
- default:
- dev_err(&client->dev, "Product ID error %04x\n", chipid);
- return -ENODEV;
- }
-
- dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid);
-
- return 0;
-}
-
-static int mt9t112_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
-{
- struct mt9t112_priv *priv;
- struct soc_camera_device *icd = client->dev.platform_data;
- struct soc_camera_link *icl;
- int ret;
-
- if (!icd) {
- dev_err(&client->dev, "mt9t112: missing soc-camera data!\n");
- return -EINVAL;
- }
-
- icl = to_soc_camera_link(icd);
- if (!icl || !icl->priv)
- return -EINVAL;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->info = icl->priv;
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
-
- icd->ops = &mt9t112_ops;
-
- ret = mt9t112_camera_probe(icd, client);
- if (ret) {
- icd->ops = NULL;
- i2c_set_clientdata(client, NULL);
- kfree(priv);
- }
-
- return ret;
-}
-
-static int mt9t112_remove(struct i2c_client *client)
-{
- struct mt9t112_priv *priv = to_mt9t112(client);
- struct soc_camera_device *icd = client->dev.platform_data;
-
- icd->ops = NULL;
- i2c_set_clientdata(client, NULL);
- kfree(priv);
- return 0;
-}
-
-static const struct i2c_device_id mt9t112_id[] = {
- { "mt9t112", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9t112_id);
-
-static struct i2c_driver mt9t112_i2c_driver = {
- .driver = {
- .name = "mt9t112",
- },
- .probe = mt9t112_probe,
- .remove = mt9t112_remove,
- .id_table = mt9t112_id,
-};
-
-/************************************************************************
-
-
- module function
-
-
-************************************************************************/
-static int __init mt9t112_module_init(void)
-{
- return i2c_add_driver(&mt9t112_i2c_driver);
-}
-
-static void __exit mt9t112_module_exit(void)
-{
- i2c_del_driver(&mt9t112_i2c_driver);
-}
-
-module_init(mt9t112_module_init);
-module_exit(mt9t112_module_exit);
-
-MODULE_DESCRIPTION("SoC Camera driver for mt9t112");
-MODULE_AUTHOR("Kuninori Morimoto");
-MODULE_LICENSE("GPL v2");
diff --git a/trunk/drivers/media/video/mt9v022.c b/trunk/drivers/media/video/mt9v022.c
index 91df7ec91fb6..995607f9d3ba 100644
--- a/trunk/drivers/media/video/mt9v022.c
+++ b/trunk/drivers/media/video/mt9v022.c
@@ -18,11 +18,9 @@
#include
#include
-/*
- * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
+/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
* The platform has to define ctruct i2c_board_info objects and link to them
- * from struct soc_camera_link
- */
+ * from struct soc_camera_link */
static char *sensor_type;
module_param(sensor_type, charp, S_IRUGO);
@@ -64,49 +62,41 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
#define MT9V022_COLUMN_SKIP 1
#define MT9V022_ROW_SKIP 4
-/* MT9V022 has only one fixed colorspace per pixelcode */
-struct mt9v022_datafmt {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-/* Find a data format by a pixel code in an array */
-static const struct mt9v022_datafmt *mt9v022_find_datafmt(
- enum v4l2_mbus_pixelcode code, const struct mt9v022_datafmt *fmt,
- int n)
-{
- int i;
- for (i = 0; i < n; i++)
- if (fmt[i].code == code)
- return fmt + i;
-
- return NULL;
-}
-
-static const struct mt9v022_datafmt mt9v022_colour_fmts[] = {
- /*
- * Order important: first natively supported,
- * second supported with a GPIO extender
- */
- {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
+static const struct soc_camera_data_format mt9v022_colour_formats[] = {
+ /* Order important: first natively supported,
+ * second supported with a GPIO extender */
+ {
+ .name = "Bayer (sRGB) 10 bit",
+ .depth = 10,
+ .fourcc = V4L2_PIX_FMT_SBGGR16,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }, {
+ .name = "Bayer (sRGB) 8 bit",
+ .depth = 8,
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }
};
-static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
+static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
/* Order important - see above */
- {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG},
+ {
+ .name = "Monochrome 10 bit",
+ .depth = 10,
+ .fourcc = V4L2_PIX_FMT_Y16,
+ }, {
+ .name = "Monochrome 8 bit",
+ .depth = 8,
+ .fourcc = V4L2_PIX_FMT_GREY,
+ },
};
struct mt9v022 {
struct v4l2_subdev subdev;
struct v4l2_rect rect; /* Sensor window */
- const struct mt9v022_datafmt *fmt;
- const struct mt9v022_datafmt *fmts;
- int num_fmts;
+ __u32 fourcc;
int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
u16 chip_control;
- unsigned short y_skip_top; /* Lines to skip at the top */
};
static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
@@ -153,11 +143,9 @@ static int mt9v022_init(struct i2c_client *client)
struct mt9v022 *mt9v022 = to_mt9v022(client);
int ret;
- /*
- * Almost the default mode: master, parallel, simultaneous, and an
+ /* Almost the default mode: master, parallel, simultaneous, and an
* undocumented bit 0x200, which is present in table 7, but not in 8,
- * plus snapshot mode to disable scan for now
- */
+ * plus snapshot mode to disable scan for now */
mt9v022->chip_control |= 0x10;
ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
if (!ret)
@@ -277,10 +265,12 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
struct i2c_client *client = sd->priv;
struct mt9v022 *mt9v022 = to_mt9v022(client);
struct v4l2_rect rect = a->c;
+ struct soc_camera_device *icd = client->dev.platform_data;
int ret;
/* Bayer format - even size lengths */
- if (mt9v022->fmts == mt9v022_colour_fmts) {
+ if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 ||
+ mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) {
rect.width = ALIGN(rect.width, 2);
rect.height = ALIGN(rect.height, 2);
/* Let the user play with the starting pixel */
@@ -297,10 +287,10 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
if (ret >= 0) {
if (ret & 1) /* Autoexposure */
ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
- rect.height + mt9v022->y_skip_top + 43);
+ rect.height + icd->y_skip_top + 43);
else
ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
- rect.height + mt9v022->y_skip_top + 43);
+ rect.height + icd->y_skip_top + 43);
}
/* Setup frame format: defaults apart from width and height */
if (!ret)
@@ -308,10 +298,8 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
if (!ret)
ret = reg_write(client, MT9V022_ROW_START, rect.top);
if (!ret)
- /*
- * Default 94, Phytec driver says:
- * "width + horizontal blank >= 660"
- */
+ /* Default 94, Phytec driver says:
+ * "width + horizontal blank >= 660" */
ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
rect.width > 660 - 43 ? 43 :
660 - rect.width);
@@ -321,7 +309,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
if (!ret)
ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
- rect.height + mt9v022->y_skip_top);
+ rect.height + icd->y_skip_top);
if (ret < 0)
return ret;
@@ -358,48 +346,46 @@ static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int mt9v022_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct mt9v022 *mt9v022 = to_mt9v022(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- mf->width = mt9v022->rect.width;
- mf->height = mt9v022->rect.height;
- mf->code = mt9v022->fmt->code;
- mf->colorspace = mt9v022->fmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
+ pix->width = mt9v022->rect.width;
+ pix->height = mt9v022->rect.height;
+ pix->pixelformat = mt9v022->fourcc;
+ pix->field = V4L2_FIELD_NONE;
+ pix->colorspace = V4L2_COLORSPACE_SRGB;
return 0;
}
-static int mt9v022_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct mt9v022 *mt9v022 = to_mt9v022(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_crop a = {
.c = {
.left = mt9v022->rect.left,
.top = mt9v022->rect.top,
- .width = mf->width,
- .height = mf->height,
+ .width = pix->width,
+ .height = pix->height,
},
};
int ret;
- /*
- * The caller provides a supported format, as verified per call to
- * icd->try_fmt(), datawidth is from our supported format list
- */
- switch (mf->code) {
- case V4L2_MBUS_FMT_GREY8_1X8:
- case V4L2_MBUS_FMT_Y10_1X10:
+ /* The caller provides a supported format, as verified per call to
+ * icd->try_fmt(), datawidth is from our supported format list */
+ switch (pix->pixelformat) {
+ case V4L2_PIX_FMT_GREY:
+ case V4L2_PIX_FMT_Y16:
if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
return -EINVAL;
break;
- case V4L2_MBUS_FMT_SBGGR8_1X8:
- case V4L2_MBUS_FMT_SBGGR10_1X10:
+ case V4L2_PIX_FMT_SBGGR8:
+ case V4L2_PIX_FMT_SBGGR16:
if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
return -EINVAL;
break;
@@ -413,38 +399,26 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
/* No support for scaling on this camera, just crop. */
ret = mt9v022_s_crop(sd, &a);
if (!ret) {
- mf->width = mt9v022->rect.width;
- mf->height = mt9v022->rect.height;
- mt9v022->fmt = mt9v022_find_datafmt(mf->code,
- mt9v022->fmts, mt9v022->num_fmts);
- mf->colorspace = mt9v022->fmt->colorspace;
+ pix->width = mt9v022->rect.width;
+ pix->height = mt9v022->rect.height;
+ mt9v022->fourcc = pix->pixelformat;
}
return ret;
}
-static int mt9v022_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
- struct mt9v022 *mt9v022 = to_mt9v022(client);
- const struct mt9v022_datafmt *fmt;
- int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
- mf->code == V4L2_MBUS_FMT_SBGGR10_1X10;
+ struct soc_camera_device *icd = client->dev.platform_data;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
+ pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
- v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH,
+ v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH,
MT9V022_MAX_WIDTH, align,
- &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top,
- MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0);
-
- fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts,
- mt9v022->num_fmts);
- if (!fmt) {
- fmt = mt9v022->fmt;
- mf->code = fmt->code;
- }
-
- mf->colorspace = fmt->colorspace;
+ &pix->height, MT9V022_MIN_HEIGHT + icd->y_skip_top,
+ MT9V022_MAX_HEIGHT + icd->y_skip_top, align, 0);
return 0;
}
@@ -661,10 +635,8 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
48 + range / 2) / range + 16;
if (gain >= 32)
gain &= ~1;
- /*
- * The user wants to set gain manually, hope, she
- * knows, what she's doing... Switch AGC off.
- */
+ /* The user wants to set gain manually, hope, she
+ * knows, what she's doing... Switch AGC off. */
if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
return -EIO;
@@ -683,10 +655,8 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
unsigned long range = qctrl->maximum - qctrl->minimum;
unsigned long shutter = ((ctrl->value - qctrl->minimum) *
479 + range / 2) / range + 1;
- /*
- * The user wants to set shutter width manually, hope,
- * she knows, what she's doing... Switch AEC off.
- */
+ /* The user wants to set shutter width manually, hope,
+ * she knows, what she's doing... Switch AEC off. */
if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
return -EIO;
@@ -719,10 +689,8 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
return 0;
}
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
static int mt9v022_video_probe(struct soc_camera_device *icd,
struct i2c_client *client)
{
@@ -765,17 +733,17 @@ static int mt9v022_video_probe(struct soc_camera_device *icd,
!strcmp("color", sensor_type))) {
ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
- mt9v022->fmts = mt9v022_colour_fmts;
+ icd->formats = mt9v022_colour_formats;
} else {
ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
- mt9v022->fmts = mt9v022_monochrome_fmts;
+ icd->formats = mt9v022_monochrome_formats;
}
if (ret < 0)
goto ei2c;
- mt9v022->num_fmts = 0;
+ icd->num_formats = 0;
/*
* This is a 10bit sensor, so by default we only allow 10bit.
@@ -788,14 +756,14 @@ static int mt9v022_video_probe(struct soc_camera_device *icd,
flags = SOCAM_DATAWIDTH_10;
if (flags & SOCAM_DATAWIDTH_10)
- mt9v022->num_fmts++;
+ icd->num_formats++;
else
- mt9v022->fmts++;
+ icd->formats++;
if (flags & SOCAM_DATAWIDTH_8)
- mt9v022->num_fmts++;
+ icd->num_formats++;
- mt9v022->fmt = &mt9v022->fmts[0];
+ mt9v022->fourcc = icd->formats->fourcc;
dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
@@ -819,16 +787,6 @@ static void mt9v022_video_remove(struct soc_camera_device *icd)
icl->free_bus(icl);
}
-static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
-{
- struct i2c_client *client = sd->priv;
- struct mt9v022 *mt9v022 = to_mt9v022(client);
-
- *lines = mt9v022->y_skip_top;
-
- return 0;
-}
-
static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
.g_ctrl = mt9v022_g_ctrl,
.s_ctrl = mt9v022_s_ctrl,
@@ -839,38 +797,19 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
#endif
};
-static int mt9v022_enum_fmt(struct v4l2_subdev *sd, int index,
- enum v4l2_mbus_pixelcode *code)
-{
- struct i2c_client *client = sd->priv;
- struct mt9v022 *mt9v022 = to_mt9v022(client);
-
- if ((unsigned int)index >= mt9v022->num_fmts)
- return -EINVAL;
-
- *code = mt9v022->fmts[index].code;
- return 0;
-}
-
static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
.s_stream = mt9v022_s_stream,
- .s_mbus_fmt = mt9v022_s_fmt,
- .g_mbus_fmt = mt9v022_g_fmt,
- .try_mbus_fmt = mt9v022_try_fmt,
+ .s_fmt = mt9v022_s_fmt,
+ .g_fmt = mt9v022_g_fmt,
+ .try_fmt = mt9v022_try_fmt,
.s_crop = mt9v022_s_crop,
.g_crop = mt9v022_g_crop,
.cropcap = mt9v022_cropcap,
- .enum_mbus_fmt = mt9v022_enum_fmt,
-};
-
-static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
- .g_skip_top_lines = mt9v022_g_skip_top_lines,
};
static struct v4l2_subdev_ops mt9v022_subdev_ops = {
.core = &mt9v022_subdev_core_ops,
.video = &mt9v022_subdev_video_ops,
- .sensor = &mt9v022_subdev_sensor_ops,
};
static int mt9v022_probe(struct i2c_client *client,
@@ -912,7 +851,8 @@ static int mt9v022_probe(struct i2c_client *client,
* MT9V022 _really_ corrupts the first read out line.
* TODO: verify on i.MX31
*/
- mt9v022->y_skip_top = 1;
+ icd->y_skip_top = 1;
+
mt9v022->rect.left = MT9V022_COLUMN_SKIP;
mt9v022->rect.top = MT9V022_ROW_SKIP;
mt9v022->rect.width = MT9V022_MAX_WIDTH;
diff --git a/trunk/drivers/media/video/mx1_camera.c b/trunk/drivers/media/video/mx1_camera.c
index 2ba14fb5b031..72802291e812 100644
--- a/trunk/drivers/media/video/mx1_camera.c
+++ b/trunk/drivers/media/video/mx1_camera.c
@@ -37,7 +37,6 @@
#include
#include
#include
-#include
#include
#include
@@ -95,16 +94,14 @@
/* buffer for one video frame */
struct mx1_buffer {
/* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
- enum v4l2_mbus_pixelcode code;
- int inwork;
+ struct videobuf_buffer vb;
+ const struct soc_camera_data_format *fmt;
+ int inwork;
};
-/*
- * i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
+/* i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
* Interface. If anyone ever builds hardware to enable more than
- * one camera, they will have to modify this driver too
- */
+ * one camera, they will have to modify this driver too */
struct mx1_camera_dev {
struct soc_camera_host soc_host;
struct soc_camera_device *icd;
@@ -129,13 +126,9 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
unsigned int *size)
{
struct soc_camera_device *icd = vq->priv_data;
- int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
- icd->current_fmt->host_fmt);
-
- if (bytes_per_line < 0)
- return bytes_per_line;
- *size = bytes_per_line * icd->user_height;
+ *size = icd->user_width * icd->user_height *
+ ((icd->current_fmt->depth + 7) >> 3);
if (!*count)
*count = 32;
@@ -158,10 +151,8 @@ static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
vb, vb->baddr, vb->bsize);
- /*
- * This waits until this buffer is out of danger, i.e., until it is no
- * longer in STATE_QUEUED or STATE_ACTIVE
- */
+ /* This waits until this buffer is out of danger, i.e., until it is no
+ * longer in STATE_QUEUED or STATE_ACTIVE */
videobuf_waiton(vb, 0, 0);
videobuf_dma_contig_free(vq, vb);
@@ -174,11 +165,6 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
struct soc_camera_device *icd = vq->priv_data;
struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
int ret;
- int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
- icd->current_fmt->host_fmt);
-
- if (bytes_per_line < 0)
- return bytes_per_line;
dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
vb, vb->baddr, vb->bsize);
@@ -188,24 +174,22 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
BUG_ON(NULL == icd->current_fmt);
- /*
- * I think, in buf_prepare you only have to protect global data,
- * the actual buffer is yours
- */
+ /* I think, in buf_prepare you only have to protect global data,
+ * the actual buffer is yours */
buf->inwork = 1;
- if (buf->code != icd->current_fmt->code ||
+ if (buf->fmt != icd->current_fmt ||
vb->width != icd->user_width ||
vb->height != icd->user_height ||
vb->field != field) {
- buf->code = icd->current_fmt->code;
+ buf->fmt = icd->current_fmt;
vb->width = icd->user_width;
vb->height = icd->user_height;
vb->field = field;
vb->state = VIDEOBUF_NEEDS_INIT;
}
- vb->size = bytes_per_line * vb->height;
+ vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
if (0 != vb->baddr && vb->bsize < vb->size) {
ret = -EINVAL;
goto out;
@@ -397,10 +381,8 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
lcdclk = clk_get_rate(pcdev->clk);
- /*
- * We verify platform_mclk_10khz != 0, so if anyone breaks it, here
- * they get a nice Oops
- */
+ /* We verify platform_mclk_10khz != 0, so if anyone breaks it, here
+ * they get a nice Oops */
div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
dev_dbg(pcdev->icd->dev.parent,
@@ -438,10 +420,8 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
clk_disable(pcdev->clk);
}
-/*
- * The following two functions absolutely depend on the fact, that
- * there can be only one camera on i.MX1/i.MXL camera sensor interface
- */
+/* The following two functions absolutely depend on the fact, that
+ * there can be only one camera on i.MX1/i.MXL camera sensor interface */
static int mx1_camera_add_device(struct soc_camera_device *icd)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -507,10 +487,12 @@ static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
/* MX1 supports only 8bit buswidth */
common_flags = soc_camera_bus_param_compatible(camera_flags,
- CSI_BUS_FLAGS);
+ CSI_BUS_FLAGS);
if (!common_flags)
return -EINVAL;
+ icd->buswidth = 8;
+
/* Make choises, based on platform choice */
if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
(common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
@@ -563,8 +545,7 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
const struct soc_camera_format_xlate *xlate;
struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret, buswidth;
+ int ret;
xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
if (!xlate) {
@@ -573,33 +554,12 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
return -EINVAL;
}
- buswidth = xlate->host_fmt->bits_per_sample;
- if (buswidth > 8) {
- dev_warn(icd->dev.parent,
- "bits-per-sample %d for format %x unsupported\n",
- buswidth, pix->pixelformat);
- return -EINVAL;
+ ret = v4l2_subdev_call(sd, video, s_fmt, f);
+ if (!ret) {
+ icd->buswidth = xlate->buswidth;
+ icd->current_fmt = xlate->host_fmt;
}
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- if (mf.code != xlate->code)
- return -EINVAL;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
- icd->current_fmt = xlate;
-
return ret;
}
@@ -607,36 +567,10 @@ static int mx1_camera_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret;
/* TODO: limit to mx1 hardware capabilities */
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(icd->dev.parent, "Format %x not found\n",
- pix->pixelformat);
- return -EINVAL;
- }
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
/* limit to sensor capabilities */
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
-
- return 0;
+ return v4l2_subdev_call(sd, video, try_fmt, f);
}
static int mx1_camera_reqbufs(struct soc_camera_file *icf,
@@ -644,12 +578,10 @@ static int mx1_camera_reqbufs(struct soc_camera_file *icf,
{
int i;
- /*
- * This is for locking debugging only. I removed spinlocks and now I
+ /* This is for locking debugging only. I removed spinlocks and now I
* check whether .prepare is ever called on a linked buffer, or whether
* a dma IRQ can occur for an in-work or unlinked buffer. Until now
- * it hadn't triggered
- */
+ * it hadn't triggered */
for (i = 0; i < p->count; i++) {
struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i],
struct mx1_buffer, vb);
diff --git a/trunk/drivers/media/video/mx3_camera.c b/trunk/drivers/media/video/mx3_camera.c
index bd297f567dc7..7db82bdf6f31 100644
--- a/trunk/drivers/media/video/mx3_camera.c
+++ b/trunk/drivers/media/video/mx3_camera.c
@@ -23,7 +23,6 @@
#include
#include
#include
-#include
#include
#include
@@ -64,7 +63,7 @@
struct mx3_camera_buffer {
/* common v4l buffer stuff -- must be first */
struct videobuf_buffer vb;
- enum v4l2_mbus_pixelcode code;
+ const struct soc_camera_data_format *fmt;
/* One descriptot per scatterlist (per frame) */
struct dma_async_tx_descriptor *txd;
@@ -119,6 +118,8 @@ struct dma_chan_request {
enum ipu_channel id;
};
+static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt);
+
static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg)
{
return __raw_readl(mx3->base + reg);
@@ -210,16 +211,17 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
struct soc_camera_device *icd = vq->priv_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
- int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
- icd->current_fmt->host_fmt);
-
- if (bytes_per_line < 0)
- return bytes_per_line;
+ /*
+ * bits-per-pixel (depth) as specified in camera's pixel format does
+ * not necessarily match what the camera interface writes to RAM, but
+ * it should be good enough for now.
+ */
+ unsigned int bpp = DIV_ROUND_UP(icd->current_fmt->depth, 8);
if (!mx3_cam->idmac_channel[0])
return -EINVAL;
- *size = bytes_per_line * icd->user_height;
+ *size = icd->user_width * icd->user_height * bpp;
if (!*count)
*count = 32;
@@ -239,26 +241,21 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq,
struct mx3_camera_dev *mx3_cam = ici->priv;
struct mx3_camera_buffer *buf =
container_of(vb, struct mx3_camera_buffer, vb);
- size_t new_size;
+ /* current_fmt _must_ always be set */
+ size_t new_size = icd->user_width * icd->user_height *
+ ((icd->current_fmt->depth + 7) >> 3);
int ret;
- int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
- icd->current_fmt->host_fmt);
-
- if (bytes_per_line < 0)
- return bytes_per_line;
-
- new_size = bytes_per_line * icd->user_height;
/*
* I think, in buf_prepare you only have to protect global data,
* the actual buffer is yours
*/
- if (buf->code != icd->current_fmt->code ||
+ if (buf->fmt != icd->current_fmt ||
vb->width != icd->user_width ||
vb->height != icd->user_height ||
vb->field != field) {
- buf->code = icd->current_fmt->code;
+ buf->fmt = icd->current_fmt;
vb->width = icd->user_width;
vb->height = icd->user_height;
vb->field = field;
@@ -351,13 +348,13 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
struct dma_async_tx_descriptor *txd = buf->txd;
struct idmac_channel *ichan = to_idmac_chan(txd->chan);
struct idmac_video_param *video = &ichan->params.video;
+ const struct soc_camera_data_format *data_fmt = icd->current_fmt;
dma_cookie_t cookie;
- u32 fourcc = icd->current_fmt->host_fmt->fourcc;
BUG_ON(!irqs_disabled());
/* This is the configuration of one sg-element */
- video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc);
+ video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc);
video->out_width = icd->user_width;
video->out_height = icd->user_height;
video->out_stride = icd->user_width;
@@ -567,37 +564,30 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
SOCAM_DATA_ACTIVE_HIGH |
SOCAM_DATA_ACTIVE_LOW;
- /*
- * If requested data width is supported by the platform, use it or any
- * possible lower value - i.MX31 is smart enough to schift bits
- */
- if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
- *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
- SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
- else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
- *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
- SOCAM_DATAWIDTH_4;
- else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
- *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
- else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
- *flags |= SOCAM_DATAWIDTH_4;
-
+ /* If requested data width is supported by the platform, use it or any
+ * possible lower value - i.MX31 is smart enough to schift bits */
switch (buswidth) {
case 15:
- if (!(*flags & SOCAM_DATAWIDTH_15))
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15))
return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
+ SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
break;
case 10:
- if (!(*flags & SOCAM_DATAWIDTH_10))
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10))
return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
+ SOCAM_DATAWIDTH_4;
break;
case 8:
- if (!(*flags & SOCAM_DATAWIDTH_8))
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8))
return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
break;
case 4:
- if (!(*flags & SOCAM_DATAWIDTH_4))
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4))
return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_4;
break;
default:
dev_warn(mx3_cam->soc_host.v4l2_dev.dev,
@@ -646,92 +636,91 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
pdata->dma_dev == chan->device->dev;
}
-static const struct soc_mbus_pixelfmt mx3_camera_formats[] = {
+static const struct soc_camera_data_format mx3_camera_formats[] = {
{
- .fourcc = V4L2_PIX_FMT_SBGGR8,
- .name = "Bayer BGGR (sRGB) 8 bit",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
+ .name = "Bayer (sRGB) 8 bit",
+ .depth = 8,
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
}, {
- .fourcc = V4L2_PIX_FMT_GREY,
- .name = "Monochrome 8 bit",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
+ .name = "Monochrome 8 bit",
+ .depth = 8,
+ .fourcc = V4L2_PIX_FMT_GREY,
+ .colorspace = V4L2_COLORSPACE_JPEG,
},
};
-/* This will be corrected as we get more formats */
-static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
+static bool buswidth_supported(struct soc_camera_host *ici, int depth)
{
- return fmt->packing == SOC_MBUS_PACKING_NONE ||
- (fmt->bits_per_sample == 8 &&
- fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
- (fmt->bits_per_sample > 8 &&
- fmt->packing == SOC_MBUS_PACKING_EXTEND16);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+
+ switch (depth) {
+ case 4:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4);
+ case 8:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8);
+ case 10:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10);
+ case 15:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15);
+ }
+ return false;
}
static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
struct soc_camera_format_xlate *xlate)
{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct device *dev = icd->dev.parent;
- int formats = 0, ret;
- enum v4l2_mbus_pixelcode code;
- const struct soc_mbus_pixelfmt *fmt;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ int formats = 0, buswidth, ret;
- ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
- if (ret < 0)
- /* No more formats */
- return 0;
+ buswidth = icd->formats[idx].depth;
- fmt = soc_mbus_get_fmtdesc(code);
- if (!fmt) {
- dev_err(icd->dev.parent,
- "Invalid format code #%d: %d\n", idx, code);
+ if (!buswidth_supported(ici, buswidth))
return 0;
- }
- /* This also checks support for the requested bits-per-sample */
- ret = mx3_camera_try_bus_param(icd, fmt->bits_per_sample);
+ ret = mx3_camera_try_bus_param(icd, buswidth);
if (ret < 0)
return 0;
- switch (code) {
- case V4L2_MBUS_FMT_SBGGR10_1X10:
+ switch (icd->formats[idx].fourcc) {
+ case V4L2_PIX_FMT_SGRBG10:
formats++;
if (xlate) {
- xlate->host_fmt = &mx3_camera_formats[0];
- xlate->code = code;
+ xlate->host_fmt = &mx3_camera_formats[0];
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
xlate++;
- dev_dbg(dev, "Providing format %s using code %d\n",
- mx3_camera_formats[0].name, code);
+ dev_dbg(icd->dev.parent,
+ "Providing format %s using %s\n",
+ mx3_camera_formats[0].name,
+ icd->formats[idx].name);
}
- break;
- case V4L2_MBUS_FMT_Y10_1X10:
+ goto passthrough;
+ case V4L2_PIX_FMT_Y16:
formats++;
if (xlate) {
- xlate->host_fmt = &mx3_camera_formats[1];
- xlate->code = code;
+ xlate->host_fmt = &mx3_camera_formats[1];
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
xlate++;
- dev_dbg(dev, "Providing format %s using code %d\n",
- mx3_camera_formats[1].name, code);
+ dev_dbg(icd->dev.parent,
+ "Providing format %s using %s\n",
+ mx3_camera_formats[0].name,
+ icd->formats[idx].name);
}
- break;
default:
- if (!mx3_camera_packing_supported(fmt))
- return 0;
- }
-
- /* Generic pass-through */
- formats++;
- if (xlate) {
- xlate->host_fmt = fmt;
- xlate->code = code;
- xlate++;
- dev_dbg(dev, "Providing format %x in pass-through mode\n",
- xlate->host_fmt->fourcc);
+passthrough:
+ /* Generic pass-through */
+ formats++;
+ if (xlate) {
+ xlate->host_fmt = icd->formats + idx;
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
+ xlate++;
+ dev_dbg(icd->dev.parent,
+ "Providing format %s in pass-through mode\n",
+ icd->formats[idx].name);
+ }
}
return formats;
@@ -815,7 +804,8 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct v4l2_mbus_framefmt mf;
+ struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
+ struct v4l2_pix_format *pix = &f.fmt.pix;
int ret;
soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
@@ -826,19 +816,19 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
return ret;
/* The capture device might have changed its output */
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
+ ret = v4l2_subdev_call(sd, video, g_fmt, &f);
if (ret < 0)
return ret;
- if (mf.width & 7) {
+ if (pix->width & 7) {
/* Ouch! We can only handle 8-byte aligned width... */
- stride_align(&mf.width);
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
+ stride_align(&pix->width);
+ ret = v4l2_subdev_call(sd, video, s_fmt, &f);
if (ret < 0)
return ret;
}
- if (mf.width != icd->user_width || mf.height != icd->user_height) {
+ if (pix->width != icd->user_width || pix->height != icd->user_height) {
/*
* We now know pixel formats and can decide upon DMA-channel(s)
* So far only direct camera-to-memory is supported
@@ -849,14 +839,14 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
return ret;
}
- configure_geometry(mx3_cam, mf.width, mf.height);
+ configure_geometry(mx3_cam, pix->width, pix->height);
}
dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
- mf.width, mf.height);
+ pix->width, pix->height);
- icd->user_width = mf.width;
- icd->user_height = mf.height;
+ icd->user_width = pix->width;
+ icd->user_height = pix->height;
return ret;
}
@@ -869,7 +859,6 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
const struct soc_camera_format_xlate *xlate;
struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
int ret;
xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
@@ -894,24 +883,11 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
configure_geometry(mx3_cam, pix->width, pix->height);
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- if (mf.code != xlate->code)
- return -EINVAL;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
- icd->current_fmt = xlate;
+ ret = v4l2_subdev_call(sd, video, s_fmt, f);
+ if (!ret) {
+ icd->buswidth = xlate->buswidth;
+ icd->current_fmt = xlate->host_fmt;
+ }
dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height);
@@ -924,8 +900,8 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
const struct soc_camera_format_xlate *xlate;
struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
__u32 pixfmt = pix->pixelformat;
+ enum v4l2_field field;
int ret;
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
@@ -940,37 +916,23 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
if (pix->width > 4096)
pix->width = 4096;
- pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
- xlate->host_fmt);
- if (pix->bytesperline < 0)
- return pix->bytesperline;
+ pix->bytesperline = pix->width *
+ DIV_ROUND_UP(xlate->host_fmt->depth, 8);
pix->sizeimage = pix->height * pix->bytesperline;
+ /* camera has to see its format, but the user the original one */
+ pix->pixelformat = xlate->cam_fmt->fourcc;
/* limit to sensor capabilities */
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
+ ret = v4l2_subdev_call(sd, video, try_fmt, f);
+ pix->pixelformat = xlate->host_fmt->fourcc;
- pix->width = mf.width;
- pix->height = mf.height;
- pix->colorspace = mf.colorspace;
+ field = pix->field;
- switch (mf.field) {
- case V4L2_FIELD_ANY:
+ if (field == V4L2_FIELD_ANY) {
pix->field = V4L2_FIELD_NONE;
- break;
- case V4L2_FIELD_NONE:
- break;
- default:
- dev_err(icd->dev.parent, "Field type %d unsupported.\n",
- mf.field);
- ret = -EINVAL;
+ } else if (field != V4L2_FIELD_NONE) {
+ dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
+ return -EINVAL;
}
return ret;
@@ -1006,26 +968,18 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
struct mx3_camera_dev *mx3_cam = ici->priv;
unsigned long bus_flags, camera_flags, common_flags;
u32 dw, sens_conf;
- const struct soc_mbus_pixelfmt *fmt;
- int buswidth;
- int ret;
+ int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags);
const struct soc_camera_format_xlate *xlate;
struct device *dev = icd->dev.parent;
- fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
- if (!fmt)
- return -EINVAL;
-
- buswidth = fmt->bits_per_sample;
- ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
-
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (!xlate) {
dev_warn(dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
- dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret);
+ dev_dbg(dev, "requested bus width %d bit: %d\n",
+ icd->buswidth, ret);
if (ret < 0)
return ret;
@@ -1073,10 +1027,8 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
}
- /*
- * Make the camera work in widest common mode, we'll take care of
- * the rest
- */
+ /* Make the camera work in widest common mode, we'll take care of
+ * the rest */
if (common_flags & SOCAM_DATAWIDTH_15)
common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
SOCAM_DATAWIDTH_15;
@@ -1126,7 +1078,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
/* Just do what we're asked to do */
- switch (xlate->host_fmt->bits_per_sample) {
+ switch (xlate->host_fmt->depth) {
case 4:
dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
break;
@@ -1200,10 +1152,8 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 |
MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 |
MX3_CAMERA_DATAWIDTH_15))) {
- /*
- * Platform hasn't set available data widths. This is bad.
- * Warn and use a default.
- */
+ /* Platform hasn't set available data widths. This is bad.
+ * Warn and use a default. */
dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
"data widths, using default 8 bit\n");
mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
diff --git a/trunk/drivers/media/video/omap24xxcam.c b/trunk/drivers/media/video/omap24xxcam.c
index 7400eacb4d64..5fc4ac0d88f0 100644
--- a/trunk/drivers/media/video/omap24xxcam.c
+++ b/trunk/drivers/media/video/omap24xxcam.c
@@ -1450,11 +1450,12 @@ static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma)
static int omap24xxcam_open(struct file *file)
{
+ int minor = video_devdata(file)->minor;
struct omap24xxcam_device *cam = omap24xxcam.priv;
struct omap24xxcam_fh *fh;
struct v4l2_format format;
- if (!cam || !cam->vfd)
+ if (!cam || !cam->vfd || (cam->vfd->minor != minor))
return -ENODEV;
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
@@ -1659,6 +1660,7 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s)
strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
vfd->fops = &omap24xxcam_fops;
+ vfd->minor = -1;
vfd->ioctl_ops = &omap24xxcam_ioctl_fops;
omap24xxcam_hwinit(cam);
@@ -1669,14 +1671,14 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s)
if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) {
dev_err(cam->dev, "could not register V4L device\n");
+ vfd->minor = -1;
rval = -EBUSY;
goto err;
}
omap24xxcam_poweron_reset(cam);
- dev_info(cam->dev, "registered device %s\n",
- video_device_node_name(vfd));
+ dev_info(cam->dev, "registered device video%d\n", vfd->minor);
return 0;
@@ -1693,7 +1695,7 @@ static void omap24xxcam_device_unregister(struct v4l2_int_device *s)
omap24xxcam_sensor_exit(cam);
if (cam->vfd) {
- if (!video_is_registered(cam->vfd)) {
+ if (cam->vfd->minor == -1) {
/*
* The device was never registered, so release the
* video_device struct directly.
diff --git a/trunk/drivers/media/video/ov511.c b/trunk/drivers/media/video/ov511.c
index e0bce8dc74bf..0bc2cf573c76 100644
--- a/trunk/drivers/media/video/ov511.c
+++ b/trunk/drivers/media/video/ov511.c
@@ -4674,6 +4674,7 @@ static struct video_device vdev_template = {
.name = "OV511 USB Camera",
.fops = &ov511_fops,
.release = video_device_release,
+ .minor = -1,
};
/****************************************************************************
@@ -5866,8 +5867,8 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
ov511_devused |= 1 << nr;
ov->nr = nr;
- dev_info(&intf->dev, "Device at %s registered to %s\n",
- ov->usb_path, video_device_node_name(ov->vdev));
+ dev_info(&intf->dev, "Device at %s registered to minor %d\n",
+ ov->usb_path, ov->vdev->minor);
usb_set_intfdata(intf, ov);
if (ov_create_sysfs(ov->vdev)) {
@@ -5877,13 +5878,13 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
goto error;
}
- mutex_unlock(&ov->lock);
+ mutex_lock(&ov->lock);
return 0;
error:
if (ov->vdev) {
- if (!video_is_registered(ov->vdev))
+ if (-1 == ov->vdev->minor)
video_device_release(ov->vdev);
else
video_unregister_device(ov->vdev);
diff --git a/trunk/drivers/media/video/ov772x.c b/trunk/drivers/media/video/ov772x.c
index 3a45e945a528..205229333466 100644
--- a/trunk/drivers/media/video/ov772x.c
+++ b/trunk/drivers/media/video/ov772x.c
@@ -24,7 +24,6 @@
#include
#include
#include
-#include
#include
/*
@@ -383,8 +382,7 @@ struct regval_list {
};
struct ov772x_color_format {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
+ const struct soc_camera_data_format *format;
u8 dsp3;
u8 com3;
u8 com7;
@@ -401,7 +399,7 @@ struct ov772x_win_size {
struct ov772x_priv {
struct v4l2_subdev subdev;
struct ov772x_camera_info *info;
- const struct ov772x_color_format *cfmt;
+ const struct ov772x_color_format *fmt;
const struct ov772x_win_size *win;
int model;
unsigned short flag_vflip:1;
@@ -436,57 +434,93 @@ static const struct regval_list ov772x_vga_regs[] = {
};
/*
- * supported color format list
+ * supported format list
+ */
+
+#define SETFOURCC(type) .name = (#type), .fourcc = (V4L2_PIX_FMT_ ## type)
+static const struct soc_camera_data_format ov772x_fmt_lists[] = {
+ {
+ SETFOURCC(YUYV),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ SETFOURCC(YVYU),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ SETFOURCC(UYVY),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ SETFOURCC(RGB555),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ },
+ {
+ SETFOURCC(RGB555X),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ },
+ {
+ SETFOURCC(RGB565),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ },
+ {
+ SETFOURCC(RGB565X),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ },
+};
+
+/*
+ * color format list
*/
static const struct ov772x_color_format ov772x_cfmts[] = {
{
- .code = V4L2_MBUS_FMT_YUYV8_2X8_LE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .dsp3 = 0x0,
- .com3 = SWAP_YUV,
- .com7 = OFMT_YUV,
+ .format = &ov772x_fmt_lists[0],
+ .dsp3 = 0x0,
+ .com3 = SWAP_YUV,
+ .com7 = OFMT_YUV,
},
{
- .code = V4L2_MBUS_FMT_YVYU8_2X8_LE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .dsp3 = UV_ON,
- .com3 = SWAP_YUV,
- .com7 = OFMT_YUV,
+ .format = &ov772x_fmt_lists[1],
+ .dsp3 = UV_ON,
+ .com3 = SWAP_YUV,
+ .com7 = OFMT_YUV,
},
{
- .code = V4L2_MBUS_FMT_YUYV8_2X8_BE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .dsp3 = 0x0,
- .com3 = 0x0,
- .com7 = OFMT_YUV,
+ .format = &ov772x_fmt_lists[2],
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = OFMT_YUV,
},
{
- .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .dsp3 = 0x0,
- .com3 = SWAP_RGB,
- .com7 = FMT_RGB555 | OFMT_RGB,
+ .format = &ov772x_fmt_lists[3],
+ .dsp3 = 0x0,
+ .com3 = SWAP_RGB,
+ .com7 = FMT_RGB555 | OFMT_RGB,
},
{
- .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .dsp3 = 0x0,
- .com3 = 0x0,
- .com7 = FMT_RGB555 | OFMT_RGB,
+ .format = &ov772x_fmt_lists[4],
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = FMT_RGB555 | OFMT_RGB,
},
{
- .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .dsp3 = 0x0,
- .com3 = SWAP_RGB,
- .com7 = FMT_RGB565 | OFMT_RGB,
+ .format = &ov772x_fmt_lists[5],
+ .dsp3 = 0x0,
+ .com3 = SWAP_RGB,
+ .com7 = FMT_RGB565 | OFMT_RGB,
},
{
- .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .dsp3 = 0x0,
- .com3 = 0x0,
- .com7 = FMT_RGB565 | OFMT_RGB,
+ .format = &ov772x_fmt_lists[6],
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = FMT_RGB565 | OFMT_RGB,
},
};
@@ -608,15 +642,15 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
- if (!priv->win || !priv->cfmt) {
+ if (!priv->win || !priv->fmt) {
dev_err(&client->dev, "norm or win select error\n");
return -EPERM;
}
ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
- dev_dbg(&client->dev, "format %d, win %s\n",
- priv->cfmt->code, priv->win->name);
+ dev_dbg(&client->dev, "format %s, win %s\n",
+ priv->fmt->format->name, priv->win->name);
return 0;
}
@@ -772,8 +806,8 @@ static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
return win;
}
-static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
- enum v4l2_mbus_pixelcode code)
+static int ov772x_set_params(struct i2c_client *client,
+ u32 *width, u32 *height, u32 pixfmt)
{
struct ov772x_priv *priv = to_ov772x(client);
int ret = -EINVAL;
@@ -783,14 +817,14 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
/*
* select format
*/
- priv->cfmt = NULL;
+ priv->fmt = NULL;
for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
- if (code == ov772x_cfmts[i].code) {
- priv->cfmt = ov772x_cfmts + i;
+ if (pixfmt == ov772x_cfmts[i].format->fourcc) {
+ priv->fmt = ov772x_cfmts + i;
break;
}
}
- if (!priv->cfmt)
+ if (!priv->fmt)
goto ov772x_set_fmt_error;
/*
@@ -860,7 +894,7 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
/*
* set DSP_CTRL3
*/
- val = priv->cfmt->dsp3;
+ val = priv->fmt->dsp3;
if (val) {
ret = ov772x_mask_set(client,
DSP_CTRL3, UV_MASK, val);
@@ -871,7 +905,7 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
/*
* set COM3
*/
- val = priv->cfmt->com3;
+ val = priv->fmt->com3;
if (priv->info->flags & OV772X_FLAG_VFLIP)
val |= VFLIP_IMG;
if (priv->info->flags & OV772X_FLAG_HFLIP)
@@ -889,9 +923,9 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
/*
* set COM7
*/
- val = priv->win->com7_bit | priv->cfmt->com7;
+ val = priv->win->com7_bit | priv->fmt->com7;
ret = ov772x_mask_set(client,
- COM7, SLCT_MASK | FMT_MASK | OFMT_MASK,
+ COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK),
val);
if (ret < 0)
goto ov772x_set_fmt_error;
@@ -917,7 +951,7 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
ov772x_reset(client);
priv->win = NULL;
- priv->cfmt = NULL;
+ priv->fmt = NULL;
return ret;
}
@@ -947,79 +981,54 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int ov772x_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct ov772x_priv *priv = to_ov772x(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- if (!priv->win || !priv->cfmt) {
+ if (!priv->win || !priv->fmt) {
u32 width = VGA_WIDTH, height = VGA_HEIGHT;
int ret = ov772x_set_params(client, &width, &height,
- V4L2_MBUS_FMT_YUYV8_2X8_LE);
+ V4L2_PIX_FMT_YUYV);
if (ret < 0)
return ret;
}
- mf->width = priv->win->width;
- mf->height = priv->win->height;
- mf->code = priv->cfmt->code;
- mf->colorspace = priv->cfmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ pix->width = priv->win->width;
+ pix->height = priv->win->height;
+ pix->pixelformat = priv->fmt->format->fourcc;
+ pix->colorspace = priv->fmt->format->colorspace;
+ pix->field = V4L2_FIELD_NONE;
return 0;
}
-static int ov772x_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
- struct ov772x_priv *priv = to_ov772x(client);
- int ret = ov772x_set_params(client, &mf->width, &mf->height,
- mf->code);
-
- if (!ret)
- mf->colorspace = priv->cfmt->colorspace;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- return ret;
+ return ov772x_set_params(client, &pix->width, &pix->height,
+ pix->pixelformat);
}
static int ov772x_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+ struct v4l2_format *f)
{
- struct i2c_client *client = sd->priv;
- struct ov772x_priv *priv = to_ov772x(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
const struct ov772x_win_size *win;
- int i;
/*
* select suitable win
*/
- win = ov772x_select_win(mf->width, mf->height);
-
- mf->width = win->width;
- mf->height = win->height;
- mf->field = V4L2_FIELD_NONE;
+ win = ov772x_select_win(pix->width, pix->height);
- for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++)
- if (mf->code == ov772x_cfmts[i].code)
- break;
-
- if (i == ARRAY_SIZE(ov772x_cfmts)) {
- /* Unsupported format requested. Propose either */
- if (priv->cfmt) {
- /* the current one or */
- mf->colorspace = priv->cfmt->colorspace;
- mf->code = priv->cfmt->code;
- } else {
- /* the default one */
- mf->colorspace = ov772x_cfmts[0].colorspace;
- mf->code = ov772x_cfmts[0].code;
- }
- } else {
- /* Also return the colorspace */
- mf->colorspace = ov772x_cfmts[i].colorspace;
- }
+ pix->width = win->width;
+ pix->height = win->height;
+ pix->field = V4L2_FIELD_NONE;
return 0;
}
@@ -1048,6 +1057,9 @@ static int ov772x_video_probe(struct soc_camera_device *icd,
return -ENODEV;
}
+ icd->formats = ov772x_fmt_lists;
+ icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists);
+
/*
* check and show product ID and manufacturer ID
*/
@@ -1097,24 +1109,13 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
#endif
};
-static int ov772x_enum_fmt(struct v4l2_subdev *sd, int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if ((unsigned int)index >= ARRAY_SIZE(ov772x_cfmts))
- return -EINVAL;
-
- *code = ov772x_cfmts[index].code;
- return 0;
-}
-
static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
.s_stream = ov772x_s_stream,
- .g_mbus_fmt = ov772x_g_fmt,
- .s_mbus_fmt = ov772x_s_fmt,
- .try_mbus_fmt = ov772x_try_fmt,
+ .g_fmt = ov772x_g_fmt,
+ .s_fmt = ov772x_s_fmt,
+ .try_fmt = ov772x_try_fmt,
.cropcap = ov772x_cropcap,
.g_crop = ov772x_g_crop,
- .enum_mbus_fmt = ov772x_enum_fmt,
};
static struct v4l2_subdev_ops ov772x_subdev_ops = {
@@ -1142,10 +1143,10 @@ static int ov772x_probe(struct i2c_client *client,
}
icl = to_soc_camera_link(icd);
- if (!icl || !icl->priv)
+ if (!icl)
return -EINVAL;
- info = icl->priv;
+ info = container_of(icl, struct ov772x_camera_info, link);
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&adapter->dev,
diff --git a/trunk/drivers/media/video/ov9640.c b/trunk/drivers/media/video/ov9640.c
index 47bf60ceb7a2..c81ae2192887 100644
--- a/trunk/drivers/media/video/ov9640.c
+++ b/trunk/drivers/media/video/ov9640.c
@@ -154,10 +154,19 @@ static const struct ov9640_reg ov9640_regs_rgb[] = {
{ OV9640_MTXS, 0x65 },
};
-static enum v4l2_mbus_pixelcode ov9640_codes[] = {
- V4L2_MBUS_FMT_YUYV8_2X8_BE,
- V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
- V4L2_MBUS_FMT_RGB565_2X8_LE,
+/*
+ * TODO: this sensor also supports RGB555 and RGB565 formats, but support for
+ * them has not yet been sufficiently tested and so it is not included with
+ * this version of the driver. To test and debug these formats add two entries
+ * to the below array, see ov722x.c for an example.
+ */
+static const struct soc_camera_data_format ov9640_fmt_lists[] = {
+ {
+ .name = "UYVY",
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
};
static const struct v4l2_queryctrl ov9640_controls[] = {
@@ -425,22 +434,20 @@ static void ov9640_res_roundup(u32 *width, u32 *height)
}
/* Prepare necessary register changes depending on color encoding */
-static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code,
- struct ov9640_reg_alt *alt)
+static void ov9640_alter_regs(u32 pixfmt, struct ov9640_reg_alt *alt)
{
- switch (code) {
- default:
- case V4L2_MBUS_FMT_YUYV8_2X8_BE:
+ switch (pixfmt) {
+ case V4L2_PIX_FMT_UYVY:
alt->com12 = OV9640_COM12_YUV_AVG;
alt->com13 = OV9640_COM13_Y_DELAY_EN |
OV9640_COM13_YUV_DLY(0x01);
break;
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
+ case V4L2_PIX_FMT_RGB555:
alt->com7 = OV9640_COM7_RGB;
alt->com13 = OV9640_COM13_RGB_AVG;
alt->com15 = OV9640_COM15_RGB_555;
break;
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
+ case V4L2_PIX_FMT_RGB565:
alt->com7 = OV9640_COM7_RGB;
alt->com13 = OV9640_COM13_RGB_AVG;
alt->com15 = OV9640_COM15_RGB_565;
@@ -449,8 +456,8 @@ static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code,
}
/* Setup registers according to resolution and color encoding */
-static int ov9640_write_regs(struct i2c_client *client, u32 width,
- enum v4l2_mbus_pixelcode code, struct ov9640_reg_alt *alts)
+static int ov9640_write_regs(struct i2c_client *client,
+ u32 width, u32 pixfmt, struct ov9640_reg_alt *alts)
{
const struct ov9640_reg *ov9640_regs, *matrix_regs;
int ov9640_regs_len, matrix_regs_len;
@@ -493,7 +500,7 @@ static int ov9640_write_regs(struct i2c_client *client, u32 width,
}
/* select color matrix configuration for given color encoding */
- if (code == V4L2_MBUS_FMT_YUYV8_2X8_BE) {
+ if (pixfmt == V4L2_PIX_FMT_UYVY) {
matrix_regs = ov9640_regs_yuv;
matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv);
} else {
@@ -555,17 +562,15 @@ static int ov9640_prog_dflt(struct i2c_client *client)
}
/* set the format we will capture in */
-static int ov9640_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov9640_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
struct ov9640_reg_alt alts = {0};
- enum v4l2_colorspace cspace;
- enum v4l2_mbus_pixelcode code = mf->code;
int ret;
- ov9640_res_roundup(&mf->width, &mf->height);
- ov9640_alter_regs(mf->code, &alts);
+ ov9640_res_roundup(&pix->width, &pix->height);
+ ov9640_alter_regs(pix->pixelformat, &alts);
ov9640_reset(client);
@@ -573,57 +578,19 @@ static int ov9640_s_fmt(struct v4l2_subdev *sd,
if (ret)
return ret;
- switch (code) {
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- cspace = V4L2_COLORSPACE_SRGB;
- break;
- default:
- code = V4L2_MBUS_FMT_YUYV8_2X8_BE;
- case V4L2_MBUS_FMT_YUYV8_2X8_BE:
- cspace = V4L2_COLORSPACE_JPEG;
- }
-
- ret = ov9640_write_regs(client, mf->width, code, &alts);
- if (!ret) {
- mf->code = code;
- mf->colorspace = cspace;
- }
-
- return ret;
+ return ov9640_write_regs(client, pix->width, pix->pixelformat, &alts);
}
-static int ov9640_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov9640_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
- ov9640_res_roundup(&mf->width, &mf->height);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- mf->field = V4L2_FIELD_NONE;
-
- switch (mf->code) {
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- mf->colorspace = V4L2_COLORSPACE_SRGB;
- break;
- default:
- mf->code = V4L2_MBUS_FMT_YUYV8_2X8_BE;
- case V4L2_MBUS_FMT_YUYV8_2X8_BE:
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- }
+ ov9640_res_roundup(&pix->width, &pix->height);
+ pix->field = V4L2_FIELD_NONE;
return 0;
}
-static int ov9640_enum_fmt(struct v4l2_subdev *sd, int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if ((unsigned int)index >= ARRAY_SIZE(ov9640_codes))
- return -EINVAL;
-
- *code = ov9640_codes[index];
- return 0;
-}
-
static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
a->c.left = 0;
@@ -670,6 +637,9 @@ static int ov9640_video_probe(struct soc_camera_device *icd,
goto err;
}
+ icd->formats = ov9640_fmt_lists;
+ icd->num_formats = ARRAY_SIZE(ov9640_fmt_lists);
+
/*
* check and show product ID and manufacturer ID
*/
@@ -732,12 +702,11 @@ static struct v4l2_subdev_core_ops ov9640_core_ops = {
};
static struct v4l2_subdev_video_ops ov9640_video_ops = {
- .s_stream = ov9640_s_stream,
- .s_mbus_fmt = ov9640_s_fmt,
- .try_mbus_fmt = ov9640_try_fmt,
- .enum_mbus_fmt = ov9640_enum_fmt,
- .cropcap = ov9640_cropcap,
- .g_crop = ov9640_g_crop,
+ .s_stream = ov9640_s_stream,
+ .s_fmt = ov9640_s_fmt,
+ .try_fmt = ov9640_try_fmt,
+ .cropcap = ov9640_cropcap,
+ .g_crop = ov9640_g_crop,
};
diff --git a/trunk/drivers/media/video/pms.c b/trunk/drivers/media/video/pms.c
index 11a2c26399b5..73ec970ca5ca 100644
--- a/trunk/drivers/media/video/pms.c
+++ b/trunk/drivers/media/video/pms.c
@@ -31,7 +31,7 @@
#include
#include
#include
-#include
+#include
#include
#include
diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index cc8ddb2d2382..6aa48e0ae731 100644
--- a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -151,6 +151,17 @@ static struct v4l2_format pvr_format [] = {
};
+static const char *get_v4l_name(int v4l_type)
+{
+ switch (v4l_type) {
+ case VFL_TYPE_GRABBER: return "video";
+ case VFL_TYPE_RADIO: return "radio";
+ case VFL_TYPE_VBI: return "vbi";
+ default: return "?";
+ }
+}
+
+
/*
* pvr_ioctl()
*
@@ -880,8 +891,10 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
{
+ int num = dip->devbase.num;
struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
enum pvr2_config cfg = dip->config;
+ int v4l_type = dip->v4l_type;
pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
@@ -893,8 +906,8 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
are gone. */
video_unregister_device(&dip->devbase);
- printk(KERN_INFO "pvrusb2: unregistered device %s [%s]\n",
- video_device_node_name(&dip->devbase),
+ printk(KERN_INFO "pvrusb2: unregistered device %s%u [%s]\n",
+ get_v4l_name(v4l_type), num,
pvr2_config_get_name(cfg));
}
@@ -1304,8 +1317,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
": Failed to register pvrusb2 v4l device\n");
}
- printk(KERN_INFO "pvrusb2: registered device %s [%s]\n",
- video_device_node_name(&dip->devbase),
+ printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
+ get_v4l_name(dip->v4l_type), dip->devbase.num,
pvr2_config_get_name(dip->config));
pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
diff --git a/trunk/drivers/media/video/pwc/pwc-if.c b/trunk/drivers/media/video/pwc/pwc-if.c
index aea7e224cef6..89b620f6db7b 100644
--- a/trunk/drivers/media/video/pwc/pwc-if.c
+++ b/trunk/drivers/media/video/pwc/pwc-if.c
@@ -169,6 +169,7 @@ static struct video_device pwc_template = {
.name = "Philips Webcam", /* Filled in later */
.release = video_device_release,
.fops = &pwc_fops,
+ .minor = -1,
};
/***************************************************************************/
@@ -1806,7 +1807,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
goto err_video_release;
}
- PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev));
+ PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->num);
/* occupy slot */
if (hint < MAX_DEV_HINTS)
@@ -1947,9 +1948,7 @@ MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif,
MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers");
-#ifdef CONFIG_USB_PWC_DEBUG
MODULE_PARM_DESC(trace, "For debugging purposes");
-#endif
MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off");
MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
diff --git a/trunk/drivers/media/video/pxa_camera.c b/trunk/drivers/media/video/pxa_camera.c
index 294f860ce2b0..51b683c63b70 100644
--- a/trunk/drivers/media/video/pxa_camera.c
+++ b/trunk/drivers/media/video/pxa_camera.c
@@ -32,7 +32,6 @@
#include
#include
#include
-#include
#include
@@ -184,21 +183,23 @@ struct pxa_cam_dma {
/* buffer for one video frame */
struct pxa_buffer {
/* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
- enum v4l2_mbus_pixelcode code;
+ struct videobuf_buffer vb;
+
+ const struct soc_camera_data_format *fmt;
+
/* our descriptor lists for Y, U and V channels */
- struct pxa_cam_dma dmas[3];
- int inwork;
- enum pxa_camera_active_dma active_dma;
+ struct pxa_cam_dma dmas[3];
+
+ int inwork;
+
+ enum pxa_camera_active_dma active_dma;
};
struct pxa_camera_dev {
struct soc_camera_host soc_host;
- /*
- * PXA27x is only supposed to handle one camera on its Quick Capture
+ /* PXA27x is only supposed to handle one camera on its Quick Capture
* interface. If anyone ever builds hardware to enable more than
- * one camera, they will have to modify this driver too
- */
+ * one camera, they will have to modify this driver too */
struct soc_camera_device *icd;
struct clk *clk;
@@ -240,15 +241,11 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
unsigned int *size)
{
struct soc_camera_device *icd = vq->priv_data;
- int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
- icd->current_fmt->host_fmt);
-
- if (bytes_per_line < 0)
- return bytes_per_line;
dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
- *size = bytes_per_line * icd->user_height;
+ *size = roundup(icd->user_width * icd->user_height *
+ ((icd->current_fmt->depth + 7) >> 3), 8);
if (0 == *count)
*count = 32;
@@ -270,10 +267,8 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
&buf->vb, buf->vb.baddr, buf->vb.bsize);
- /*
- * This waits until this buffer is out of danger, i.e., until it is no
- * longer in STATE_QUEUED or STATE_ACTIVE
- */
+ /* This waits until this buffer is out of danger, i.e., until it is no
+ * longer in STATE_QUEUED or STATE_ACTIVE */
videobuf_waiton(&buf->vb, 0, 0);
videobuf_dma_unmap(vq, dma);
videobuf_dma_free(dma);
@@ -434,11 +429,6 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
int ret;
int size_y, size_u = 0, size_v = 0;
- int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
- icd->current_fmt->host_fmt);
-
- if (bytes_per_line < 0)
- return bytes_per_line;
dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
vb, vb->baddr, vb->bsize);
@@ -447,33 +437,29 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
WARN_ON(!list_empty(&vb->queue));
#ifdef DEBUG
- /*
- * This can be useful if you want to see if we actually fill
- * the buffer with something
- */
+ /* This can be useful if you want to see if we actually fill
+ * the buffer with something */
memset((void *)vb->baddr, 0xaa, vb->bsize);
#endif
BUG_ON(NULL == icd->current_fmt);
- /*
- * I think, in buf_prepare you only have to protect global data,
- * the actual buffer is yours
- */
+ /* I think, in buf_prepare you only have to protect global data,
+ * the actual buffer is yours */
buf->inwork = 1;
- if (buf->code != icd->current_fmt->code ||
+ if (buf->fmt != icd->current_fmt ||
vb->width != icd->user_width ||
vb->height != icd->user_height ||
vb->field != field) {
- buf->code = icd->current_fmt->code;
+ buf->fmt = icd->current_fmt;
vb->width = icd->user_width;
vb->height = icd->user_height;
vb->field = field;
vb->state = VIDEOBUF_NEEDS_INIT;
}
- vb->size = bytes_per_line * vb->height;
+ vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
if (0 != vb->baddr && vb->bsize < vb->size) {
ret = -EINVAL;
goto out;
@@ -848,10 +834,8 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q,
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv;
- /*
- * We must pass NULL as dev pointer, then all pci_* dma operations
- * transform to normal dma_* ones.
- */
+ /* We must pass NULL as dev pointer, then all pci_* dma operations
+ * transform to normal dma_* ones. */
videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
sizeof(struct pxa_buffer), icd);
@@ -1067,18 +1051,11 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
unsigned long dw, bpp;
- u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0, y_skip_top;
- int ret = v4l2_subdev_call(sd, sensor, g_skip_top_lines, &y_skip_top);
-
- if (ret < 0)
- y_skip_top = 0;
+ u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0;
- /*
- * Datawidth is now guaranteed to be equal to one of the three values.
- * We fix bit-per-pixel equal to data-width...
- */
+ /* Datawidth is now guaranteed to be equal to one of the three values.
+ * We fix bit-per-pixel equal to data-width... */
switch (flags & SOCAM_DATAWIDTH_MASK) {
case SOCAM_DATAWIDTH_10:
dw = 4;
@@ -1089,10 +1066,8 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
bpp = 0x20;
break;
default:
- /*
- * Actually it can only be 8 now,
- * default is just to silence compiler warnings
- */
+ /* Actually it can only be 8 now,
+ * default is just to silence compiler warnings */
case SOCAM_DATAWIDTH_8:
dw = 2;
bpp = 0;
@@ -1143,7 +1118,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
cicr2 = 0;
cicr3 = CICR3_LPF_VAL(icd->user_height - 1) |
- CICR3_BFW_VAL(min((u32)255, y_skip_top));
+ CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top));
cicr4 |= pcdev->mclk_divisor;
__raw_writel(cicr1, pcdev->base + CICR1);
@@ -1163,15 +1138,9 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv;
unsigned long bus_flags, camera_flags, common_flags;
- const struct soc_mbus_pixelfmt *fmt;
- int ret;
+ int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags);
struct pxa_cam *cam = icd->host_priv;
- fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
- if (!fmt)
- return -EINVAL;
-
- ret = test_platform_param(pcdev, fmt->bits_per_sample, &bus_flags);
if (ret < 0)
return ret;
@@ -1235,49 +1204,59 @@ static int pxa_camera_try_bus_param(struct soc_camera_device *icd,
return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL;
}
-static const struct soc_mbus_pixelfmt pxa_camera_formats[] = {
+static const struct soc_camera_data_format pxa_camera_formats[] = {
{
- .fourcc = V4L2_PIX_FMT_YUV422P,
- .name = "Planar YUV422 16 bit",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
+ .name = "Planar YUV422 16 bit",
+ .depth = 16,
+ .fourcc = V4L2_PIX_FMT_YUV422P,
+ .colorspace = V4L2_COLORSPACE_JPEG,
},
};
-/* This will be corrected as we get more formats */
-static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
+static bool buswidth_supported(struct soc_camera_device *icd, int depth)
{
- return fmt->packing == SOC_MBUS_PACKING_NONE ||
- (fmt->bits_per_sample == 8 &&
- fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
- (fmt->bits_per_sample > 8 &&
- fmt->packing == SOC_MBUS_PACKING_EXTEND16);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct pxa_camera_dev *pcdev = ici->priv;
+
+ switch (depth) {
+ case 8:
+ return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8);
+ case 9:
+ return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9);
+ case 10:
+ return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10);
+ }
+ return false;
+}
+
+static int required_buswidth(const struct soc_camera_data_format *fmt)
+{
+ switch (fmt->fourcc) {
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_VYUY:
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_RGB555:
+ return 8;
+ default:
+ return fmt->depth;
+ }
}
static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
struct soc_camera_format_xlate *xlate)
{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct device *dev = icd->dev.parent;
- int formats = 0, ret;
+ int formats = 0, buswidth, ret;
struct pxa_cam *cam;
- enum v4l2_mbus_pixelcode code;
- const struct soc_mbus_pixelfmt *fmt;
- ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
- if (ret < 0)
- /* No more formats */
- return 0;
+ buswidth = required_buswidth(icd->formats + idx);
- fmt = soc_mbus_get_fmtdesc(code);
- if (!fmt) {
- dev_err(dev, "Invalid format code #%d: %d\n", idx, code);
+ if (!buswidth_supported(icd, buswidth))
return 0;
- }
- /* This also checks support for the requested bits-per-sample */
- ret = pxa_camera_try_bus_param(icd, fmt->bits_per_sample);
+ ret = pxa_camera_try_bus_param(icd, buswidth);
if (ret < 0)
return 0;
@@ -1291,40 +1270,45 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
cam = icd->host_priv;
}
- switch (code) {
- case V4L2_MBUS_FMT_YUYV8_2X8_BE:
+ switch (icd->formats[idx].fourcc) {
+ case V4L2_PIX_FMT_UYVY:
formats++;
if (xlate) {
- xlate->host_fmt = &pxa_camera_formats[0];
- xlate->code = code;
+ xlate->host_fmt = &pxa_camera_formats[0];
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
xlate++;
- dev_dbg(dev, "Providing format %s using code %d\n",
- pxa_camera_formats[0].name, code);
+ dev_dbg(dev, "Providing format %s using %s\n",
+ pxa_camera_formats[0].name,
+ icd->formats[idx].name);
}
- case V4L2_MBUS_FMT_YVYU8_2X8_BE:
- case V4L2_MBUS_FMT_YUYV8_2X8_LE:
- case V4L2_MBUS_FMT_YVYU8_2X8_LE:
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
- if (xlate)
+ case V4L2_PIX_FMT_VYUY:
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_RGB555:
+ formats++;
+ if (xlate) {
+ xlate->host_fmt = icd->formats + idx;
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
+ xlate++;
dev_dbg(dev, "Providing format %s packed\n",
- fmt->name);
+ icd->formats[idx].name);
+ }
break;
default:
- if (!pxa_camera_packing_supported(fmt))
- return 0;
- if (xlate)
+ /* Generic pass-through */
+ formats++;
+ if (xlate) {
+ xlate->host_fmt = icd->formats + idx;
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = icd->formats[idx].depth;
+ xlate++;
dev_dbg(dev,
"Providing format %s in pass-through mode\n",
- fmt->name);
- }
-
- /* Generic pass-through */
- formats++;
- if (xlate) {
- xlate->host_fmt = fmt;
- xlate->code = code;
- xlate++;
+ icd->formats[idx].name);
+ }
}
return formats;
@@ -1336,11 +1320,11 @@ static void pxa_camera_put_formats(struct soc_camera_device *icd)
icd->host_priv = NULL;
}
-static int pxa_camera_check_frame(u32 width, u32 height)
+static int pxa_camera_check_frame(struct v4l2_pix_format *pix)
{
/* limit to pxa hardware capabilities */
- return height < 32 || height > 2048 || width < 48 || width > 2048 ||
- (width & 0x01);
+ return pix->height < 32 || pix->height > 2048 || pix->width < 48 ||
+ pix->width > 2048 || (pix->width & 0x01);
}
static int pxa_camera_set_crop(struct soc_camera_device *icd,
@@ -1355,9 +1339,9 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
.master_clock = pcdev->mclk,
.pixel_clock_max = pcdev->ciclk / 4,
};
- struct v4l2_mbus_framefmt mf;
+ struct v4l2_format f;
+ struct v4l2_pix_format *pix = &f.fmt.pix, pix_tmp;
struct pxa_cam *cam = icd->host_priv;
- u32 fourcc = icd->current_fmt->host_fmt->fourcc;
int ret;
/* If PCLK is used to latch data from the sensor, check sense */
@@ -1374,23 +1358,27 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
return ret;
}
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
+ f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ ret = v4l2_subdev_call(sd, video, g_fmt, &f);
if (ret < 0)
return ret;
- if (pxa_camera_check_frame(mf.width, mf.height)) {
+ pix_tmp = *pix;
+ if (pxa_camera_check_frame(pix)) {
/*
* Camera cropping produced a frame beyond our capabilities.
* FIXME: just extract a subframe, that we can process.
*/
- v4l_bound_align_image(&mf.width, 48, 2048, 1,
- &mf.height, 32, 2048, 0,
- fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0);
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
+ v4l_bound_align_image(&pix->width, 48, 2048, 1,
+ &pix->height, 32, 2048, 0,
+ icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P ?
+ 4 : 0);
+ ret = v4l2_subdev_call(sd, video, s_fmt, &f);
if (ret < 0)
return ret;
- if (pxa_camera_check_frame(mf.width, mf.height)) {
+ if (pxa_camera_check_frame(pix)) {
dev_warn(icd->dev.parent,
"Inconsistent state. Use S_FMT to repair\n");
return -EINVAL;
@@ -1407,10 +1395,10 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
recalculate_fifo_timeout(pcdev, sense.pixel_clock);
}
- icd->user_width = mf.width;
- icd->user_height = mf.height;
+ icd->user_width = pix->width;
+ icd->user_height = pix->height;
- pxa_camera_setup_cicr(icd, cam->flags, fourcc);
+ pxa_camera_setup_cicr(icd, cam->flags, icd->current_fmt->fourcc);
return ret;
}
@@ -1422,13 +1410,14 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
struct pxa_camera_dev *pcdev = ici->priv;
struct device *dev = icd->dev.parent;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+ const struct soc_camera_data_format *cam_fmt = NULL;
const struct soc_camera_format_xlate *xlate = NULL;
struct soc_camera_sense sense = {
.master_clock = pcdev->mclk,
.pixel_clock_max = pcdev->ciclk / 4,
};
struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
+ struct v4l2_format cam_f = *f;
int ret;
xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
@@ -1437,31 +1426,26 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
return -EINVAL;
}
+ cam_fmt = xlate->cam_fmt;
+
/* If PCLK is used to latch data from the sensor, check sense */
if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
- /* The caller holds a mutex. */
icd->sense = &sense;
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
-
- if (mf.code != xlate->code)
- return -EINVAL;
+ cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
+ ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f);
+ cam_f.fmt.pix.pixelformat = pix->pixelformat;
+ *pix = cam_f.fmt.pix;
icd->sense = NULL;
if (ret < 0) {
dev_warn(dev, "Failed to configure for format %x\n",
pix->pixelformat);
- } else if (pxa_camera_check_frame(mf.width, mf.height)) {
+ } else if (pxa_camera_check_frame(pix)) {
dev_warn(dev,
"Camera driver produced an unsupported frame %dx%d\n",
- mf.width, mf.height);
+ pix->width, pix->height);
ret = -EINVAL;
} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
if (sense.pixel_clock > sense.pixel_clock_max) {
@@ -1473,14 +1457,10 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
recalculate_fifo_timeout(pcdev, sense.pixel_clock);
}
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
- icd->current_fmt = xlate;
+ if (!ret) {
+ icd->buswidth = xlate->buswidth;
+ icd->current_fmt = xlate->host_fmt;
+ }
return ret;
}
@@ -1488,16 +1468,17 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
static int pxa_camera_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
const struct soc_camera_format_xlate *xlate;
struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
__u32 pixfmt = pix->pixelformat;
+ enum v4l2_field field;
int ret;
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (!xlate) {
- dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt);
+ dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
@@ -1511,36 +1492,22 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
&pix->height, 32, 2048, 0,
pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0);
- pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
- xlate->host_fmt);
- if (pix->bytesperline < 0)
- return pix->bytesperline;
+ pix->bytesperline = pix->width *
+ DIV_ROUND_UP(xlate->host_fmt->depth, 8);
pix->sizeimage = pix->height * pix->bytesperline;
+ /* camera has to see its format, but the user the original one */
+ pix->pixelformat = xlate->cam_fmt->fourcc;
/* limit to sensor capabilities */
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
+ ret = v4l2_subdev_call(sd, video, try_fmt, f);
+ pix->pixelformat = pixfmt;
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
+ field = pix->field;
- pix->width = mf.width;
- pix->height = mf.height;
- pix->colorspace = mf.colorspace;
-
- switch (mf.field) {
- case V4L2_FIELD_ANY:
- case V4L2_FIELD_NONE:
- pix->field = V4L2_FIELD_NONE;
- break;
- default:
- /* TODO: support interlaced at least in pass-through mode */
- dev_err(icd->dev.parent, "Field type %d unsupported.\n",
- mf.field);
+ if (field == V4L2_FIELD_ANY) {
+ pix->field = V4L2_FIELD_NONE;
+ } else if (field != V4L2_FIELD_NONE) {
+ dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
return -EINVAL;
}
@@ -1552,12 +1519,10 @@ static int pxa_camera_reqbufs(struct soc_camera_file *icf,
{
int i;
- /*
- * This is for locking debugging only. I removed spinlocks and now I
+ /* This is for locking debugging only. I removed spinlocks and now I
* check whether .prepare is ever called on a linked buffer, or whether
* a dma IRQ can occur for an in-work or unlinked buffer. Until now
- * it hadn't triggered
- */
+ * it hadn't triggered */
for (i = 0; i < p->count; i++) {
struct pxa_buffer *buf = container_of(icf->vb_vidq.bufs[i],
struct pxa_buffer, vb);
@@ -1692,10 +1657,8 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
pcdev->platform_flags = pcdev->pdata->flags;
if (!(pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 |
PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10))) {
- /*
- * Platform hasn't set available data widths. This is bad.
- * Warn and use a default.
- */
+ /* Platform hasn't set available data widths. This is bad.
+ * Warn and use a default. */
dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
"data widths, using default 10 bit\n");
pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10;
diff --git a/trunk/drivers/media/video/rj54n1cb0c.c b/trunk/drivers/media/video/rj54n1cb0c.c
index 7e42989ce0e4..373f2a30a677 100644
--- a/trunk/drivers/media/video/rj54n1cb0c.c
+++ b/trunk/drivers/media/video/rj54n1cb0c.c
@@ -13,11 +13,9 @@
#include
#include
-#include
-#include
-#include
#include
#include
+#include
#define RJ54N1_DEV_CODE 0x0400
#define RJ54N1_DEV_CODE2 0x0401
@@ -40,7 +38,6 @@
#define RJ54N1_H_OBEN_OFS 0x0413
#define RJ54N1_V_OBEN_OFS 0x0414
#define RJ54N1_RESIZE_CONTROL 0x0415
-#define RJ54N1_STILL_CONTROL 0x0417
#define RJ54N1_INC_USE_SEL_H 0x0425
#define RJ54N1_INC_USE_SEL_L 0x0426
#define RJ54N1_MIRROR_STILL_MODE 0x0427
@@ -52,21 +49,10 @@
#define RJ54N1_RA_SEL_UL 0x0530
#define RJ54N1_BYTE_SWAP 0x0531
#define RJ54N1_OUT_SIGPO 0x053b
-#define RJ54N1_WB_SEL_WEIGHT_I 0x054e
-#define RJ54N1_BIT8_WB 0x0569
-#define RJ54N1_HCAPS_WB 0x056a
-#define RJ54N1_VCAPS_WB 0x056b
-#define RJ54N1_HCAPE_WB 0x056c
-#define RJ54N1_VCAPE_WB 0x056d
-#define RJ54N1_EXPOSURE_CONTROL 0x058c
#define RJ54N1_FRAME_LENGTH_S_H 0x0595
#define RJ54N1_FRAME_LENGTH_S_L 0x0596
#define RJ54N1_FRAME_LENGTH_P_H 0x0597
#define RJ54N1_FRAME_LENGTH_P_L 0x0598
-#define RJ54N1_PEAK_H 0x05b7
-#define RJ54N1_PEAK_50 0x05b8
-#define RJ54N1_PEAK_60 0x05b9
-#define RJ54N1_PEAK_DIFF 0x05ba
#define RJ54N1_IOC 0x05ef
#define RJ54N1_TG_BYPASS 0x0700
#define RJ54N1_PLL_L 0x0701
@@ -82,7 +68,6 @@
#define RJ54N1_OCLK_SEL_EN 0x0713
#define RJ54N1_CLK_RST 0x0717
#define RJ54N1_RESET_STANDBY 0x0718
-#define RJ54N1_FWFLG 0x07fe
#define E_EXCLK (1 << 7)
#define SOFT_STDBY (1 << 4)
@@ -93,53 +78,29 @@
#define RESIZE_HOLD_SEL (1 << 2)
#define RESIZE_GO (1 << 1)
-/*
- * When cropping, the camera automatically centers the cropped region, there
- * doesn't seem to be a way to specify an explicit location of the rectangle.
- */
#define RJ54N1_COLUMN_SKIP 0
#define RJ54N1_ROW_SKIP 0
#define RJ54N1_MAX_WIDTH 1600
#define RJ54N1_MAX_HEIGHT 1200
-#define PLL_L 2
-#define PLL_N 0x31
-
/* I2C addresses: 0x50, 0x51, 0x60, 0x61 */
-/* RJ54N1CB0C has only one fixed colorspace per pixelcode */
-struct rj54n1_datafmt {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
-};
-
-/* Find a data format by a pixel code in an array */
-static const struct rj54n1_datafmt *rj54n1_find_datafmt(
- enum v4l2_mbus_pixelcode code, const struct rj54n1_datafmt *fmt,
- int n)
-{
- int i;
- for (i = 0; i < n; i++)
- if (fmt[i].code == code)
- return fmt + i;
-
- return NULL;
-}
-
-static const struct rj54n1_datafmt rj54n1_colour_fmts[] = {
- {V4L2_MBUS_FMT_YUYV8_2X8_LE, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_YVYU8_2X8_LE, V4L2_COLORSPACE_JPEG},
- {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB},
- {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
+static const struct soc_camera_data_format rj54n1_colour_formats[] = {
+ {
+ .name = "YUYV",
+ .depth = 16,
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ }, {
+ .name = "RGB565",
+ .depth = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }
};
struct rj54n1_clock_div {
- u8 ratio_tg; /* can be 0 or an odd number */
+ u8 ratio_tg;
u8 ratio_t;
u8 ratio_r;
u8 ratio_op;
@@ -148,14 +109,12 @@ struct rj54n1_clock_div {
struct rj54n1 {
struct v4l2_subdev subdev;
- struct rj54n1_clock_div clk_div;
- const struct rj54n1_datafmt *fmt;
struct v4l2_rect rect; /* Sensor window */
- unsigned int tgclk_mhz;
- bool auto_wb;
unsigned short width; /* Output window */
unsigned short height;
unsigned short resize; /* Sensor * 1024 / resize = Output */
+ struct rj54n1_clock_div clk_div;
+ u32 fourcc;
unsigned short scale;
u8 bank;
};
@@ -212,7 +171,7 @@ const static struct rj54n1_reg_val bank_7[] = {
{0x714, 0xff},
{0x715, 0xff},
{0x716, 0x1f},
- {0x7FE, 2},
+ {0x7FE, 0x02},
};
const static struct rj54n1_reg_val bank_8[] = {
@@ -400,7 +359,7 @@ const static struct rj54n1_reg_val bank_8[] = {
{0x8BB, 0x00},
{0x8BC, 0xFF},
{0x8BD, 0x00},
- {0x8FE, 2},
+ {0x8FE, 0x02},
};
const static struct rj54n1_reg_val bank_10[] = {
@@ -481,22 +440,10 @@ static int reg_write_multiple(struct i2c_client *client,
return 0;
}
-static int rj54n1_enum_fmt(struct v4l2_subdev *sd, int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if ((unsigned int)index >= ARRAY_SIZE(rj54n1_colour_fmts))
- return -EINVAL;
-
- *code = rj54n1_colour_fmts[index].code;
- return 0;
-}
-
static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
{
- struct i2c_client *client = sd->priv;
-
- /* Switch between preview and still shot modes */
- return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80);
+ /* TODO: start / stop streaming */
+ return 0;
}
static int rj54n1_set_bus_param(struct soc_camera_device *icd,
@@ -555,44 +502,6 @@ static int rj54n1_commit(struct i2c_client *client)
return ret;
}
-static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
- u32 *out_w, u32 *out_h);
-
-static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- struct i2c_client *client = sd->priv;
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- struct v4l2_rect *rect = &a->c;
- unsigned int dummy, output_w, output_h,
- input_w = rect->width, input_h = rect->height;
- int ret;
-
- /* arbitrary minimum width and height, edges unimportant */
- soc_camera_limit_side(&dummy, &input_w,
- RJ54N1_COLUMN_SKIP, 8, RJ54N1_MAX_WIDTH);
-
- soc_camera_limit_side(&dummy, &input_h,
- RJ54N1_ROW_SKIP, 8, RJ54N1_MAX_HEIGHT);
-
- output_w = (input_w * 1024 + rj54n1->resize / 2) / rj54n1->resize;
- output_h = (input_h * 1024 + rj54n1->resize / 2) / rj54n1->resize;
-
- dev_dbg(&client->dev, "Scaling for %ux%u : %u = %ux%u\n",
- input_w, input_h, rj54n1->resize, output_w, output_h);
-
- ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
- if (ret < 0)
- return ret;
-
- rj54n1->width = output_w;
- rj54n1->height = output_h;
- rj54n1->resize = ret;
- rj54n1->rect.width = input_w;
- rj54n1->rect.height = input_h;
-
- return 0;
-}
-
static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
struct i2c_client *client = sd->priv;
@@ -618,17 +527,16 @@ static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int rj54n1_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int rj54n1_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct rj54n1 *rj54n1 = to_rj54n1(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- mf->code = rj54n1->fmt->code;
- mf->colorspace = rj54n1->fmt->colorspace;
- mf->field = V4L2_FIELD_NONE;
- mf->width = rj54n1->width;
- mf->height = rj54n1->height;
+ pix->pixelformat = rj54n1->fourcc;
+ pix->field = V4L2_FIELD_NONE;
+ pix->width = rj54n1->width;
+ pix->height = rj54n1->height;
return 0;
}
@@ -642,44 +550,11 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
u32 *out_w, u32 *out_h)
{
struct i2c_client *client = sd->priv;
- struct rj54n1 *rj54n1 = to_rj54n1(client);
unsigned int skip, resize, input_w = *in_w, input_h = *in_h,
output_w = *out_w, output_h = *out_h;
- u16 inc_sel, wb_bit8, wb_left, wb_right, wb_top, wb_bottom;
- unsigned int peak, peak_50, peak_60;
+ u16 inc_sel;
int ret;
- /*
- * We have a problem with crops, where the window is larger than 512x384
- * and output window is larger than a half of the input one. In this
- * case we have to either reduce the input window to equal or below
- * 512x384 or the output window to equal or below 1/2 of the input.
- */
- if (output_w > max(512U, input_w / 2)) {
- if (2 * output_w > RJ54N1_MAX_WIDTH) {
- input_w = RJ54N1_MAX_WIDTH;
- output_w = RJ54N1_MAX_WIDTH / 2;
- } else {
- input_w = output_w * 2;
- }
-
- dev_dbg(&client->dev, "Adjusted output width: in %u, out %u\n",
- input_w, output_w);
- }
-
- if (output_h > max(384U, input_h / 2)) {
- if (2 * output_h > RJ54N1_MAX_HEIGHT) {
- input_h = RJ54N1_MAX_HEIGHT;
- output_h = RJ54N1_MAX_HEIGHT / 2;
- } else {
- input_h = output_h * 2;
- }
-
- dev_dbg(&client->dev, "Adjusted output height: in %u, out %u\n",
- input_h, output_h);
- }
-
- /* Idea: use the read mode for snapshots, handle separate geometries */
ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L,
RJ54N1_Y_OUTPUT_SIZE_S_L,
RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h);
@@ -691,27 +566,17 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
if (ret < 0)
return ret;
- if (output_w > input_w && output_h > input_h) {
+ if (output_w > input_w || output_h > input_h) {
input_w = output_w;
input_h = output_h;
resize = 1024;
} else {
unsigned int resize_x, resize_y;
- resize_x = (input_w * 1024 + output_w / 2) / output_w;
- resize_y = (input_h * 1024 + output_h / 2) / output_h;
-
- /* We want max(resize_x, resize_y), check if it still fits */
- if (resize_x > resize_y &&
- (output_h * resize_x + 512) / 1024 > RJ54N1_MAX_HEIGHT)
- resize = (RJ54N1_MAX_HEIGHT * 1024 + output_h / 2) /
- output_h;
- else if (resize_y > resize_x &&
- (output_w * resize_y + 512) / 1024 > RJ54N1_MAX_WIDTH)
- resize = (RJ54N1_MAX_WIDTH * 1024 + output_w / 2) /
- output_w;
- else
- resize = max(resize_x, resize_y);
+ resize_x = input_w * 1024 / output_w;
+ resize_y = input_h * 1024 / output_h;
+
+ resize = min(resize_x, resize_y);
/* Prohibited value ranges */
switch (resize) {
@@ -724,9 +589,12 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
case 8160 ... 8191:
resize = 8159;
break;
- case 16320 ... 16384:
+ case 16320 ... 16383:
resize = 16319;
}
+
+ input_w = output_w * resize / 1024;
+ input_h = output_h * resize / 1024;
}
/* Set scaling */
@@ -739,18 +607,9 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
/*
* Configure a skipping bitmask. The sensor will select a skipping value
- * among set bits automatically. This is very unclear in the datasheet
- * too. I was told, in this register one enables all skipping values,
- * that are required for a specific resize, and the camera selects
- * automatically, which ones to use. But it is unclear how to identify,
- * which cropping values are needed. Secondly, why don't we just set all
- * bits and let the camera choose? Would it increase processing time and
- * reduce the framerate? Using 0xfffc for INC_USE_SEL doesn't seem to
- * improve the image quality or stability for larger frames (see comment
- * above), but I didn't check the framerate.
+ * among set bits automatically.
*/
skip = min(resize / 1024, (unsigned)15);
-
inc_sel = 1 << skip;
if (inc_sel <= 2)
@@ -762,43 +621,6 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
if (!ret)
ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8);
- if (!rj54n1->auto_wb) {
- /* Auto white balance window */
- wb_left = output_w / 16;
- wb_right = (3 * output_w / 4 - 3) / 4;
- wb_top = output_h / 16;
- wb_bottom = (3 * output_h / 4 - 3) / 4;
- wb_bit8 = ((wb_left >> 2) & 0x40) | ((wb_top >> 4) & 0x10) |
- ((wb_right >> 6) & 4) | ((wb_bottom >> 8) & 1);
-
- if (!ret)
- ret = reg_write(client, RJ54N1_BIT8_WB, wb_bit8);
- if (!ret)
- ret = reg_write(client, RJ54N1_HCAPS_WB, wb_left);
- if (!ret)
- ret = reg_write(client, RJ54N1_VCAPS_WB, wb_top);
- if (!ret)
- ret = reg_write(client, RJ54N1_HCAPE_WB, wb_right);
- if (!ret)
- ret = reg_write(client, RJ54N1_VCAPE_WB, wb_bottom);
- }
-
- /* Antiflicker */
- peak = 12 * RJ54N1_MAX_WIDTH * (1 << 14) * resize / rj54n1->tgclk_mhz /
- 10000;
- peak_50 = peak / 6;
- peak_60 = peak / 5;
-
- if (!ret)
- ret = reg_write(client, RJ54N1_PEAK_H,
- ((peak_50 >> 4) & 0xf0) | (peak_60 >> 8));
- if (!ret)
- ret = reg_write(client, RJ54N1_PEAK_50, peak_50);
- if (!ret)
- ret = reg_write(client, RJ54N1_PEAK_60, peak_60);
- if (!ret)
- ret = reg_write(client, RJ54N1_PEAK_DIFF, peak / 150);
-
/* Start resizing */
if (!ret)
ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
@@ -807,6 +629,8 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
if (ret < 0)
return ret;
+ dev_dbg(&client->dev, "resize %u, skip %u\n", resize, skip);
+
/* Constant taken from manufacturer's example */
msleep(230);
@@ -814,14 +638,11 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
if (ret < 0)
return ret;
- *in_w = (output_w * resize + 512) / 1024;
- *in_h = (output_h * resize + 512) / 1024;
+ *in_w = input_w;
+ *in_h = input_h;
*out_w = output_w;
*out_h = output_h;
- dev_dbg(&client->dev, "Scaled for %ux%u : %u = %ux%u, skip %u\n",
- *in_w, *in_h, resize, output_w, output_h, skip);
-
return resize;
}
@@ -832,14 +653,14 @@ static int rj54n1_set_clock(struct i2c_client *client)
/* Enable external clock */
ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY);
- /* Leave stand-by. Note: use this when implementing suspend / resume */
+ /* Leave stand-by */
if (!ret)
ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK);
if (!ret)
- ret = reg_write(client, RJ54N1_PLL_L, PLL_L);
+ ret = reg_write(client, RJ54N1_PLL_L, 2);
if (!ret)
- ret = reg_write(client, RJ54N1_PLL_N, PLL_N);
+ ret = reg_write(client, RJ54N1_PLL_N, 0x31);
/* TGCLK dividers */
if (!ret)
@@ -898,7 +719,6 @@ static int rj54n1_set_clock(struct i2c_client *client)
"Resetting RJ54N1CB0C clock failed: %d!\n", ret);
return -EIO;
}
-
/* Start the PLL */
ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1);
@@ -911,7 +731,6 @@ static int rj54n1_set_clock(struct i2c_client *client)
static int rj54n1_reg_init(struct i2c_client *client)
{
- struct rj54n1 *rj54n1 = to_rj54n1(client);
int ret = rj54n1_set_clock(client);
if (!ret)
@@ -934,26 +753,14 @@ static int rj54n1_reg_init(struct i2c_client *client)
if (!ret)
ret = reg_write(client, RJ54N1_Y_GAIN, 0x84);
- /*
- * Mirror the image back: default is upside down and left-to-right...
- * Set manual preview / still shot switching
- */
+ /* Mirror the image back: default is upside down and left-to-right... */
if (!ret)
- ret = reg_write(client, RJ54N1_MIRROR_STILL_MODE, 0x27);
+ ret = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 3, 3);
if (!ret)
ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4));
-
- /* Auto exposure area */
if (!ret)
- ret = reg_write(client, RJ54N1_EXPOSURE_CONTROL, 0x80);
- /* Check current auto WB config */
- if (!ret)
- ret = reg_read(client, RJ54N1_WB_SEL_WEIGHT_I);
- if (ret >= 0) {
- rj54n1->auto_wb = ret & 0x80;
ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5));
- }
if (!ret)
ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8));
@@ -970,9 +777,8 @@ static int rj54n1_reg_init(struct i2c_client *client)
ret = reg_write(client, RJ54N1_RESET_STANDBY,
E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX);
- /* Start register update? Same register as 0x?FE in many bank_* sets */
if (!ret)
- ret = reg_write(client, RJ54N1_FWFLG, 2);
+ ret = reg_write(client, 0x7fe, 2);
/* Constant taken from manufacturer's example */
msleep(700);
@@ -980,44 +786,27 @@ static int rj54n1_reg_init(struct i2c_client *client)
return ret;
}
-static int rj54n1_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+/* FIXME: streaming output only up to 800x600 is functional */
+static int rj54n1_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
- struct i2c_client *client = sd->priv;
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- const struct rj54n1_datafmt *fmt;
- int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 ||
- mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE ||
- mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE ||
- mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE ||
- mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE;
-
- dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n",
- __func__, mf->code, mf->width, mf->height);
-
- fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts,
- ARRAY_SIZE(rj54n1_colour_fmts));
- if (!fmt) {
- fmt = rj54n1->fmt;
- mf->code = fmt->code;
- }
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- mf->field = V4L2_FIELD_NONE;
- mf->colorspace = fmt->colorspace;
+ pix->field = V4L2_FIELD_NONE;
- v4l_bound_align_image(&mf->width, 112, RJ54N1_MAX_WIDTH, align,
- &mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0);
+ if (pix->width > 800)
+ pix->width = 800;
+ if (pix->height > 600)
+ pix->height = 600;
return 0;
}
-static int rj54n1_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct rj54n1 *rj54n1 = to_rj54n1(client);
- const struct rj54n1_datafmt *fmt;
- unsigned int output_w, output_h, max_w, max_h,
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ unsigned int output_w, output_h,
input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
int ret;
@@ -1025,13 +814,14 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd,
* The host driver can call us without .try_fmt(), so, we have to take
* care ourseleves
*/
- rj54n1_try_fmt(sd, mf);
+ ret = rj54n1_try_fmt(sd, f);
/*
* Verify if the sensor has just been powered on. TODO: replace this
* with proper PM, when a suitable API is available.
*/
- ret = reg_read(client, RJ54N1_RESET_STANDBY);
+ if (!ret)
+ ret = reg_read(client, RJ54N1_RESET_STANDBY);
if (ret < 0)
return ret;
@@ -1041,105 +831,50 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd,
return ret;
}
- dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n",
- __func__, mf->code, mf->width, mf->height);
-
/* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */
- switch (mf->code) {
- case V4L2_MBUS_FMT_YUYV8_2X8_LE:
+ switch (pix->pixelformat) {
+ case V4L2_PIX_FMT_YUYV:
ret = reg_write(client, RJ54N1_OUT_SEL, 0);
if (!ret)
ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
break;
- case V4L2_MBUS_FMT_YVYU8_2X8_LE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 0);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
- break;
- case V4L2_MBUS_FMT_RGB565_2X8_LE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
- break;
- case V4L2_MBUS_FMT_RGB565_2X8_BE:
+ case V4L2_PIX_FMT_RGB565:
ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
- break;
- case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 4);
if (!ret)
ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
- if (!ret)
- ret = reg_write(client, RJ54N1_RA_SEL_UL, 0);
- break;
- case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 4);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
- if (!ret)
- ret = reg_write(client, RJ54N1_RA_SEL_UL, 8);
- break;
- case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 4);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
- if (!ret)
- ret = reg_write(client, RJ54N1_RA_SEL_UL, 0);
- break;
- case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE:
- ret = reg_write(client, RJ54N1_OUT_SEL, 4);
- if (!ret)
- ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
- if (!ret)
- ret = reg_write(client, RJ54N1_RA_SEL_UL, 8);
- break;
- case V4L2_MBUS_FMT_SBGGR10_1X10:
- ret = reg_write(client, RJ54N1_OUT_SEL, 5);
break;
default:
ret = -EINVAL;
}
- /* Special case: a raw mode with 10 bits of data per clock tick */
- if (!ret)
- ret = reg_set(client, RJ54N1_OCLK_SEL_EN,
- (mf->code == V4L2_MBUS_FMT_SBGGR10_1X10) << 1, 2);
-
if (ret < 0)
return ret;
- /* Supported scales 1:1 >= scale > 1:16 */
- max_w = mf->width * (16 * 1024 - 1) / 1024;
- if (input_w > max_w)
- input_w = max_w;
- max_h = mf->height * (16 * 1024 - 1) / 1024;
- if (input_h > max_h)
- input_h = max_h;
+ /* Supported scales 1:1 - 1:16 */
+ if (pix->width < input_w / 16)
+ pix->width = input_w / 16;
+ if (pix->height < input_h / 16)
+ pix->height = input_h / 16;
- output_w = mf->width;
- output_h = mf->height;
+ output_w = pix->width;
+ output_h = pix->height;
ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
if (ret < 0)
return ret;
- fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts,
- ARRAY_SIZE(rj54n1_colour_fmts));
-
- rj54n1->fmt = fmt;
+ rj54n1->fourcc = pix->pixelformat;
rj54n1->resize = ret;
rj54n1->rect.width = input_w;
rj54n1->rect.height = input_h;
rj54n1->width = output_w;
rj54n1->height = output_h;
- mf->width = output_w;
- mf->height = output_h;
- mf->field = V4L2_FIELD_NONE;
- mf->colorspace = fmt->colorspace;
+ pix->width = output_w;
+ pix->height = output_h;
+ pix->field = V4L2_FIELD_NONE;
- return 0;
+ return ret;
}
static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
@@ -1228,14 +963,6 @@ static const struct v4l2_queryctrl rj54n1_controls[] = {
.step = 1,
.default_value = 66,
.flags = V4L2_CTRL_FLAG_SLIDER,
- }, {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Auto white balance",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
},
};
@@ -1249,7 +976,6 @@ static struct soc_camera_ops rj54n1_ops = {
static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct i2c_client *client = sd->priv;
- struct rj54n1 *rj54n1 = to_rj54n1(client);
int data;
switch (ctrl->id) {
@@ -1272,9 +998,6 @@ static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
ctrl->value = data / 2;
break;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ctrl->value = rj54n1->auto_wb;
- break;
}
return 0;
@@ -1284,7 +1007,6 @@ static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
int data;
struct i2c_client *client = sd->priv;
- struct rj54n1 *rj54n1 = to_rj54n1(client);
const struct v4l2_queryctrl *qctrl;
qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id);
@@ -1315,13 +1037,6 @@ static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0)
return -EIO;
break;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- /* Auto WB area - whole image */
- if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->value << 7,
- 0x80) < 0)
- return -EIO;
- rj54n1->auto_wb = ctrl->value;
- break;
}
return 0;
@@ -1339,12 +1054,10 @@ static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
.s_stream = rj54n1_s_stream,
- .s_mbus_fmt = rj54n1_s_fmt,
- .g_mbus_fmt = rj54n1_g_fmt,
- .try_mbus_fmt = rj54n1_try_fmt,
- .enum_mbus_fmt = rj54n1_enum_fmt,
+ .s_fmt = rj54n1_s_fmt,
+ .g_fmt = rj54n1_g_fmt,
+ .try_fmt = rj54n1_try_fmt,
.g_crop = rj54n1_g_crop,
- .s_crop = rj54n1_s_crop,
.cropcap = rj54n1_cropcap,
};
@@ -1353,13 +1066,21 @@ static struct v4l2_subdev_ops rj54n1_subdev_ops = {
.video = &rj54n1_subdev_video_ops,
};
+static int rj54n1_pin_config(struct i2c_client *client)
+{
+ /*
+ * Experimentally found out IOCTRL wired to 0. TODO: add to platform
+ * data: 0 or 1 << 7.
+ */
+ return reg_write(client, RJ54N1_IOC, 0);
+}
+
/*
* Interface active, can use i2c. If it fails, it can indeed mean, that
* this wasn't our capture interface, so, we wait for the right one
*/
static int rj54n1_video_probe(struct soc_camera_device *icd,
- struct i2c_client *client,
- struct rj54n1_pdata *priv)
+ struct i2c_client *client)
{
int data1, data2;
int ret;
@@ -1380,8 +1101,7 @@ static int rj54n1_video_probe(struct soc_camera_device *icd,
goto ei2c;
}
- /* Configure IOCTL polarity from the platform data: 0 or 1 << 7. */
- ret = reg_write(client, RJ54N1_IOC, priv->ioctl_high << 7);
+ ret = rj54n1_pin_config(client);
if (ret < 0)
goto ei2c;
@@ -1399,7 +1119,6 @@ static int rj54n1_probe(struct i2c_client *client,
struct soc_camera_device *icd = client->dev.platform_data;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct soc_camera_link *icl;
- struct rj54n1_pdata *rj54n1_priv;
int ret;
if (!icd) {
@@ -1408,13 +1127,11 @@ static int rj54n1_probe(struct i2c_client *client,
}
icl = to_soc_camera_link(icd);
- if (!icl || !icl->priv) {
+ if (!icl) {
dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
return -EINVAL;
}
- rj54n1_priv = icl->priv;
-
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_warn(&adapter->dev,
"I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
@@ -1436,12 +1153,10 @@ static int rj54n1_probe(struct i2c_client *client,
rj54n1->rect.height = RJ54N1_MAX_HEIGHT;
rj54n1->width = RJ54N1_MAX_WIDTH;
rj54n1->height = RJ54N1_MAX_HEIGHT;
- rj54n1->fmt = &rj54n1_colour_fmts[0];
+ rj54n1->fourcc = V4L2_PIX_FMT_YUYV;
rj54n1->resize = 1024;
- rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
- (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
- ret = rj54n1_video_probe(icd, client, rj54n1_priv);
+ ret = rj54n1_video_probe(icd, client);
if (ret < 0) {
icd->ops = NULL;
i2c_set_clientdata(client, NULL);
@@ -1449,6 +1164,9 @@ static int rj54n1_probe(struct i2c_client *client,
return ret;
}
+ icd->formats = rj54n1_colour_formats;
+ icd->num_formats = ARRAY_SIZE(rj54n1_colour_formats);
+
return ret;
}
diff --git a/trunk/drivers/media/video/s2255drv.c b/trunk/drivers/media/video/s2255drv.c
index fb742f1ae711..41765f3c7c28 100644
--- a/trunk/drivers/media/video/s2255drv.c
+++ b/trunk/drivers/media/video/s2255drv.c
@@ -233,6 +233,7 @@ struct s2255_dev {
struct s2255_dmaqueue vidq[MAX_CHANNELS];
struct video_device *vdev[MAX_CHANNELS];
+ struct list_head s2255_devlist;
struct timer_list timer;
struct s2255_fw *fw_data;
struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS];
@@ -312,6 +313,8 @@ struct s2255_fh {
/* Channels on box are in reverse order */
static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
+static LIST_HEAD(s2255_devlist);
+
static int debug;
static int *s2255_debug = &debug;
@@ -1530,26 +1533,34 @@ static int vidioc_s_parm(struct file *file, void *priv,
}
static int s2255_open(struct file *file)
{
- struct video_device *vdev = video_devdata(file);
- struct s2255_dev *dev = video_drvdata(file);
+ int minor = video_devdata(file)->minor;
+ struct s2255_dev *h, *dev = NULL;
struct s2255_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ struct list_head *list;
+ enum v4l2_buf_type type = 0;
int i = 0;
int cur_channel = -1;
int state;
-
- dprintk(1, "s2255: open called (dev=%s)\n",
- video_device_node_name(vdev));
+ dprintk(1, "s2255: open called (minor=%d)\n", minor);
lock_kernel();
-
- for (i = 0; i < MAX_CHANNELS; i++) {
- if (dev->vdev[i] == vdev) {
- cur_channel = i;
- break;
+ list_for_each(list, &s2255_devlist) {
+ h = list_entry(list, struct s2255_dev, s2255_devlist);
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (h->vdev[i]->minor == minor) {
+ cur_channel = i;
+ dev = h;
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ }
}
}
+ if ((NULL == dev) || (cur_channel == -1)) {
+ unlock_kernel();
+ printk(KERN_INFO "s2255: openv4l no dev\n");
+ return -ENODEV;
+ }
+
if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_DISCONNECTING) {
unlock_kernel();
printk(KERN_INFO "disconnecting\n");
@@ -1651,9 +1662,8 @@ static int s2255_open(struct file *file)
for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++)
qctl_regs[i] = s2255_qctrl[i].default_value;
- dprintk(1, "s2255drv: open dev=%s type=%s users=%d\n",
- video_device_node_name(vdev), v4l2_type_names[type],
- dev->users[cur_channel]);
+ dprintk(1, "s2255drv: open minor=%d type=%s users=%d\n",
+ minor, v4l2_type_names[type], dev->users[cur_channel]);
dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n",
(unsigned long)fh, (unsigned long)dev,
(unsigned long)&dev->vidq[cur_channel]);
@@ -1689,6 +1699,7 @@ static unsigned int s2255_poll(struct file *file,
static void s2255_destroy(struct kref *kref)
{
struct s2255_dev *dev = to_s2255_dev(kref);
+ struct list_head *list;
int i;
if (!dev) {
printk(KERN_ERR "s2255drv: kref problem\n");
@@ -1722,6 +1733,10 @@ static void s2255_destroy(struct kref *kref)
usb_put_dev(dev->udev);
dprintk(1, "%s", __func__);
+ while (!list_empty(&s2255_devlist)) {
+ list = s2255_devlist.next;
+ list_del(list);
+ }
mutex_unlock(&dev->open_lock);
kfree(dev);
}
@@ -1730,8 +1745,7 @@ static int s2255_close(struct file *file)
{
struct s2255_fh *fh = file->private_data;
struct s2255_dev *dev = fh->dev;
- struct video_device *vdev = video_devdata(file);
-
+ int minor = video_devdata(file)->minor;
if (!dev)
return -ENODEV;
@@ -1751,8 +1765,8 @@ static int s2255_close(struct file *file)
mutex_unlock(&dev->open_lock);
kref_put(&dev->kref, s2255_destroy);
- dprintk(1, "s2255: close called (dev=%s, users=%d)\n",
- video_device_node_name(vdev), dev->users[fh->channel]);
+ dprintk(1, "s2255: close called (minor=%d, users=%d)\n",
+ minor, dev->users[fh->channel]);
kfree(fh);
return 0;
}
@@ -1816,6 +1830,7 @@ static struct video_device template = {
.name = "s2255v",
.fops = &s2255_fops_v4l,
.ioctl_ops = &s2255_ioctl_ops,
+ .minor = -1,
.release = video_device_release,
.tvnorms = S2255_NORMS,
.current_norm = V4L2_STD_NTSC_M,
@@ -1828,6 +1843,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
int cur_nr = video_nr;
/* initialize all video 4 linux */
+ list_add_tail(&dev->s2255_devlist, &s2255_devlist);
/* register 4 video devices */
for (i = 0; i < MAX_CHANNELS; i++) {
INIT_LIST_HEAD(&dev->vidq[i].active);
@@ -1837,7 +1853,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
dev->vdev[i] = video_device_alloc();
memcpy(dev->vdev[i], &template, sizeof(struct video_device));
dev->vdev[i]->parent = &dev->interface->dev;
- video_set_drvdata(dev->vdev[i], dev);
if (video_nr == -1)
ret = video_register_device(dev->vdev[i],
VFL_TYPE_GRABBER,
@@ -1865,7 +1880,7 @@ static void s2255_exit_v4l(struct s2255_dev *dev)
int i;
for (i = 0; i < MAX_CHANNELS; i++) {
- if (video_is_registered(dev->vdev[i])) {
+ if (-1 != dev->vdev[i]->minor) {
video_unregister_device(dev->vdev[i]);
printk(KERN_INFO "s2255 unregistered\n");
} else {
diff --git a/trunk/drivers/media/video/saa5246a.c b/trunk/drivers/media/video/saa5246a.c
index 5ab6a0f901c0..b624a4c01fdc 100644
--- a/trunk/drivers/media/video/saa5246a.c
+++ b/trunk/drivers/media/video/saa5246a.c
@@ -1036,6 +1036,7 @@ static struct video_device saa_template =
.name = "saa5246a",
.fops = &saa_fops,
.release = video_device_release,
+ .minor = -1,
};
static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
diff --git a/trunk/drivers/media/video/saa7134/saa7134-cards.c b/trunk/drivers/media/video/saa7134/saa7134-cards.c
index 03f572708b85..7e40d6d99dd0 100644
--- a/trunk/drivers/media/video/saa7134/saa7134-cards.c
+++ b/trunk/drivers/media/video/saa7134/saa7134-cards.c
@@ -7211,31 +7211,9 @@ int saa7134_board_init2(struct saa7134_dev *dev)
}
case SAA7134_BOARD_FLYDVB_TRIO:
{
- u8 temp = 0;
- int rc;
u8 data[] = { 0x3c, 0x33, 0x62};
struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)};
i2c_transfer(&dev->i2c_adap, &msg, 1);
-
- /*
- * send weak up message to pic16C505 chip
- * @ LifeView FlyDVB Trio
- */
- msg.buf = &temp;
- msg.addr = 0x0b;
- msg.len = 1;
- if (1 != i2c_transfer(&dev->i2c_adap, &msg, 1)) {
- printk(KERN_WARNING "%s: send wake up byte to pic16C505"
- "(IR chip) failed\n", dev->name);
- } else {
- msg.flags = I2C_M_RD;
- rc = i2c_transfer(&dev->i2c_adap, &msg, 1);
- printk(KERN_INFO "%s: probe IR chip @ i2c 0x%02x: %s\n",
- dev->name, msg.addr,
- (1 == rc) ? "yes" : "no");
- if (rc == 1)
- dev->has_remote = SAA7134_REMOTE_I2C;
- }
break;
}
case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
diff --git a/trunk/drivers/media/video/saa7134/saa7134-core.c b/trunk/drivers/media/video/saa7134/saa7134-core.c
index 9f85e917f9f3..0ba7f5af0fc3 100644
--- a/trunk/drivers/media/video/saa7134/saa7134-core.c
+++ b/trunk/drivers/media/video/saa7134/saa7134-core.c
@@ -797,28 +797,27 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,
vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
dev->name, type, saa7134_boards[dev->board].name);
- video_set_drvdata(vfd, dev);
return vfd;
}
static void saa7134_unregister_video(struct saa7134_dev *dev)
{
if (dev->video_dev) {
- if (video_is_registered(dev->video_dev))
+ if (-1 != dev->video_dev->minor)
video_unregister_device(dev->video_dev);
else
video_device_release(dev->video_dev);
dev->video_dev = NULL;
}
if (dev->vbi_dev) {
- if (video_is_registered(dev->vbi_dev))
+ if (-1 != dev->vbi_dev->minor)
video_unregister_device(dev->vbi_dev);
else
video_device_release(dev->vbi_dev);
dev->vbi_dev = NULL;
}
if (dev->radio_dev) {
- if (video_is_registered(dev->radio_dev))
+ if (-1 != dev->radio_dev->minor)
video_unregister_device(dev->radio_dev);
else
video_device_release(dev->radio_dev);
@@ -1047,8 +1046,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
dev->name);
goto fail4;
}
- printk(KERN_INFO "%s: registered device %s [v4l2]\n",
- dev->name, video_device_node_name(dev->video_dev));
+ printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
+ dev->name, dev->video_dev->num);
dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi");
@@ -1056,8 +1055,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
vbi_nr[dev->nr]);
if (err < 0)
goto fail4;
- printk(KERN_INFO "%s: registered device %s\n",
- dev->name, video_device_node_name(dev->vbi_dev));
+ printk(KERN_INFO "%s: registered device vbi%d\n",
+ dev->name, dev->vbi_dev->num);
if (card_has_radio(dev)) {
dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
@@ -1065,8 +1064,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
radio_nr[dev->nr]);
if (err < 0)
goto fail4;
- printk(KERN_INFO "%s: registered device %s\n",
- dev->name, video_device_node_name(dev->radio_dev));
+ printk(KERN_INFO "%s: registered device radio%d\n",
+ dev->name, dev->radio_dev->num);
}
/* everything worked */
diff --git a/trunk/drivers/media/video/saa7134/saa7134-empress.c b/trunk/drivers/media/video/saa7134/saa7134-empress.c
index 7dfecfc6017c..296788c3bf0e 100644
--- a/trunk/drivers/media/video/saa7134/saa7134-empress.c
+++ b/trunk/drivers/media/video/saa7134/saa7134-empress.c
@@ -86,11 +86,19 @@ static int ts_init_encoder(struct saa7134_dev* dev)
static int ts_open(struct file *file)
{
- struct video_device *vdev = video_devdata(file);
- struct saa7134_dev *dev = video_drvdata(file);
+ int minor = video_devdata(file)->minor;
+ struct saa7134_dev *dev;
int err;
- dprintk("open dev=%s\n", video_device_node_name(vdev));
+ lock_kernel();
+ list_for_each_entry(dev, &saa7134_devlist, devlist)
+ if (dev->empress_dev && dev->empress_dev->minor == minor)
+ goto found;
+ unlock_kernel();
+ return -ENODEV;
+ found:
+
+ dprintk("open minor=%d\n",minor);
err = -EBUSY;
if (!mutex_trylock(&dev->empress_tsq.vb_lock))
goto done;
@@ -481,6 +489,7 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = {
static struct video_device saa7134_empress_template = {
.name = "saa7134-empress",
.fops = &ts_fops,
+ .minor = -1,
.ioctl_ops = &ts_ioctl_ops,
.tvnorms = SAA7134_NORMS,
@@ -522,7 +531,6 @@ static int empress_init(struct saa7134_dev *dev)
INIT_WORK(&dev->empress_workqueue, empress_signal_update);
- video_set_drvdata(dev->empress_dev, dev);
err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
empress_nr[dev->nr]);
if (err < 0) {
@@ -532,8 +540,8 @@ static int empress_init(struct saa7134_dev *dev)
dev->empress_dev = NULL;
return err;
}
- printk(KERN_INFO "%s: registered device %s [mpeg]\n",
- dev->name, video_device_node_name(dev->empress_dev));
+ printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
+ dev->name, dev->empress_dev->num);
videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops,
&dev->pci->dev, &dev->slock,
diff --git a/trunk/drivers/media/video/saa7134/saa7134-input.c b/trunk/drivers/media/video/saa7134/saa7134-input.c
index f8e985989ca0..744918b1cd47 100644
--- a/trunk/drivers/media/video/saa7134/saa7134-input.c
+++ b/trunk/drivers/media/video/saa7134/saa7134-input.c
@@ -127,61 +127,6 @@ static int build_key(struct saa7134_dev *dev)
/* --------------------- Chip specific I2C key builders ----------------- */
-static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- int gpio;
- int attempt = 0;
- unsigned char b;
-
- /* We need this to access GPI Used by the saa_readl macro. */
- struct saa7134_dev *dev = ir->c->adapter->algo_data;
-
- if (dev == NULL) {
- dprintk("get_key_flydvb_trio: "
- "gir->c->adapter->algo_data is NULL!\n");
- return -EIO;
- }
-
- /* rising SAA7134_GPIGPRESCAN reads the status */
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-
- gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
-
- if (0x40000 & ~gpio)
- return 0; /* No button press */
-
- /* No button press - only before first key pressed */
- if (b == 0xFF)
- return 0;
-
- /* poll IR chip */
- /* weak up the IR chip */
- b = 0;
-
- while (1 != i2c_master_send(ir->c, &b, 1)) {
- if ((attempt++) < 10) {
- /*
- * wait a bit for next attempt -
- * I don't know how make it better
- */
- msleep(10);
- continue;
- }
- i2cdprintk("send wake up byte to pic16C505 (IR chip)"
- "failed %dx\n", attempt);
- return -EIO;
- }
- if (1 != i2c_master_recv(ir->c, &b, 1)) {
- i2cdprintk("read error\n");
- return -EIO;
- }
-
- *ir_key = b;
- *ir_raw = b;
- return 1;
-}
-
static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
u32 *ir_raw)
{
@@ -677,7 +622,6 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keyup = 0x020000;
polling = 50; /* ms */
break;
- break;
}
if (NULL == ir_codes) {
printk("%s: Oops: IR config error [card=%d]\n",
@@ -708,7 +652,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(dev->pci));
- err = ir_input_init(input_dev, &ir->ir, ir_type);
+ err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
if (err < 0)
goto err_out_free;
@@ -728,7 +672,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
dev->remote = ir;
saa7134_ir_start(dev, ir);
- err = ir_input_register(ir->dev, ir_codes);
+ err = input_register_device(ir->dev);
if (err)
goto err_out_stop;
@@ -742,6 +686,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
saa7134_ir_stop(dev);
dev->remote = NULL;
err_out_free:
+ ir_input_free(input_dev);
+ input_free_device(input_dev);
kfree(ir);
return err;
}
@@ -752,7 +698,8 @@ void saa7134_input_fini(struct saa7134_dev *dev)
return;
saa7134_ir_stop(dev);
- ir_input_unregister(dev->remote->dev);
+ ir_input_free(dev->remote->dev);
+ input_unregister_device(dev->remote->dev);
kfree(dev->remote);
dev->remote = NULL;
}
@@ -841,12 +788,6 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
info.addr = 0x40;
break;
- case SAA7134_BOARD_FLYDVB_TRIO:
- dev->init_data.name = "FlyDVB Trio";
- dev->init_data.get_key = get_key_flydvb_trio;
- dev->init_data.ir_codes = &ir_codes_flydvb_table;
- info.addr = 0x0b;
- break;
default:
dprintk("No I2C IR support for board %x\n", dev->board);
return;
diff --git a/trunk/drivers/media/video/saa7134/saa7134-video.c b/trunk/drivers/media/video/saa7134/saa7134-video.c
index cb732640ac4a..35f8daa3a359 100644
--- a/trunk/drivers/media/video/saa7134/saa7134-video.c
+++ b/trunk/drivers/media/video/saa7134/saa7134-video.c
@@ -1326,26 +1326,33 @@ static int saa7134_resource(struct saa7134_fh *fh)
static int video_open(struct file *file)
{
- struct video_device *vdev = video_devdata(file);
- struct saa7134_dev *dev = video_drvdata(file);
+ int minor = video_devdata(file)->minor;
+ struct saa7134_dev *dev;
struct saa7134_fh *fh;
- enum v4l2_buf_type type = 0;
+ enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
int radio = 0;
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
+ mutex_lock(&saa7134_devlist_lock);
+ list_for_each_entry(dev, &saa7134_devlist, devlist) {
+ if (dev->video_dev && (dev->video_dev->minor == minor))
+ goto found;
+ if (dev->radio_dev && (dev->radio_dev->minor == minor)) {
+ radio = 1;
+ goto found;
+ }
+ if (dev->vbi_dev && (dev->vbi_dev->minor == minor)) {
+ type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ goto found;
+ }
}
+ mutex_unlock(&saa7134_devlist_lock);
+ return -ENODEV;
+
+found:
+ mutex_unlock(&saa7134_devlist_lock);
- dprintk("open dev=%s radio=%d type=%s\n", video_device_node_name(vdev),
- radio, v4l2_type_names[type]);
+ dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
+ v4l2_type_names[type]);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh),GFP_KERNEL);
@@ -2495,6 +2502,7 @@ struct video_device saa7134_video_template = {
.name = "saa7134-video",
.fops = &video_fops,
.ioctl_ops = &video_ioctl_ops,
+ .minor = -1,
.tvnorms = SAA7134_NORMS,
.current_norm = V4L2_STD_PAL,
};
@@ -2503,6 +2511,7 @@ struct video_device saa7134_radio_template = {
.name = "saa7134-radio",
.fops = &radio_fops,
.ioctl_ops = &radio_ioctl_ops,
+ .minor = -1,
};
int saa7134_video_init1(struct saa7134_dev *dev)
diff --git a/trunk/drivers/media/video/se401.c b/trunk/drivers/media/video/se401.c
index 41d0166c0f95..85ffc2cba039 100644
--- a/trunk/drivers/media/video/se401.c
+++ b/trunk/drivers/media/video/se401.c
@@ -1428,8 +1428,8 @@ static int se401_probe(struct usb_interface *intf,
err("video_register_device failed");
return -EIO;
}
- dev_info(&intf->dev, "registered new video device: %s\n",
- video_device_node_name(&se401->vdev));
+ dev_info(&intf->dev, "registered new video device: video%d\n",
+ se401->vdev.num);
usb_set_intfdata(intf, se401);
return 0;
diff --git a/trunk/drivers/media/video/sh_mobile_ceu_camera.c b/trunk/drivers/media/video/sh_mobile_ceu_camera.c
index d69363f0d8c9..961e4484d721 100644
--- a/trunk/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/trunk/drivers/media/video/sh_mobile_ceu_camera.c
@@ -38,8 +38,6 @@
#include
#include
#include
-#include
-#include
/* register offsets for sh7722 / sh7723 */
@@ -87,7 +85,7 @@
/* per video frame buffer */
struct sh_mobile_ceu_buffer {
struct videobuf_buffer vb; /* v4l buffer must be first */
- enum v4l2_mbus_pixelcode code;
+ const struct soc_camera_data_format *fmt;
};
struct sh_mobile_ceu_dev {
@@ -107,8 +105,7 @@ struct sh_mobile_ceu_dev {
u32 cflcr;
- enum v4l2_field field;
-
+ unsigned int is_interlaced:1;
unsigned int image_mode:1;
unsigned int is_16bit:1;
};
@@ -117,8 +114,8 @@ struct sh_mobile_ceu_cam {
struct v4l2_rect ceu_rect;
unsigned int cam_width;
unsigned int cam_height;
- const struct soc_mbus_pixelfmt *extra_fmt;
- enum v4l2_mbus_pixelcode code;
+ const struct soc_camera_data_format *extra_fmt;
+ const struct soc_camera_data_format *camera_fmt;
};
static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
@@ -200,19 +197,16 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
struct soc_camera_device *icd = vq->priv_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
- int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
- icd->current_fmt->host_fmt);
-
- if (bytes_per_line < 0)
- return bytes_per_line;
+ int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
- *size = bytes_per_line * icd->user_height;
+ *size = PAGE_ALIGN(icd->user_width * icd->user_height *
+ bytes_per_pixel);
if (0 == *count)
*count = 2;
if (pcdev->video_limit) {
- while (PAGE_ALIGN(*size) * *count > pcdev->video_limit)
+ while (*size * *count > pcdev->video_limit)
(*count)--;
}
@@ -255,13 +249,10 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
{
struct soc_camera_device *icd = pcdev->icd;
dma_addr_t phys_addr_top, phys_addr_bottom;
- unsigned long top1, top2;
- unsigned long bottom1, bottom2;
u32 status;
int ret = 0;
- /*
- * The hardware is _very_ picky about this sequence. Especially
+ /* The hardware is _very_ picky about this sequence. Especially
* the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
* several not-so-well documented interrupt sources in CETCR.
*/
@@ -285,36 +276,25 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
if (!pcdev->active)
return ret;
- if (V4L2_FIELD_INTERLACED_BT == pcdev->field) {
- top1 = CDBYR;
- top2 = CDBCR;
- bottom1 = CDAYR;
- bottom2 = CDACR;
- } else {
- top1 = CDAYR;
- top2 = CDACR;
- bottom1 = CDBYR;
- bottom2 = CDBCR;
- }
-
phys_addr_top = videobuf_to_dma_contig(pcdev->active);
- ceu_write(pcdev, top1, phys_addr_top);
- if (V4L2_FIELD_NONE != pcdev->field) {
+ ceu_write(pcdev, CDAYR, phys_addr_top);
+ if (pcdev->is_interlaced) {
phys_addr_bottom = phys_addr_top + icd->user_width;
- ceu_write(pcdev, bottom1, phys_addr_bottom);
+ ceu_write(pcdev, CDBYR, phys_addr_bottom);
}
- switch (icd->current_fmt->host_fmt->fourcc) {
+ switch (icd->current_fmt->fourcc) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61:
phys_addr_top += icd->user_width *
icd->user_height;
- ceu_write(pcdev, top2, phys_addr_top);
- if (V4L2_FIELD_NONE != pcdev->field) {
- phys_addr_bottom = phys_addr_top + icd->user_width;
- ceu_write(pcdev, bottom2, phys_addr_bottom);
+ ceu_write(pcdev, CDACR, phys_addr_top);
+ if (pcdev->is_interlaced) {
+ phys_addr_bottom = phys_addr_top +
+ icd->user_width;
+ ceu_write(pcdev, CDBCR, phys_addr_bottom);
}
}
@@ -330,13 +310,8 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
{
struct soc_camera_device *icd = vq->priv_data;
struct sh_mobile_ceu_buffer *buf;
- int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
- icd->current_fmt->host_fmt);
int ret;
- if (bytes_per_line < 0)
- return bytes_per_line;
-
buf = container_of(vb, struct sh_mobile_ceu_buffer, vb);
dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
@@ -346,27 +321,25 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
WARN_ON(!list_empty(&vb->queue));
#ifdef DEBUG
- /*
- * This can be useful if you want to see if we actually fill
- * the buffer with something
- */
+ /* This can be useful if you want to see if we actually fill
+ * the buffer with something */
memset((void *)vb->baddr, 0xaa, vb->bsize);
#endif
BUG_ON(NULL == icd->current_fmt);
- if (buf->code != icd->current_fmt->code ||
+ if (buf->fmt != icd->current_fmt ||
vb->width != icd->user_width ||
vb->height != icd->user_height ||
vb->field != field) {
- buf->code = icd->current_fmt->code;
+ buf->fmt = icd->current_fmt;
vb->width = icd->user_width;
vb->height = icd->user_height;
vb->field = field;
vb->state = VIDEOBUF_NEEDS_INIT;
}
- vb->size = vb->height * bytes_per_line;
+ vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
if (0 != vb->baddr && vb->bsize < vb->size) {
ret = -EINVAL;
goto out;
@@ -483,7 +456,6 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
- int ret;
if (pcdev->icd)
return -EBUSY;
@@ -494,11 +466,9 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
pm_runtime_get_sync(ici->v4l2_dev.dev);
- ret = sh_mobile_ceu_soft_reset(pcdev);
- if (!ret)
- pcdev->icd = icd;
+ pcdev->icd = icd;
- return ret;
+ return sh_mobile_ceu_soft_reset(pcdev);
}
/* Called with .video_lock held */
@@ -588,35 +558,24 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd,
in_width *= 2;
left_offset *= 2;
}
- width = out_width;
- cdwdr_width = out_width;
+ width = cdwdr_width = out_width;
} else {
- int bytes_per_line = soc_mbus_bytes_per_line(out_width,
- icd->current_fmt->host_fmt);
- unsigned int w_factor;
+ unsigned int w_factor = (icd->current_fmt->depth + 7) >> 3;
- width = out_width;
+ width = out_width * w_factor / 2;
- switch (icd->current_fmt->host_fmt->packing) {
- case SOC_MBUS_PACKING_2X8_PADHI:
- w_factor = 2;
- break;
- default:
- w_factor = 1;
- }
+ if (!pcdev->is_16bit)
+ w_factor *= 2;
- in_width = rect->width * w_factor;
- left_offset = left_offset * w_factor;
+ in_width = rect->width * w_factor / 2;
+ left_offset = left_offset * w_factor / 2;
- if (bytes_per_line < 0)
- cdwdr_width = out_width;
- else
- cdwdr_width = bytes_per_line;
+ cdwdr_width = width * 2;
}
height = out_height;
in_height = rect->height;
- if (V4L2_FIELD_NONE != pcdev->field) {
+ if (pcdev->is_interlaced) {
height /= 2;
in_height /= 2;
top_offset /= 2;
@@ -687,23 +646,6 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
if (!common_flags)
return -EINVAL;
- /* Make choises, based on platform preferences */
- if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
- (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
- if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
- common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
- else
- common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
- }
-
- if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
- (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
- if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
- common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
- else
- common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
- }
-
ret = icd->ops->set_bus_param(icd, common_flags);
if (ret < 0)
return ret;
@@ -725,24 +667,24 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
value = 0x00000010; /* data fetch by default */
yuv_lineskip = 0;
- switch (icd->current_fmt->host_fmt->fourcc) {
+ switch (icd->current_fmt->fourcc) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */
/* fall-through */
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61:
- switch (cam->code) {
- case V4L2_MBUS_FMT_YUYV8_2X8_BE:
+ switch (cam->camera_fmt->fourcc) {
+ case V4L2_PIX_FMT_UYVY:
value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */
break;
- case V4L2_MBUS_FMT_YVYU8_2X8_BE:
+ case V4L2_PIX_FMT_VYUY:
value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */
break;
- case V4L2_MBUS_FMT_YUYV8_2X8_LE:
+ case V4L2_PIX_FMT_YUYV:
value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */
break;
- case V4L2_MBUS_FMT_YVYU8_2X8_LE:
+ case V4L2_PIX_FMT_YVYU:
value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */
break;
default:
@@ -750,8 +692,8 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
}
}
- if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV21 ||
- icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61)
+ if (icd->current_fmt->fourcc == V4L2_PIX_FMT_NV21 ||
+ icd->current_fmt->fourcc == V4L2_PIX_FMT_NV61)
value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
@@ -760,27 +702,14 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
ceu_write(pcdev, CAMCR, value);
ceu_write(pcdev, CAPCR, 0x00300000);
-
- switch (pcdev->field) {
- case V4L2_FIELD_INTERLACED_TB:
- value = 0x101;
- break;
- case V4L2_FIELD_INTERLACED_BT:
- value = 0x102;
- break;
- default:
- value = 0;
- break;
- }
- ceu_write(pcdev, CAIFR, value);
+ ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0);
sh_mobile_ceu_set_rect(icd, icd->user_width, icd->user_height);
mdelay(1);
ceu_write(pcdev, CFLCR, pcdev->cflcr);
- /*
- * A few words about byte order (observed in Big Endian mode)
+ /* A few words about byte order (observed in Big Endian mode)
*
* In data fetch mode bytes are received in chunks of 8 bytes.
* D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first)
@@ -810,8 +739,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
return 0;
}
-static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
- unsigned char buswidth)
+static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
@@ -820,75 +748,48 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
camera_flags = icd->ops->query_bus_param(icd);
common_flags = soc_camera_bus_param_compatible(camera_flags,
make_bus_param(pcdev));
- if (!common_flags || buswidth > 16 ||
- (buswidth > 8 && !(common_flags & SOCAM_DATAWIDTH_16)))
+ if (!common_flags)
return -EINVAL;
return 0;
}
-static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = {
+static const struct soc_camera_data_format sh_mobile_ceu_formats[] = {
+ {
+ .name = "NV12",
+ .depth = 12,
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ .name = "NV21",
+ .depth = 12,
+ .fourcc = V4L2_PIX_FMT_NV21,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ .name = "NV16",
+ .depth = 16,
+ .fourcc = V4L2_PIX_FMT_NV16,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
{
- .fourcc = V4L2_PIX_FMT_NV12,
- .name = "NV12",
- .bits_per_sample = 12,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- }, {
- .fourcc = V4L2_PIX_FMT_NV21,
- .name = "NV21",
- .bits_per_sample = 12,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- }, {
- .fourcc = V4L2_PIX_FMT_NV16,
- .name = "NV16",
- .bits_per_sample = 16,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- }, {
- .fourcc = V4L2_PIX_FMT_NV61,
- .name = "NV61",
- .bits_per_sample = 16,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
+ .name = "NV61",
+ .depth = 16,
+ .fourcc = V4L2_PIX_FMT_NV61,
+ .colorspace = V4L2_COLORSPACE_JPEG,
},
};
-/* This will be corrected as we get more formats */
-static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
-{
- return fmt->packing == SOC_MBUS_PACKING_NONE ||
- (fmt->bits_per_sample == 8 &&
- fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
- (fmt->bits_per_sample > 8 &&
- fmt->packing == SOC_MBUS_PACKING_EXTEND16);
-}
-
static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
struct soc_camera_format_xlate *xlate)
{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct device *dev = icd->dev.parent;
int ret, k, n;
int formats = 0;
struct sh_mobile_ceu_cam *cam;
- enum v4l2_mbus_pixelcode code;
- const struct soc_mbus_pixelfmt *fmt;
- ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
- if (ret < 0)
- /* No more formats */
- return 0;
-
- fmt = soc_mbus_get_fmtdesc(code);
- if (!fmt) {
- dev_err(icd->dev.parent,
- "Invalid format code #%d: %d\n", idx, code);
- return -EINVAL;
- }
-
- ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
+ ret = sh_mobile_ceu_try_bus_param(icd);
if (ret < 0)
return 0;
@@ -906,13 +807,13 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
if (!idx)
cam->extra_fmt = NULL;
- switch (code) {
- case V4L2_MBUS_FMT_YUYV8_2X8_BE:
- case V4L2_MBUS_FMT_YVYU8_2X8_BE:
- case V4L2_MBUS_FMT_YUYV8_2X8_LE:
- case V4L2_MBUS_FMT_YVYU8_2X8_LE:
+ switch (icd->formats[idx].fourcc) {
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_VYUY:
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_YVYU:
if (cam->extra_fmt)
- break;
+ goto add_single_format;
/*
* Our case is simple so far: for any of the above four camera
@@ -923,31 +824,32 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
* the host_priv pointer and check whether the format you're
* going to add now is already there.
*/
- cam->extra_fmt = sh_mobile_ceu_formats;
+ cam->extra_fmt = (void *)sh_mobile_ceu_formats;
n = ARRAY_SIZE(sh_mobile_ceu_formats);
formats += n;
for (k = 0; xlate && k < n; k++) {
- xlate->host_fmt = &sh_mobile_ceu_formats[k];
- xlate->code = code;
+ xlate->host_fmt = &sh_mobile_ceu_formats[k];
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = icd->formats[idx].depth;
xlate++;
- dev_dbg(dev, "Providing format %s using code %d\n",
- sh_mobile_ceu_formats[k].name, code);
+ dev_dbg(dev, "Providing format %s using %s\n",
+ sh_mobile_ceu_formats[k].name,
+ icd->formats[idx].name);
}
- break;
default:
- if (!sh_mobile_ceu_packing_supported(fmt))
- return 0;
- }
-
- /* Generic pass-through */
- formats++;
- if (xlate) {
- xlate->host_fmt = fmt;
- xlate->code = code;
- xlate++;
- dev_dbg(dev, "Providing format %s in pass-through mode\n",
- xlate->host_fmt->name);
+add_single_format:
+ /* Generic pass-through */
+ formats++;
+ if (xlate) {
+ xlate->host_fmt = icd->formats + idx;
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = icd->formats[idx].depth;
+ xlate++;
+ dev_dbg(dev,
+ "Providing format %s in pass-through mode\n",
+ icd->formats[idx].name);
+ }
}
return formats;
@@ -1127,15 +1029,17 @@ static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop,
static int get_camera_scales(struct v4l2_subdev *sd, struct v4l2_rect *rect,
unsigned int *scale_h, unsigned int *scale_v)
{
- struct v4l2_mbus_framefmt mf;
+ struct v4l2_format f;
int ret;
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
+ f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ ret = v4l2_subdev_call(sd, video, g_fmt, &f);
if (ret < 0)
return ret;
- *scale_h = calc_generic_scale(rect->width, mf.width);
- *scale_v = calc_generic_scale(rect->height, mf.height);
+ *scale_h = calc_generic_scale(rect->width, f.fmt.pix.width);
+ *scale_v = calc_generic_scale(rect->height, f.fmt.pix.height);
return 0;
}
@@ -1150,29 +1054,32 @@ static int get_camera_subwin(struct soc_camera_device *icd,
if (!ceu_rect->width) {
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct device *dev = icd->dev.parent;
- struct v4l2_mbus_framefmt mf;
+ struct v4l2_format f;
+ struct v4l2_pix_format *pix = &f.fmt.pix;
int ret;
/* First time */
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
+ f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ ret = v4l2_subdev_call(sd, video, g_fmt, &f);
if (ret < 0)
return ret;
- dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height);
+ dev_geo(dev, "camera fmt %ux%u\n", pix->width, pix->height);
- if (mf.width > 2560) {
+ if (pix->width > 2560) {
ceu_rect->width = 2560;
- ceu_rect->left = (mf.width - 2560) / 2;
+ ceu_rect->left = (pix->width - 2560) / 2;
} else {
- ceu_rect->width = mf.width;
+ ceu_rect->width = pix->width;
ceu_rect->left = 0;
}
- if (mf.height > 1920) {
+ if (pix->height > 1920) {
ceu_rect->height = 1920;
- ceu_rect->top = (mf.height - 1920) / 2;
+ ceu_rect->top = (pix->height - 1920) / 2;
} else {
- ceu_rect->height = mf.height;
+ ceu_rect->height = pix->height;
ceu_rect->top = 0;
}
@@ -1189,12 +1096,13 @@ static int get_camera_subwin(struct soc_camera_device *icd,
return 0;
}
-static int client_s_fmt(struct soc_camera_device *icd,
- struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
+static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f,
+ bool ceu_can_scale)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct device *dev = icd->dev.parent;
- unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ unsigned int width = pix->width, height = pix->height, tmp_w, tmp_h;
unsigned int max_width, max_height;
struct v4l2_cropcap cap;
int ret;
@@ -1208,29 +1116,29 @@ static int client_s_fmt(struct soc_camera_device *icd,
max_width = min(cap.bounds.width, 2560);
max_height = min(cap.bounds.height, 1920);
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf);
+ ret = v4l2_subdev_call(sd, video, s_fmt, f);
if (ret < 0)
return ret;
- dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
+ dev_geo(dev, "camera scaled to %ux%u\n", pix->width, pix->height);
- if ((width == mf->width && height == mf->height) || !ceu_can_scale)
+ if ((width == pix->width && height == pix->height) || !ceu_can_scale)
return 0;
/* Camera set a format, but geometry is not precise, try to improve */
- tmp_w = mf->width;
- tmp_h = mf->height;
+ tmp_w = pix->width;
+ tmp_h = pix->height;
/* width <= max_width && height <= max_height - guaranteed by try_fmt */
while ((width > tmp_w || height > tmp_h) &&
tmp_w < max_width && tmp_h < max_height) {
tmp_w = min(2 * tmp_w, max_width);
tmp_h = min(2 * tmp_h, max_height);
- mf->width = tmp_w;
- mf->height = tmp_h;
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf);
+ pix->width = tmp_w;
+ pix->height = tmp_h;
+ ret = v4l2_subdev_call(sd, video, s_fmt, f);
dev_geo(dev, "Camera scaled to %ux%u\n",
- mf->width, mf->height);
+ pix->width, pix->height);
if (ret < 0) {
/* This shouldn't happen */
dev_err(dev, "Client failed to set format: %d\n", ret);
@@ -1248,26 +1156,27 @@ static int client_s_fmt(struct soc_camera_device *icd,
*/
static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect,
struct v4l2_rect *sub_rect, struct v4l2_rect *ceu_rect,
- struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
+ struct v4l2_format *f, bool ceu_can_scale)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct sh_mobile_ceu_cam *cam = icd->host_priv;
struct device *dev = icd->dev.parent;
- struct v4l2_mbus_framefmt mf_tmp = *mf;
+ struct v4l2_format f_tmp = *f;
+ struct v4l2_pix_format *pix_tmp = &f_tmp.fmt.pix;
unsigned int scale_h, scale_v;
int ret;
/* 5. Apply iterative camera S_FMT for camera user window. */
- ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale);
+ ret = client_s_fmt(icd, &f_tmp, ceu_can_scale);
if (ret < 0)
return ret;
dev_geo(dev, "5: camera scaled to %ux%u\n",
- mf_tmp.width, mf_tmp.height);
+ pix_tmp->width, pix_tmp->height);
/* 6. Retrieve camera output window (g_fmt) */
- /* unneeded - it is already in "mf_tmp" */
+ /* unneeded - it is already in "f_tmp" */
/* 7. Calculate new camera scales. */
ret = get_camera_scales(sd, rect, &scale_h, &scale_v);
@@ -1276,11 +1185,10 @@ static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect,
dev_geo(dev, "7: camera scales %u:%u\n", scale_h, scale_v);
- cam->cam_width = mf_tmp.width;
- cam->cam_height = mf_tmp.height;
- mf->width = mf_tmp.width;
- mf->height = mf_tmp.height;
- mf->colorspace = mf_tmp.colorspace;
+ cam->cam_width = pix_tmp->width;
+ cam->cam_height = pix_tmp->height;
+ f->fmt.pix.width = pix_tmp->width;
+ f->fmt.pix.height = pix_tmp->height;
/*
* 8. Calculate new CEU crop - apply camera scales to previously
@@ -1344,7 +1252,8 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
struct v4l2_rect *cam_rect = &cam_crop.c, *ceu_rect = &cam->ceu_rect;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct device *dev = icd->dev.parent;
- struct v4l2_mbus_framefmt mf;
+ struct v4l2_format f;
+ struct v4l2_pix_format *pix = &f.fmt.pix;
unsigned int scale_comb_h, scale_comb_v, scale_ceu_h, scale_ceu_v,
out_width, out_height;
u32 capsr, cflcr;
@@ -1393,25 +1302,26 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
* 5. Using actual input window and calculated combined scales calculate
* camera target output window.
*/
- mf.width = scale_down(cam_rect->width, scale_comb_h);
- mf.height = scale_down(cam_rect->height, scale_comb_v);
+ pix->width = scale_down(cam_rect->width, scale_comb_h);
+ pix->height = scale_down(cam_rect->height, scale_comb_v);
- dev_geo(dev, "5: camera target %ux%u\n", mf.width, mf.height);
+ dev_geo(dev, "5: camera target %ux%u\n", pix->width, pix->height);
/* 6. - 9. */
- mf.code = cam->code;
- mf.field = pcdev->field;
+ pix->pixelformat = cam->camera_fmt->fourcc;
+ pix->colorspace = cam->camera_fmt->colorspace;
capsr = capture_save_reset(pcdev);
dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
/* Make relative to camera rectangle */
- rect->left -= cam_rect->left;
- rect->top -= cam_rect->top;
+ rect->left -= cam_rect->left;
+ rect->top -= cam_rect->top;
- ret = client_scale(icd, cam_rect, rect, ceu_rect, &mf,
- pcdev->image_mode &&
- V4L2_FIELD_NONE == pcdev->field);
+ f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ ret = client_scale(icd, cam_rect, rect, ceu_rect, &f,
+ pcdev->image_mode && !pcdev->is_interlaced);
dev_geo(dev, "6-9: %d\n", ret);
@@ -1458,7 +1368,8 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
struct sh_mobile_ceu_dev *pcdev = ici->priv;
struct sh_mobile_ceu_cam *cam = icd->host_priv;
struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
+ struct v4l2_format cam_f = *f;
+ struct v4l2_pix_format *cam_pix = &cam_f.fmt.pix;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct device *dev = icd->dev.parent;
__u32 pixfmt = pix->pixelformat;
@@ -1468,20 +1379,18 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
unsigned int scale_cam_h, scale_cam_v;
u16 scale_v, scale_h;
int ret;
- bool image_mode;
- enum v4l2_field field;
+ bool is_interlaced, image_mode;
switch (pix->field) {
+ case V4L2_FIELD_INTERLACED:
+ is_interlaced = true;
+ break;
+ case V4L2_FIELD_ANY:
default:
pix->field = V4L2_FIELD_NONE;
/* fall-through */
- case V4L2_FIELD_INTERLACED_TB:
- case V4L2_FIELD_INTERLACED_BT:
case V4L2_FIELD_NONE:
- field = pix->field;
- break;
- case V4L2_FIELD_INTERLACED:
- field = V4L2_FIELD_INTERLACED_TB;
+ is_interlaced = false;
break;
}
@@ -1529,11 +1438,9 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
* 4. Calculate camera output window by applying combined scales to real
* input window.
*/
- mf.width = scale_down(cam_rect->width, scale_h);
- mf.height = scale_down(cam_rect->height, scale_v);
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
+ cam_pix->width = scale_down(cam_rect->width, scale_h);
+ cam_pix->height = scale_down(cam_rect->height, scale_v);
+ cam_pix->pixelformat = xlate->cam_fmt->fourcc;
switch (pixfmt) {
case V4L2_PIX_FMT_NV12:
@@ -1546,61 +1453,51 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
image_mode = false;
}
- dev_geo(dev, "4: camera output %ux%u\n", mf.width, mf.height);
+ dev_geo(dev, "4: camera output %ux%u\n",
+ cam_pix->width, cam_pix->height);
/* 5. - 9. */
- ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &mf,
- image_mode && V4L2_FIELD_NONE == field);
+ ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &cam_f,
+ image_mode && !is_interlaced);
dev_geo(dev, "5-9: client scale %d\n", ret);
/* Done with the camera. Now see if we can improve the result */
dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
- ret, mf.width, mf.height, pix->width, pix->height);
+ ret, cam_pix->width, cam_pix->height, pix->width, pix->height);
if (ret < 0)
return ret;
- if (mf.code != xlate->code)
- return -EINVAL;
-
/* 10. Use CEU scaling to scale to the requested user window. */
/* We cannot scale up */
- if (pix->width > mf.width)
- pix->width = mf.width;
+ if (pix->width > cam_pix->width)
+ pix->width = cam_pix->width;
if (pix->width > ceu_rect.width)
pix->width = ceu_rect.width;
- if (pix->height > mf.height)
- pix->height = mf.height;
+ if (pix->height > cam_pix->height)
+ pix->height = cam_pix->height;
if (pix->height > ceu_rect.height)
pix->height = ceu_rect.height;
- pix->colorspace = mf.colorspace;
-
- if (image_mode) {
- /* Scale pix->{width x height} down to width x height */
- scale_h = calc_scale(ceu_rect.width, &pix->width);
- scale_v = calc_scale(ceu_rect.height, &pix->height);
-
- pcdev->cflcr = scale_h | (scale_v << 16);
- } else {
- pix->width = ceu_rect.width;
- pix->height = ceu_rect.height;
- scale_h = scale_v = 0;
- pcdev->cflcr = 0;
- }
+ /* Let's rock: scale pix->{width x height} down to width x height */
+ scale_h = calc_scale(ceu_rect.width, &pix->width);
+ scale_v = calc_scale(ceu_rect.height, &pix->height);
dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n",
ceu_rect.width, scale_h, pix->width,
ceu_rect.height, scale_v, pix->height);
- cam->code = xlate->code;
- cam->ceu_rect = ceu_rect;
- icd->current_fmt = xlate;
+ pcdev->cflcr = scale_h | (scale_v << 16);
- pcdev->field = field;
+ icd->buswidth = xlate->buswidth;
+ icd->current_fmt = xlate->host_fmt;
+ cam->camera_fmt = xlate->cam_fmt;
+ cam->ceu_rect = ceu_rect;
+
+ pcdev->is_interlaced = is_interlaced;
pcdev->image_mode = image_mode;
return 0;
@@ -1612,7 +1509,6 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
const struct soc_camera_format_xlate *xlate;
struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct v4l2_mbus_framefmt mf;
__u32 pixfmt = pix->pixelformat;
int width, height;
int ret;
@@ -1631,27 +1527,18 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
width = pix->width;
height = pix->height;
- pix->bytesperline = soc_mbus_bytes_per_line(width, xlate->host_fmt);
- if (pix->bytesperline < 0)
- return pix->bytesperline;
- pix->sizeimage = height * pix->bytesperline;
+ pix->bytesperline = pix->width *
+ DIV_ROUND_UP(xlate->host_fmt->depth, 8);
+ pix->sizeimage = pix->height * pix->bytesperline;
- /* limit to sensor capabilities */
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.code = xlate->code;
- mf.colorspace = pix->colorspace;
+ pix->pixelformat = xlate->cam_fmt->fourcc;
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
+ /* limit to sensor capabilities */
+ ret = v4l2_subdev_call(sd, video, try_fmt, f);
+ pix->pixelformat = pixfmt;
if (ret < 0)
return ret;
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
-
switch (pixfmt) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
@@ -1660,25 +1547,21 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
/* FIXME: check against rect_max after converting soc-camera */
/* We can scale precisely, need a bigger image from camera */
if (pix->width < width || pix->height < height) {
- /*
- * We presume, the sensor behaves sanely, i.e., if
- * requested a bigger rectangle, it will not return a
- * smaller one.
- */
- mf.width = 2560;
- mf.height = 1920;
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
+ int tmp_w = pix->width, tmp_h = pix->height;
+ pix->width = 2560;
+ pix->height = 1920;
+ ret = v4l2_subdev_call(sd, video, try_fmt, f);
if (ret < 0) {
/* Shouldn't actually happen... */
dev_err(icd->dev.parent,
- "FIXME: client try_fmt() = %d\n", ret);
- return ret;
+ "FIXME: try_fmt() returned %d\n", ret);
+ pix->width = tmp_w;
+ pix->height = tmp_h;
}
}
- /* We will scale exactly */
- if (mf.width > width)
+ if (pix->width > width)
pix->width = width;
- if (mf.height > height)
+ if (pix->height > height)
pix->height = height;
}
@@ -1690,12 +1573,10 @@ static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf,
{
int i;
- /*
- * This is for locking debugging only. I removed spinlocks and now I
+ /* This is for locking debugging only. I removed spinlocks and now I
* check whether .prepare is ever called on a linked buffer, or whether
* a dma IRQ can occur for an in-work or unlinked buffer. Until now
- * it hadn't triggered
- */
+ * it hadn't triggered */
for (i = 0; i < p->count; i++) {
struct sh_mobile_ceu_buffer *buf;
@@ -1743,7 +1624,8 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
&sh_mobile_ceu_videobuf_ops,
icd->dev.parent, &pcdev->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
- pcdev->field,
+ pcdev->is_interlaced ?
+ V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
sizeof(struct sh_mobile_ceu_buffer),
icd);
}
@@ -1772,7 +1654,7 @@ static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd,
switch (ctrl->id) {
case V4L2_CID_SHARPNESS:
- switch (icd->current_fmt->host_fmt->fourcc) {
+ switch (icd->current_fmt->fourcc) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
case V4L2_PIX_FMT_NV16:
@@ -1954,7 +1836,7 @@ static struct platform_driver sh_mobile_ceu_driver = {
.pm = &sh_mobile_ceu_dev_pm_ops,
},
.probe = sh_mobile_ceu_probe,
- .remove = __devexit_p(sh_mobile_ceu_remove),
+ .remove = __exit_p(sh_mobile_ceu_remove),
};
static int __init sh_mobile_ceu_init(void)
diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_core.c b/trunk/drivers/media/video/sn9c102/sn9c102_core.c
index cbf8087b286f..4a7711c3e745 100644
--- a/trunk/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/trunk/drivers/media/video/sn9c102/sn9c102_core.c
@@ -1007,8 +1007,8 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
else if (cam->stream != STREAM_OFF) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "URB timeout reached. The camera is misconfigured. "
- "To use it, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "To use it, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -EIO;
}
@@ -1734,8 +1734,7 @@ static void sn9c102_release_resources(struct kref *kref)
cam = container_of(kref, struct sn9c102_device, kref);
- DBG(2, "V4L2 device %s deregistered",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num);
video_set_drvdata(cam->v4ldev, NULL);
video_unregister_device(cam->v4ldev);
usb_put_dev(cam->usbdev);
@@ -1792,8 +1791,8 @@ static int sn9c102_open(struct file *filp)
}
if (cam->users) {
- DBG(2, "Device %s is already in use",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "Device /dev/video%d is already in use",
+ cam->v4ldev->num);
DBG(3, "Simultaneous opens are not supported");
/*
open() must follow the open flags and should block
@@ -1846,7 +1845,7 @@ static int sn9c102_open(struct file *filp)
cam->frame_count = 0;
sn9c102_empty_framequeues(cam);
- DBG(3, "Video device %s is open", video_device_node_name(cam->v4ldev));
+ DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num);
out:
mutex_unlock(&cam->open_mutex);
@@ -1871,7 +1870,7 @@ static int sn9c102_release(struct file *filp)
cam->users--;
wake_up_interruptible_nr(&cam->wait_open, 1);
- DBG(3, "Video device %s closed", video_device_node_name(cam->v4ldev));
+ DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num);
kref_put(&cam->kref, sn9c102_release_resources);
@@ -2434,8 +2433,8 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
if (err) { /* atomic, no rollback in ioctl() */
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -EIO;
}
@@ -2447,8 +2446,8 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -ENOMEM;
}
@@ -2691,8 +2690,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
if (err) { /* atomic, no rollback in ioctl() */
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -EIO;
}
@@ -2703,8 +2702,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -ENOMEM;
}
@@ -2749,9 +2748,9 @@ sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg)
err += sn9c102_set_compression(cam, &jc);
if (err) { /* atomic, no rollback in ioctl() */
cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware problems. "
- "To use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
+ "problems. To use the camera, close and open "
+ "/dev/video%d again.", cam->v4ldev->num);
return -EIO;
}
@@ -3329,6 +3328,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
cam->v4ldev->fops = &sn9c102_fops;
+ cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
cam->v4ldev->parent = &udev->dev;
@@ -3346,8 +3346,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
goto fail;
}
- DBG(2, "V4L2 device registered as %s",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num);
video_set_drvdata(cam->v4ldev, cam);
cam->module_param.force_munmap = force_munmap[dev_nr];
@@ -3399,9 +3398,9 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf)
DBG(2, "Disconnecting %s...", cam->v4ldev->name);
if (cam->users) {
- DBG(2, "Device %s is open! Deregistration and memory "
- "deallocation are deferred.",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "Device /dev/video%d is open! Deregistration and "
+ "memory deallocation are deferred.",
+ cam->v4ldev->num);
cam->state |= DEV_MISCONFIGURED;
sn9c102_stop_transfer(cam);
cam->state |= DEV_DISCONNECTED;
diff --git a/trunk/drivers/media/video/soc_camera.c b/trunk/drivers/media/video/soc_camera.c
index 6b3fbcca7747..95fdeb23c2c1 100644
--- a/trunk/drivers/media/video/soc_camera.c
+++ b/trunk/drivers/media/video/soc_camera.c
@@ -31,7 +31,6 @@
#include
#include
#include
-#include
/* Default to VGA resolution */
#define DEFAULT_WIDTH 640
@@ -41,6 +40,18 @@ static LIST_HEAD(hosts);
static LIST_HEAD(devices);
static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
+const struct soc_camera_data_format *soc_camera_format_by_fourcc(
+ struct soc_camera_device *icd, unsigned int fourcc)
+{
+ unsigned int i;
+
+ for (i = 0; i < icd->num_formats; i++)
+ if (icd->formats[i].fourcc == fourcc)
+ return icd->formats + i;
+ return NULL;
+}
+EXPORT_SYMBOL(soc_camera_format_by_fourcc);
+
const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
struct soc_camera_device *icd, unsigned int fourcc)
{
@@ -196,26 +207,21 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
/* Always entered with .video_lock held */
static int soc_camera_init_user_formats(struct soc_camera_device *icd)
{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
- int i, fmts = 0, raw_fmts = 0, ret;
- enum v4l2_mbus_pixelcode code;
-
- while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code))
- raw_fmts++;
+ int i, fmts = 0, ret;
if (!ici->ops->get_formats)
/*
* Fallback mode - the host will have to serve all
* sensor-provided formats one-to-one to the user
*/
- fmts = raw_fmts;
+ fmts = icd->num_formats;
else
/*
* First pass - only count formats this host-sensor
* configuration can provide
*/
- for (i = 0; i < raw_fmts; i++) {
+ for (i = 0; i < icd->num_formats; i++) {
ret = ici->ops->get_formats(icd, i, NULL);
if (ret < 0)
return ret;
@@ -236,12 +242,11 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
/* Second pass - actually fill data formats */
fmts = 0;
- for (i = 0; i < raw_fmts; i++)
+ for (i = 0; i < icd->num_formats; i++)
if (!ici->ops->get_formats) {
- v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code);
- icd->user_formats[i].host_fmt =
- soc_mbus_get_fmtdesc(code);
- icd->user_formats[i].code = code;
+ icd->user_formats[i].host_fmt = icd->formats + i;
+ icd->user_formats[i].cam_fmt = icd->formats + i;
+ icd->user_formats[i].buswidth = icd->formats[i].depth;
} else {
ret = ici->ops->get_formats(icd, i,
&icd->user_formats[fmts]);
@@ -250,7 +255,7 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
fmts += ret;
}
- icd->current_fmt = &icd->user_formats[0];
+ icd->current_fmt = icd->user_formats[0].host_fmt;
return 0;
@@ -276,7 +281,7 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd)
#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
((x) >> 24) & 0xff
-/* Called with .vb_lock held, or from the first open(2), see comment there */
+/* Called with .vb_lock held */
static int soc_camera_set_fmt(struct soc_camera_file *icf,
struct v4l2_format *f)
{
@@ -297,7 +302,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
if (ret < 0) {
return ret;
} else if (!icd->current_fmt ||
- icd->current_fmt->host_fmt->fourcc != pix->pixelformat) {
+ icd->current_fmt->fourcc != pix->pixelformat) {
dev_err(&icd->dev,
"Host driver hasn't set up current format correctly!\n");
return -EINVAL;
@@ -305,7 +310,6 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
icd->user_width = pix->width;
icd->user_height = pix->height;
- icd->colorspace = pix->colorspace;
icf->vb_vidq.field =
icd->field = pix->field;
@@ -365,9 +369,8 @@ static int soc_camera_open(struct file *file)
.width = icd->user_width,
.height = icd->user_height,
.field = icd->field,
- .colorspace = icd->colorspace,
- .pixelformat =
- icd->current_fmt->host_fmt->fourcc,
+ .pixelformat = icd->current_fmt->fourcc,
+ .colorspace = icd->current_fmt->colorspace,
},
};
@@ -387,12 +390,7 @@ static int soc_camera_open(struct file *file)
goto eiciadd;
}
- /*
- * Try to configure with default parameters. Notice: this is the
- * very first open, so, we cannot race against other calls,
- * apart from someone else calling open() simultaneously, but
- * .video_lock is protecting us against it.
- */
+ /* Try to configure with default parameters */
ret = soc_camera_set_fmt(icf, &f);
if (ret < 0)
goto esfmt;
@@ -536,7 +534,7 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
{
struct soc_camera_file *icf = file->private_data;
struct soc_camera_device *icd = icf->icd;
- const struct soc_mbus_pixelfmt *format;
+ const struct soc_camera_data_format *format;
WARN_ON(priv != file->private_data);
@@ -545,8 +543,7 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
format = icd->user_formats[f->index].host_fmt;
- if (format->name)
- strlcpy(f->description, format->name, sizeof(f->description));
+ strlcpy(f->description, format->name, sizeof(f->description));
f->pixelformat = format->fourcc;
return 0;
}
@@ -563,15 +560,12 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
pix->width = icd->user_width;
pix->height = icd->user_height;
pix->field = icf->vb_vidq.field;
- pix->pixelformat = icd->current_fmt->host_fmt->fourcc;
- pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
- icd->current_fmt->host_fmt);
- pix->colorspace = icd->colorspace;
- if (pix->bytesperline < 0)
- return pix->bytesperline;
+ pix->pixelformat = icd->current_fmt->fourcc;
+ pix->bytesperline = pix->width *
+ DIV_ROUND_UP(icd->current_fmt->depth, 8);
pix->sizeimage = pix->height * pix->bytesperline;
dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n",
- icd->current_fmt->host_fmt->fourcc);
+ icd->current_fmt->fourcc);
return 0;
}
@@ -627,10 +621,8 @@ static int soc_camera_streamoff(struct file *file, void *priv,
mutex_lock(&icd->video_lock);
- /*
- * This calls buf_release from host driver's videobuf_queue_ops for all
- * remaining buffers. When the last buffer is freed, stop capture
- */
+ /* This calls buf_release from host driver's videobuf_queue_ops for all
+ * remaining buffers. When the last buffer is freed, stop capture */
videobuf_streamoff(&icf->vb_vidq);
v4l2_subdev_call(sd, video, s_stream, 0);
@@ -900,7 +892,7 @@ static int soc_camera_probe(struct device *dev)
struct soc_camera_link *icl = to_soc_camera_link(icd);
struct device *control = NULL;
struct v4l2_subdev *sd;
- struct v4l2_mbus_framefmt mf;
+ struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
int ret;
dev_info(dev, "Probing %s\n", dev_name(dev));
@@ -971,11 +963,9 @@ static int soc_camera_probe(struct device *dev)
/* Try to improve our guess of a reasonable window format */
sd = soc_camera_to_subdev(icd);
- if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
- icd->user_width = mf.width;
- icd->user_height = mf.height;
- icd->colorspace = mf.colorspace;
- icd->field = mf.field;
+ if (!v4l2_subdev_call(sd, video, g_fmt, &f)) {
+ icd->user_width = f.fmt.pix.width;
+ icd->user_height = f.fmt.pix.height;
}
/* Do we have to sysfs_remove_link() before device_unregister()? */
@@ -1014,10 +1004,8 @@ static int soc_camera_probe(struct device *dev)
return ret;
}
-/*
- * This is called on device_unregister, which only means we have to disconnect
- * from the host, but not remove ourselves from the device list
- */
+/* This is called on device_unregister, which only means we have to disconnect
+ * from the host, but not remove ourselves from the device list */
static int soc_camera_remove(struct device *dev)
{
struct soc_camera_device *icd = to_soc_camera_dev(dev);
@@ -1217,10 +1205,8 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
}
if (num < 0)
- /*
- * ok, we have 256 cameras on this host...
- * man, stay reasonable...
- */
+ /* ok, we have 256 cameras on this host...
+ * man, stay reasonable... */
return -ENOMEM;
icd->devnum = num;
@@ -1282,6 +1268,7 @@ static int video_dev_create(struct soc_camera_device *icd)
vdev->fops = &soc_camera_fops;
vdev->ioctl_ops = &soc_camera_ioctl_ops;
vdev->release = video_device_release;
+ vdev->minor = -1;
vdev->tvnorms = V4L2_STD_UNKNOWN;
icd->vdev = vdev;
@@ -1304,7 +1291,8 @@ static int soc_camera_video_start(struct soc_camera_device *icd)
!icd->ops->set_bus_param)
return -EINVAL;
- ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1);
+ ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER,
+ icd->vdev->minor);
if (ret < 0) {
dev_err(&icd->dev, "video_register_device failed: %d\n", ret);
return ret;
@@ -1347,11 +1335,9 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
return ret;
}
-/*
- * Only called on rmmod for each platform device, since they are not
+/* Only called on rmmod for each platform device, since they are not
* hot-pluggable. Now we know, that all our users - hosts and devices have
- * been unloaded already
- */
+ * been unloaded already */
static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
{
struct soc_camera_device *icd = platform_get_drvdata(pdev);
diff --git a/trunk/drivers/media/video/soc_camera_platform.c b/trunk/drivers/media/video/soc_camera_platform.c
index 10b003a8be83..b6a575ce5da2 100644
--- a/trunk/drivers/media/video/soc_camera_platform.c
+++ b/trunk/drivers/media/video/soc_camera_platform.c
@@ -22,6 +22,7 @@
struct soc_camera_platform_priv {
struct v4l2_subdev subdev;
+ struct soc_camera_data_format format;
};
static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev)
@@ -57,36 +58,36 @@ soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
}
static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+ struct v4l2_format *f)
{
struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
- mf->width = p->format.width;
- mf->height = p->format.height;
- mf->code = p->format.code;
- mf->colorspace = p->format.colorspace;
-
+ pix->width = p->format.width;
+ pix->height = p->format.height;
return 0;
}
-static struct v4l2_subdev_core_ops platform_subdev_core_ops;
-
-static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, int index,
- enum v4l2_mbus_pixelcode *code)
+static void soc_camera_platform_video_probe(struct soc_camera_device *icd,
+ struct platform_device *pdev)
{
- struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
+ struct soc_camera_platform_priv *priv = get_priv(pdev);
+ struct soc_camera_platform_info *p = pdev->dev.platform_data;
- if (index)
- return -EINVAL;
+ priv->format.name = p->format_name;
+ priv->format.depth = p->format_depth;
+ priv->format.fourcc = p->format.pixelformat;
+ priv->format.colorspace = p->format.colorspace;
- *code = p->format.code;
- return 0;
+ icd->formats = &priv->format;
+ icd->num_formats = 1;
}
+static struct v4l2_subdev_core_ops platform_subdev_core_ops;
+
static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
.s_stream = soc_camera_platform_s_stream,
- .try_mbus_fmt = soc_camera_platform_try_fmt,
- .enum_mbus_fmt = soc_camera_platform_enum_fmt,
+ .try_fmt = soc_camera_platform_try_fmt,
};
static struct v4l2_subdev_ops platform_subdev_ops = {
@@ -127,10 +128,13 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
/* Set the control device reference */
dev_set_drvdata(&icd->dev, &pdev->dev);
- icd->ops = &soc_camera_platform_ops;
+ icd->y_skip_top = 0;
+ icd->ops = &soc_camera_platform_ops;
ici = to_soc_camera_host(icd->dev.parent);
+ soc_camera_platform_video_probe(icd, pdev);
+
v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
v4l2_set_subdevdata(&priv->subdev, p);
strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);
diff --git a/trunk/drivers/media/video/soc_mediabus.c b/trunk/drivers/media/video/soc_mediabus.c
deleted file mode 100644
index f8d5c87dc2aa..000000000000
--- a/trunk/drivers/media/video/soc_mediabus.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * soc-camera media bus helper routines
- *
- * Copyright (C) 2009, Guennadi Liakhovetski
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include
-#include
-
-#include
-#include
-#include
-
-#define MBUS_IDX(f) (V4L2_MBUS_FMT_ ## f - V4L2_MBUS_FMT_FIXED - 1)
-
-static const struct soc_mbus_pixelfmt mbus_fmt[] = {
- [MBUS_IDX(YUYV8_2X8_LE)] = {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .name = "YUYV",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(YVYU8_2X8_LE)] = {
- .fourcc = V4L2_PIX_FMT_YVYU,
- .name = "YVYU",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(YUYV8_2X8_BE)] = {
- .fourcc = V4L2_PIX_FMT_UYVY,
- .name = "UYVY",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(YVYU8_2X8_BE)] = {
- .fourcc = V4L2_PIX_FMT_VYUY,
- .name = "VYUY",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(RGB555_2X8_PADHI_LE)] = {
- .fourcc = V4L2_PIX_FMT_RGB555,
- .name = "RGB555",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(RGB555_2X8_PADHI_BE)] = {
- .fourcc = V4L2_PIX_FMT_RGB555X,
- .name = "RGB555X",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(RGB565_2X8_LE)] = {
- .fourcc = V4L2_PIX_FMT_RGB565,
- .name = "RGB565",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(RGB565_2X8_BE)] = {
- .fourcc = V4L2_PIX_FMT_RGB565X,
- .name = "RGB565X",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(SBGGR8_1X8)] = {
- .fourcc = V4L2_PIX_FMT_SBGGR8,
- .name = "Bayer 8 BGGR",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(SBGGR10_1X10)] = {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .name = "Bayer 10 BGGR",
- .bits_per_sample = 10,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(GREY8_1X8)] = {
- .fourcc = V4L2_PIX_FMT_GREY,
- .name = "Grey",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_NONE,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(Y10_1X10)] = {
- .fourcc = V4L2_PIX_FMT_Y10,
- .name = "Grey 10bit",
- .bits_per_sample = 10,
- .packing = SOC_MBUS_PACKING_EXTEND16,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .name = "Bayer 10 BGGR",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .name = "Bayer 10 BGGR",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADLO,
- .order = SOC_MBUS_ORDER_LE,
- }, [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .name = "Bayer 10 BGGR",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADHI,
- .order = SOC_MBUS_ORDER_BE,
- }, [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .name = "Bayer 10 BGGR",
- .bits_per_sample = 8,
- .packing = SOC_MBUS_PACKING_2X8_PADLO,
- .order = SOC_MBUS_ORDER_BE,
- },
-};
-
-s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
-{
- switch (mf->packing) {
- case SOC_MBUS_PACKING_NONE:
- return width * mf->bits_per_sample / 8;
- case SOC_MBUS_PACKING_2X8_PADHI:
- case SOC_MBUS_PACKING_2X8_PADLO:
- case SOC_MBUS_PACKING_EXTEND16:
- return width * 2;
- }
- return -EINVAL;
-}
-EXPORT_SYMBOL(soc_mbus_bytes_per_line);
-
-const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
- enum v4l2_mbus_pixelcode code)
-{
- if ((unsigned int)(code - V4L2_MBUS_FMT_FIXED) > ARRAY_SIZE(mbus_fmt))
- return NULL;
- return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1;
-}
-EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
-
-static int __init soc_mbus_init(void)
-{
- return 0;
-}
-
-static void __exit soc_mbus_exit(void)
-{
-}
-
-module_init(soc_mbus_init);
-module_exit(soc_mbus_exit);
-
-MODULE_DESCRIPTION("soc-camera media bus interface");
-MODULE_AUTHOR("Guennadi Liakhovetski ");
-MODULE_LICENSE("GPL v2");
diff --git a/trunk/drivers/media/video/stk-webcam.c b/trunk/drivers/media/video/stk-webcam.c
index f07a0f6b71c4..6b41865f42bd 100644
--- a/trunk/drivers/media/video/stk-webcam.c
+++ b/trunk/drivers/media/video/stk-webcam.c
@@ -1307,6 +1307,7 @@ static void stk_v4l_dev_release(struct video_device *vd)
static struct video_device stk_v4l_data = {
.name = "stkwebcam",
+ .minor = -1,
.tvnorms = V4L2_STD_UNKNOWN,
.current_norm = V4L2_STD_UNKNOWN,
.fops = &v4l_stk_fops,
@@ -1326,8 +1327,8 @@ static int stk_register_video_device(struct stk_camera *dev)
if (err)
STK_ERROR("v4l registration failed\n");
else
- STK_INFO("Syntek USB2.0 Camera is now controlling device %s\n",
- video_device_node_name(&dev->vdev));
+ STK_INFO("Syntek USB2.0 Camera is now controlling video device"
+ " /dev/video%d\n", dev->vdev.num);
return err;
}
@@ -1417,8 +1418,8 @@ static void stk_camera_disconnect(struct usb_interface *interface)
wake_up_interruptible(&dev->wait_frame);
stk_remove_sysfs_files(&dev->vdev);
- STK_INFO("Syntek USB2.0 Camera release resources device %s\n",
- video_device_node_name(&dev->vdev));
+ STK_INFO("Syntek USB2.0 Camera release resources "
+ "video device /dev/video%d\n", dev->vdev.num);
video_unregister_device(&dev->vdev);
}
diff --git a/trunk/drivers/media/video/stradis.c b/trunk/drivers/media/video/stradis.c
index a057824e7ebc..eaada39c76fd 100644
--- a/trunk/drivers/media/video/stradis.c
+++ b/trunk/drivers/media/video/stradis.c
@@ -1921,6 +1921,7 @@ static const struct v4l2_file_operations saa_fops = {
static struct video_device saa_template = {
.name = "SAA7146A",
.fops = &saa_fops,
+ .minor = -1,
.release = video_device_release_empty,
};
@@ -1971,6 +1972,7 @@ static int __devinit configure_saa7146(struct pci_dev *pdev, int num)
saa->id = pdev->device;
saa->irq = pdev->irq;
+ saa->video_dev.minor = -1;
saa->saa7146_adr = pci_resource_start(pdev, 0);
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &saa->revision);
@@ -2132,7 +2134,7 @@ static void stradis_release_saa(struct pci_dev *pdev)
free_irq(saa->irq, saa);
if (saa->saa7146_mem)
iounmap(saa->saa7146_mem);
- if (video_is_registered(&saa->video_dev))
+ if (saa->video_dev.minor != -1)
video_unregister_device(&saa->video_dev);
}
diff --git a/trunk/drivers/media/video/stv680.c b/trunk/drivers/media/video/stv680.c
index 5938ad8702ef..6a91714125d2 100644
--- a/trunk/drivers/media/video/stv680.c
+++ b/trunk/drivers/media/video/stv680.c
@@ -1405,6 +1405,7 @@ static struct video_device stv680_template = {
.name = "STV0680 USB camera",
.fops = &stv680_fops,
.release = video_device_release,
+ .minor = -1,
};
static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id)
@@ -1466,8 +1467,8 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id
retval = -EIO;
goto error_vdev;
}
- PDEBUG(0, "STV(i): registered new video device: %s",
- video_device_node_name(stv680->vdev));
+ PDEBUG(0, "STV(i): registered new video device: video%d",
+ stv680->vdev->num);
usb_set_intfdata (intf, stv680);
retval = stv680_create_sysfs_files(stv680->vdev);
diff --git a/trunk/drivers/media/video/tw9910.c b/trunk/drivers/media/video/tw9910.c
index 5b801a6e1eea..269ab044072a 100644
--- a/trunk/drivers/media/video/tw9910.c
+++ b/trunk/drivers/media/video/tw9910.c
@@ -29,7 +29,7 @@
#include
#define GET_ID(val) ((val & 0xF8) >> 3)
-#define GET_REV(val) (val & 0x07)
+#define GET_ReV(val) (val & 0x07)
/*
* register offset
@@ -117,7 +117,7 @@
#define LCTL24 0x68
#define LCTL25 0x69
#define LCTL26 0x6A
-#define HSBEGIN 0x6B
+#define HSGEGIN 0x6B
#define HSEND 0x6C
#define OVSDLY 0x6D
#define OVSEND 0x6E
@@ -152,10 +152,7 @@
/* 1 : non-auto */
#define VSCTL 0x08 /* 1 : Vertical out ctrl by DVALID */
/* 0 : Vertical out ctrl by HACTIVE and DVALID */
-#define OEN_TRI_SEL_MASK 0x07
-#define OEN_TRI_SEL_ALL_ON 0x00 /* Enable output for Rev0/Rev1 */
-#define OEN_TRI_SEL_ALL_OFF_r0 0x06 /* All tri-stated for Rev0 */
-#define OEN_TRI_SEL_ALL_OFF_r1 0x07 /* All tri-stated for Rev1 */
+#define OEN 0x04 /* Output Enable together with TRI_SEL. */
/* OUTCTR1 */
#define VSP_LO 0x00 /* 0 : VS pin output polarity is active low */
@@ -181,18 +178,11 @@
* but all register content remain unchanged.
* This bit is self-resetting.
*/
-#define ACNTL1_PDN_MASK 0x0e
-#define CLK_PDN 0x08 /* system clock power down */
-#define Y_PDN 0x04 /* Luma ADC power down */
-#define C_PDN 0x02 /* Chroma ADC power down */
-
-/* ACNTL2 */
-#define ACNTL2_PDN_MASK 0x40
-#define PLL_PDN 0x40 /* PLL power down */
/* VBICNTL */
-
-/* RTSEL : control the real time signal output from the MPOUT pin */
+/* RTSEL : control the real time signal
+* output from the MPOUT pin
+*/
#define RTSEL_MASK 0x07
#define RTSEL_VLOSS 0x00 /* 0000 = Video loss */
#define RTSEL_HLOCK 0x01 /* 0001 = H-lock */
@@ -236,7 +226,28 @@ struct tw9910_priv {
struct v4l2_subdev subdev;
struct tw9910_video_info *info;
const struct tw9910_scale_ctrl *scale;
- u32 revision;
+};
+
+/*
+ * register settings
+ */
+
+#define ENDMARKER { 0xff, 0xff }
+
+static const struct regval_list tw9910_default_regs[] =
+{
+ { OPFORM, 0x00 },
+ { OUTCTR1, VSP_LO | VSSL_VVALID | HSP_HI | HSSL_HSYNC },
+ ENDMARKER,
+};
+
+static const struct soc_camera_data_format tw9910_color_fmt[] = {
+ {
+ .name = "VYUY",
+ .fourcc = V4L2_PIX_FMT_VYUY,
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
+ }
};
static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
@@ -329,6 +340,13 @@ static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
},
};
+static const struct tw9910_cropping_ctrl tw9910_cropping_ctrl = {
+ .vdelay = 0x0012,
+ .vactive = 0x00F0,
+ .hdelay = 0x0010,
+ .hactive = 0x02D0,
+};
+
static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
.start = 0x0260,
.end = 0x0300,
@@ -343,19 +361,6 @@ static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
subdev);
}
-static int tw9910_mask_set(struct i2c_client *client, u8 command,
- u8 mask, u8 set)
-{
- s32 val = i2c_smbus_read_byte_data(client, command);
- if (val < 0)
- return val;
-
- val &= ~mask;
- val |= set & mask;
-
- return i2c_smbus_write_byte_data(client, command, val);
-}
-
static int tw9910_set_scale(struct i2c_client *client,
const struct tw9910_scale_ctrl *scale)
{
@@ -378,14 +383,47 @@ static int tw9910_set_scale(struct i2c_client *client,
return ret;
}
+static int tw9910_set_cropping(struct i2c_client *client,
+ const struct tw9910_cropping_ctrl *cropping)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, CROP_HI,
+ (cropping->vdelay & 0x0300) >> 2 |
+ (cropping->vactive & 0x0300) >> 4 |
+ (cropping->hdelay & 0x0300) >> 6 |
+ (cropping->hactive & 0x0300) >> 8);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
+ cropping->vdelay & 0x00FF);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
+ cropping->vactive & 0x00FF);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(client, HDELAY_LO,
+ cropping->hdelay & 0x00FF);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(client, HACTIVE_LO,
+ cropping->hactive & 0x00FF);
+
+ return ret;
+}
+
static int tw9910_set_hsync(struct i2c_client *client,
const struct tw9910_hsync_ctrl *hsync)
{
- struct tw9910_priv *priv = to_tw9910(client);
int ret;
/* bit 10 - 3 */
- ret = i2c_smbus_write_byte_data(client, HSBEGIN,
+ ret = i2c_smbus_write_byte_data(client, HSGEGIN,
(hsync->start & 0x07F8) >> 3);
if (ret < 0)
return ret;
@@ -396,41 +434,50 @@ static int tw9910_set_hsync(struct i2c_client *client,
if (ret < 0)
return ret;
- /* So far only revisions 0 and 1 have been seen */
/* bit 2 - 0 */
- if (1 == priv->revision)
- ret = tw9910_mask_set(client, HSLOWCTL, 0x77,
- (hsync->start & 0x0007) << 4 |
- (hsync->end & 0x0007));
+ ret = i2c_smbus_read_byte_data(client, HSLOWCTL);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(client, HSLOWCTL,
+ (ret & 0x88) |
+ (hsync->start & 0x0007) << 4 |
+ (hsync->end & 0x0007));
return ret;
}
-static void tw9910_reset(struct i2c_client *client)
+static int tw9910_write_array(struct i2c_client *client,
+ const struct regval_list *vals)
{
- tw9910_mask_set(client, ACNTL1, SRESET, SRESET);
- msleep(1);
+ while (vals->reg_num != 0xff) {
+ int ret = i2c_smbus_write_byte_data(client,
+ vals->reg_num,
+ vals->value);
+ if (ret < 0)
+ return ret;
+ vals++;
+ }
+ return 0;
}
-static int tw9910_power(struct i2c_client *client, int enable)
+static int tw9910_mask_set(struct i2c_client *client, u8 command,
+ u8 mask, u8 set)
{
- int ret;
- u8 acntl1;
- u8 acntl2;
+ s32 val = i2c_smbus_read_byte_data(client, command);
+ if (val < 0)
+ return val;
- if (enable) {
- acntl1 = 0;
- acntl2 = 0;
- } else {
- acntl1 = CLK_PDN | Y_PDN | C_PDN;
- acntl2 = PLL_PDN;
- }
+ val &= ~mask;
+ val |= set & mask;
- ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1);
- if (ret < 0)
- return ret;
+ return i2c_smbus_write_byte_data(client, command, val);
+}
- return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
+static void tw9910_reset(struct i2c_client *client)
+{
+ i2c_smbus_write_byte_data(client, ACNTL1, SRESET);
+ msleep(1);
}
static const struct tw9910_scale_ctrl*
@@ -471,62 +518,27 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
{
struct i2c_client *client = sd->priv;
struct tw9910_priv *priv = to_tw9910(client);
- u8 val;
- int ret;
- if (!enable) {
- switch (priv->revision) {
- case 0:
- val = OEN_TRI_SEL_ALL_OFF_r0;
- break;
- case 1:
- val = OEN_TRI_SEL_ALL_OFF_r1;
- break;
- default:
- dev_err(&client->dev, "un-supported revision\n");
- return -EINVAL;
- }
- } else {
- val = OEN_TRI_SEL_ALL_ON;
-
- if (!priv->scale) {
- dev_err(&client->dev, "norm select error\n");
- return -EPERM;
- }
+ if (!enable)
+ return 0;
- dev_dbg(&client->dev, "%s %dx%d\n",
- priv->scale->name,
- priv->scale->width,
- priv->scale->height);
+ if (!priv->scale) {
+ dev_err(&client->dev, "norm select error\n");
+ return -EPERM;
}
- ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val);
- if (ret < 0)
- return ret;
+ dev_dbg(&client->dev, "%s %dx%d\n",
+ priv->scale->name,
+ priv->scale->width,
+ priv->scale->height);
- return tw9910_power(client, enable);
+ return 0;
}
static int tw9910_set_bus_param(struct soc_camera_device *icd,
unsigned long flags)
{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct i2c_client *client = sd->priv;
- u8 val = VSSL_VVALID | HSSL_DVALID;
-
- /*
- * set OUTCTR1
- *
- * We use VVALID and DVALID signals to control VSYNC and HSYNC
- * outputs, in this mode their polarity is inverted.
- */
- if (flags & SOCAM_HSYNC_ACTIVE_LOW)
- val |= HSP_HI;
-
- if (flags & SOCAM_VSYNC_ACTIVE_LOW)
- val |= VSP_HI;
-
- return i2c_smbus_write_byte_data(client, OUTCTR1, val);
+ return 0;
}
static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
@@ -536,7 +548,6 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
struct soc_camera_link *icl = to_soc_camera_link(icd);
unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
- SOCAM_VSYNC_ACTIVE_LOW | SOCAM_HSYNC_ACTIVE_LOW |
SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
return soc_camera_apply_sensor_flags(icl, flags);
@@ -565,11 +576,8 @@ static int tw9910_enum_input(struct soc_camera_device *icd,
static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = sd->priv;
- struct tw9910_priv *priv = to_tw9910(client);
-
id->ident = V4L2_IDENT_TW9910;
- id->revision = priv->revision;
+ id->revision = 0;
return 0;
}
@@ -588,8 +596,7 @@ static int tw9910_g_register(struct v4l2_subdev *sd,
if (ret < 0)
return ret;
- /*
- * ret = int
+ /* ret = int
* reg->val = __u64
*/
reg->val = (__u64)ret;
@@ -630,6 +637,9 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
* reset hardware
*/
tw9910_reset(client);
+ ret = tw9910_write_array(client, tw9910_default_regs);
+ if (ret < 0)
+ goto tw9910_set_fmt_error;
/*
* set bus width
@@ -677,6 +687,13 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
if (ret < 0)
goto tw9910_set_fmt_error;
+ /*
+ * set cropping
+ */
+ ret = tw9910_set_cropping(client, &tw9910_cropping_ctrl);
+ if (ret < 0)
+ goto tw9910_set_fmt_error;
+
/*
* set hsync
*/
@@ -745,11 +762,11 @@ static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int tw9910_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct tw9910_priv *priv = to_tw9910(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
if (!priv->scale) {
int ret;
@@ -766,76 +783,74 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd,
return ret;
}
- mf->width = priv->scale->width;
- mf->height = priv->scale->height;
- mf->code = V4L2_MBUS_FMT_YUYV8_2X8_BE;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- mf->field = V4L2_FIELD_INTERLACED_BT;
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ pix->width = priv->scale->width;
+ pix->height = priv->scale->height;
+ pix->pixelformat = V4L2_PIX_FMT_VYUY;
+ pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ pix->field = V4L2_FIELD_INTERLACED;
return 0;
}
-static int tw9910_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct tw9910_priv *priv = to_tw9910(client);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
/* See tw9910_s_crop() - no proper cropping support */
struct v4l2_crop a = {
.c = {
.left = 0,
.top = 0,
- .width = mf->width,
- .height = mf->height,
+ .width = pix->width,
+ .height = pix->height,
},
};
- int ret;
-
- WARN_ON(mf->field != V4L2_FIELD_ANY &&
- mf->field != V4L2_FIELD_INTERLACED_BT);
+ int i, ret;
/*
* check color format
*/
- if (mf->code != V4L2_MBUS_FMT_YUYV8_2X8_BE)
- return -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(tw9910_color_fmt); i++)
+ if (pix->pixelformat == tw9910_color_fmt[i].fourcc)
+ break;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
+ if (i == ARRAY_SIZE(tw9910_color_fmt))
+ return -EINVAL;
ret = tw9910_s_crop(sd, &a);
if (!ret) {
- mf->width = priv->scale->width;
- mf->height = priv->scale->height;
+ pix->width = priv->scale->width;
+ pix->height = priv->scale->height;
}
return ret;
}
-static int tw9910_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int tw9910_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
{
struct i2c_client *client = sd->priv;
struct soc_camera_device *icd = client->dev.platform_data;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
const struct tw9910_scale_ctrl *scale;
- if (V4L2_FIELD_ANY == mf->field) {
- mf->field = V4L2_FIELD_INTERLACED_BT;
- } else if (V4L2_FIELD_INTERLACED_BT != mf->field) {
- dev_err(&client->dev, "Field type %d invalid.\n", mf->field);
+ if (V4L2_FIELD_ANY == pix->field) {
+ pix->field = V4L2_FIELD_INTERLACED;
+ } else if (V4L2_FIELD_INTERLACED != pix->field) {
+ dev_err(&client->dev, "Field type invalid.\n");
return -EINVAL;
}
- mf->code = V4L2_MBUS_FMT_YUYV8_2X8_BE;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
-
/*
* select suitable norm
*/
- scale = tw9910_select_norm(icd, mf->width, mf->height);
+ scale = tw9910_select_norm(icd, pix->width, pix->height);
if (!scale)
return -EINVAL;
- mf->width = scale->width;
- mf->height = scale->height;
+ pix->width = scale->width;
+ pix->height = scale->height;
return 0;
}
@@ -844,7 +859,7 @@ static int tw9910_video_probe(struct soc_camera_device *icd,
struct i2c_client *client)
{
struct tw9910_priv *priv = to_tw9910(client);
- s32 id;
+ s32 val;
/*
* We must have a parent by now. And it cannot be a wrong one.
@@ -863,24 +878,23 @@ static int tw9910_video_probe(struct soc_camera_device *icd,
return -ENODEV;
}
+ icd->formats = tw9910_color_fmt;
+ icd->num_formats = ARRAY_SIZE(tw9910_color_fmt);
+
/*
* check and show Product ID
- * So far only revisions 0 and 1 have been seen
*/
- id = i2c_smbus_read_byte_data(client, ID);
- priv->revision = GET_REV(id);
- id = GET_ID(id);
+ val = i2c_smbus_read_byte_data(client, ID);
- if (0x0B != id ||
- 0x01 < priv->revision) {
+ if (0x0B != GET_ID(val) ||
+ 0x00 != GET_ReV(val)) {
dev_err(&client->dev,
- "Product ID error %x:%x\n",
- id, priv->revision);
+ "Product ID error %x:%x\n", GET_ID(val), GET_ReV(val));
return -ENODEV;
}
dev_info(&client->dev,
- "tw9910 Product ID %0x:%0x\n", id, priv->revision);
+ "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val));
icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL;
icd->vdev->current_norm = V4L2_STD_NTSC;
@@ -903,25 +917,14 @@ static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
#endif
};
-static int tw9910_enum_fmt(struct v4l2_subdev *sd, int index,
- enum v4l2_mbus_pixelcode *code)
-{
- if (index)
- return -EINVAL;
-
- *code = V4L2_MBUS_FMT_YUYV8_2X8_BE;
- return 0;
-}
-
static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
.s_stream = tw9910_s_stream,
- .g_mbus_fmt = tw9910_g_fmt,
- .s_mbus_fmt = tw9910_s_fmt,
- .try_mbus_fmt = tw9910_try_fmt,
+ .g_fmt = tw9910_g_fmt,
+ .s_fmt = tw9910_s_fmt,
+ .try_fmt = tw9910_try_fmt,
.cropcap = tw9910_cropcap,
.g_crop = tw9910_g_crop,
.s_crop = tw9910_s_crop,
- .enum_mbus_fmt = tw9910_enum_fmt,
};
static struct v4l2_subdev_ops tw9910_subdev_ops = {
@@ -951,10 +954,10 @@ static int tw9910_probe(struct i2c_client *client,
}
icl = to_soc_camera_link(icd);
- if (!icl || !icl->priv)
+ if (!icl)
return -EINVAL;
- info = icl->priv;
+ info = container_of(icl, struct tw9910_video_info, link);
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&client->dev,
@@ -972,7 +975,7 @@ static int tw9910_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
icd->ops = &tw9910_ops;
- icd->iface = icl->bus_id;
+ icd->iface = info->link.bus_id;
ret = tw9910_video_probe(icd, client);
if (ret) {
diff --git a/trunk/drivers/media/video/usbvideo/usbvideo.c b/trunk/drivers/media/video/usbvideo/usbvideo.c
index 5ac37c6c4313..dea8b321fb4a 100644
--- a/trunk/drivers/media/video/usbvideo/usbvideo.c
+++ b/trunk/drivers/media/video/usbvideo/usbvideo.c
@@ -1053,9 +1053,9 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd)
"%s: video_register_device() successful\n", __func__);
}
- dev_info(&uvd->dev->dev, "%s on %s: canvas=%s videosize=%s\n",
+ dev_info(&uvd->dev->dev, "%s on /dev/video%d: canvas=%s videosize=%s\n",
(uvd->handle != NULL) ? uvd->handle->drvName : "???",
- video_device_node_name(&uvd->vdev), tmp2, tmp1);
+ uvd->vdev.num, tmp2, tmp1);
usb_get_dev(uvd->dev);
return 0;
diff --git a/trunk/drivers/media/video/usbvideo/vicam.c b/trunk/drivers/media/video/usbvideo/vicam.c
index 6030410c6677..45fce39ec9ad 100644
--- a/trunk/drivers/media/video/usbvideo/vicam.c
+++ b/trunk/drivers/media/video/usbvideo/vicam.c
@@ -796,6 +796,7 @@ static const struct v4l2_file_operations vicam_fops = {
static struct video_device vicam_template = {
.name = "ViCam-based USB Camera",
.fops = &vicam_fops,
+ .minor = -1,
.release = video_device_release_empty,
};
@@ -872,8 +873,8 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
return -EIO;
}
- printk(KERN_INFO "ViCam webcam driver now controlling device %s\n",
- video_device_node_name(&cam->vdev));
+ printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",
+ cam->vdev.num);
usb_set_intfdata (intf, cam);
diff --git a/trunk/drivers/media/video/usbvision/usbvision-i2c.c b/trunk/drivers/media/video/usbvision/usbvision-i2c.c
index 0613922997e0..c19f51dba2ee 100644
--- a/trunk/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/trunk/drivers/media/video/usbvision/usbvision-i2c.c
@@ -215,8 +215,8 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
memcpy(&usbvision->i2c_adap, &i2c_adap_template,
sizeof(struct i2c_adapter));
- sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name,
- usbvision->dev->bus->busnum, usbvision->dev->devpath);
+ sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name),
+ " #%d", usbvision->vdev->num);
PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name);
usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
diff --git a/trunk/drivers/media/video/usbvision/usbvision-video.c b/trunk/drivers/media/video/usbvision/usbvision-video.c
index 1054546db908..c07b0ac452ab 100644
--- a/trunk/drivers/media/video/usbvision/usbvision-video.c
+++ b/trunk/drivers/media/video/usbvision/usbvision-video.c
@@ -1328,6 +1328,7 @@ static struct video_device usbvision_video_template = {
.ioctl_ops = &usbvision_ioctl_ops,
.name = "usbvision-video",
.release = video_device_release,
+ .minor = -1,
.tvnorms = USBVISION_NORMS,
.current_norm = V4L2_STD_PAL
};
@@ -1361,6 +1362,7 @@ static struct video_device usbvision_radio_template = {
.fops = &usbvision_radio_fops,
.name = "usbvision-radio",
.release = video_device_release,
+ .minor = -1,
.ioctl_ops = &usbvision_radio_ioctl_ops,
.tvnorms = USBVISION_NORMS,
@@ -1380,6 +1382,7 @@ static struct video_device usbvision_vbi_template=
.fops = &usbvision_vbi_fops,
.release = video_device_release,
.name = "usbvision-vbi",
+ .minor = -1,
};
@@ -1401,6 +1404,7 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
return NULL;
}
*vdev = *vdev_template;
+// vdev->minor = -1;
vdev->v4l2_dev = &usbvision->v4l2_dev;
snprintf(vdev->name, sizeof(vdev->name), "%s", name);
video_set_drvdata(vdev, usbvision);
@@ -1412,9 +1416,9 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision)
{
// vbi Device:
if (usbvision->vbi) {
- PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
- video_device_node_name(usbvision->vbi));
- if (video_is_registered(usbvision->vbi)) {
+ PDEBUG(DBG_PROBE, "unregister /dev/vbi%d [v4l2]",
+ usbvision->vbi->num);
+ if (usbvision->vbi->minor != -1) {
video_unregister_device(usbvision->vbi);
} else {
video_device_release(usbvision->vbi);
@@ -1424,9 +1428,9 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision)
// Radio Device:
if (usbvision->rdev) {
- PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
- video_device_node_name(usbvision->rdev));
- if (video_is_registered(usbvision->rdev)) {
+ PDEBUG(DBG_PROBE, "unregister /dev/radio%d [v4l2]",
+ usbvision->rdev->num);
+ if (usbvision->rdev->minor != -1) {
video_unregister_device(usbvision->rdev);
} else {
video_device_release(usbvision->rdev);
@@ -1436,9 +1440,9 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision)
// Video Device:
if (usbvision->vdev) {
- PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
- video_device_node_name(usbvision->vdev));
- if (video_is_registered(usbvision->vdev)) {
+ PDEBUG(DBG_PROBE, "unregister /dev/video%d [v4l2]",
+ usbvision->vdev->num);
+ if (usbvision->vdev->minor != -1) {
video_unregister_device(usbvision->vdev);
} else {
video_device_release(usbvision->vdev);
@@ -1462,8 +1466,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
video_nr)<0) {
goto err_exit;
}
- printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n",
- usbvision->nr, video_device_node_name(usbvision->vdev));
+ printk(KERN_INFO "USBVision[%d]: registered USBVision Video device /dev/video%d [v4l2]\n",
+ usbvision->nr, usbvision->vdev->num);
// Radio Device:
if (usbvision_device_data[usbvision->DevModel].Radio) {
@@ -1479,8 +1483,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
radio_nr)<0) {
goto err_exit;
}
- printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n",
- usbvision->nr, video_device_node_name(usbvision->rdev));
+ printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device /dev/radio%d [v4l2]\n",
+ usbvision->nr, usbvision->rdev->num);
}
// vbi Device:
if (usbvision_device_data[usbvision->DevModel].vbi) {
@@ -1495,8 +1499,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
vbi_nr)<0) {
goto err_exit;
}
- printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device %s [v4l2] (Not Working Yet!)\n",
- usbvision->nr, video_device_node_name(usbvision->vbi));
+ printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device /dev/vbi%d [v4l2] (Not Working Yet!)\n",
+ usbvision->nr, usbvision->vbi->num);
}
// all done
return 0;
diff --git a/trunk/drivers/media/video/uvc/uvc_driver.c b/trunk/drivers/media/video/uvc/uvc_driver.c
index 391cccca7ffc..c31bc50113bc 100644
--- a/trunk/drivers/media/video/uvc/uvc_driver.c
+++ b/trunk/drivers/media/video/uvc/uvc_driver.c
@@ -1651,6 +1651,7 @@ static int uvc_register_video(struct uvc_device *dev,
* get another one.
*/
vdev->parent = &dev->intf->dev;
+ vdev->minor = -1;
vdev->fops = &uvc_fops;
vdev->release = uvc_release;
strlcpy(vdev->name, dev->name, sizeof vdev->name);
diff --git a/trunk/drivers/media/video/uvc/uvc_video.c b/trunk/drivers/media/video/uvc/uvc_video.c
index 9a9802830d41..05139a4f14f6 100644
--- a/trunk/drivers/media/video/uvc/uvc_video.c
+++ b/trunk/drivers/media/video/uvc/uvc_video.c
@@ -145,7 +145,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream,
uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non "
"compliance - GET_MIN/MAX(PROBE) incorrectly "
"supported. Enabling workaround.\n");
- memset(ctrl, 0, sizeof *ctrl);
+ memset(ctrl, 0, sizeof ctrl);
ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
ret = 0;
goto out;
diff --git a/trunk/drivers/media/video/v4l2-common.c b/trunk/drivers/media/video/v4l2-common.c
index 36b5cb86fb57..e8e5affbabce 100644
--- a/trunk/drivers/media/video/v4l2-common.c
+++ b/trunk/drivers/media/video/v4l2-common.c
@@ -1024,50 +1024,3 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
}
}
EXPORT_SYMBOL_GPL(v4l_bound_align_image);
-
-/**
- * v4l_fill_dv_preset_info - fill description of a digital video preset
- * @preset - preset value
- * @info - pointer to struct v4l2_dv_enum_preset
- *
- * drivers can use this helper function to fill description of dv preset
- * in info.
- */
-int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info)
-{
- static const struct v4l2_dv_preset_info {
- u16 width;
- u16 height;
- const char *name;
- } dv_presets[] = {
- { 0, 0, "Invalid" }, /* V4L2_DV_INVALID */
- { 720, 480, "480p@59.94" }, /* V4L2_DV_480P59_94 */
- { 720, 576, "576p@50" }, /* V4L2_DV_576P50 */
- { 1280, 720, "720p@24" }, /* V4L2_DV_720P24 */
- { 1280, 720, "720p@25" }, /* V4L2_DV_720P25 */
- { 1280, 720, "720p@30" }, /* V4L2_DV_720P30 */
- { 1280, 720, "720p@50" }, /* V4L2_DV_720P50 */
- { 1280, 720, "720p@59.94" }, /* V4L2_DV_720P59_94 */
- { 1280, 720, "720p@60" }, /* V4L2_DV_720P60 */
- { 1920, 1080, "1080i@29.97" }, /* V4L2_DV_1080I29_97 */
- { 1920, 1080, "1080i@30" }, /* V4L2_DV_1080I30 */
- { 1920, 1080, "1080i@25" }, /* V4L2_DV_1080I25 */
- { 1920, 1080, "1080i@50" }, /* V4L2_DV_1080I50 */
- { 1920, 1080, "1080i@60" }, /* V4L2_DV_1080I60 */
- { 1920, 1080, "1080p@24" }, /* V4L2_DV_1080P24 */
- { 1920, 1080, "1080p@25" }, /* V4L2_DV_1080P25 */
- { 1920, 1080, "1080p@30" }, /* V4L2_DV_1080P30 */
- { 1920, 1080, "1080p@50" }, /* V4L2_DV_1080P50 */
- { 1920, 1080, "1080p@60" }, /* V4L2_DV_1080P60 */
- };
-
- if (info == NULL || preset >= ARRAY_SIZE(dv_presets))
- return -EINVAL;
-
- info->preset = preset;
- info->width = dv_presets[preset].width;
- info->height = dv_presets[preset].height;
- strlcpy(info->name, dv_presets[preset].name, sizeof(info->name));
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l_fill_dv_preset_info);
diff --git a/trunk/drivers/media/video/v4l2-compat-ioctl32.c b/trunk/drivers/media/video/v4l2-compat-ioctl32.c
index c4150bd26337..997975d5e024 100644
--- a/trunk/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/trunk/drivers/media/video/v4l2-compat-ioctl32.c
@@ -1077,12 +1077,6 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
case VIDIOC_DBG_G_REGISTER:
case VIDIOC_DBG_G_CHIP_IDENT:
case VIDIOC_S_HW_FREQ_SEEK:
- case VIDIOC_ENUM_DV_PRESETS:
- case VIDIOC_S_DV_PRESET:
- case VIDIOC_G_DV_PRESET:
- case VIDIOC_QUERY_DV_PRESET:
- case VIDIOC_S_DV_TIMINGS:
- case VIDIOC_G_DV_TIMINGS:
ret = do_video_ioctl(file, cmd, arg);
break;
diff --git a/trunk/drivers/media/video/v4l2-dev.c b/trunk/drivers/media/video/v4l2-dev.c
index 709069916068..500cbe9891ac 100644
--- a/trunk/drivers/media/video/v4l2-dev.c
+++ b/trunk/drivers/media/video/v4l2-dev.c
@@ -189,7 +189,7 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf,
if (!vdev->fops->read)
return -EINVAL;
- if (!video_is_registered(vdev))
+ if (video_is_unregistered(vdev))
return -EIO;
return vdev->fops->read(filp, buf, sz, off);
}
@@ -201,7 +201,7 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
if (!vdev->fops->write)
return -EINVAL;
- if (!video_is_registered(vdev))
+ if (video_is_unregistered(vdev))
return -EIO;
return vdev->fops->write(filp, buf, sz, off);
}
@@ -210,7 +210,7 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
{
struct video_device *vdev = video_devdata(filp);
- if (!vdev->fops->poll || !video_is_registered(vdev))
+ if (!vdev->fops->poll || video_is_unregistered(vdev))
return DEFAULT_POLLMASK;
return vdev->fops->poll(filp, poll);
}
@@ -250,7 +250,7 @@ static unsigned long v4l2_get_unmapped_area(struct file *filp,
if (!vdev->fops->get_unmapped_area)
return -ENOSYS;
- if (!video_is_registered(vdev))
+ if (video_is_unregistered(vdev))
return -ENODEV;
return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
}
@@ -260,7 +260,8 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
{
struct video_device *vdev = video_devdata(filp);
- if (!vdev->fops->mmap || !video_is_registered(vdev))
+ if (!vdev->fops->mmap ||
+ video_is_unregistered(vdev))
return -ENODEV;
return vdev->fops->mmap(filp, vm);
}
@@ -276,7 +277,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
vdev = video_devdata(filp);
/* return ENODEV if the video device has been removed
already or if it is not registered anymore. */
- if (vdev == NULL || !video_is_registered(vdev)) {
+ if (vdev == NULL || video_is_unregistered(vdev)) {
mutex_unlock(&videodev_lock);
return -ENODEV;
}
@@ -550,11 +551,10 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
vdev->dev.release = v4l2_device_release;
if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
- printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__,
- name_base, nr, video_device_node_name(vdev));
+ printk(KERN_WARNING "%s: requested %s%d, got %s%d\n",
+ __func__, name_base, nr, name_base, vdev->num);
/* Part 5: Activate this minor. The char device can now be used. */
- set_bit(V4L2_FL_REGISTERED, &vdev->flags);
mutex_lock(&videodev_lock);
video_device[vdev->minor] = vdev;
mutex_unlock(&videodev_lock);
@@ -593,11 +593,11 @@ EXPORT_SYMBOL(video_register_device_no_warn);
void video_unregister_device(struct video_device *vdev)
{
/* Check if vdev was ever registered at all */
- if (!vdev || !video_is_registered(vdev))
+ if (!vdev || vdev->minor < 0)
return;
mutex_lock(&videodev_lock);
- clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
+ set_bit(V4L2_FL_UNREGISTERED, &vdev->flags);
mutex_unlock(&videodev_lock);
device_unregister(&vdev->dev);
}
diff --git a/trunk/drivers/media/video/v4l2-ioctl.c b/trunk/drivers/media/video/v4l2-ioctl.c
index 4b11257c3184..30cc3347ae52 100644
--- a/trunk/drivers/media/video/v4l2-ioctl.c
+++ b/trunk/drivers/media/video/v4l2-ioctl.c
@@ -284,12 +284,6 @@ static const char *v4l2_ioctls[] = {
[_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT",
[_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
#endif
- [_IOC_NR(VIDIOC_ENUM_DV_PRESETS)] = "VIDIOC_ENUM_DV_PRESETS",
- [_IOC_NR(VIDIOC_S_DV_PRESET)] = "VIDIOC_S_DV_PRESET",
- [_IOC_NR(VIDIOC_G_DV_PRESET)] = "VIDIOC_G_DV_PRESET",
- [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET",
- [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS",
- [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS",
};
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
@@ -1141,19 +1135,6 @@ static long __video_do_ioctl(struct file *file,
{
struct v4l2_input *p = arg;
- /*
- * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
- * CAP_STD here based on ioctl handler provided by the
- * driver. If the driver doesn't support these
- * for a specific input, it must override these flags.
- */
- if (ops->vidioc_s_std)
- p->capabilities |= V4L2_IN_CAP_STD;
- if (ops->vidioc_s_dv_preset)
- p->capabilities |= V4L2_IN_CAP_PRESETS;
- if (ops->vidioc_s_dv_timings)
- p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS;
-
if (!ops->vidioc_enum_input)
break;
@@ -1198,19 +1179,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_enum_output)
break;
- /*
- * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
- * CAP_STD here based on ioctl handler provided by the
- * driver. If the driver doesn't support these
- * for a specific output, it must override these flags.
- */
- if (ops->vidioc_s_std)
- p->capabilities |= V4L2_OUT_CAP_STD;
- if (ops->vidioc_s_dv_preset)
- p->capabilities |= V4L2_OUT_CAP_PRESETS;
- if (ops->vidioc_s_dv_timings)
- p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS;
-
ret = ops->vidioc_enum_output(file, fh, p);
if (!ret)
dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1826,121 +1794,6 @@ static long __video_do_ioctl(struct file *file,
}
break;
}
- case VIDIOC_ENUM_DV_PRESETS:
- {
- struct v4l2_dv_enum_preset *p = arg;
-
- if (!ops->vidioc_enum_dv_presets)
- break;
-
- ret = ops->vidioc_enum_dv_presets(file, fh, p);
- if (!ret)
- dbgarg(cmd,
- "index=%d, preset=%d, name=%s, width=%d,"
- " height=%d ",
- p->index, p->preset, p->name, p->width,
- p->height);
- break;
- }
- case VIDIOC_S_DV_PRESET:
- {
- struct v4l2_dv_preset *p = arg;
-
- if (!ops->vidioc_s_dv_preset)
- break;
-
- dbgarg(cmd, "preset=%d\n", p->preset);
- ret = ops->vidioc_s_dv_preset(file, fh, p);
- break;
- }
- case VIDIOC_G_DV_PRESET:
- {
- struct v4l2_dv_preset *p = arg;
-
- if (!ops->vidioc_g_dv_preset)
- break;
-
- ret = ops->vidioc_g_dv_preset(file, fh, p);
- if (!ret)
- dbgarg(cmd, "preset=%d\n", p->preset);
- break;
- }
- case VIDIOC_QUERY_DV_PRESET:
- {
- struct v4l2_dv_preset *p = arg;
-
- if (!ops->vidioc_query_dv_preset)
- break;
-
- ret = ops->vidioc_query_dv_preset(file, fh, p);
- if (!ret)
- dbgarg(cmd, "preset=%d\n", p->preset);
- break;
- }
- case VIDIOC_S_DV_TIMINGS:
- {
- struct v4l2_dv_timings *p = arg;
-
- if (!ops->vidioc_s_dv_timings)
- break;
-
- switch (p->type) {
- case V4L2_DV_BT_656_1120:
- dbgarg2("bt-656/1120:interlaced=%d, pixelclock=%lld,"
- " width=%d, height=%d, polarities=%x,"
- " hfrontporch=%d, hsync=%d, hbackporch=%d,"
- " vfrontporch=%d, vsync=%d, vbackporch=%d,"
- " il_vfrontporch=%d, il_vsync=%d,"
- " il_vbackporch=%d\n",
- p->bt.interlaced, p->bt.pixelclock,
- p->bt.width, p->bt.height, p->bt.polarities,
- p->bt.hfrontporch, p->bt.hsync,
- p->bt.hbackporch, p->bt.vfrontporch,
- p->bt.vsync, p->bt.vbackporch,
- p->bt.il_vfrontporch, p->bt.il_vsync,
- p->bt.il_vbackporch);
- ret = ops->vidioc_s_dv_timings(file, fh, p);
- break;
- default:
- dbgarg2("Unknown type %d!\n", p->type);
- break;
- }
- break;
- }
- case VIDIOC_G_DV_TIMINGS:
- {
- struct v4l2_dv_timings *p = arg;
-
- if (!ops->vidioc_g_dv_timings)
- break;
-
- ret = ops->vidioc_g_dv_timings(file, fh, p);
- if (!ret) {
- switch (p->type) {
- case V4L2_DV_BT_656_1120:
- dbgarg2("bt-656/1120:interlaced=%d,"
- " pixelclock=%lld,"
- " width=%d, height=%d, polarities=%x,"
- " hfrontporch=%d, hsync=%d,"
- " hbackporch=%d, vfrontporch=%d,"
- " vsync=%d, vbackporch=%d,"
- " il_vfrontporch=%d, il_vsync=%d,"
- " il_vbackporch=%d\n",
- p->bt.interlaced, p->bt.pixelclock,
- p->bt.width, p->bt.height,
- p->bt.polarities, p->bt.hfrontporch,
- p->bt.hsync, p->bt.hbackporch,
- p->bt.vfrontporch, p->bt.vsync,
- p->bt.vbackporch, p->bt.il_vfrontporch,
- p->bt.il_vsync, p->bt.il_vbackporch);
- break;
- default:
- dbgarg2("Unknown type %d!\n", p->type);
- break;
- }
- }
- break;
- }
default:
{
diff --git a/trunk/drivers/media/video/videobuf-dma-contig.c b/trunk/drivers/media/video/videobuf-dma-contig.c
index 22c01097e8a8..d25f28461da1 100644
--- a/trunk/drivers/media/video/videobuf-dma-contig.c
+++ b/trunk/drivers/media/video/videobuf-dma-contig.c
@@ -141,11 +141,9 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
struct vm_area_struct *vma;
unsigned long prev_pfn, this_pfn;
unsigned long pages_done, user_address;
- unsigned int offset;
int ret;
- offset = vb->baddr & ~PAGE_MASK;
- mem->size = PAGE_ALIGN(vb->size + offset);
+ mem->size = PAGE_ALIGN(vb->size);
mem->is_userptr = 0;
ret = -EINVAL;
@@ -168,7 +166,7 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
break;
if (pages_done == 0)
- mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset;
+ mem->dma_handle = this_pfn << PAGE_SHIFT;
else if (this_pfn != (prev_pfn + 1))
ret = -EFAULT;
diff --git a/trunk/drivers/media/video/vino.c b/trunk/drivers/media/video/vino.c
index a15d1e7cbed8..b034a81d2b1c 100644
--- a/trunk/drivers/media/video/vino.c
+++ b/trunk/drivers/media/video/vino.c
@@ -4068,6 +4068,7 @@ static struct video_device vdev_template = {
.fops = &vino_fops,
.ioctl_ops = &vino_ioctl_ops,
.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+ .minor = -1,
};
static void vino_module_cleanup(int stage)
diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c
index 37632a064966..7705fc6baf00 100644
--- a/trunk/drivers/media/video/vivi.c
+++ b/trunk/drivers/media/video/vivi.c
@@ -1148,8 +1148,7 @@ static int vivi_open(struct file *file)
return -EBUSY;
}
- dprintk(dev, 1, "open %s type=%s users=%d\n",
- video_device_node_name(dev->vfd),
+ dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num,
v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
/* allocate + initialize per filehandle data */
@@ -1222,7 +1221,8 @@ static int vivi_close(struct file *file)
struct vivi_fh *fh = file->private_data;
struct vivi_dev *dev = fh->dev;
struct vivi_dmaqueue *vidq = &dev->vidq;
- struct video_device *vdev = video_devdata(file);
+
+ int minor = video_devdata(file)->minor;
vivi_stop_thread(vidq);
videobuf_stop(&fh->vb_vidq);
@@ -1234,8 +1234,8 @@ static int vivi_close(struct file *file)
dev->users--;
mutex_unlock(&dev->mutex);
- dprintk(dev, 1, "close called (dev=%s, users=%d)\n",
- video_device_node_name(vdev), dev->users);
+ dprintk(dev, 1, "close called (minor=%d, users=%d)\n",
+ minor, dev->users);
return 0;
}
@@ -1296,6 +1296,7 @@ static struct video_device vivi_template = {
.name = "vivi",
.fops = &vivi_fops,
.ioctl_ops = &vivi_ioctl_ops,
+ .minor = -1,
.release = video_device_release,
.tvnorms = V4L2_STD_525_60,
@@ -1316,8 +1317,8 @@ static int vivi_release(void)
list_del(list);
dev = list_entry(list, struct vivi_dev, vivi_devlist);
- v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
- video_device_node_name(dev->vfd));
+ v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n",
+ dev->vfd->num);
video_unregister_device(dev->vfd);
v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev);
@@ -1371,12 +1372,15 @@ static int __init vivi_create_instance(int inst)
/* Now that everything is fine, let's add it to device list */
list_add_tail(&dev->vivi_devlist, &vivi_devlist);
+ snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
+ vivi_template.name, vfd->num);
+
if (video_nr >= 0)
video_nr++;
dev->vfd = vfd;
- v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
- video_device_node_name(vfd));
+ v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n",
+ vfd->num);
return 0;
rel_vdev:
diff --git a/trunk/drivers/media/video/w9968cf.c b/trunk/drivers/media/video/w9968cf.c
index d807eea91757..37fcdc447db5 100644
--- a/trunk/drivers/media/video/w9968cf.c
+++ b/trunk/drivers/media/video/w9968cf.c
@@ -2323,9 +2323,9 @@ static int w9968cf_sensor_init(struct w9968cf_device* cam)
error:
cam->sensor_initialized = 0;
cam->sensor = CC_UNKNOWN;
- DBG(1, "Image sensor initialization failed for %s (%s). "
+ DBG(1, "Image sensor initialization failed for %s (/dev/video%d). "
"Try to detach and attach this device again",
- symbolic(camlist, cam->id), video_device_node_name(cam->v4ldev))
+ symbolic(camlist, cam->id), cam->v4ldev->num)
return err;
}
@@ -2571,8 +2571,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam)
{
mutex_lock(&w9968cf_devlist_mutex);
- DBG(2, "V4L device deregistered: %s",
- video_device_node_name(cam->v4ldev))
+ DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->num)
video_unregister_device(cam->v4ldev);
list_del(&cam->v4llist);
@@ -2606,19 +2605,17 @@ static int w9968cf_open(struct file *filp)
if (cam->sensor == CC_UNKNOWN) {
DBG(2, "No supported image sensor has been detected by the "
- "'ovcamchip' module for the %s (%s). Make sure "
- "it is loaded *before* (re)connecting the camera.",
- symbolic(camlist, cam->id),
- video_device_node_name(cam->v4ldev))
+ "'ovcamchip' module for the %s (/dev/video%d). Make "
+ "sure it is loaded *before* (re)connecting the camera.",
+ symbolic(camlist, cam->id), cam->v4ldev->num)
mutex_unlock(&cam->dev_mutex);
up_read(&w9968cf_disconnect);
return -ENODEV;
}
if (cam->users) {
- DBG(2, "%s (%s) has been already occupied by '%s'",
- symbolic(camlist, cam->id),
- video_device_node_name(cam->v4ldev), cam->command)
+ DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
+ symbolic(camlist, cam->id), cam->v4ldev->num, cam->command)
if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
mutex_unlock(&cam->dev_mutex);
up_read(&w9968cf_disconnect);
@@ -2639,8 +2636,8 @@ static int w9968cf_open(struct file *filp)
mutex_lock(&cam->dev_mutex);
}
- DBG(5, "Opening '%s', %s ...",
- symbolic(camlist, cam->id), video_device_node_name(cam->v4ldev))
+ DBG(5, "Opening '%s', /dev/video%d ...",
+ symbolic(camlist, cam->id), cam->v4ldev->num)
cam->streaming = 0;
cam->misconfigured = 0;
@@ -2877,7 +2874,8 @@ static long w9968cf_v4l_ioctl(struct file *filp,
.minwidth = cam->minwidth,
.minheight = cam->minheight,
};
- sprintf(cap.name, "W996[87]CF USB Camera");
+ sprintf(cap.name, "W996[87]CF USB Camera #%d",
+ cam->v4ldev->num);
cap.maxwidth = (cam->upscaling && w9968cf_vpp)
? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
: cam->maxwidth;
@@ -3487,6 +3485,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
cam->v4ldev->fops = &w9968cf_fops;
+ cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
video_set_drvdata(cam->v4ldev, cam);
cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
@@ -3502,8 +3501,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
goto fail;
}
- DBG(2, "V4L device registered as %s",
- video_device_node_name(cam->v4ldev))
+ DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->num)
/* Set some basic constants */
w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
@@ -3559,10 +3557,10 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
wake_up_interruptible_all(&cam->open);
if (cam->users) {
- DBG(2, "The device is open (%s)! "
+ DBG(2, "The device is open (/dev/video%d)! "
"Process name: %s. Deregistration and memory "
"deallocation are deferred on close.",
- video_device_node_name(cam->v4ldev), cam->command)
+ cam->v4ldev->num, cam->command)
cam->misconfigured = 1;
w9968cf_stop_transfer(cam);
wake_up_interruptible(&cam->wait_queue);
diff --git a/trunk/drivers/media/video/zc0301/zc0301_core.c b/trunk/drivers/media/video/zc0301/zc0301_core.c
index e44e4b5f3e50..312a71336fd0 100644
--- a/trunk/drivers/media/video/zc0301/zc0301_core.c
+++ b/trunk/drivers/media/video/zc0301/zc0301_core.c
@@ -538,8 +538,8 @@ static int zc0301_stream_interrupt(struct zc0301_device* cam)
else if (cam->stream != STREAM_OFF) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "URB timeout reached. The camera is misconfigured. To "
- "use it, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use it, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -EIO;
}
@@ -640,8 +640,7 @@ static void zc0301_release_resources(struct kref *kref)
{
struct zc0301_device *cam = container_of(kref, struct zc0301_device,
kref);
- DBG(2, "V4L2 device %s deregistered",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num);
video_set_drvdata(cam->v4ldev, NULL);
video_unregister_device(cam->v4ldev);
usb_put_dev(cam->usbdev);
@@ -680,8 +679,7 @@ static int zc0301_open(struct file *filp)
}
if (cam->users) {
- DBG(2, "Device %s is busy...",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->num);
DBG(3, "Simultaneous opens are not supported");
if ((filp->f_flags & O_NONBLOCK) ||
(filp->f_flags & O_NDELAY)) {
@@ -724,8 +722,7 @@ static int zc0301_open(struct file *filp)
cam->frame_count = 0;
zc0301_empty_framequeues(cam);
- DBG(3, "Video device %s is open",
- video_device_node_name(cam->v4ldev));
+ DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num);
out:
mutex_unlock(&cam->open_mutex);
@@ -749,8 +746,7 @@ static int zc0301_release(struct file *filp)
cam->users--;
wake_up_interruptible_nr(&cam->wait_open, 1);
- DBG(3, "Video device %s closed",
- video_device_node_name(cam->v4ldev));
+ DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num);
kref_put(&cam->kref, zc0301_release_resources);
@@ -1280,8 +1276,8 @@ zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
if (err) { /* atomic, no rollback in ioctl() */
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -EIO;
}
@@ -1293,8 +1289,8 @@ zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -ENOMEM;
}
@@ -1475,8 +1471,8 @@ zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
if (err) { /* atomic, no rollback in ioctl() */
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -EIO;
}
@@ -1487,8 +1483,8 @@ zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "use the camera, close and open /dev/video%d again.",
+ cam->v4ldev->num);
return -ENOMEM;
}
@@ -1534,8 +1530,8 @@ zc0301_vidioc_s_jpegcomp(struct zc0301_device* cam, void __user * arg)
if (err) { /* atomic, no rollback in ioctl() */
cam->state |= DEV_MISCONFIGURED;
DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
- "problems. To use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
+ "problems. To use the camera, close and open "
+ "/dev/video%d again.", cam->v4ldev->num);
return -EIO;
}
@@ -1988,6 +1984,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera");
cam->v4ldev->fops = &zc0301_fops;
+ cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
cam->v4ldev->parent = &udev->dev;
video_set_drvdata(cam->v4ldev, cam);
@@ -2006,8 +2003,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
goto fail;
}
- DBG(2, "V4L2 device registered as %s",
- video_device_node_name(cam->v4ldev));
+ DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num);
cam->module_param.force_munmap = force_munmap[dev_nr];
cam->module_param.frame_timeout = frame_timeout[dev_nr];
@@ -2044,9 +2040,9 @@ static void zc0301_usb_disconnect(struct usb_interface* intf)
DBG(2, "Disconnecting %s...", cam->v4ldev->name);
if (cam->users) {
- DBG(2, "Device %s is open! Deregistration and "
+ DBG(2, "Device /dev/video%d is open! Deregistration and "
"memory deallocation are deferred.",
- video_device_node_name(cam->v4ldev));
+ cam->v4ldev->num);
cam->state |= DEV_MISCONFIGURED;
zc0301_stop_transfer(cam);
cam->state |= DEV_DISCONNECTED;
diff --git a/trunk/drivers/media/video/zoran/zoran_driver.c b/trunk/drivers/media/video/zoran/zoran_driver.c
index 2ddffed019ee..e9f72ca458f1 100644
--- a/trunk/drivers/media/video/zoran/zoran_driver.c
+++ b/trunk/drivers/media/video/zoran/zoran_driver.c
@@ -3387,5 +3387,6 @@ struct video_device zoran_template __devinitdata = {
.ioctl_ops = &zoran_ioctl_ops,
.release = &zoran_vdev_release,
.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+ .minor = -1
};
diff --git a/trunk/drivers/media/video/zr364xx.c b/trunk/drivers/media/video/zr364xx.c
index f0eae83e3d89..2ef110b5221b 100644
--- a/trunk/drivers/media/video/zr364xx.c
+++ b/trunk/drivers/media/video/zr364xx.c
@@ -1455,6 +1455,7 @@ static struct video_device zr364xx_template = {
.fops = &zr364xx_fops,
.ioctl_ops = &zr364xx_ioctl_ops,
.release = video_device_release,
+ .minor = -1,
};
@@ -1634,8 +1635,8 @@ static int zr364xx_probe(struct usb_interface *intf,
spin_lock_init(&cam->slock);
- dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n",
- video_device_node_name(cam->vdev));
+ dev_info(&udev->dev, DRIVER_DESC " controlling video device %d\n",
+ cam->vdev->num);
return 0;
}
diff --git a/trunk/drivers/misc/sgi-gru/gru.h b/trunk/drivers/misc/sgi-gru/gru.h
index 3ad76cd18b4b..f93f03a9e6e9 100644
--- a/trunk/drivers/misc/sgi-gru/gru.h
+++ b/trunk/drivers/misc/sgi-gru/gru.h
@@ -53,17 +53,6 @@ struct gru_chiplet_info {
int free_user_cbr;
};
-/*
- * Statictics kept for each context.
- */
-struct gru_gseg_statistics {
- unsigned long fmm_tlbmiss;
- unsigned long upm_tlbmiss;
- unsigned long tlbdropin;
- unsigned long context_stolen;
- unsigned long reserved[10];
-};
-
/* Flags for GRU options on the gru_create_context() call */
/* Select one of the follow 4 options to specify how TLB misses are handled */
#define GRU_OPT_MISS_DEFAULT 0x0000 /* Use default mode */
diff --git a/trunk/drivers/misc/sgi-gru/gru_instructions.h b/trunk/drivers/misc/sgi-gru/gru_instructions.h
index d95587cc794c..3c9c06618e6a 100644
--- a/trunk/drivers/misc/sgi-gru/gru_instructions.h
+++ b/trunk/drivers/misc/sgi-gru/gru_instructions.h
@@ -34,17 +34,17 @@ extern void gru_wait_abort_proc(void *cb);
#include
#define __flush_cache(p) ia64_fc((unsigned long)p)
/* Use volatile on IA64 to ensure ordering via st4.rel */
-#define gru_ordered_store_ulong(p, v) \
+#define gru_ordered_store_int(p, v) \
do { \
barrier(); \
- *((volatile unsigned long *)(p)) = v; /* force st.rel */ \
+ *((volatile int *)(p)) = v; /* force st.rel */ \
} while (0)
#elif defined(CONFIG_X86_64)
#define __flush_cache(p) clflush(p)
-#define gru_ordered_store_ulong(p, v) \
+#define gru_ordered_store_int(p, v) \
do { \
barrier(); \
- *(unsigned long *)p = v; \
+ *(int *)p = v; \
} while (0)
#else
#error "Unsupported architecture"
@@ -129,13 +129,8 @@ struct gru_instruction_bits {
*/
struct gru_instruction {
/* DW 0 */
- union {
- unsigned long op64; /* icmd,xtype,iaa0,ima,opc,tri0 */
- struct {
- unsigned int op32;
- unsigned int tri0;
- };
- };
+ unsigned int op32; /* icmd,xtype,iaa0,ima,opc */
+ unsigned int tri0;
unsigned long tri1_bufsize; /* DW 1 */
unsigned long baddr0; /* DW 2 */
unsigned long nelem; /* DW 3 */
@@ -145,7 +140,7 @@ struct gru_instruction {
unsigned long avalue; /* DW 7 */
};
-/* Some shifts and masks for the low 64 bits of a GRU command */
+/* Some shifts and masks for the low 32 bits of a GRU command */
#define GRU_CB_ICMD_SHFT 0
#define GRU_CB_ICMD_MASK 0x1
#define GRU_CB_XTYPE_SHFT 8
@@ -160,10 +155,6 @@ struct gru_instruction {
#define GRU_CB_OPC_MASK 0xff
#define GRU_CB_EXOPC_SHFT 24
#define GRU_CB_EXOPC_MASK 0xff
-#define GRU_IDEF2_SHFT 32
-#define GRU_IDEF2_MASK 0x3ffff
-#define GRU_ISTATUS_SHFT 56
-#define GRU_ISTATUS_MASK 0x3
/* GRU instruction opcodes (opc field) */
#define OP_NOP 0x00
@@ -265,7 +256,6 @@ struct gru_instruction {
#define CBE_CAUSE_PROTOCOL_STATE_DATA_ERROR (1 << 16)
#define CBE_CAUSE_RA_RESPONSE_DATA_ERROR (1 << 17)
#define CBE_CAUSE_HA_RESPONSE_DATA_ERROR (1 << 18)
-#define CBE_CAUSE_FORCED_ERROR (1 << 19)
/* CBE cbrexecstatus bits */
#define CBR_EXS_ABORT_OCC_BIT 0
@@ -274,15 +264,13 @@ struct gru_instruction {
#define CBR_EXS_QUEUED_BIT 3
#define CBR_EXS_TLB_INVAL_BIT 4
#define CBR_EXS_EXCEPTION_BIT 5
-#define CBR_EXS_CB_INT_PENDING_BIT 6
#define CBR_EXS_ABORT_OCC (1 << CBR_EXS_ABORT_OCC_BIT)
#define CBR_EXS_INT_OCC (1 << CBR_EXS_INT_OCC_BIT)
#define CBR_EXS_PENDING (1 << CBR_EXS_PENDING_BIT)
#define CBR_EXS_QUEUED (1 << CBR_EXS_QUEUED_BIT)
-#define CBR_EXS_TLB_INVAL (1 << CBR_EXS_TLB_INVAL_BIT)
+#define CBR_TLB_INVAL (1 << CBR_EXS_TLB_INVAL_BIT)
#define CBR_EXS_EXCEPTION (1 << CBR_EXS_EXCEPTION_BIT)
-#define CBR_EXS_CB_INT_PENDING (1 << CBR_EXS_CB_INT_PENDING_BIT)
/*
* Exceptions are retried for the following cases. If any OTHER bits are set
@@ -308,14 +296,12 @@ union gru_mesqhead {
/* Generate the low word of a GRU instruction */
-static inline unsigned long
-__opdword(unsigned char opcode, unsigned char exopc, unsigned char xtype,
+static inline unsigned int
+__opword(unsigned char opcode, unsigned char exopc, unsigned char xtype,
unsigned char iaa0, unsigned char iaa1,
- unsigned long idef2, unsigned char ima)
+ unsigned char ima)
{
return (1 << GRU_CB_ICMD_SHFT) |
- ((unsigned long)CBS_ACTIVE << GRU_ISTATUS_SHFT) |
- (idef2<< GRU_IDEF2_SHFT) |
(iaa0 << GRU_CB_IAA0_SHFT) |
(iaa1 << GRU_CB_IAA1_SHFT) |
(ima << GRU_CB_IMA_SHFT) |
@@ -333,13 +319,12 @@ static inline void gru_flush_cache(void *p)
}
/*
- * Store the lower 64 bits of the command including the "start" bit. Then
+ * Store the lower 32 bits of the command including the "start" bit. Then
* start the instruction executing.
*/
-static inline void gru_start_instruction(struct gru_instruction *ins, unsigned long op64)
+static inline void gru_start_instruction(struct gru_instruction *ins, int op32)
{
- gru_ordered_store_ulong(ins, op64);
- mb();
+ gru_ordered_store_int(ins, op32);
gru_flush_cache(ins);
}
@@ -355,30 +340,6 @@ static inline void gru_start_instruction(struct gru_instruction *ins, unsigned l
* - nelem and stride are in elements
* - tri0/tri1 is in bytes for the beginning of the data segment.
*/
-static inline void gru_vload_phys(void *cb, unsigned long gpa,
- unsigned int tri0, int iaa, unsigned long hints)
-{
- struct gru_instruction *ins = (struct gru_instruction *)cb;
-
- ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
- ins->nelem = 1;
- ins->op1_stride = 1;
- gru_start_instruction(ins, __opdword(OP_VLOAD, 0, XTYPE_DW, iaa, 0,
- (unsigned long)tri0, CB_IMA(hints)));
-}
-
-static inline void gru_vstore_phys(void *cb, unsigned long gpa,
- unsigned int tri0, int iaa, unsigned long hints)
-{
- struct gru_instruction *ins = (struct gru_instruction *)cb;
-
- ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
- ins->nelem = 1;
- ins->op1_stride = 1;
- gru_start_instruction(ins, __opdword(OP_VSTORE, 0, XTYPE_DW, iaa, 0,
- (unsigned long)tri0, CB_IMA(hints)));
-}
-
static inline void gru_vload(void *cb, unsigned long mem_addr,
unsigned int tri0, unsigned char xtype, unsigned long nelem,
unsigned long stride, unsigned long hints)
@@ -387,9 +348,10 @@ static inline void gru_vload(void *cb, unsigned long mem_addr,
ins->baddr0 = (long)mem_addr;
ins->nelem = nelem;
+ ins->tri0 = tri0;
ins->op1_stride = stride;
- gru_start_instruction(ins, __opdword(OP_VLOAD, 0, xtype, IAA_RAM, 0,
- (unsigned long)tri0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_VLOAD, 0, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_vstore(void *cb, unsigned long mem_addr,
@@ -400,9 +362,10 @@ static inline void gru_vstore(void *cb, unsigned long mem_addr,
ins->baddr0 = (long)mem_addr;
ins->nelem = nelem;
+ ins->tri0 = tri0;
ins->op1_stride = stride;
- gru_start_instruction(ins, __opdword(OP_VSTORE, 0, xtype, IAA_RAM, 0,
- tri0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_VSTORE, 0, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_ivload(void *cb, unsigned long mem_addr,
@@ -413,9 +376,10 @@ static inline void gru_ivload(void *cb, unsigned long mem_addr,
ins->baddr0 = (long)mem_addr;
ins->nelem = nelem;
+ ins->tri0 = tri0;
ins->tri1_bufsize = tri1;
- gru_start_instruction(ins, __opdword(OP_IVLOAD, 0, xtype, IAA_RAM, 0,
- tri0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_IVLOAD, 0, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_ivstore(void *cb, unsigned long mem_addr,
@@ -426,9 +390,10 @@ static inline void gru_ivstore(void *cb, unsigned long mem_addr,
ins->baddr0 = (long)mem_addr;
ins->nelem = nelem;
+ ins->tri0 = tri0;
ins->tri1_bufsize = tri1;
- gru_start_instruction(ins, __opdword(OP_IVSTORE, 0, xtype, IAA_RAM, 0,
- tri0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_IVSTORE, 0, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_vset(void *cb, unsigned long mem_addr,
@@ -441,8 +406,8 @@ static inline void gru_vset(void *cb, unsigned long mem_addr,
ins->op2_value_baddr1 = value;
ins->nelem = nelem;
ins->op1_stride = stride;
- gru_start_instruction(ins, __opdword(OP_VSET, 0, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_VSET, 0, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_ivset(void *cb, unsigned long mem_addr,
@@ -455,8 +420,8 @@ static inline void gru_ivset(void *cb, unsigned long mem_addr,
ins->op2_value_baddr1 = value;
ins->nelem = nelem;
ins->tri1_bufsize = tri1;
- gru_start_instruction(ins, __opdword(OP_IVSET, 0, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_IVSET, 0, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_vflush(void *cb, unsigned long mem_addr,
@@ -468,15 +433,15 @@ static inline void gru_vflush(void *cb, unsigned long mem_addr,
ins->baddr0 = (long)mem_addr;
ins->op1_stride = stride;
ins->nelem = nelem;
- gru_start_instruction(ins, __opdword(OP_VFLUSH, 0, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_VFLUSH, 0, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_nop(void *cb, int hints)
{
struct gru_instruction *ins = (void *)cb;
- gru_start_instruction(ins, __opdword(OP_NOP, 0, 0, 0, 0, 0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_NOP, 0, 0, 0, 0, CB_IMA(hints)));
}
@@ -490,9 +455,10 @@ static inline void gru_bcopy(void *cb, const unsigned long src,
ins->baddr0 = (long)src;
ins->op2_value_baddr1 = (long)dest;
ins->nelem = nelem;
+ ins->tri0 = tri0;
ins->tri1_bufsize = bufsize;
- gru_start_instruction(ins, __opdword(OP_BCOPY, 0, xtype, IAA_RAM,
- IAA_RAM, tri0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_BCOPY, 0, xtype, IAA_RAM,
+ IAA_RAM, CB_IMA(hints)));
}
static inline void gru_bstore(void *cb, const unsigned long src,
@@ -504,8 +470,9 @@ static inline void gru_bstore(void *cb, const unsigned long src,
ins->baddr0 = (long)src;
ins->op2_value_baddr1 = (long)dest;
ins->nelem = nelem;
- gru_start_instruction(ins, __opdword(OP_BSTORE, 0, xtype, 0, IAA_RAM,
- tri0, CB_IMA(hints)));
+ ins->tri0 = tri0;
+ gru_start_instruction(ins, __opword(OP_BSTORE, 0, xtype, 0, IAA_RAM,
+ CB_IMA(hints)));
}
static inline void gru_gamir(void *cb, int exopc, unsigned long src,
@@ -514,8 +481,8 @@ static inline void gru_gamir(void *cb, int exopc, unsigned long src,
struct gru_instruction *ins = (void *)cb;
ins->baddr0 = (long)src;
- gru_start_instruction(ins, __opdword(OP_GAMIR, exopc, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_GAMIR, exopc, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_gamirr(void *cb, int exopc, unsigned long src,
@@ -524,8 +491,8 @@ static inline void gru_gamirr(void *cb, int exopc, unsigned long src,
struct gru_instruction *ins = (void *)cb;
ins->baddr0 = (long)src;
- gru_start_instruction(ins, __opdword(OP_GAMIRR, exopc, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_GAMIRR, exopc, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_gamer(void *cb, int exopc, unsigned long src,
@@ -538,8 +505,8 @@ static inline void gru_gamer(void *cb, int exopc, unsigned long src,
ins->baddr0 = (long)src;
ins->op1_stride = operand1;
ins->op2_value_baddr1 = operand2;
- gru_start_instruction(ins, __opdword(OP_GAMER, exopc, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_GAMER, exopc, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_gamerr(void *cb, int exopc, unsigned long src,
@@ -551,8 +518,8 @@ static inline void gru_gamerr(void *cb, int exopc, unsigned long src,
ins->baddr0 = (long)src;
ins->op1_stride = operand1;
ins->op2_value_baddr1 = operand2;
- gru_start_instruction(ins, __opdword(OP_GAMERR, exopc, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_GAMERR, exopc, xtype, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline void gru_gamxr(void *cb, unsigned long src,
@@ -562,8 +529,8 @@ static inline void gru_gamxr(void *cb, unsigned long src,
ins->baddr0 = (long)src;
ins->nelem = 4;
- gru_start_instruction(ins, __opdword(OP_GAMXR, EOP_XR_CSWAP, XTYPE_DW,
- IAA_RAM, 0, 0, CB_IMA(hints)));
+ gru_start_instruction(ins, __opword(OP_GAMXR, EOP_XR_CSWAP, XTYPE_DW,
+ IAA_RAM, 0, CB_IMA(hints)));
}
static inline void gru_mesq(void *cb, unsigned long queue,
@@ -574,8 +541,9 @@ static inline void gru_mesq(void *cb, unsigned long queue,
ins->baddr0 = (long)queue;
ins->nelem = nelem;
- gru_start_instruction(ins, __opdword(OP_MESQ, 0, XTYPE_CL, IAA_RAM, 0,
- tri0, CB_IMA(hints)));
+ ins->tri0 = tri0;
+ gru_start_instruction(ins, __opword(OP_MESQ, 0, XTYPE_CL, IAA_RAM, 0,
+ CB_IMA(hints)));
}
static inline unsigned long gru_get_amo_value(void *cb)
@@ -694,14 +662,6 @@ static inline void gru_wait_abort(void *cb)
gru_wait_abort_proc(cb);
}
-/*
- * Get a pointer to the start of a gseg
- * p - Any valid pointer within the gseg
- */
-static inline void *gru_get_gseg_pointer (void *p)
-{
- return (void *)((unsigned long)p & ~(GRU_GSEG_PAGESIZE - 1));
-}
/*
* Get a pointer to a control block
diff --git a/trunk/drivers/misc/sgi-gru/grufault.c b/trunk/drivers/misc/sgi-gru/grufault.c
index 38657cdaf54d..679e01778286 100644
--- a/trunk/drivers/misc/sgi-gru/grufault.c
+++ b/trunk/drivers/misc/sgi-gru/grufault.c
@@ -40,12 +40,6 @@
#include "gru_instructions.h"
#include
-/* Return codes for vtop functions */
-#define VTOP_SUCCESS 0
-#define VTOP_INVALID -1
-#define VTOP_RETRY -2
-
-
/*
* Test if a physical address is a valid GRU GSEG address
*/
@@ -96,22 +90,19 @@ static struct gru_thread_state *gru_alloc_locked_gts(unsigned long vaddr)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- struct gru_thread_state *gts = ERR_PTR(-EINVAL);
+ struct gru_thread_state *gts = NULL;
down_write(&mm->mmap_sem);
vma = gru_find_vma(vaddr);
- if (!vma)
- goto err;
-
- gts = gru_alloc_thread_state(vma, TSID(vaddr, vma));
- if (IS_ERR(gts))
- goto err;
- mutex_lock(>s->ts_ctxlock);
- downgrade_write(&mm->mmap_sem);
- return gts;
+ if (vma)
+ gts = gru_alloc_thread_state(vma, TSID(vaddr, vma));
+ if (gts) {
+ mutex_lock(>s->ts_ctxlock);
+ downgrade_write(&mm->mmap_sem);
+ } else {
+ up_write(&mm->mmap_sem);
+ }
-err:
- up_write(&mm->mmap_sem);
return gts;
}
@@ -131,14 +122,38 @@ static void gru_unlock_gts(struct gru_thread_state *gts)
* is necessary to prevent the user from seeing a stale cb.istatus that will
* change as soon as the TFH restart is complete. Races may cause an
* occasional failure to clear the cb.istatus, but that is ok.
+ *
+ * If the cb address is not valid (should not happen, but...), nothing
+ * bad will happen.. The get_user()/put_user() will fail but there
+ * are no bad side-effects.
*/
-static void gru_cb_set_istatus_active(struct gru_instruction_bits *cbk)
+static void gru_cb_set_istatus_active(unsigned long __user *cb)
{
- if (cbk) {
- cbk->istatus = CBS_ACTIVE;
+ union {
+ struct gru_instruction_bits bits;
+ unsigned long dw;
+ } u;
+
+ if (cb) {
+ get_user(u.dw, cb);
+ u.bits.istatus = CBS_ACTIVE;
+ put_user(u.dw, cb);
}
}
+/*
+ * Convert a interrupt IRQ to a pointer to the GRU GTS that caused the
+ * interrupt. Interrupts are always sent to a cpu on the blade that contains the
+ * GRU (except for headless blades which are not currently supported). A blade
+ * has N grus; a block of N consecutive IRQs is assigned to the GRUs. The IRQ
+ * number uniquely identifies the GRU chiplet on the local blade that caused the
+ * interrupt. Always called in interrupt context.
+ */
+static inline struct gru_state *irq_to_gru(int irq)
+{
+ return &gru_base[uv_numa_blade_id()]->bs_grus[irq - IRQ_GRU];
+}
+
/*
* Read & clear a TFM
*
@@ -192,11 +207,10 @@ static int non_atomic_pte_lookup(struct vm_area_struct *vma,
{
struct page *page;
-#ifdef CONFIG_HUGETLB_PAGE
- *pageshift = is_vm_hugetlb_page(vma) ? HPAGE_SHIFT : PAGE_SHIFT;
-#else
+ /* ZZZ Need to handle HUGE pages */
+ if (is_vm_hugetlb_page(vma))
+ return -EFAULT;
*pageshift = PAGE_SHIFT;
-#endif
if (get_user_pages
(current, current->mm, vaddr, 1, write, 0, &page, NULL) <= 0)
return -EFAULT;
@@ -254,6 +268,7 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
return 0;
err:
+ local_irq_enable();
return 1;
}
@@ -286,69 +301,14 @@ static int gru_vtop(struct gru_thread_state *gts, unsigned long vaddr,
paddr = paddr & ~((1UL << ps) - 1);
*gpa = uv_soc_phys_ram_to_gpa(paddr);
*pageshift = ps;
- return VTOP_SUCCESS;
+ return 0;
inval:
- return VTOP_INVALID;
+ return -1;
upm:
- return VTOP_RETRY;
-}
-
-
-/*
- * Flush a CBE from cache. The CBE is clean in the cache. Dirty the
- * CBE cacheline so that the line will be written back to home agent.
- * Otherwise the line may be silently dropped. This has no impact
- * except on performance.
- */
-static void gru_flush_cache_cbe(struct gru_control_block_extended *cbe)
-{
- if (unlikely(cbe)) {
- cbe->cbrexecstatus = 0; /* make CL dirty */
- gru_flush_cache(cbe);
- }
+ return -2;
}
-/*
- * Preload the TLB with entries that may be required. Currently, preloading
- * is implemented only for BCOPY. Preload pages OR to
- * the end of the bcopy tranfer, whichever is smaller.
- */
-static void gru_preload_tlb(struct gru_state *gru,
- struct gru_thread_state *gts, int atomic,
- unsigned long fault_vaddr, int asid, int write,
- unsigned char tlb_preload_count,
- struct gru_tlb_fault_handle *tfh,
- struct gru_control_block_extended *cbe)
-{
- unsigned long vaddr = 0, gpa;
- int ret, pageshift;
-
- if (cbe->opccpy != OP_BCOPY)
- return;
-
- if (fault_vaddr == cbe->cbe_baddr0)
- vaddr = fault_vaddr + GRU_CACHE_LINE_BYTES * cbe->cbe_src_cl - 1;
- else if (fault_vaddr == cbe->cbe_baddr1)
- vaddr = fault_vaddr + (1 << cbe->xtypecpy) * cbe->cbe_nelemcur - 1;
-
- fault_vaddr &= PAGE_MASK;
- vaddr &= PAGE_MASK;
- vaddr = min(vaddr, fault_vaddr + tlb_preload_count * PAGE_SIZE);
-
- while (vaddr > fault_vaddr) {
- ret = gru_vtop(gts, vaddr, write, atomic, &gpa, &pageshift);
- if (ret || tfh_write_only(tfh, gpa, GAA_RAM, vaddr, asid, write,
- GRU_PAGESIZE(pageshift)))
- return;
- gru_dbg(grudev,
- "%s: gid %d, gts 0x%p, tfh 0x%p, vaddr 0x%lx, asid 0x%x, rw %d, ps %d, gpa 0x%lx\n",
- atomic ? "atomic" : "non-atomic", gru->gs_gid, gts, tfh,
- vaddr, asid, write, pageshift, gpa);
- vaddr -= PAGE_SIZE;
- STAT(tlb_preload_page);
- }
-}
/*
* Drop a TLB entry into the GRU. The fault is described by info in an TFH.
@@ -360,14 +320,11 @@ static void gru_preload_tlb(struct gru_state *gru,
* < 0 = error code
*
*/
-static int gru_try_dropin(struct gru_state *gru,
- struct gru_thread_state *gts,
+static int gru_try_dropin(struct gru_thread_state *gts,
struct gru_tlb_fault_handle *tfh,
- struct gru_instruction_bits *cbk)
+ unsigned long __user *cb)
{
- struct gru_control_block_extended *cbe = NULL;
- unsigned char tlb_preload_count = gts->ts_tlb_preload_count;
- int pageshift = 0, asid, write, ret, atomic = !cbk, indexway;
+ int pageshift = 0, asid, write, ret, atomic = !cb;
unsigned long gpa = 0, vaddr = 0;
/*
@@ -377,14 +334,6 @@ static int gru_try_dropin(struct gru_state *gru,
* the dropin is ignored. This eliminates the need for additional locks.
*/
- /*
- * Prefetch the CBE if doing TLB preloading
- */
- if (unlikely(tlb_preload_count)) {
- cbe = gru_tfh_to_cbe(tfh);
- prefetchw(cbe);
- }
-
/*
* Error if TFH state is IDLE or FMM mode & the user issuing a UPM call.
* Might be a hardware race OR a stupid user. Ignore FMM because FMM
@@ -392,20 +341,18 @@ static int gru_try_dropin(struct gru_state *gru,
*/
if (tfh->status != TFHSTATUS_EXCEPTION) {
gru_flush_cache(tfh);
- sync_core();
if (tfh->status != TFHSTATUS_EXCEPTION)
goto failnoexception;
STAT(tfh_stale_on_fault);
}
if (tfh->state == TFHSTATE_IDLE)
goto failidle;
- if (tfh->state == TFHSTATE_MISS_FMM && cbk)
+ if (tfh->state == TFHSTATE_MISS_FMM && cb)
goto failfmm;
write = (tfh->cause & TFHCAUSE_TLB_MOD) != 0;
vaddr = tfh->missvaddr;
asid = tfh->missasid;
- indexway = tfh->indexway;
if (asid == 0)
goto failnoasid;
@@ -419,51 +366,41 @@ static int gru_try_dropin(struct gru_state *gru,
goto failactive;
ret = gru_vtop(gts, vaddr, write, atomic, &gpa, &pageshift);
- if (ret == VTOP_INVALID)
+ if (ret == -1)
goto failinval;
- if (ret == VTOP_RETRY)
+ if (ret == -2)
goto failupm;
if (!(gts->ts_sizeavail & GRU_SIZEAVAIL(pageshift))) {
gts->ts_sizeavail |= GRU_SIZEAVAIL(pageshift);
- if (atomic || !gru_update_cch(gts)) {
+ if (atomic || !gru_update_cch(gts, 0)) {
gts->ts_force_cch_reload = 1;
goto failupm;
}
}
-
- if (unlikely(cbe) && pageshift == PAGE_SHIFT) {
- gru_preload_tlb(gru, gts, atomic, vaddr, asid, write, tlb_preload_count, tfh, cbe);
- gru_flush_cache_cbe(cbe);
- }
-
- gru_cb_set_istatus_active(cbk);
- gts->ustats.tlbdropin++;
+ gru_cb_set_istatus_active(cb);
tfh_write_restart(tfh, gpa, GAA_RAM, vaddr, asid, write,
GRU_PAGESIZE(pageshift));
- gru_dbg(grudev,
- "%s: gid %d, gts 0x%p, tfh 0x%p, vaddr 0x%lx, asid 0x%x, indexway 0x%x,"
- " rw %d, ps %d, gpa 0x%lx\n",
- atomic ? "atomic" : "non-atomic", gru->gs_gid, gts, tfh, vaddr, asid,
- indexway, write, pageshift, gpa);
STAT(tlb_dropin);
+ gru_dbg(grudev,
+ "%s: tfh 0x%p, vaddr 0x%lx, asid 0x%x, ps %d, gpa 0x%lx\n",
+ ret ? "non-atomic" : "atomic", tfh, vaddr, asid,
+ pageshift, gpa);
return 0;
failnoasid:
/* No asid (delayed unload). */
STAT(tlb_dropin_fail_no_asid);
gru_dbg(grudev, "FAILED no_asid tfh: 0x%p, vaddr 0x%lx\n", tfh, vaddr);
- if (!cbk)
+ if (!cb)
tfh_user_polling_mode(tfh);
else
gru_flush_cache(tfh);
- gru_flush_cache_cbe(cbe);
return -EAGAIN;
failupm:
/* Atomic failure switch CBR to UPM */
tfh_user_polling_mode(tfh);
- gru_flush_cache_cbe(cbe);
STAT(tlb_dropin_fail_upm);
gru_dbg(grudev, "FAILED upm tfh: 0x%p, vaddr 0x%lx\n", tfh, vaddr);
return 1;
@@ -471,7 +408,6 @@ static int gru_try_dropin(struct gru_state *gru,
failfmm:
/* FMM state on UPM call */
gru_flush_cache(tfh);
- gru_flush_cache_cbe(cbe);
STAT(tlb_dropin_fail_fmm);
gru_dbg(grudev, "FAILED fmm tfh: 0x%p, state %d\n", tfh, tfh->state);
return 0;
@@ -479,20 +415,17 @@ static int gru_try_dropin(struct gru_state *gru,
failnoexception:
/* TFH status did not show exception pending */
gru_flush_cache(tfh);
- gru_flush_cache_cbe(cbe);
- if (cbk)
- gru_flush_cache(cbk);
+ if (cb)
+ gru_flush_cache(cb);
STAT(tlb_dropin_fail_no_exception);
- gru_dbg(grudev, "FAILED non-exception tfh: 0x%p, status %d, state %d\n",
- tfh, tfh->status, tfh->state);
+ gru_dbg(grudev, "FAILED non-exception tfh: 0x%p, status %d, state %d\n", tfh, tfh->status, tfh->state);
return 0;
failidle:
/* TFH state was idle - no miss pending */
gru_flush_cache(tfh);
- gru_flush_cache_cbe(cbe);
- if (cbk)
- gru_flush_cache(cbk);
+ if (cb)
+ gru_flush_cache(cb);
STAT(tlb_dropin_fail_idle);
gru_dbg(grudev, "FAILED idle tfh: 0x%p, state %d\n", tfh, tfh->state);
return 0;
@@ -500,18 +433,16 @@ static int gru_try_dropin(struct gru_state *gru,
failinval:
/* All errors (atomic & non-atomic) switch CBR to EXCEPTION state */
tfh_exception(tfh);
- gru_flush_cache_cbe(cbe);
STAT(tlb_dropin_fail_invalid);
gru_dbg(grudev, "FAILED inval tfh: 0x%p, vaddr 0x%lx\n", tfh, vaddr);
return -EFAULT;
failactive:
/* Range invalidate active. Switch to UPM iff atomic */
- if (!cbk)
+ if (!cb)
tfh_user_polling_mode(tfh);
else
gru_flush_cache(tfh);
- gru_flush_cache_cbe(cbe);
STAT(tlb_dropin_fail_range_active);
gru_dbg(grudev, "FAILED range active: tfh 0x%p, vaddr 0x%lx\n",
tfh, vaddr);
@@ -524,41 +455,31 @@ static int gru_try_dropin(struct gru_state *gru,
* Note that this is the interrupt handler that is registered with linux
* interrupt handlers.
*/
-static irqreturn_t gru_intr(int chiplet, int blade)
+irqreturn_t gru_intr(int irq, void *dev_id)
{
struct gru_state *gru;
struct gru_tlb_fault_map imap, dmap;
struct gru_thread_state *gts;
struct gru_tlb_fault_handle *tfh = NULL;
- struct completion *cmp;
int cbrnum, ctxnum;
STAT(intr);
- gru = &gru_base[blade]->bs_grus[chiplet];
+ gru = irq_to_gru(irq);
if (!gru) {
- dev_err(grudev, "GRU: invalid interrupt: cpu %d, chiplet %d\n",
- raw_smp_processor_id(), chiplet);
+ dev_err(grudev, "GRU: invalid interrupt: cpu %d, irq %d\n",
+ raw_smp_processor_id(), irq);
return IRQ_NONE;
}
get_clear_fault_map(gru, &imap, &dmap);
- gru_dbg(grudev,
- "cpu %d, chiplet %d, gid %d, imap %016lx %016lx, dmap %016lx %016lx\n",
- smp_processor_id(), chiplet, gru->gs_gid,
- imap.fault_bits[0], imap.fault_bits[1],
- dmap.fault_bits[0], dmap.fault_bits[1]);
for_each_cbr_in_tfm(cbrnum, dmap.fault_bits) {
- STAT(intr_cbr);
- cmp = gru->gs_blade->bs_async_wq;
- if (cmp)
- complete(cmp);
+ complete(gru->gs_blade->bs_async_wq);
gru_dbg(grudev, "gid %d, cbr_done %d, done %d\n",
- gru->gs_gid, cbrnum, cmp ? cmp->done : -1);
+ gru->gs_gid, cbrnum, gru->gs_blade->bs_async_wq->done);
}
for_each_cbr_in_tfm(cbrnum, imap.fault_bits) {
- STAT(intr_tfh);
tfh = get_tfh_by_index(gru, cbrnum);
prefetchw(tfh); /* Helps on hdw, required for emulator */
@@ -571,20 +492,14 @@ static irqreturn_t gru_intr(int chiplet, int blade)
ctxnum = tfh->ctxnum;
gts = gru->gs_gts[ctxnum];
- /* Spurious interrupts can cause this. Ignore. */
- if (!gts) {
- STAT(intr_spurious);
- continue;
- }
-
/*
* This is running in interrupt context. Trylock the mmap_sem.
* If it fails, retry the fault in user context.
*/
- gts->ustats.fmm_tlbmiss++;
if (!gts->ts_force_cch_reload &&
down_read_trylock(>s->ts_mm->mmap_sem)) {
- gru_try_dropin(gru, gts, tfh, NULL);
+ gts->ustats.fmm_tlbdropin++;
+ gru_try_dropin(gts, tfh, NULL);
up_read(>s->ts_mm->mmap_sem);
} else {
tfh_user_polling_mode(tfh);
@@ -594,43 +509,20 @@ static irqreturn_t gru_intr(int chiplet, int blade)
return IRQ_HANDLED;
}
-irqreturn_t gru0_intr(int irq, void *dev_id)
-{
- return gru_intr(0, uv_numa_blade_id());
-}
-
-irqreturn_t gru1_intr(int irq, void *dev_id)
-{
- return gru_intr(1, uv_numa_blade_id());
-}
-
-irqreturn_t gru_intr_mblade(int irq, void *dev_id)
-{
- int blade;
-
- for_each_possible_blade(blade) {
- if (uv_blade_nr_possible_cpus(blade))
- continue;
- gru_intr(0, blade);
- gru_intr(1, blade);
- }
- return IRQ_HANDLED;
-}
-
static int gru_user_dropin(struct gru_thread_state *gts,
struct gru_tlb_fault_handle *tfh,
- void *cb)
+ unsigned long __user *cb)
{
struct gru_mm_struct *gms = gts->ts_gms;
int ret;
- gts->ustats.upm_tlbmiss++;
+ gts->ustats.upm_tlbdropin++;
while (1) {
wait_event(gms->ms_wait_queue,
atomic_read(&gms->ms_range_active) == 0);
prefetchw(tfh); /* Helps on hdw, required for emulator */
- ret = gru_try_dropin(gts->ts_gru, gts, tfh, cb);
+ ret = gru_try_dropin(gts, tfh, cb);
if (ret <= 0)
return ret;
STAT(call_os_wait_queue);
@@ -646,41 +538,52 @@ int gru_handle_user_call_os(unsigned long cb)
{
struct gru_tlb_fault_handle *tfh;
struct gru_thread_state *gts;
- void *cbk;
+ unsigned long __user *cbp;
int ucbnum, cbrnum, ret = -EINVAL;
STAT(call_os);
+ gru_dbg(grudev, "address 0x%lx\n", cb);
/* sanity check the cb pointer */
ucbnum = get_cb_number((void *)cb);
if ((cb & (GRU_HANDLE_STRIDE - 1)) || ucbnum >= GRU_NUM_CB)
return -EINVAL;
+ cbp = (unsigned long *)cb;
gts = gru_find_lock_gts(cb);
if (!gts)
return -EINVAL;
- gru_dbg(grudev, "address 0x%lx, gid %d, gts 0x%p\n", cb, gts->ts_gru ? gts->ts_gru->gs_gid : -1, gts);
if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
goto exit;
- gru_check_context_placement(gts);
+ /*
+ * If force_unload is set, the UPM TLB fault is phony. The task
+ * has migrated to another node and the GSEG must be moved. Just
+ * unload the context. The task will page fault and assign a new
+ * context.
+ */
+ if (gts->ts_tgid_owner == current->tgid && gts->ts_blade >= 0 &&
+ gts->ts_blade != uv_numa_blade_id()) {
+ STAT(call_os_offnode_reference);
+ gts->ts_force_unload = 1;
+ }
/*
* CCH may contain stale data if ts_force_cch_reload is set.
*/
if (gts->ts_gru && gts->ts_force_cch_reload) {
gts->ts_force_cch_reload = 0;
- gru_update_cch(gts);
+ gru_update_cch(gts, 0);
}
ret = -EAGAIN;
cbrnum = thread_cbr_number(gts, ucbnum);
- if (gts->ts_gru) {
+ if (gts->ts_force_unload) {
+ gru_unload_context(gts, 1);
+ } else if (gts->ts_gru) {
tfh = get_tfh_by_index(gts->ts_gru, cbrnum);
- cbk = get_gseg_base_address_cb(gts->ts_gru->gs_gru_base_vaddr,
- gts->ts_ctxnum, ucbnum);
- ret = gru_user_dropin(gts, tfh, cbk);
+ ret = gru_user_dropin(gts, tfh, cbp);
}
exit:
gru_unlock_gts(gts);
@@ -702,11 +605,11 @@ int gru_get_exception_detail(unsigned long arg)
if (copy_from_user(&excdet, (void __user *)arg, sizeof(excdet)))
return -EFAULT;
+ gru_dbg(grudev, "address 0x%lx\n", excdet.cb);
gts = gru_find_lock_gts(excdet.cb);
if (!gts)
return -EINVAL;
- gru_dbg(grudev, "address 0x%lx, gid %d, gts 0x%p\n", excdet.cb, gts->ts_gru ? gts->ts_gru->gs_gid : -1, gts);
ucbnum = get_cb_number((void *)excdet.cb);
if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
ret = -EINVAL;
@@ -714,7 +617,6 @@ int gru_get_exception_detail(unsigned long arg)
cbrnum = thread_cbr_number(gts, ucbnum);
cbe = get_cbe_by_index(gts->ts_gru, cbrnum);
gru_flush_cache(cbe); /* CBE not coherent */
- sync_core(); /* make sure we are have current data */
excdet.opc = cbe->opccpy;
excdet.exopc = cbe->exopccpy;
excdet.ecause = cbe->ecause;
@@ -722,7 +624,7 @@ int gru_get_exception_detail(unsigned long arg)
excdet.exceptdet1 = cbe->idef3upd;
excdet.cbrstate = cbe->cbrstate;
excdet.cbrexecstatus = cbe->cbrexecstatus;
- gru_flush_cache_cbe(cbe);
+ gru_flush_cache(cbe);
ret = 0;
} else {
ret = -EAGAIN;
@@ -831,11 +733,6 @@ long gru_get_gseg_statistics(unsigned long arg)
if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
return -EFAULT;
- /*
- * The library creates arrays of contexts for threaded programs.
- * If no gts exists in the array, the context has never been used & all
- * statistics are implicitly 0.
- */
gts = gru_find_lock_gts(req.gseg);
if (gts) {
memcpy(&req.stats, >s->ustats, sizeof(gts->ustats));
@@ -865,25 +762,11 @@ int gru_set_context_option(unsigned long arg)
return -EFAULT;
gru_dbg(grudev, "op %d, gseg 0x%lx, value1 0x%lx\n", req.op, req.gseg, req.val1);
- gts = gru_find_lock_gts(req.gseg);
- if (!gts) {
- gts = gru_alloc_locked_gts(req.gseg);
- if (IS_ERR(gts))
- return PTR_ERR(gts);
- }
+ gts = gru_alloc_locked_gts(req.gseg);
+ if (!gts)
+ return -EINVAL;
switch (req.op) {
- case sco_blade_chiplet:
- /* Select blade/chiplet for GRU context */
- if (req.val1 < -1 || req.val1 >= GRU_MAX_BLADES || !gru_base[req.val1] ||
- req.val0 < -1 || req.val0 >= GRU_CHIPLETS_PER_HUB) {
- ret = -EINVAL;
- } else {
- gts->ts_user_blade_id = req.val1;
- gts->ts_user_chiplet_id = req.val0;
- gru_check_context_placement(gts);
- }
- break;
case sco_gseg_owner:
/* Register the current task as the GSEG owner */
gts->ts_tgid_owner = current->tgid;
diff --git a/trunk/drivers/misc/sgi-gru/grufile.c b/trunk/drivers/misc/sgi-gru/grufile.c
index cb3b4d228475..ce5eda985ab0 100644
--- a/trunk/drivers/misc/sgi-gru/grufile.c
+++ b/trunk/drivers/misc/sgi-gru/grufile.c
@@ -35,9 +35,6 @@
#include
#include
#include
-#ifdef CONFIG_X86_64
-#include
-#endif
#include
#include "gru.h"
#include "grulib.h"
@@ -133,6 +130,7 @@ static int gru_create_new_context(unsigned long arg)
struct gru_vma_data *vdata;
int ret = -EINVAL;
+
if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
return -EFAULT;
@@ -152,7 +150,6 @@ static int gru_create_new_context(unsigned long arg)
vdata->vd_dsr_au_count =
GRU_DS_BYTES_TO_AU(req.data_segment_bytes);
vdata->vd_cbr_au_count = GRU_CB_COUNT_TO_AU(req.control_blocks);
- vdata->vd_tlb_preload_count = req.tlb_preload_count;
ret = 0;
}
up_write(¤t->mm->mmap_sem);
@@ -193,7 +190,7 @@ static long gru_file_unlocked_ioctl(struct file *file, unsigned int req,
{
int err = -EBADRQC;
- gru_dbg(grudev, "file %p, req 0x%x, 0x%lx\n", file, req, arg);
+ gru_dbg(grudev, "file %p\n", file);
switch (req) {
case GRU_CREATE_CONTEXT:
@@ -235,24 +232,23 @@ static long gru_file_unlocked_ioctl(struct file *file, unsigned int req,
* system.
*/
static void gru_init_chiplet(struct gru_state *gru, unsigned long paddr,
- void *vaddr, int blade_id, int chiplet_id)
+ void *vaddr, int nid, int bid, int grunum)
{
spin_lock_init(&gru->gs_lock);
spin_lock_init(&gru->gs_asid_lock);
gru->gs_gru_base_paddr = paddr;
gru->gs_gru_base_vaddr = vaddr;
- gru->gs_gid = blade_id * GRU_CHIPLETS_PER_BLADE + chiplet_id;
- gru->gs_blade = gru_base[blade_id];
- gru->gs_blade_id = blade_id;
- gru->gs_chiplet_id = chiplet_id;
+ gru->gs_gid = bid * GRU_CHIPLETS_PER_BLADE + grunum;
+ gru->gs_blade = gru_base[bid];
+ gru->gs_blade_id = bid;
gru->gs_cbr_map = (GRU_CBR_AU == 64) ? ~0 : (1UL << GRU_CBR_AU) - 1;
gru->gs_dsr_map = (1UL << GRU_DSR_AU) - 1;
gru->gs_asid_limit = MAX_ASID;
gru_tgh_flush_init(gru);
if (gru->gs_gid >= gru_max_gids)
gru_max_gids = gru->gs_gid + 1;
- gru_dbg(grudev, "bid %d, gid %d, vaddr %p (0x%lx)\n",
- blade_id, gru->gs_gid, gru->gs_gru_base_vaddr,
+ gru_dbg(grudev, "bid %d, nid %d, gid %d, vaddr %p (0x%lx)\n",
+ bid, nid, gru->gs_gid, gru->gs_gru_base_vaddr,
gru->gs_gru_base_paddr);
}
@@ -268,10 +264,12 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr)
max_user_cbrs = GRU_NUM_CB;
max_user_dsr_bytes = GRU_NUM_DSR_BYTES;
- for_each_possible_blade(bid) {
- pnode = uv_blade_to_pnode(bid);
- nid = uv_blade_to_memory_nid(bid);/* -1 if no memory on blade */
- page = alloc_pages_node(nid, GFP_KERNEL, order);
+ for_each_online_node(nid) {
+ bid = uv_node_to_blade_id(nid);
+ pnode = uv_node_to_pnode(nid);
+ if (bid < 0 || gru_base[bid])
+ continue;
+ page = alloc_pages_exact_node(nid, GFP_KERNEL, order);
if (!page)
goto fail;
gru_base[bid] = page_address(page);
@@ -287,7 +285,7 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr)
chip++, gru++) {
paddr = gru_chiplet_paddr(gru_base_paddr, pnode, chip);
vaddr = gru_chiplet_vaddr(gru_base_vaddr, pnode, chip);
- gru_init_chiplet(gru, paddr, vaddr, bid, chip);
+ gru_init_chiplet(gru, paddr, vaddr, nid, bid, chip);
n = hweight64(gru->gs_cbr_map) * GRU_CBR_AU_SIZE;
cbrs = max(cbrs, n);
n = hweight64(gru->gs_dsr_map) * GRU_DSR_AU_BYTES;
@@ -300,214 +298,38 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr)
return 0;
fail:
- for (bid--; bid >= 0; bid--)
- free_pages((unsigned long)gru_base[bid], order);
+ for (nid--; nid >= 0; nid--)
+ free_pages((unsigned long)gru_base[nid], order);
return -ENOMEM;
}
-static void gru_free_tables(void)
-{
- int bid;
- int order = get_order(sizeof(struct gru_state) *
- GRU_CHIPLETS_PER_BLADE);
-
- for (bid = 0; bid < GRU_MAX_BLADES; bid++)
- free_pages((unsigned long)gru_base[bid], order);
-}
-
-static unsigned long gru_chiplet_cpu_to_mmr(int chiplet, int cpu, int *corep)
-{
- unsigned long mmr = 0;
- int core;
-
- /*
- * We target the cores of a blade and not the hyperthreads themselves.
- * There is a max of 8 cores per socket and 2 sockets per blade,
- * making for a max total of 16 cores (i.e., 16 CPUs without
- * hyperthreading and 32 CPUs with hyperthreading).
- */
- core = uv_cpu_core_number(cpu) + UV_MAX_INT_CORES * uv_cpu_socket_number(cpu);
- if (core >= GRU_NUM_TFM || uv_cpu_ht_number(cpu))
- return 0;
-
- if (chiplet == 0) {
- mmr = UVH_GR0_TLB_INT0_CONFIG +
- core * (UVH_GR0_TLB_INT1_CONFIG - UVH_GR0_TLB_INT0_CONFIG);
- } else if (chiplet == 1) {
- mmr = UVH_GR1_TLB_INT0_CONFIG +
- core * (UVH_GR1_TLB_INT1_CONFIG - UVH_GR1_TLB_INT0_CONFIG);
- } else {
- BUG();
- }
-
- *corep = core;
- return mmr;
-}
-
#ifdef CONFIG_IA64
-static int gru_irq_count[GRU_CHIPLETS_PER_BLADE];
-
-static void gru_noop(unsigned int irq)
-{
-}
-
-static struct irq_chip gru_chip[GRU_CHIPLETS_PER_BLADE] = {
- [0 ... GRU_CHIPLETS_PER_BLADE - 1] {
- .mask = gru_noop,
- .unmask = gru_noop,
- .ack = gru_noop
- }
-};
-
-static int gru_chiplet_setup_tlb_irq(int chiplet, char *irq_name,
- irq_handler_t irq_handler, int cpu, int blade)
-{
- unsigned long mmr;
- int irq = IRQ_GRU + chiplet;
- int ret, core;
-
- mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
- if (mmr == 0)
- return 0;
-
- if (gru_irq_count[chiplet] == 0) {
- gru_chip[chiplet].name = irq_name;
- ret = set_irq_chip(irq, &gru_chip[chiplet]);
- if (ret) {
- printk(KERN_ERR "%s: set_irq_chip failed, errno=%d\n",
- GRU_DRIVER_ID_STR, -ret);
- return ret;
- }
-
- ret = request_irq(irq, irq_handler, 0, irq_name, NULL);
- if (ret) {
- printk(KERN_ERR "%s: request_irq failed, errno=%d\n",
- GRU_DRIVER_ID_STR, -ret);
- return ret;
- }
- }
- gru_irq_count[chiplet]++;
-
- return 0;
-}
-
-static void gru_chiplet_teardown_tlb_irq(int chiplet, int cpu, int blade)
+static int get_base_irq(void)
{
- unsigned long mmr;
- int core, irq = IRQ_GRU + chiplet;
-
- if (gru_irq_count[chiplet] == 0)
- return;
-
- mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
- if (mmr == 0)
- return;
-
- if (--gru_irq_count[chiplet] == 0)
- free_irq(irq, NULL);
+ return IRQ_GRU;
}
#elif defined CONFIG_X86_64
-static int gru_chiplet_setup_tlb_irq(int chiplet, char *irq_name,
- irq_handler_t irq_handler, int cpu, int blade)
-{
- unsigned long mmr;
- int irq, core;
- int ret;
-
- mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
- if (mmr == 0)
- return 0;
-
- irq = uv_setup_irq(irq_name, cpu, blade, mmr, UV_AFFINITY_CPU);
- if (irq < 0) {
- printk(KERN_ERR "%s: uv_setup_irq failed, errno=%d\n",
- GRU_DRIVER_ID_STR, -irq);
- return irq;
- }
-
- ret = request_irq(irq, irq_handler, 0, irq_name, NULL);
- if (ret) {
- uv_teardown_irq(irq);
- printk(KERN_ERR "%s: request_irq failed, errno=%d\n",
- GRU_DRIVER_ID_STR, -ret);
- return ret;
- }
- gru_base[blade]->bs_grus[chiplet].gs_irq[core] = irq;
- return 0;
-}
-
-static void gru_chiplet_teardown_tlb_irq(int chiplet, int cpu, int blade)
+static void noop(unsigned int irq)
{
- int irq, core;
- unsigned long mmr;
-
- mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
- if (mmr) {
- irq = gru_base[blade]->bs_grus[chiplet].gs_irq[core];
- if (irq) {
- free_irq(irq, NULL);
- uv_teardown_irq(irq);
- }
- }
}
-#endif
-
-static void gru_teardown_tlb_irqs(void)
-{
- int blade;
- int cpu;
-
- for_each_online_cpu(cpu) {
- blade = uv_cpu_to_blade_id(cpu);
- gru_chiplet_teardown_tlb_irq(0, cpu, blade);
- gru_chiplet_teardown_tlb_irq(1, cpu, blade);
- }
- for_each_possible_blade(blade) {
- if (uv_blade_nr_possible_cpus(blade))
- continue;
- gru_chiplet_teardown_tlb_irq(0, 0, blade);
- gru_chiplet_teardown_tlb_irq(1, 0, blade);
- }
-}
+static struct irq_chip gru_chip = {
+ .name = "gru",
+ .mask = noop,
+ .unmask = noop,
+ .ack = noop,
+};
-static int gru_setup_tlb_irqs(void)
+static int get_base_irq(void)
{
- int blade;
- int cpu;
- int ret;
-
- for_each_online_cpu(cpu) {
- blade = uv_cpu_to_blade_id(cpu);
- ret = gru_chiplet_setup_tlb_irq(0, "GRU0_TLB", gru0_intr, cpu, blade);
- if (ret != 0)
- goto exit1;
-
- ret = gru_chiplet_setup_tlb_irq(1, "GRU1_TLB", gru1_intr, cpu, blade);
- if (ret != 0)
- goto exit1;
- }
- for_each_possible_blade(blade) {
- if (uv_blade_nr_possible_cpus(blade))
- continue;
- ret = gru_chiplet_setup_tlb_irq(0, "GRU0_TLB", gru_intr_mblade, 0, blade);
- if (ret != 0)
- goto exit1;
-
- ret = gru_chiplet_setup_tlb_irq(1, "GRU1_TLB", gru_intr_mblade, 0, blade);
- if (ret != 0)
- goto exit1;
- }
-
- return 0;
-
-exit1:
- gru_teardown_tlb_irqs();
- return ret;
+ set_irq_chip(IRQ_GRU, &gru_chip);
+ set_irq_chip(IRQ_GRU + 1, &gru_chip);
+ return IRQ_GRU;
}
+#endif
/*
* gru_init
@@ -516,7 +338,8 @@ static int gru_setup_tlb_irqs(void)
*/
static int __init gru_init(void)
{
- int ret;
+ int ret, irq, chip;
+ char id[10];
if (!is_uv_system())
return 0;
@@ -531,29 +354,41 @@ static int __init gru_init(void)
gru_end_paddr = gru_start_paddr + GRU_MAX_BLADES * GRU_SIZE;
printk(KERN_INFO "GRU space: 0x%lx - 0x%lx\n",
gru_start_paddr, gru_end_paddr);
+ irq = get_base_irq();
+ for (chip = 0; chip < GRU_CHIPLETS_PER_BLADE; chip++) {
+ ret = request_irq(irq + chip, gru_intr, 0, id, NULL);
+ /* TODO: fix irq handling on x86. For now ignore failure because
+ * interrupts are not required & not yet fully supported */
+ if (ret) {
+ printk(KERN_WARNING
+ "!!!WARNING: GRU ignoring request failure!!!\n");
+ ret = 0;
+ }
+ if (ret) {
+ printk(KERN_ERR "%s: request_irq failed\n",
+ GRU_DRIVER_ID_STR);
+ goto exit1;
+ }
+ }
+
ret = misc_register(&gru_miscdev);
if (ret) {
printk(KERN_ERR "%s: misc_register failed\n",
GRU_DRIVER_ID_STR);
- goto exit0;
+ goto exit1;
}
ret = gru_proc_init();
if (ret) {
printk(KERN_ERR "%s: proc init failed\n", GRU_DRIVER_ID_STR);
- goto exit1;
+ goto exit2;
}
ret = gru_init_tables(gru_start_paddr, gru_start_vaddr);
if (ret) {
printk(KERN_ERR "%s: init tables failed\n", GRU_DRIVER_ID_STR);
- goto exit2;
- }
-
- ret = gru_setup_tlb_irqs();
- if (ret != 0)
goto exit3;
-
+ }
gru_kservices_init();
printk(KERN_INFO "%s: v%s\n", GRU_DRIVER_ID_STR,
@@ -561,24 +396,31 @@ static int __init gru_init(void)
return 0;
exit3:
- gru_free_tables();
-exit2:
gru_proc_exit();
-exit1:
+exit2:
misc_deregister(&gru_miscdev);
-exit0:
+exit1:
+ for (--chip; chip >= 0; chip--)
+ free_irq(irq + chip, NULL);
return ret;
}
static void __exit gru_exit(void)
{
+ int i, bid;
+ int order = get_order(sizeof(struct gru_state) *
+ GRU_CHIPLETS_PER_BLADE);
+
if (!is_uv_system())
return;
- gru_teardown_tlb_irqs();
+ for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++)
+ free_irq(IRQ_GRU + i, NULL);
gru_kservices_exit();
- gru_free_tables();
+ for (bid = 0; bid < GRU_MAX_BLADES; bid++)
+ free_pages((unsigned long)gru_base[bid], order);
+
misc_deregister(&gru_miscdev);
gru_proc_exit();
}
diff --git a/trunk/drivers/misc/sgi-gru/gruhandles.c b/trunk/drivers/misc/sgi-gru/gruhandles.c
index 2f30badc6ffd..37e7cfc53b9c 100644
--- a/trunk/drivers/misc/sgi-gru/gruhandles.c
+++ b/trunk/drivers/misc/sgi-gru/gruhandles.c
@@ -27,11 +27,9 @@
#ifdef CONFIG_IA64
#include
#define GRU_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
-#define CLKS2NSEC(c) ((c) *1000000000 / local_cpu_data->itc_freq)
#else
#include
#define GRU_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
-#define CLKS2NSEC(c) ((c) * 1000000 / tsc_khz)
#endif
/* Extract the status field from a kernel handle */
@@ -41,39 +39,21 @@ struct mcs_op_statistic mcs_op_statistics[mcsop_last];
static void update_mcs_stats(enum mcs_op op, unsigned long clks)
{
- unsigned long nsec;
-
- nsec = CLKS2NSEC(clks);
atomic_long_inc(&mcs_op_statistics[op].count);
- atomic_long_add(nsec, &mcs_op_statistics[op].total);
- if (mcs_op_statistics[op].max < nsec)
- mcs_op_statistics[op].max = nsec;
+ atomic_long_add(clks, &mcs_op_statistics[op].total);
+ if (mcs_op_statistics[op].max < clks)
+ mcs_op_statistics[op].max = clks;
}
static void start_instruction(void *h)
{
unsigned long *w0 = h;
- wmb(); /* setting CMD/STATUS bits must be last */
- *w0 = *w0 | 0x20001;
+ wmb(); /* setting CMD bit must be last */
+ *w0 = *w0 | 1;
gru_flush_cache(h);
}
-static void report_instruction_timeout(void *h)
-{
- unsigned long goff = GSEGPOFF((unsigned long)h);
- char *id = "???";
-
- if (TYPE_IS(CCH, goff))
- id = "CCH";
- else if (TYPE_IS(TGH, goff))
- id = "TGH";
- else if (TYPE_IS(TFH, goff))
- id = "TFH";
-
- panic(KERN_ALERT "GRU %p (%s) is malfunctioning\n", h, id);
-}
-
static int wait_instruction_complete(void *h, enum mcs_op opc)
{
int status;
@@ -84,10 +64,9 @@ static int wait_instruction_complete(void *h, enum mcs_op opc)
status = GET_MSEG_HANDLE_STATUS(h);
if (status != CCHSTATUS_ACTIVE)
break;
- if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time)) {
- report_instruction_timeout(h);
- start_time = get_cycles();
- }
+ if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time))
+ panic("GRU %p is malfunctioning: start %ld, end %ld\n",
+ h, start_time, (unsigned long)get_cycles());
}
if (gru_options & OPT_STATS)
update_mcs_stats(opc, get_cycles() - start_time);
@@ -96,18 +75,9 @@ static int wait_instruction_complete(void *h, enum mcs_op opc)
int cch_allocate(struct gru_context_configuration_handle *cch)
{
- int ret;
-
cch->opc = CCHOP_ALLOCATE;
start_instruction(cch);
- ret = wait_instruction_complete(cch, cchop_allocate);
-
- /*
- * Stop speculation into the GSEG being mapped by the previous ALLOCATE.
- * The GSEG memory does not exist until the ALLOCATE completes.
- */
- sync_core();
- return ret;
+ return wait_instruction_complete(cch, cchop_allocate);
}
int cch_start(struct gru_context_configuration_handle *cch)
@@ -126,18 +96,9 @@ int cch_interrupt(struct gru_context_configuration_handle *cch)
int cch_deallocate(struct gru_context_configuration_handle *cch)
{
- int ret;
-
cch->opc = CCHOP_DEALLOCATE;
start_instruction(cch);
- ret = wait_instruction_complete(cch, cchop_deallocate);
-
- /*
- * Stop speculation into the GSEG being unmapped by the previous
- * DEALLOCATE.
- */
- sync_core();
- return ret;
+ return wait_instruction_complete(cch, cchop_deallocate);
}
int cch_interrupt_sync(struct gru_context_configuration_handle
@@ -165,20 +126,17 @@ int tgh_invalidate(struct gru_tlb_global_handle *tgh,
return wait_instruction_complete(tgh, tghop_invalidate);
}
-int tfh_write_only(struct gru_tlb_fault_handle *tfh,
- unsigned long paddr, int gaa,
- unsigned long vaddr, int asid, int dirty,
- int pagesize)
+void tfh_write_only(struct gru_tlb_fault_handle *tfh,
+ unsigned long pfn, unsigned long vaddr,
+ int asid, int dirty, int pagesize)
{
tfh->fillasid = asid;
tfh->fillvaddr = vaddr;
- tfh->pfn = paddr >> GRU_PADDR_SHIFT;
- tfh->gaa = gaa;
+ tfh->pfn = pfn;
tfh->dirty = dirty;
tfh->pagesize = pagesize;
tfh->opc = TFHOP_WRITE_ONLY;
start_instruction(tfh);
- return wait_instruction_complete(tfh, tfhop_write_only);
}
void tfh_write_restart(struct gru_tlb_fault_handle *tfh,
diff --git a/trunk/drivers/misc/sgi-gru/gruhandles.h b/trunk/drivers/misc/sgi-gru/gruhandles.h
index 3f998b924d8f..f44112242d00 100644
--- a/trunk/drivers/misc/sgi-gru/gruhandles.h
+++ b/trunk/drivers/misc/sgi-gru/gruhandles.h
@@ -91,12 +91,6 @@
/* Convert an arbitrary handle address to the beginning of the GRU segment */
#define GRUBASE(h) ((void *)((unsigned long)(h) & ~(GRU_SIZE - 1)))
-/* Test a valid handle address to determine the type */
-#define TYPE_IS(hn, h) ((h) >= GRU_##hn##_BASE && (h) < \
- GRU_##hn##_BASE + GRU_NUM_##hn * GRU_HANDLE_STRIDE && \
- (((h) & (GRU_HANDLE_STRIDE - 1)) == 0))
-
-
/* General addressing macros. */
static inline void *get_gseg_base_address(void *base, int ctxnum)
{
@@ -164,16 +158,6 @@ static inline void *gru_chiplet_vaddr(void *vaddr, int pnode, int chiplet)
return vaddr + GRU_SIZE * (2 * pnode + chiplet);
}
-static inline struct gru_control_block_extended *gru_tfh_to_cbe(
- struct gru_tlb_fault_handle *tfh)
-{
- unsigned long cbe;
-
- cbe = (unsigned long)tfh - GRU_TFH_BASE + GRU_CBE_BASE;
- return (struct gru_control_block_extended*)cbe;
-}
-
-
/*
@@ -252,17 +236,6 @@ enum gru_tgh_state {
TGHSTATE_RESTART_CTX,
};
-enum gru_tgh_cause {
- TGHCAUSE_RR_ECC,
- TGHCAUSE_TLB_ECC,
- TGHCAUSE_LRU_ECC,
- TGHCAUSE_PS_ECC,
- TGHCAUSE_MUL_ERR,
- TGHCAUSE_DATA_ERR,
- TGHCAUSE_SW_FORCE
-};
-
-
/*
* TFH - TLB Global Handle
* Used for TLB dropins into the GRU TLB.
@@ -467,12 +440,6 @@ struct gru_control_block_extended {
unsigned int cbrexecstatus:8;
};
-/* CBE fields for active BCOPY instructions */
-#define cbe_baddr0 idef1upd
-#define cbe_baddr1 idef3upd
-#define cbe_src_cl idef6cpy
-#define cbe_nelemcur idef5upd
-
enum gru_cbr_state {
CBRSTATE_INACTIVE,
CBRSTATE_IDLE,
@@ -520,8 +487,8 @@ int cch_interrupt_sync(struct gru_context_configuration_handle *cch);
int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr,
unsigned long vaddrmask, int asid, int pagesize, int global, int n,
unsigned short ctxbitmap);
-int tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
- int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
+void tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long pfn,
+ unsigned long vaddr, int asid, int dirty, int pagesize);
void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
void tfh_restart(struct gru_tlb_fault_handle *tfh);
diff --git a/trunk/drivers/misc/sgi-gru/grukdump.c b/trunk/drivers/misc/sgi-gru/grukdump.c
index 9b2062d17327..55eabfa85585 100644
--- a/trunk/drivers/misc/sgi-gru/grukdump.c
+++ b/trunk/drivers/misc/sgi-gru/grukdump.c
@@ -44,8 +44,7 @@ static int gru_user_copy_handle(void __user **dp, void *s)
static int gru_dump_context_data(void *grubase,
struct gru_context_configuration_handle *cch,
- void __user *ubuf, int ctxnum, int dsrcnt,
- int flush_cbrs)
+ void __user *ubuf, int ctxnum, int dsrcnt)
{
void *cb, *cbe, *tfh, *gseg;
int i, scr;
@@ -56,8 +55,6 @@ static int gru_dump_context_data(void *grubase,
tfh = grubase + GRU_TFH_BASE;
for_each_cbr_in_allocation_map(i, &cch->cbr_allocation_map, scr) {
- if (flush_cbrs)
- gru_flush_cache(cb);
if (gru_user_copy_handle(&ubuf, cb))
goto fail;
if (gru_user_copy_handle(&ubuf, tfh + i * GRU_HANDLE_STRIDE))
@@ -118,7 +115,7 @@ static int gru_dump_tgh(struct gru_state *gru,
static int gru_dump_context(struct gru_state *gru, int ctxnum,
void __user *ubuf, void __user *ubufend, char data_opt,
- char lock_cch, char flush_cbrs)
+ char lock_cch)
{
struct gru_dump_context_header hdr;
struct gru_dump_context_header __user *uhdr = ubuf;
@@ -162,7 +159,8 @@ static int gru_dump_context(struct gru_state *gru, int ctxnum,
ret = -EFBIG;
else
ret = gru_dump_context_data(grubase, cch, ubuf, ctxnum,
- dsrcnt, flush_cbrs);
+ dsrcnt);
+
}
if (cch_locked)
unlock_cch_handle(cch);
@@ -217,8 +215,7 @@ int gru_dump_chiplet_request(unsigned long arg)
for (ctxnum = 0; ctxnum < GRU_NUM_CCH; ctxnum++) {
if (req.ctxnum == ctxnum || req.ctxnum < 0) {
ret = gru_dump_context(gru, ctxnum, ubuf, ubufend,
- req.data_opt, req.lock_cch,
- req.flush_cbrs);
+ req.data_opt, req.lock_cch);
if (ret < 0)
goto fail;
ubuf += ret;
diff --git a/trunk/drivers/misc/sgi-gru/grukservices.c b/trunk/drivers/misc/sgi-gru/grukservices.c
index 34749ee88dfa..766e21e15574 100644
--- a/trunk/drivers/misc/sgi-gru/grukservices.c
+++ b/trunk/drivers/misc/sgi-gru/grukservices.c
@@ -31,7 +31,6 @@
#include
#include
#include
-#include
#include "gru.h"
#include "grulib.h"
#include "grutables.h"
@@ -98,6 +97,9 @@
#define ASYNC_HAN_TO_BID(h) ((h) - 1)
#define ASYNC_BID_TO_HAN(b) ((b) + 1)
#define ASYNC_HAN_TO_BS(h) gru_base[ASYNC_HAN_TO_BID(h)]
+#define KCB_TO_GID(cb) ((cb - gru_start_vaddr) / \
+ (GRU_SIZE * GRU_CHIPLETS_PER_BLADE))
+#define KCB_TO_BS(cb) gru_base[KCB_TO_GID(cb)]
#define GRU_NUM_KERNEL_CBR 1
#define GRU_NUM_KERNEL_DSR_BYTES 256
@@ -158,10 +160,8 @@ static void gru_load_kernel_context(struct gru_blade_state *bs, int blade_id)
up_read(&bs->bs_kgts_sema);
down_write(&bs->bs_kgts_sema);
- if (!bs->bs_kgts) {
- bs->bs_kgts = gru_alloc_gts(NULL, 0, 0, 0, 0, 0);
- bs->bs_kgts->ts_user_blade_id = blade_id;
- }
+ if (!bs->bs_kgts)
+ bs->bs_kgts = gru_alloc_gts(NULL, 0, 0, 0, 0);
kgts = bs->bs_kgts;
if (!kgts->ts_gru) {
@@ -172,9 +172,9 @@ static void gru_load_kernel_context(struct gru_blade_state *bs, int blade_id)
kgts->ts_dsr_au_count = GRU_DS_BYTES_TO_AU(
GRU_NUM_KERNEL_DSR_BYTES * ncpus +
bs->bs_async_dsr_bytes);
- while (!gru_assign_gru_context(kgts)) {
+ while (!gru_assign_gru_context(kgts, blade_id)) {
msleep(1);
- gru_steal_context(kgts);
+ gru_steal_context(kgts, blade_id);
}
gru_load_context(kgts);
gru = bs->bs_kgts->ts_gru;
@@ -200,15 +200,13 @@ static int gru_free_kernel_contexts(void)
bs = gru_base[bid];
if (!bs)
continue;
-
- /* Ignore busy contexts. Don't want to block here. */
if (down_write_trylock(&bs->bs_kgts_sema)) {
kgts = bs->bs_kgts;
if (kgts && kgts->ts_gru)
gru_unload_context(kgts, 0);
+ kfree(kgts);
bs->bs_kgts = NULL;
up_write(&bs->bs_kgts_sema);
- kfree(kgts);
} else {
ret++;
}
@@ -222,21 +220,13 @@ static int gru_free_kernel_contexts(void)
static struct gru_blade_state *gru_lock_kernel_context(int blade_id)
{
struct gru_blade_state *bs;
- int bid;
STAT(lock_kernel_context);
-again:
- bid = blade_id < 0 ? uv_numa_blade_id() : blade_id;
- bs = gru_base[bid];
+ bs = gru_base[blade_id];
- /* Handle the case where migration occured while waiting for the sema */
down_read(&bs->bs_kgts_sema);
- if (blade_id < 0 && bid != uv_numa_blade_id()) {
- up_read(&bs->bs_kgts_sema);
- goto again;
- }
if (!bs->bs_kgts || !bs->bs_kgts->ts_gru)
- gru_load_kernel_context(bs, bid);
+ gru_load_kernel_context(bs, blade_id);
return bs;
}
@@ -265,7 +255,7 @@ static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr)
BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES);
preempt_disable();
- bs = gru_lock_kernel_context(-1);
+ bs = gru_lock_kernel_context(uv_numa_blade_id());
lcpu = uv_blade_processor_id();
*cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE;
*dsr = bs->kernel_dsr + lcpu * GRU_NUM_KERNEL_DSR_BYTES;
@@ -394,31 +384,13 @@ int gru_get_cb_exception_detail(void *cb,
struct control_block_extended_exc_detail *excdet)
{
struct gru_control_block_extended *cbe;
- struct gru_thread_state *kgts = NULL;
- unsigned long off;
- int cbrnum, bid;
-
- /*
- * Locate kgts for cb. This algorithm is SLOW but
- * this function is rarely called (ie., almost never).
- * Performance does not matter.
- */
- for_each_possible_blade(bid) {
- if (!gru_base[bid])
- break;
- kgts = gru_base[bid]->bs_kgts;
- if (!kgts || !kgts->ts_gru)
- continue;
- off = cb - kgts->ts_gru->gs_gru_base_vaddr;
- if (off < GRU_SIZE)
- break;
- kgts = NULL;
- }
- BUG_ON(!kgts);
- cbrnum = thread_cbr_number(kgts, get_cb_number(cb));
+ struct gru_blade_state *bs;
+ int cbrnum;
+
+ bs = KCB_TO_BS(cb);
+ cbrnum = thread_cbr_number(bs->bs_kgts, get_cb_number(cb));
cbe = get_cbe(GRUBASE(cb), cbrnum);
gru_flush_cache(cbe); /* CBE not coherent */
- sync_core();
excdet->opc = cbe->opccpy;
excdet->exopc = cbe->exopccpy;
excdet->ecause = cbe->ecause;
@@ -437,8 +409,8 @@ char *gru_get_cb_exception_detail_str(int ret, void *cb,
if (ret > 0 && gen->istatus == CBS_EXCEPTION) {
gru_get_cb_exception_detail(cb, &excdet);
snprintf(buf, size,
- "GRU:%d exception: cb %p, opc %d, exopc %d, ecause 0x%x,"
- "excdet0 0x%lx, excdet1 0x%x", smp_processor_id(),
+ "GRU exception: cb %p, opc %d, exopc %d, ecause 0x%x,"
+ "excdet0 0x%lx, excdet1 0x%x",
gen, excdet.opc, excdet.exopc, excdet.ecause,
excdet.exceptdet0, excdet.exceptdet1);
} else {
@@ -485,10 +457,9 @@ int gru_check_status_proc(void *cb)
int ret;
ret = gen->istatus;
- if (ret == CBS_EXCEPTION)
- ret = gru_retry_exception(cb);
- rmb();
- return ret;
+ if (ret != CBS_EXCEPTION)
+ return ret;
+ return gru_retry_exception(cb);
}
@@ -500,7 +471,7 @@ int gru_wait_proc(void *cb)
ret = gru_wait_idle_or_exception(gen);
if (ret == CBS_EXCEPTION)
ret = gru_retry_exception(cb);
- rmb();
+
return ret;
}
@@ -567,7 +538,7 @@ int gru_create_message_queue(struct gru_message_queue_desc *mqd,
mqd->mq = mq;
mqd->mq_gpa = uv_gpa(mq);
mqd->qlines = qlines;
- mqd->interrupt_pnode = nasid >> 1;
+ mqd->interrupt_pnode = UV_NASID_TO_PNODE(nasid);
mqd->interrupt_vector = vector;
mqd->interrupt_apicid = apicid;
return 0;
@@ -627,8 +598,6 @@ static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd,
ret = MQE_UNEXPECTED_CB_ERR;
break;
case CBSS_PAGE_OVERFLOW:
- STAT(mesq_noop_page_overflow);
- /* fallthru */
default:
BUG();
}
@@ -703,6 +672,18 @@ static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd,
return MQE_UNEXPECTED_CB_ERR;
}
+/*
+ * Send a cross-partition interrupt to the SSI that contains the target
+ * message queue. Normally, the interrupt is automatically delivered by hardware
+ * but some error conditions require explicit delivery.
+ */
+static void send_message_queue_interrupt(struct gru_message_queue_desc *mqd)
+{
+ if (mqd->interrupt_vector)
+ uv_hub_send_ipi(mqd->interrupt_pnode, mqd->interrupt_apicid,
+ mqd->interrupt_vector);
+}
+
/*
* Handle a PUT failure. Note: if message was a 2-line message, one of the
* lines might have successfully have been written. Before sending the
@@ -712,8 +693,7 @@ static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd,
static int send_message_put_nacked(void *cb, struct gru_message_queue_desc *mqd,
void *mesg, int lines)
{
- unsigned long m, *val = mesg, gpa, save;
- int ret;
+ unsigned long m;
m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
if (lines == 2) {
@@ -724,26 +704,7 @@ static int send_message_put_nacked(void *cb, struct gru_message_queue_desc *mqd,
gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
if (gru_wait(cb) != CBS_IDLE)
return MQE_UNEXPECTED_CB_ERR;
-
- if (!mqd->interrupt_vector)
- return MQE_OK;
-
- /*
- * Send a cross-partition interrupt to the SSI that contains the target
- * message queue. Normally, the interrupt is automatically delivered by
- * hardware but some error conditions require explicit delivery.
- * Use the GRU to deliver the interrupt. Otherwise partition failures
- * could cause unrecovered errors.
- */
- gpa = uv_global_gru_mmr_address(mqd->interrupt_pnode, UVH_IPI_INT);
- save = *val;
- *val = uv_hub_ipi_value(mqd->interrupt_apicid, mqd->interrupt_vector,
- dest_Fixed);
- gru_vstore_phys(cb, gpa, gru_get_tri(mesg), IAA_REGISTER, IMA);
- ret = gru_wait(cb);
- *val = save;
- if (ret != CBS_IDLE)
- return MQE_UNEXPECTED_CB_ERR;
+ send_message_queue_interrupt(mqd);
return MQE_OK;
}
@@ -778,9 +739,6 @@ static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
STAT(mesq_send_put_nacked);
ret = send_message_put_nacked(cb, mqd, mesg, lines);
break;
- case CBSS_PAGE_OVERFLOW:
- STAT(mesq_page_overflow);
- /* fallthru */
default:
BUG();
}
@@ -873,6 +831,7 @@ void *gru_get_next_message(struct gru_message_queue_desc *mqd)
int present = mhdr->present;
/* skip NOOP messages */
+ STAT(mesq_receive);
while (present == MQS_NOOP) {
gru_free_message(mqd, mhdr);
mhdr = mq->next;
@@ -892,36 +851,12 @@ void *gru_get_next_message(struct gru_message_queue_desc *mqd)
if (mhdr->lines == 2)
restore_present2(mhdr, mhdr->present2);
- STAT(mesq_receive);
return mhdr;
}
EXPORT_SYMBOL_GPL(gru_get_next_message);
/* ---------------------- GRU DATA COPY FUNCTIONS ---------------------------*/
-/*
- * Load a DW from a global GPA. The GPA can be a memory or MMR address.
- */
-int gru_read_gpa(unsigned long *value, unsigned long gpa)
-{
- void *cb;
- void *dsr;
- int ret, iaa;
-
- STAT(read_gpa);
- if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr))
- return MQE_BUG_NO_RESOURCES;
- iaa = gpa >> 62;
- gru_vload_phys(cb, gpa, gru_get_tri(dsr), iaa, IMA);
- ret = gru_wait(cb);
- if (ret == CBS_IDLE)
- *value = *(unsigned long *)dsr;
- gru_free_cpu_resources(cb, dsr);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gru_read_gpa);
-
-
/*
* Copy a block of data using the GRU resources
*/
@@ -963,24 +898,24 @@ static int quicktest0(unsigned long arg)
gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
if (gru_wait(cb) != CBS_IDLE) {
- printk(KERN_DEBUG "GRU:%d quicktest0: CBR failure 1\n", smp_processor_id());
+ printk(KERN_DEBUG "GRU quicktest0: CBR failure 1\n");
goto done;
}
if (*p != MAGIC) {
- printk(KERN_DEBUG "GRU:%d quicktest0 bad magic 0x%lx\n", smp_processor_id(), *p);
+ printk(KERN_DEBUG "GRU: quicktest0 bad magic 0x%lx\n", *p);
goto done;
}
gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
if (gru_wait(cb) != CBS_IDLE) {
- printk(KERN_DEBUG "GRU:%d quicktest0: CBR failure 2\n", smp_processor_id());
+ printk(KERN_DEBUG "GRU quicktest0: CBR failure 2\n");
goto done;
}
if (word0 != word1 || word1 != MAGIC) {
printk(KERN_DEBUG
- "GRU:%d quicktest0 err: found 0x%lx, expected 0x%lx\n",
- smp_processor_id(), word1, MAGIC);
+ "GRU quicktest0 err: found 0x%lx, expected 0x%lx\n",
+ word1, MAGIC);
goto done;
}
ret = 0;
@@ -1017,11 +952,8 @@ static int quicktest1(unsigned long arg)
if (ret)
break;
}
- if (ret != MQE_QUEUE_FULL || i != 4) {
- printk(KERN_DEBUG "GRU:%d quicktest1: unexpect status %d, i %d\n",
- smp_processor_id(), ret, i);
+ if (ret != MQE_QUEUE_FULL || i != 4)
goto done;
- }
for (i = 0; i < 6; i++) {
m = gru_get_next_message(&mqd);
@@ -1029,12 +961,7 @@ static int quicktest1(unsigned long arg)
break;
gru_free_message(&mqd, m);
}
- if (i != 4) {
- printk(KERN_DEBUG "GRU:%d quicktest2: bad message, i %d, m %p, m8 %d\n",
- smp_processor_id(), i, m, m ? m[8] : -1);
- goto done;
- }
- ret = 0;
+ ret = (i == 4) ? 0 : -EIO;
done:
kfree(p);
@@ -1050,7 +977,6 @@ static int quicktest2(unsigned long arg)
int ret = 0;
unsigned long *buf;
void *cb0, *cb;
- struct gru_control_block_status *gen;
int i, k, istatus, bytes;
bytes = numcb * 4 * 8;
@@ -1070,30 +996,20 @@ static int quicktest2(unsigned long arg)
XTYPE_DW, 4, 1, IMA_INTERRUPT);
ret = 0;
- k = numcb;
- do {
+ for (k = 0; k < numcb; k++) {
gru_wait_async_cbr(han);
for (i = 0; i < numcb; i++) {
cb = cb0 + i * GRU_HANDLE_STRIDE;
istatus = gru_check_status(cb);
- if (istatus != CBS_ACTIVE && istatus != CBS_CALL_OS)
- break;
+ if (istatus == CBS_ACTIVE)
+ continue;
+ if (istatus == CBS_EXCEPTION)
+ ret = -EFAULT;
+ else if (buf[i] || buf[i + 1] || buf[i + 2] ||
+ buf[i + 3])
+ ret = -EIO;
}
- if (i == numcb)
- continue;
- if (istatus != CBS_IDLE) {
- printk(KERN_DEBUG "GRU:%d quicktest2: cb %d, exception\n", smp_processor_id(), i);
- ret = -EFAULT;
- } else if (buf[4 * i] || buf[4 * i + 1] || buf[4 * i + 2] ||
- buf[4 * i + 3]) {
- printk(KERN_DEBUG "GRU:%d quicktest2:cb %d, buf 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
- smp_processor_id(), i, buf[4 * i], buf[4 * i + 1], buf[4 * i + 2], buf[4 * i + 3]);
- ret = -EIO;
- }
- k--;
- gen = cb;
- gen->istatus = CBS_CALL_OS; /* don't handle this CBR again */
- } while (k);
+ }
BUG_ON(cmp.done);
gru_unlock_async_resource(han);
@@ -1103,22 +1019,6 @@ static int quicktest2(unsigned long arg)
return ret;
}
-#define BUFSIZE 200
-static int quicktest3(unsigned long arg)
-{
- char buf1[BUFSIZE], buf2[BUFSIZE];
- int ret = 0;
-
- memset(buf2, 0, sizeof(buf2));
- memset(buf1, get_cycles() & 255, sizeof(buf1));
- gru_copy_gpa(uv_gpa(buf2), uv_gpa(buf1), BUFSIZE);
- if (memcmp(buf1, buf2, BUFSIZE)) {
- printk(KERN_DEBUG "GRU:%d quicktest3 error\n", smp_processor_id());
- ret = -EIO;
- }
- return ret;
-}
-
/*
* Debugging only. User hook for various kernel tests
* of driver & gru.
@@ -1137,9 +1037,6 @@ int gru_ktest(unsigned long arg)
case 2:
ret = quicktest2(arg);
break;
- case 3:
- ret = quicktest3(arg);
- break;
case 99:
ret = gru_free_kernel_contexts();
break;
diff --git a/trunk/drivers/misc/sgi-gru/grukservices.h b/trunk/drivers/misc/sgi-gru/grukservices.h
index 02aa94d8484a..d60d34bca44d 100644
--- a/trunk/drivers/misc/sgi-gru/grukservices.h
+++ b/trunk/drivers/misc/sgi-gru/grukservices.h
@@ -130,20 +130,6 @@ extern void gru_free_message(struct gru_message_queue_desc *mqd,
extern void *gru_get_next_message(struct gru_message_queue_desc *mqd);
-/*
- * Read a GRU global GPA. Source can be located in a remote partition.
- *
- * Input:
- * value memory address where MMR value is returned
- * gpa source numalink physical address of GPA
- *
- * Output:
- * 0 OK
- * >0 error
- */
-int gru_read_gpa(unsigned long *value, unsigned long gpa);
-
-
/*
* Copy data using the GRU. Source or destination can be located in a remote
* partition.
diff --git a/trunk/drivers/misc/sgi-gru/grulib.h b/trunk/drivers/misc/sgi-gru/grulib.h
index e77d1b1f9d05..889bc442a3e8 100644
--- a/trunk/drivers/misc/sgi-gru/grulib.h
+++ b/trunk/drivers/misc/sgi-gru/grulib.h
@@ -63,9 +63,18 @@
#define THREAD_POINTER(p, th) (p + GRU_GSEG_PAGESIZE * (th))
#define GSEG_START(cb) ((void *)((unsigned long)(cb) & ~(GRU_GSEG_PAGESIZE - 1)))
+/*
+ * Statictics kept on a per-GTS basis.
+ */
+struct gts_statistics {
+ unsigned long fmm_tlbdropin;
+ unsigned long upm_tlbdropin;
+ unsigned long context_stolen;
+};
+
struct gru_get_gseg_statistics_req {
- unsigned long gseg;
- struct gru_gseg_statistics stats;
+ unsigned long gseg;
+ struct gts_statistics stats;
};
/*
@@ -77,7 +86,6 @@ struct gru_create_context_req {
unsigned int control_blocks;
unsigned int maximum_thread_count;
unsigned int options;
- unsigned char tlb_preload_count;
};
/*
@@ -90,12 +98,11 @@ struct gru_unload_context_req {
/*
* Structure used to set context options
*/
-enum {sco_gseg_owner, sco_cch_req_slice, sco_blade_chiplet};
+enum {sco_gseg_owner, sco_cch_req_slice};
struct gru_set_context_option_req {
unsigned long gseg;
int op;
- int val0;
- long val1;
+ unsigned long val1;
};
/*
@@ -117,8 +124,6 @@ struct gru_dump_chiplet_state_req {
int ctxnum;
char data_opt;
char lock_cch;
- char flush_cbrs;
- char fill[10];
pid_t pid;
void *buf;
size_t buflen;
diff --git a/trunk/drivers/misc/sgi-gru/grumain.c b/trunk/drivers/misc/sgi-gru/grumain.c
index f8538bbd0bfa..3bc643dad606 100644
--- a/trunk/drivers/misc/sgi-gru/grumain.c
+++ b/trunk/drivers/misc/sgi-gru/grumain.c
@@ -27,7 +27,6 @@
#include
#include
#include
-#include
#include
#include "gru.h"
#include "grutables.h"
@@ -49,20 +48,12 @@ struct device *grudev = &gru_device;
/*
* Select a gru fault map to be used by the current cpu. Note that
* multiple cpus may be using the same map.
+ * ZZZ should "shift" be used?? Depends on HT cpu numbering
* ZZZ should be inline but did not work on emulator
*/
int gru_cpu_fault_map_id(void)
{
-#ifdef CONFIG_IA64
return uv_blade_processor_id() % GRU_NUM_TFM;
-#else
- int cpu = smp_processor_id();
- int id, core;
-
- core = uv_cpu_core_number(cpu);
- id = core + UV_MAX_INT_CORES * uv_cpu_socket_number(cpu);
- return id;
-#endif
}
/*--------- ASID Management -------------------------------------------
@@ -295,8 +286,7 @@ static void gru_unload_mm_tracker(struct gru_state *gru,
void gts_drop(struct gru_thread_state *gts)
{
if (gts && atomic_dec_return(>s->ts_refcnt) == 0) {
- if (gts->ts_gms)
- gru_drop_mmu_notifier(gts->ts_gms);
+ gru_drop_mmu_notifier(gts->ts_gms);
kfree(gts);
STAT(gts_free);
}
@@ -320,18 +310,16 @@ static struct gru_thread_state *gru_find_current_gts_nolock(struct gru_vma_data
* Allocate a thread state structure.
*/
struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
- int cbr_au_count, int dsr_au_count,
- unsigned char tlb_preload_count, int options, int tsid)
+ int cbr_au_count, int dsr_au_count, int options, int tsid)
{
struct gru_thread_state *gts;
- struct gru_mm_struct *gms;
int bytes;
bytes = DSR_BYTES(dsr_au_count) + CBR_BYTES(cbr_au_count);
bytes += sizeof(struct gru_thread_state);
gts = kmalloc(bytes, GFP_KERNEL);
if (!gts)
- return ERR_PTR(-ENOMEM);
+ return NULL;
STAT(gts_alloc);
memset(gts, 0, sizeof(struct gru_thread_state)); /* zero out header */
@@ -339,10 +327,7 @@ struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
mutex_init(>s->ts_ctxlock);
gts->ts_cbr_au_count = cbr_au_count;
gts->ts_dsr_au_count = dsr_au_count;
- gts->ts_tlb_preload_count = tlb_preload_count;
gts->ts_user_options = options;
- gts->ts_user_blade_id = -1;
- gts->ts_user_chiplet_id = -1;
gts->ts_tsid = tsid;
gts->ts_ctxnum = NULLCTX;
gts->ts_tlb_int_select = -1;
@@ -351,10 +336,9 @@ struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
if (vma) {
gts->ts_mm = current->mm;
gts->ts_vma = vma;
- gms = gru_register_mmu_notifier();
- if (IS_ERR(gms))
+ gts->ts_gms = gru_register_mmu_notifier();
+ if (!gts->ts_gms)
goto err;
- gts->ts_gms = gms;
}
gru_dbg(grudev, "alloc gts %p\n", gts);
@@ -362,7 +346,7 @@ struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
err:
gts_drop(gts);
- return ERR_CAST(gms);
+ return NULL;
}
/*
@@ -376,7 +360,6 @@ struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma, int tsid)
if (!vdata)
return NULL;
- STAT(vdata_alloc);
INIT_LIST_HEAD(&vdata->vd_head);
spin_lock_init(&vdata->vd_lock);
gru_dbg(grudev, "alloc vdata %p\n", vdata);
@@ -409,12 +392,10 @@ struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct *vma,
struct gru_vma_data *vdata = vma->vm_private_data;
struct gru_thread_state *gts, *ngts;
- gts = gru_alloc_gts(vma, vdata->vd_cbr_au_count,
- vdata->vd_dsr_au_count,
- vdata->vd_tlb_preload_count,
+ gts = gru_alloc_gts(vma, vdata->vd_cbr_au_count, vdata->vd_dsr_au_count,
vdata->vd_user_options, tsid);
- if (IS_ERR(gts))
- return gts;
+ if (!gts)
+ return NULL;
spin_lock(&vdata->vd_lock);
ngts = gru_find_current_gts_nolock(vdata, tsid);
@@ -512,9 +493,6 @@ static void gru_load_context_data(void *save, void *grubase, int ctxnum,
memset(cbe + i * GRU_HANDLE_STRIDE, 0,
GRU_CACHE_LINE_BYTES);
}
- /* Flush CBE to hide race in context restart */
- mb();
- gru_flush_cache(cbe + i * GRU_HANDLE_STRIDE);
cb += GRU_HANDLE_STRIDE;
}
@@ -535,12 +513,6 @@ static void gru_unload_context_data(void *save, void *grubase, int ctxnum,
cb = gseg + GRU_CB_BASE;
cbe = grubase + GRU_CBE_BASE;
length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
-
- /* CBEs may not be coherent. Flush them from cache */
- for_each_cbr_in_allocation_map(i, &cbrmap, scr)
- gru_flush_cache(cbe + i * GRU_HANDLE_STRIDE);
- mb(); /* Let the CL flush complete */
-
gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
@@ -561,8 +533,7 @@ void gru_unload_context(struct gru_thread_state *gts, int savestate)
zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE);
cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
- gru_dbg(grudev, "gts %p, cbrmap 0x%lx, dsrmap 0x%lx\n",
- gts, gts->ts_cbr_map, gts->ts_dsr_map);
+ gru_dbg(grudev, "gts %p\n", gts);
lock_cch_handle(cch);
if (cch_interrupt_sync(cch))
BUG();
@@ -578,6 +549,7 @@ void gru_unload_context(struct gru_thread_state *gts, int savestate)
if (cch_deallocate(cch))
BUG();
+ gts->ts_force_unload = 0; /* ts_force_unload locked by CCH lock */
unlock_cch_handle(cch);
gru_free_gru_context(gts);
@@ -593,7 +565,9 @@ void gru_load_context(struct gru_thread_state *gts)
struct gru_context_configuration_handle *cch;
int i, err, asid, ctxnum = gts->ts_ctxnum;
+ gru_dbg(grudev, "gts %p\n", gts);
cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
+
lock_cch_handle(cch);
cch->tfm_fault_bit_enable =
(gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
@@ -617,7 +591,6 @@ void gru_load_context(struct gru_thread_state *gts)
cch->unmap_enable = 1;
cch->tfm_done_bit_enable = 1;
cch->cb_int_enable = 1;
- cch->tlb_int_select = 0; /* For now, ints go to cpu 0 */
} else {
cch->unmap_enable = 0;
cch->tfm_done_bit_enable = 0;
@@ -643,18 +616,17 @@ void gru_load_context(struct gru_thread_state *gts)
if (cch_start(cch))
BUG();
unlock_cch_handle(cch);
-
- gru_dbg(grudev, "gid %d, gts %p, cbrmap 0x%lx, dsrmap 0x%lx, tie %d, tis %d\n",
- gts->ts_gru->gs_gid, gts, gts->ts_cbr_map, gts->ts_dsr_map,
- (gts->ts_user_options == GRU_OPT_MISS_FMM_INTR), gts->ts_tlb_int_select);
}
/*
* Update fields in an active CCH:
* - retarget interrupts on local blade
* - update sizeavail mask
+ * - force a delayed context unload by clearing the CCH asids. This
+ * forces TLB misses for new GRU instructions. The context is unloaded
+ * when the next TLB miss occurs.
*/
-int gru_update_cch(struct gru_thread_state *gts)
+int gru_update_cch(struct gru_thread_state *gts, int force_unload)
{
struct gru_context_configuration_handle *cch;
struct gru_state *gru = gts->ts_gru;
@@ -668,13 +640,21 @@ int gru_update_cch(struct gru_thread_state *gts)
goto exit;
if (cch_interrupt(cch))
BUG();
- for (i = 0; i < 8; i++)
- cch->sizeavail[i] = gts->ts_sizeavail;
- gts->ts_tlb_int_select = gru_cpu_fault_map_id();
- cch->tlb_int_select = gru_cpu_fault_map_id();
- cch->tfm_fault_bit_enable =
- (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
- || gts->ts_user_options == GRU_OPT_MISS_FMM_INTR);
+ if (!force_unload) {
+ for (i = 0; i < 8; i++)
+ cch->sizeavail[i] = gts->ts_sizeavail;
+ gts->ts_tlb_int_select = gru_cpu_fault_map_id();
+ cch->tlb_int_select = gru_cpu_fault_map_id();
+ cch->tfm_fault_bit_enable =
+ (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
+ || gts->ts_user_options == GRU_OPT_MISS_FMM_INTR);
+ } else {
+ for (i = 0; i < 8; i++)
+ cch->asid[i] = 0;
+ cch->tfm_fault_bit_enable = 0;
+ cch->tlb_int_enable = 0;
+ gts->ts_force_unload = 1;
+ }
if (cch_start(cch))
BUG();
ret = 1;
@@ -699,54 +679,7 @@ static int gru_retarget_intr(struct gru_thread_state *gts)
gru_dbg(grudev, "retarget from %d to %d\n", gts->ts_tlb_int_select,
gru_cpu_fault_map_id());
- return gru_update_cch(gts);
-}
-
-/*
- * Check if a GRU context is allowed to use a specific chiplet. By default
- * a context is assigned to any blade-local chiplet. However, users can
- * override this.
- * Returns 1 if assignment allowed, 0 otherwise
- */
-static int gru_check_chiplet_assignment(struct gru_state *gru,
- struct gru_thread_state *gts)
-{
- int blade_id;
- int chiplet_id;
-
- blade_id = gts->ts_user_blade_id;
- if (blade_id < 0)
- blade_id = uv_numa_blade_id();
-
- chiplet_id = gts->ts_user_chiplet_id;
- return gru->gs_blade_id == blade_id &&
- (chiplet_id < 0 || chiplet_id == gru->gs_chiplet_id);
-}
-
-/*
- * Unload the gru context if it is not assigned to the correct blade or
- * chiplet. Misassignment can occur if the process migrates to a different
- * blade or if the user changes the selected blade/chiplet.
- */
-void gru_check_context_placement(struct gru_thread_state *gts)
-{
- struct gru_state *gru;
-
- /*
- * If the current task is the context owner, verify that the
- * context is correctly placed. This test is skipped for non-owner
- * references. Pthread apps use non-owner references to the CBRs.
- */
- gru = gts->ts_gru;
- if (!gru || gts->ts_tgid_owner != current->tgid)
- return;
-
- if (!gru_check_chiplet_assignment(gru, gts)) {
- STAT(check_context_unload);
- gru_unload_context(gts, 1);
- } else if (gru_retarget_intr(gts)) {
- STAT(check_context_retarget_intr);
- }
+ return gru_update_cch(gts, 0);
}
@@ -779,17 +712,13 @@ static void gts_stolen(struct gru_thread_state *gts,
}
}
-void gru_steal_context(struct gru_thread_state *gts)
+void gru_steal_context(struct gru_thread_state *gts, int blade_id)
{
struct gru_blade_state *blade;
struct gru_state *gru, *gru0;
struct gru_thread_state *ngts = NULL;
int ctxnum, ctxnum0, flag = 0, cbr, dsr;
- int blade_id;
- blade_id = gts->ts_user_blade_id;
- if (blade_id < 0)
- blade_id = uv_numa_blade_id();
cbr = gts->ts_cbr_au_count;
dsr = gts->ts_dsr_au_count;
@@ -800,39 +729,35 @@ void gru_steal_context(struct gru_thread_state *gts)
gru = blade->bs_lru_gru;
if (ctxnum == 0)
gru = next_gru(blade, gru);
- blade->bs_lru_gru = gru;
- blade->bs_lru_ctxnum = ctxnum;
ctxnum0 = ctxnum;
gru0 = gru;
while (1) {
- if (gru_check_chiplet_assignment(gru, gts)) {
- if (check_gru_resources(gru, cbr, dsr, GRU_NUM_CCH))
+ if (check_gru_resources(gru, cbr, dsr, GRU_NUM_CCH))
+ break;
+ spin_lock(&gru->gs_lock);
+ for (; ctxnum < GRU_NUM_CCH; ctxnum++) {
+ if (flag && gru == gru0 && ctxnum == ctxnum0)
break;
- spin_lock(&gru->gs_lock);
- for (; ctxnum < GRU_NUM_CCH; ctxnum++) {
- if (flag && gru == gru0 && ctxnum == ctxnum0)
- break;
- ngts = gru->gs_gts[ctxnum];
- /*
- * We are grabbing locks out of order, so trylock is
- * needed. GTSs are usually not locked, so the odds of
- * success are high. If trylock fails, try to steal a
- * different GSEG.
- */
- if (ngts && is_gts_stealable(ngts, blade))
- break;
- ngts = NULL;
- }
- spin_unlock(&gru->gs_lock);
- if (ngts || (flag && gru == gru0 && ctxnum == ctxnum0))
+ ngts = gru->gs_gts[ctxnum];
+ /*
+ * We are grabbing locks out of order, so trylock is
+ * needed. GTSs are usually not locked, so the odds of
+ * success are high. If trylock fails, try to steal a
+ * different GSEG.
+ */
+ if (ngts && is_gts_stealable(ngts, blade))
break;
+ ngts = NULL;
+ flag = 1;
}
- if (flag && gru == gru0)
+ spin_unlock(&gru->gs_lock);
+ if (ngts || (flag && gru == gru0 && ctxnum == ctxnum0))
break;
- flag = 1;
ctxnum = 0;
gru = next_gru(blade, gru);
}
+ blade->bs_lru_gru = gru;
+ blade->bs_lru_ctxnum = ctxnum;
spin_unlock(&blade->bs_lock);
if (ngts) {
@@ -850,35 +775,20 @@ void gru_steal_context(struct gru_thread_state *gts)
hweight64(gru->gs_dsr_map));
}
-/*
- * Assign a gru context.
- */
-static int gru_assign_context_number(struct gru_state *gru)
-{
- int ctxnum;
-
- ctxnum = find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH);
- __set_bit(ctxnum, &gru->gs_context_map);
- return ctxnum;
-}
-
/*
* Scan the GRUs on the local blade & assign a GRU context.
*/
-struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts)
+struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts,
+ int blade)
{
struct gru_state *gru, *grux;
int i, max_active_contexts;
- int blade_id = gts->ts_user_blade_id;
- if (blade_id < 0)
- blade_id = uv_numa_blade_id();
+
again:
gru = NULL;
max_active_contexts = GRU_NUM_CCH;
- for_each_gru_on_blade(grux, blade_id, i) {
- if (!gru_check_chiplet_assignment(grux, gts))
- continue;
+ for_each_gru_on_blade(grux, blade, i) {
if (check_gru_resources(grux, gts->ts_cbr_au_count,
gts->ts_dsr_au_count,
max_active_contexts)) {
@@ -899,9 +809,12 @@ struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts)
reserve_gru_resources(gru, gts);
gts->ts_gru = gru;
gts->ts_blade = gru->gs_blade_id;
- gts->ts_ctxnum = gru_assign_context_number(gru);
+ gts->ts_ctxnum =
+ find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH);
+ BUG_ON(gts->ts_ctxnum == GRU_NUM_CCH);
atomic_inc(>s->ts_refcnt);
gru->gs_gts[gts->ts_ctxnum] = gts;
+ __set_bit(gts->ts_ctxnum, &gru->gs_context_map);
spin_unlock(&gru->gs_lock);
STAT(assign_context);
@@ -929,6 +842,7 @@ int gru_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct gru_thread_state *gts;
unsigned long paddr, vaddr;
+ int blade_id;
vaddr = (unsigned long)vmf->virtual_address;
gru_dbg(grudev, "vma %p, vaddr 0x%lx (0x%lx)\n",
@@ -943,18 +857,28 @@ int gru_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
again:
mutex_lock(>s->ts_ctxlock);
preempt_disable();
+ blade_id = uv_numa_blade_id();
- gru_check_context_placement(gts);
+ if (gts->ts_gru) {
+ if (gts->ts_gru->gs_blade_id != blade_id) {
+ STAT(migrated_nopfn_unload);
+ gru_unload_context(gts, 1);
+ } else {
+ if (gru_retarget_intr(gts))
+ STAT(migrated_nopfn_retarget);
+ }
+ }
if (!gts->ts_gru) {
STAT(load_user_context);
- if (!gru_assign_gru_context(gts)) {
+ if (!gru_assign_gru_context(gts, blade_id)) {
preempt_enable();
mutex_unlock(>s->ts_ctxlock);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */
+ blade_id = uv_numa_blade_id();
if (gts->ts_steal_jiffies + GRU_STEAL_DELAY < jiffies)
- gru_steal_context(gts);
+ gru_steal_context(gts, blade_id);
goto again;
}
gru_load_context(gts);
diff --git a/trunk/drivers/misc/sgi-gru/gruprocfs.c b/trunk/drivers/misc/sgi-gru/gruprocfs.c
index 7768b87d995b..3f2375c5ba5b 100644
--- a/trunk/drivers/misc/sgi-gru/gruprocfs.c
+++ b/trunk/drivers/misc/sgi-gru/gruprocfs.c
@@ -36,7 +36,8 @@ static void printstat_val(struct seq_file *s, atomic_long_t *v, char *id)
{
unsigned long val = atomic_long_read(v);
- seq_printf(s, "%16lu %s\n", val, id);
+ if (val)
+ seq_printf(s, "%16lu %s\n", val, id);
}
static int statistics_show(struct seq_file *s, void *p)
@@ -45,8 +46,7 @@ static int statistics_show(struct seq_file *s, void *p)
printstat(s, vdata_free);
printstat(s, gts_alloc);
printstat(s, gts_free);
- printstat(s, gms_alloc);
- printstat(s, gms_free);
+ printstat(s, vdata_double_alloc);
printstat(s, gts_double_allocate);
printstat(s, assign_context);
printstat(s, assign_context_failed);
@@ -59,25 +59,28 @@ static int statistics_show(struct seq_file *s, void *p)
printstat(s, steal_kernel_context);
printstat(s, steal_context_failed);
printstat(s, nopfn);
+ printstat(s, break_cow);
printstat(s, asid_new);
printstat(s, asid_next);
printstat(s, asid_wrap);
printstat(s, asid_reuse);
printstat(s, intr);
- printstat(s, intr_cbr);
- printstat(s, intr_tfh);
- printstat(s, intr_spurious);
printstat(s, intr_mm_lock_failed);
printstat(s, call_os);
+ printstat(s, call_os_offnode_reference);
+ printstat(s, call_os_check_for_bug);
printstat(s, call_os_wait_queue);
printstat(s, user_flush_tlb);
printstat(s, user_unload_context);
printstat(s, user_exception);
printstat(s, set_context_option);
- printstat(s, check_context_retarget_intr);
- printstat(s, check_context_unload);
+ printstat(s, migrate_check);
+ printstat(s, migrated_retarget);
+ printstat(s, migrated_unload);
+ printstat(s, migrated_unload_delay);
+ printstat(s, migrated_nopfn_retarget);
+ printstat(s, migrated_nopfn_unload);
printstat(s, tlb_dropin);
- printstat(s, tlb_preload_page);
printstat(s, tlb_dropin_fail_no_asid);
printstat(s, tlb_dropin_fail_upm);
printstat(s, tlb_dropin_fail_invalid);
@@ -85,15 +88,16 @@ static int statistics_show(struct seq_file *s, void *p)
printstat(s, tlb_dropin_fail_idle);
printstat(s, tlb_dropin_fail_fmm);
printstat(s, tlb_dropin_fail_no_exception);
+ printstat(s, tlb_dropin_fail_no_exception_war);
printstat(s, tfh_stale_on_fault);
printstat(s, mmu_invalidate_range);
printstat(s, mmu_invalidate_page);
+ printstat(s, mmu_clear_flush_young);
printstat(s, flush_tlb);
printstat(s, flush_tlb_gru);
printstat(s, flush_tlb_gru_tgh);
printstat(s, flush_tlb_gru_zero_asid);
printstat(s, copy_gpa);
- printstat(s, read_gpa);
printstat(s, mesq_receive);
printstat(s, mesq_receive_none);
printstat(s, mesq_send);
@@ -104,6 +108,7 @@ static int statistics_show(struct seq_file *s, void *p)
printstat(s, mesq_send_qlimit_reached);
printstat(s, mesq_send_amo_nacked);
printstat(s, mesq_send_put_nacked);
+ printstat(s, mesq_qf_not_full);
printstat(s, mesq_qf_locked);
printstat(s, mesq_qf_noop_not_full);
printstat(s, mesq_qf_switch_head_failed);
@@ -113,7 +118,6 @@ static int statistics_show(struct seq_file *s, void *p)
printstat(s, mesq_noop_qlimit_reached);
printstat(s, mesq_noop_amo_nacked);
printstat(s, mesq_noop_put_nacked);
- printstat(s, mesq_noop_page_overflow);
return 0;
}
@@ -129,10 +133,8 @@ static int mcs_statistics_show(struct seq_file *s, void *p)
int op;
unsigned long total, count, max;
static char *id[] = {"cch_allocate", "cch_start", "cch_interrupt",
- "cch_interrupt_sync", "cch_deallocate", "tfh_write_only",
- "tfh_write_restart", "tgh_invalidate"};
+ "cch_interrupt_sync", "cch_deallocate", "tgh_invalidate"};
- seq_printf(s, "%-20s%12s%12s%12s\n", "#id", "count", "aver-clks", "max-clks");
for (op = 0; op < mcsop_last; op++) {
count = atomic_long_read(&mcs_op_statistics[op].count);
total = atomic_long_read(&mcs_op_statistics[op].total);
@@ -152,7 +154,6 @@ static ssize_t mcs_statistics_write(struct file *file,
static int options_show(struct seq_file *s, void *p)
{
- seq_printf(s, "#bitmask: 1=trace, 2=statistics\n");
seq_printf(s, "0x%lx\n", gru_options);
return 0;
}
@@ -182,17 +183,16 @@ static int cch_seq_show(struct seq_file *file, void *data)
const char *mode[] = { "??", "UPM", "INTR", "OS_POLL" };
if (gid == 0)
- seq_printf(file, "#%5s%5s%6s%7s%9s%6s%8s%8s\n", "gid", "bid",
- "ctx#", "asid", "pid", "cbrs", "dsbytes", "mode");
+ seq_printf(file, "#%5s%5s%6s%9s%6s%8s%8s\n", "gid", "bid",
+ "ctx#", "pid", "cbrs", "dsbytes", "mode");
if (gru)
for (i = 0; i < GRU_NUM_CCH; i++) {
ts = gru->gs_gts[i];
if (!ts)
continue;
- seq_printf(file, " %5d%5d%6d%7d%9d%6d%8d%8s\n",
+ seq_printf(file, " %5d%5d%6d%9d%6d%8d%8s\n",
gru->gs_gid, gru->gs_blade_id, i,
- is_kernel_context(ts) ? 0 : ts->ts_gms->ms_asids[gid].mt_asid,
- is_kernel_context(ts) ? 0 : ts->ts_tgid_owner,
+ ts->ts_tgid_owner,
ts->ts_cbr_au_count * GRU_CBR_AU_SIZE,
ts->ts_cbr_au_count * GRU_DSR_AU_BYTES,
mode[ts->ts_user_options &
@@ -355,7 +355,7 @@ static void delete_proc_files(void)
for (p = proc_files; p->name; p++)
if (p->entry)
remove_proc_entry(p->name, proc_gru);
- remove_proc_entry("gru", proc_gru->parent);
+ remove_proc_entry("gru", NULL);
}
}
diff --git a/trunk/drivers/misc/sgi-gru/grutables.h b/trunk/drivers/misc/sgi-gru/grutables.h
index 02a77b8b8eef..46990bcfa536 100644
--- a/trunk/drivers/misc/sgi-gru/grutables.h
+++ b/trunk/drivers/misc/sgi-gru/grutables.h
@@ -161,7 +161,7 @@ extern unsigned int gru_max_gids;
#define GRU_MAX_GRUS (GRU_MAX_BLADES * GRU_CHIPLETS_PER_BLADE)
#define GRU_DRIVER_ID_STR "SGI GRU Device Driver"
-#define GRU_DRIVER_VERSION_STR "0.85"
+#define GRU_DRIVER_VERSION_STR "0.80"
/*
* GRU statistics.
@@ -171,8 +171,7 @@ struct gru_stats_s {
atomic_long_t vdata_free;
atomic_long_t gts_alloc;
atomic_long_t gts_free;
- atomic_long_t gms_alloc;
- atomic_long_t gms_free;
+ atomic_long_t vdata_double_alloc;
atomic_long_t gts_double_allocate;
atomic_long_t assign_context;
atomic_long_t assign_context_failed;
@@ -185,25 +184,28 @@ struct gru_stats_s {
atomic_long_t steal_kernel_context;
atomic_long_t steal_context_failed;
atomic_long_t nopfn;
+ atomic_long_t break_cow;
atomic_long_t asid_new;
atomic_long_t asid_next;
atomic_long_t asid_wrap;
atomic_long_t asid_reuse;
atomic_long_t intr;
- atomic_long_t intr_cbr;
- atomic_long_t intr_tfh;
- atomic_long_t intr_spurious;
atomic_long_t intr_mm_lock_failed;
atomic_long_t call_os;
+ atomic_long_t call_os_offnode_reference;
+ atomic_long_t call_os_check_for_bug;
atomic_long_t call_os_wait_queue;
atomic_long_t user_flush_tlb;
atomic_long_t user_unload_context;
atomic_long_t user_exception;
atomic_long_t set_context_option;
- atomic_long_t check_context_retarget_intr;
- atomic_long_t check_context_unload;
+ atomic_long_t migrate_check;
+ atomic_long_t migrated_retarget;
+ atomic_long_t migrated_unload;
+ atomic_long_t migrated_unload_delay;
+ atomic_long_t migrated_nopfn_retarget;
+ atomic_long_t migrated_nopfn_unload;
atomic_long_t tlb_dropin;
- atomic_long_t tlb_preload_page;
atomic_long_t tlb_dropin_fail_no_asid;
atomic_long_t tlb_dropin_fail_upm;
atomic_long_t tlb_dropin_fail_invalid;
@@ -211,16 +213,17 @@ struct gru_stats_s {
atomic_long_t tlb_dropin_fail_idle;
atomic_long_t tlb_dropin_fail_fmm;
atomic_long_t tlb_dropin_fail_no_exception;
+ atomic_long_t tlb_dropin_fail_no_exception_war;
atomic_long_t tfh_stale_on_fault;
atomic_long_t mmu_invalidate_range;
atomic_long_t mmu_invalidate_page;
+ atomic_long_t mmu_clear_flush_young;
atomic_long_t flush_tlb;
atomic_long_t flush_tlb_gru;
atomic_long_t flush_tlb_gru_tgh;
atomic_long_t flush_tlb_gru_zero_asid;
atomic_long_t copy_gpa;
- atomic_long_t read_gpa;
atomic_long_t mesq_receive;
atomic_long_t mesq_receive_none;
@@ -232,7 +235,7 @@ struct gru_stats_s {
atomic_long_t mesq_send_qlimit_reached;
atomic_long_t mesq_send_amo_nacked;
atomic_long_t mesq_send_put_nacked;
- atomic_long_t mesq_page_overflow;
+ atomic_long_t mesq_qf_not_full;
atomic_long_t mesq_qf_locked;
atomic_long_t mesq_qf_noop_not_full;
atomic_long_t mesq_qf_switch_head_failed;
@@ -242,13 +245,11 @@ struct gru_stats_s {
atomic_long_t mesq_noop_qlimit_reached;
atomic_long_t mesq_noop_amo_nacked;
atomic_long_t mesq_noop_put_nacked;
- atomic_long_t mesq_noop_page_overflow;
};
enum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync,
- cchop_deallocate, tfhop_write_only, tfhop_write_restart,
- tghop_invalidate, mcsop_last};
+ cchop_deallocate, tghop_invalidate, mcsop_last};
struct mcs_op_statistic {
atomic_long_t count;
@@ -258,8 +259,8 @@ struct mcs_op_statistic {
extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
-#define OPT_DPRINT 1
-#define OPT_STATS 2
+#define OPT_DPRINT 1
+#define OPT_STATS 2
#define IRQ_GRU 110 /* Starting IRQ number for interrupts */
@@ -282,7 +283,7 @@ extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
#define gru_dbg(dev, fmt, x...) \
do { \
if (gru_options & OPT_DPRINT) \
- printk(KERN_DEBUG "GRU:%d %s: " fmt, smp_processor_id(), __func__, x);\
+ dev_dbg(dev, "%s: " fmt, __func__, x); \
} while (0)
#else
#define gru_dbg(x...)
@@ -296,7 +297,13 @@ extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
#define ASID_INC 8 /* number of regions */
/* Generate a GRU asid value from a GRU base asid & a virtual address. */
+#if defined CONFIG_IA64
#define VADDR_HI_BIT 64
+#elif defined CONFIG_X86_64
+#define VADDR_HI_BIT 48
+#else
+#error "Unsupported architecture"
+#endif
#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3)
#define GRUASID(asid, addr) ((asid) + GRUREGION(addr))
@@ -338,7 +345,6 @@ struct gru_vma_data {
long vd_user_options;/* misc user option flags */
int vd_cbr_au_count;
int vd_dsr_au_count;
- unsigned char vd_tlb_preload_count;
};
/*
@@ -354,7 +360,6 @@ struct gru_thread_state {
struct gru_state *ts_gru; /* GRU where the context is
loaded */
struct gru_mm_struct *ts_gms; /* asid & ioproc struct */
- unsigned char ts_tlb_preload_count; /* TLB preload pages */
unsigned long ts_cbr_map; /* map of allocated CBRs */
unsigned long ts_dsr_map; /* map of allocated DATA
resources */
@@ -363,8 +368,6 @@ struct gru_thread_state {
long ts_user_options;/* misc user option flags */
pid_t ts_tgid_owner; /* task that is using the
context - for migration */
- short ts_user_blade_id;/* user selected blade */
- char ts_user_chiplet_id;/* user selected chiplet */
unsigned short ts_sizeavail; /* Pagesizes in use */
int ts_tsid; /* thread that owns the
structure */
@@ -381,11 +384,13 @@ struct gru_thread_state {
char ts_blade; /* If >= 0, migrate context if
ref from diferent blade */
char ts_force_cch_reload;
+ char ts_force_unload;/* force context to be unloaded
+ after migration */
char ts_cbr_idx[GRU_CBR_AU];/* CBR numbers of each
allocated CB */
int ts_data_valid; /* Indicates if ts_gdata has
valid data */
- struct gru_gseg_statistics ustats; /* User statistics */
+ struct gts_statistics ustats; /* User statistics */
unsigned long ts_gdata[0]; /* save area for GRU data (CB,
DS, CBE) */
};
@@ -417,7 +422,6 @@ struct gru_state {
gru segments (64) */
unsigned short gs_gid; /* unique GRU number */
unsigned short gs_blade_id; /* blade of GRU */
- unsigned char gs_chiplet_id; /* blade chiplet of GRU */
unsigned char gs_tgh_local_shift; /* used to pick TGH for
local flush */
unsigned char gs_tgh_first_remote; /* starting TGH# for
@@ -449,7 +453,6 @@ struct gru_state {
in use */
struct gru_thread_state *gs_gts[GRU_NUM_CCH]; /* GTS currently using
the context */
- int gs_irq[GRU_NUM_TFM]; /* Interrupt irqs */
};
/*
@@ -616,15 +619,6 @@ static inline int is_kernel_context(struct gru_thread_state *gts)
return !gts->ts_mm;
}
-/*
- * The following are for Nehelem-EX. A more general scheme is needed for
- * future processors.
- */
-#define UV_MAX_INT_CORES 8
-#define uv_cpu_socket_number(p) ((cpu_physical_id(p) >> 5) & 1)
-#define uv_cpu_ht_number(p) (cpu_physical_id(p) & 1)
-#define uv_cpu_core_number(p) (((cpu_physical_id(p) >> 2) & 4) | \
- ((cpu_physical_id(p) >> 1) & 3))
/*-----------------------------------------------------------------------------
* Function prototypes & externs
*/
@@ -639,26 +633,24 @@ extern struct gru_thread_state *gru_find_thread_state(struct vm_area_struct
*vma, int tsid);
extern struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct
*vma, int tsid);
-extern struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts);
+extern struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts,
+ int blade);
extern void gru_load_context(struct gru_thread_state *gts);
-extern void gru_steal_context(struct gru_thread_state *gts);
+extern void gru_steal_context(struct gru_thread_state *gts, int blade_id);
extern void gru_unload_context(struct gru_thread_state *gts, int savestate);
-extern int gru_update_cch(struct gru_thread_state *gts);
+extern int gru_update_cch(struct gru_thread_state *gts, int force_unload);
extern void gts_drop(struct gru_thread_state *gts);
extern void gru_tgh_flush_init(struct gru_state *gru);
extern int gru_kservices_init(void);
extern void gru_kservices_exit(void);
-extern irqreturn_t gru0_intr(int irq, void *dev_id);
-extern irqreturn_t gru1_intr(int irq, void *dev_id);
-extern irqreturn_t gru_intr_mblade(int irq, void *dev_id);
extern int gru_dump_chiplet_request(unsigned long arg);
extern long gru_get_gseg_statistics(unsigned long arg);
+extern irqreturn_t gru_intr(int irq, void *dev_id);
extern int gru_handle_user_call_os(unsigned long address);
extern int gru_user_flush_tlb(unsigned long arg);
extern int gru_user_unload_context(unsigned long arg);
extern int gru_get_exception_detail(unsigned long arg);
extern int gru_set_context_option(unsigned long address);
-extern void gru_check_context_placement(struct gru_thread_state *gts);
extern int gru_cpu_fault_map_id(void);
extern struct vm_area_struct *gru_find_vma(unsigned long vaddr);
extern void gru_flush_all_tlb(struct gru_state *gru);
@@ -666,8 +658,7 @@ extern int gru_proc_init(void);
extern void gru_proc_exit(void);
extern struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
- int cbr_au_count, int dsr_au_count,
- unsigned char tlb_preload_count, int options, int tsid);
+ int cbr_au_count, int dsr_au_count, int options, int tsid);
extern unsigned long gru_reserve_cb_resources(struct gru_state *gru,
int cbr_au_count, char *cbmap);
extern unsigned long gru_reserve_ds_resources(struct gru_state *gru,
diff --git a/trunk/drivers/misc/sgi-gru/grutlbpurge.c b/trunk/drivers/misc/sgi-gru/grutlbpurge.c
index 240a6d361665..1d125091f5e7 100644
--- a/trunk/drivers/misc/sgi-gru/grutlbpurge.c
+++ b/trunk/drivers/misc/sgi-gru/grutlbpurge.c
@@ -184,8 +184,8 @@ void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start,
STAT(flush_tlb_gru_tgh);
asid = GRUASID(asid, start);
gru_dbg(grudev,
- " FLUSH gruid %d, asid 0x%x, vaddr 0x%lx, vamask 0x%x, num %ld, cbmap 0x%x\n",
- gid, asid, start, grupagesize, num, asids->mt_ctxbitmap);
+ " FLUSH gruid %d, asid 0x%x, num %ld, cbmap 0x%x\n",
+ gid, asid, num, asids->mt_ctxbitmap);
tgh = get_lock_tgh_handle(gru);
tgh_invalidate(tgh, start, ~0, asid, grupagesize, 0,
num - 1, asids->mt_ctxbitmap);
@@ -299,7 +299,6 @@ struct gru_mm_struct *gru_register_mmu_notifier(void)
{
struct gru_mm_struct *gms;
struct mmu_notifier *mn;
- int err;
mn = mmu_find_ops(current->mm, &gru_mmuops);
if (mn) {
@@ -308,22 +307,16 @@ struct gru_mm_struct *gru_register_mmu_notifier(void)
} else {
gms = kzalloc(sizeof(*gms), GFP_KERNEL);
if (gms) {
- STAT(gms_alloc);
spin_lock_init(&gms->ms_asid_lock);
gms->ms_notifier.ops = &gru_mmuops;
atomic_set(&gms->ms_refcnt, 1);
init_waitqueue_head(&gms->ms_wait_queue);
- err = __mmu_notifier_register(&gms->ms_notifier, current->mm);
- if (err)
- goto error;
+ __mmu_notifier_register(&gms->ms_notifier, current->mm);
}
}
gru_dbg(grudev, "gms %p, refcnt %d\n", gms,
atomic_read(&gms->ms_refcnt));
return gms;
-error:
- kfree(gms);
- return ERR_PTR(err);
}
void gru_drop_mmu_notifier(struct gru_mm_struct *gms)
@@ -334,7 +327,6 @@ void gru_drop_mmu_notifier(struct gru_mm_struct *gms)
if (!gms->ms_released)
mmu_notifier_unregister(&gms->ms_notifier, current->mm);
kfree(gms);
- STAT(gms_free);
}
}
diff --git a/trunk/drivers/misc/sgi-xp/xp.h b/trunk/drivers/misc/sgi-xp/xp.h
index 851b2f25ce0e..2275126cb334 100644
--- a/trunk/drivers/misc/sgi-xp/xp.h
+++ b/trunk/drivers/misc/sgi-xp/xp.h
@@ -339,7 +339,6 @@ extern short xp_partition_id;
extern u8 xp_region_size;
extern unsigned long (*xp_pa) (void *);
-extern unsigned long (*xp_socket_pa) (unsigned long);
extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
size_t);
extern int (*xp_cpu_to_nasid) (int);
diff --git a/trunk/drivers/misc/sgi-xp/xp_main.c b/trunk/drivers/misc/sgi-xp/xp_main.c
index 01be66d02ca8..7896849b16dc 100644
--- a/trunk/drivers/misc/sgi-xp/xp_main.c
+++ b/trunk/drivers/misc/sgi-xp/xp_main.c
@@ -44,9 +44,6 @@ EXPORT_SYMBOL_GPL(xp_region_size);
unsigned long (*xp_pa) (void *addr);
EXPORT_SYMBOL_GPL(xp_pa);
-unsigned long (*xp_socket_pa) (unsigned long gpa);
-EXPORT_SYMBOL_GPL(xp_socket_pa);
-
enum xp_retval (*xp_remote_memcpy) (unsigned long dst_gpa,
const unsigned long src_gpa, size_t len);
EXPORT_SYMBOL_GPL(xp_remote_memcpy);
diff --git a/trunk/drivers/misc/sgi-xp/xp_sn2.c b/trunk/drivers/misc/sgi-xp/xp_sn2.c
index d8e463f87241..fb3ec9d735a9 100644
--- a/trunk/drivers/misc/sgi-xp/xp_sn2.c
+++ b/trunk/drivers/misc/sgi-xp/xp_sn2.c
@@ -83,15 +83,6 @@ xp_pa_sn2(void *addr)
return __pa(addr);
}
-/*
- * Convert a global physical to a socket physical address.
- */
-static unsigned long
-xp_socket_pa_sn2(unsigned long gpa)
-{
- return gpa;
-}
-
/*
* Wrapper for bte_copy().
*
@@ -171,7 +162,6 @@ xp_init_sn2(void)
xp_region_size = sn_region_size;
xp_pa = xp_pa_sn2;
- xp_socket_pa = xp_socket_pa_sn2;
xp_remote_memcpy = xp_remote_memcpy_sn2;
xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
xp_expand_memprotect = xp_expand_memprotect_sn2;
diff --git a/trunk/drivers/misc/sgi-xp/xp_uv.c b/trunk/drivers/misc/sgi-xp/xp_uv.c
index a0d093274dc0..d238576b26fa 100644
--- a/trunk/drivers/misc/sgi-xp/xp_uv.c
+++ b/trunk/drivers/misc/sgi-xp/xp_uv.c
@@ -32,44 +32,12 @@ xp_pa_uv(void *addr)
return uv_gpa(addr);
}
-/*
- * Convert a global physical to socket physical address.
- */
-static unsigned long
-xp_socket_pa_uv(unsigned long gpa)
-{
- return uv_gpa_to_soc_phys_ram(gpa);
-}
-
-static enum xp_retval
-xp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa,
- size_t len)
-{
- int ret;
- unsigned long *dst_va = __va(uv_gpa_to_soc_phys_ram(dst_gpa));
-
- BUG_ON(!uv_gpa_in_mmr_space(src_gpa));
- BUG_ON(len != 8);
-
- ret = gru_read_gpa(dst_va, src_gpa);
- if (ret == 0)
- return xpSuccess;
-
- dev_err(xp, "gru_read_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
- "len=%ld\n", dst_gpa, src_gpa, len);
- return xpGruCopyError;
-}
-
-
static enum xp_retval
xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
size_t len)
{
int ret;
- if (uv_gpa_in_mmr_space(src_gpa))
- return xp_remote_mmr_read(dst_gpa, src_gpa, len);
-
ret = gru_copy_gpa(dst_gpa, src_gpa, len);
if (ret == 0)
return xpSuccess;
@@ -155,7 +123,6 @@ xp_init_uv(void)
xp_region_size = sn_region_size;
xp_pa = xp_pa_uv;
- xp_socket_pa = xp_socket_pa_uv;
xp_remote_memcpy = xp_remote_memcpy_uv;
xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
xp_expand_memprotect = xp_expand_memprotect_uv;
diff --git a/trunk/drivers/misc/sgi-xp/xpc_partition.c b/trunk/drivers/misc/sgi-xp/xpc_partition.c
index 9a6268c89fdd..65877bc5edaa 100644
--- a/trunk/drivers/misc/sgi-xp/xpc_partition.c
+++ b/trunk/drivers/misc/sgi-xp/xpc_partition.c
@@ -18,7 +18,6 @@
#include
#include
#include "xpc.h"
-#include
/* XPC is exiting flag */
int xpc_exiting;
@@ -93,12 +92,8 @@ xpc_get_rsvd_page_pa(int nasid)
break;
/* !!! L1_CACHE_ALIGN() is only a sn2-bte_copy requirement */
- if (is_shub())
- len = L1_CACHE_ALIGN(len);
-
- if (len > buf_len) {
- if (buf_base != NULL)
- kfree(buf_base);
+ if (L1_CACHE_ALIGN(len) > buf_len) {
+ kfree(buf_base);
buf_len = L1_CACHE_ALIGN(len);
buf = xpc_kmalloc_cacheline_aligned(buf_len, GFP_KERNEL,
&buf_base);
@@ -110,7 +105,7 @@ xpc_get_rsvd_page_pa(int nasid)
}
}
- ret = xp_remote_memcpy(xp_pa(buf), rp_pa, len);
+ ret = xp_remote_memcpy(xp_pa(buf), rp_pa, buf_len);
if (ret != xpSuccess) {
dev_dbg(xpc_part, "xp_remote_memcpy failed %d\n", ret);
break;
@@ -148,7 +143,7 @@ xpc_setup_rsvd_page(void)
dev_err(xpc_part, "SAL failed to locate the reserved page\n");
return -ESRCH;
}
- rp = (struct xpc_rsvd_page *)__va(xp_socket_pa(rp_pa));
+ rp = (struct xpc_rsvd_page *)__va(rp_pa);
if (rp->SAL_version < 3) {
/* SAL_versions < 3 had a SAL_partid defined as a u8 */
diff --git a/trunk/drivers/misc/sgi-xp/xpc_uv.c b/trunk/drivers/misc/sgi-xp/xpc_uv.c
index 8725d5e8ab0c..b5bbe59f9c57 100644
--- a/trunk/drivers/misc/sgi-xp/xpc_uv.c
+++ b/trunk/drivers/misc/sgi-xp/xpc_uv.c
@@ -157,24 +157,22 @@ xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq)
{
int ret;
-#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
-
- ret = sn_mq_watchlist_alloc(mmr_pnode, (void *)uv_gpa(mq->address),
- mq->order, &mq->mmr_offset);
- if (ret < 0) {
- dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
- ret);
- return -EBUSY;
- }
-#elif defined CONFIG_X86_64
- ret = uv_bios_mq_watchlist_alloc(uv_gpa(mq->address),
+#if defined CONFIG_X86_64
+ ret = uv_bios_mq_watchlist_alloc(mq->mmr_blade, uv_gpa(mq->address),
mq->order, &mq->mmr_offset);
if (ret < 0) {
dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, "
"ret=%d\n", ret);
return ret;
}
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+ ret = sn_mq_watchlist_alloc(mq->mmr_blade, (void *)uv_gpa(mq->address),
+ mq->order, &mq->mmr_offset);
+ if (ret < 0) {
+ dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
+ ret);
+ return -EBUSY;
+ }
#else
#error not a supported configuration
#endif
@@ -187,13 +185,12 @@ static void
xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq)
{
int ret;
- int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
#if defined CONFIG_X86_64
- ret = uv_bios_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
+ ret = uv_bios_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num);
BUG_ON(ret != BIOS_STATUS_SUCCESS);
#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- ret = sn_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
+ ret = sn_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num);
BUG_ON(ret != SALRET_OK);
#else
#error not a supported configuration
@@ -207,7 +204,6 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
enum xp_retval xp_ret;
int ret;
int nid;
- int nasid;
int pg_order;
struct page *page;
struct xpc_gru_mq_uv *mq;
@@ -263,11 +259,9 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
goto out_5;
}
- nasid = UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpu));
-
mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value;
ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size,
- nasid, mmr_value->vector, mmr_value->dest);
+ nid, mmr_value->vector, mmr_value->dest);
if (ret != 0) {
dev_err(xpc_part, "gru_create_message_queue() returned "
"error=%d\n", ret);
@@ -952,13 +946,11 @@ xpc_get_fifo_entry_uv(struct xpc_fifo_head_uv *head)
head->first = first->next;
if (head->first == NULL)
head->last = NULL;
-
- head->n_entries--;
- BUG_ON(head->n_entries < 0);
-
- first->next = NULL;
}
+ head->n_entries--;
+ BUG_ON(head->n_entries < 0);
spin_unlock_irqrestore(&head->lock, irq_flags);
+ first->next = NULL;
return first;
}
@@ -1027,8 +1019,7 @@ xpc_make_first_contact_uv(struct xpc_partition *part)
xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV);
- while (!((part->sn.uv.remote_act_state == XPC_P_AS_ACTIVATING) ||
- (part->sn.uv.remote_act_state == XPC_P_AS_ACTIVE))) {
+ while (part->sn.uv.remote_act_state != XPC_P_AS_ACTIVATING) {
dev_dbg(xpc_part, "waiting to make first contact with "
"partition %d\n", XPC_PARTID(part));
@@ -1431,6 +1422,7 @@ xpc_handle_notify_mq_msg_uv(struct xpc_partition *part,
msg_slot = ch_uv->recv_msg_slots +
(msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size;
+ BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number);
BUG_ON(msg_slot->hdr.size != 0);
memcpy(msg_slot, msg, msg->hdr.size);
@@ -1654,6 +1646,8 @@ xpc_received_payload_uv(struct xpc_channel *ch, void *payload)
sizeof(struct xpc_notify_mq_msghdr_uv));
if (ret != xpSuccess)
XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
+
+ msg->hdr.msg_slot_number += ch->remote_nentries;
}
static struct xpc_arch_operations xpc_arch_ops_uv = {
diff --git a/trunk/drivers/net/mlx4/alloc.c b/trunk/drivers/net/mlx4/alloc.c
index 8c8515619b8e..ad95d5f7b630 100644
--- a/trunk/drivers/net/mlx4/alloc.c
+++ b/trunk/drivers/net/mlx4/alloc.c
@@ -72,6 +72,35 @@ void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj)
mlx4_bitmap_free_range(bitmap, obj, 1);
}
+static unsigned long find_aligned_range(unsigned long *bitmap,
+ u32 start, u32 nbits,
+ int len, int align)
+{
+ unsigned long end, i;
+
+again:
+ start = ALIGN(start, align);
+
+ while ((start < nbits) && test_bit(start, bitmap))
+ start += align;
+
+ if (start >= nbits)
+ return -1;
+
+ end = start+len;
+ if (end > nbits)
+ return -1;
+
+ for (i = start + 1; i < end; i++) {
+ if (test_bit(i, bitmap)) {
+ start = i + 1;
+ goto again;
+ }
+ }
+
+ return start;
+}
+
u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
{
u32 obj, i;
@@ -81,13 +110,13 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
spin_lock(&bitmap->lock);
- obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max,
- bitmap->last, cnt, align - 1);
+ obj = find_aligned_range(bitmap->table, bitmap->last,
+ bitmap->max, cnt, align);
if (obj >= bitmap->max) {
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
& bitmap->mask;
- obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max,
- 0, cnt, align - 1);
+ obj = find_aligned_range(bitmap->table, 0, bitmap->max,
+ cnt, align);
}
if (obj < bitmap->max) {
diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c
index ad113b0f62db..2597145a066e 100644
--- a/trunk/drivers/parport/parport_pc.c
+++ b/trunk/drivers/parport/parport_pc.c
@@ -3403,7 +3403,7 @@ static int __init parport_parse_param(const char *s, int *val,
*val = automatic;
else if (!strncmp(s, "none", 4))
*val = none;
- else if (nofifo && !strncmp(s, "nofifo", 6))
+ else if (nofifo && !strncmp(s, "nofifo", 4))
*val = nofifo;
else {
char *ep;
diff --git a/trunk/drivers/pci/dmar.c b/trunk/drivers/pci/dmar.c
index 83aae4747594..6cdc931f7c17 100644
--- a/trunk/drivers/pci/dmar.c
+++ b/trunk/drivers/pci/dmar.c
@@ -339,35 +339,6 @@ int dmar_find_matched_atsr_unit(struct pci_dev *dev)
}
#endif
-#ifdef CONFIG_ACPI_NUMA
-static int __init
-dmar_parse_one_rhsa(struct acpi_dmar_header *header)
-{
- struct acpi_dmar_rhsa *rhsa;
- struct dmar_drhd_unit *drhd;
-
- rhsa = (struct acpi_dmar_rhsa *)header;
- for_each_drhd_unit(drhd) {
- if (drhd->reg_base_addr == rhsa->base_address) {
- int node = acpi_map_pxm_to_node(rhsa->proximity_domain);
-
- if (!node_online(node))
- node = -1;
- drhd->iommu->node = node;
- return 0;
- }
- }
- WARN(1, "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n"
- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
- drhd->reg_base_addr,
- dmi_get_system_info(DMI_BIOS_VENDOR),
- dmi_get_system_info(DMI_BIOS_VERSION),
- dmi_get_system_info(DMI_PRODUCT_VERSION));
-
- return 0;
-}
-#endif
-
static void __init
dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
{
@@ -487,9 +458,7 @@ parse_dmar_table(void)
#endif
break;
case ACPI_DMAR_HARDWARE_AFFINITY:
-#ifdef CONFIG_ACPI_NUMA
- ret = dmar_parse_one_rhsa(entry_header);
-#endif
+ /* We don't do anything with RHSA (yet?) */
break;
default:
printk(KERN_WARNING PREFIX
@@ -613,8 +582,6 @@ int __init dmar_table_init(void)
return 0;
}
-static int bios_warned;
-
int __init check_zero_address(void)
{
struct acpi_table_dmar *dmar;
@@ -634,9 +601,6 @@ int __init check_zero_address(void)
}
if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) {
- void __iomem *addr;
- u64 cap, ecap;
-
drhd = (void *)entry_header;
if (!drhd->address) {
/* Promote an attitude of violence to a BIOS engineer today */
@@ -645,40 +609,17 @@ int __init check_zero_address(void)
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
- bios_warned = 1;
- goto failed;
- }
-
- addr = early_ioremap(drhd->address, VTD_PAGE_SIZE);
- if (!addr ) {
- printk("IOMMU: can't validate: %llx\n", drhd->address);
- goto failed;
- }
- cap = dmar_readq(addr + DMAR_CAP_REG);
- ecap = dmar_readq(addr + DMAR_ECAP_REG);
- early_iounmap(addr, VTD_PAGE_SIZE);
- if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) {
- /* Promote an attitude of violence to a BIOS engineer today */
- WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
- drhd->address,
- dmi_get_system_info(DMI_BIOS_VENDOR),
- dmi_get_system_info(DMI_BIOS_VERSION),
- dmi_get_system_info(DMI_PRODUCT_VERSION));
- bios_warned = 1;
- goto failed;
+#ifdef CONFIG_DMAR
+ dmar_disabled = 1;
+#endif
+ return 0;
}
+ break;
}
entry_header = ((void *)entry_header + entry_header->length);
}
return 1;
-
-failed:
-#ifdef CONFIG_DMAR
- dmar_disabled = 1;
-#endif
- return 0;
}
void __init detect_intel_iommu(void)
@@ -729,18 +670,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
int agaw = 0;
int msagaw = 0;
- if (!drhd->reg_base_addr) {
- if (!bios_warned) {
- WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
- dmi_get_system_info(DMI_BIOS_VENDOR),
- dmi_get_system_info(DMI_BIOS_VERSION),
- dmi_get_system_info(DMI_PRODUCT_VERSION));
- bios_warned = 1;
- }
- return -EINVAL;
- }
-
iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
if (!iommu)
return -ENOMEM;
@@ -757,16 +686,13 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) {
- if (!bios_warned) {
- /* Promote an attitude of violence to a BIOS engineer today */
- WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
- drhd->reg_base_addr,
- dmi_get_system_info(DMI_BIOS_VENDOR),
- dmi_get_system_info(DMI_BIOS_VERSION),
- dmi_get_system_info(DMI_PRODUCT_VERSION));
- bios_warned = 1;
- }
+ /* Promote an attitude of violence to a BIOS engineer today */
+ WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
+ "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+ drhd->reg_base_addr,
+ dmi_get_system_info(DMI_BIOS_VENDOR),
+ dmi_get_system_info(DMI_BIOS_VERSION),
+ dmi_get_system_info(DMI_PRODUCT_VERSION));
goto err_unmap;
}
@@ -789,8 +715,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
iommu->agaw = agaw;
iommu->msagaw = msagaw;
- iommu->node = -1;
-
/* the registers might be more than one page */
map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
cap_max_fault_reg_offset(iommu->cap));
@@ -1132,7 +1056,6 @@ static void __dmar_enable_qi(struct intel_iommu *iommu)
int dmar_enable_qi(struct intel_iommu *iommu)
{
struct q_inval *qi;
- struct page *desc_page;
if (!ecap_qis(iommu->ecap))
return -ENOENT;
@@ -1149,16 +1072,13 @@ int dmar_enable_qi(struct intel_iommu *iommu)
qi = iommu->qi;
-
- desc_page = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO, 0);
- if (!desc_page) {
+ qi->desc = (void *)(get_zeroed_page(GFP_ATOMIC));
+ if (!qi->desc) {
kfree(qi);
iommu->qi = 0;
return -ENOMEM;
}
- qi->desc = page_address(desc_page);
-
qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC);
if (!qi->desc_status) {
free_page((unsigned long) qi->desc);
diff --git a/trunk/drivers/pci/intel-iommu.c b/trunk/drivers/pci/intel-iommu.c
index e56f9bed6f2b..8d6159426311 100644
--- a/trunk/drivers/pci/intel-iommu.c
+++ b/trunk/drivers/pci/intel-iommu.c
@@ -277,7 +277,6 @@ static int hw_pass_through = 1;
struct dmar_domain {
int id; /* domain id */
- int nid; /* node id */
unsigned long iommu_bmp; /* bitmap of iommus this domain uses*/
struct list_head devices; /* all devices' list */
@@ -387,14 +386,30 @@ static struct kmem_cache *iommu_domain_cache;
static struct kmem_cache *iommu_devinfo_cache;
static struct kmem_cache *iommu_iova_cache;
-static inline void *alloc_pgtable_page(int node)
+static inline void *iommu_kmem_cache_alloc(struct kmem_cache *cachep)
{
- struct page *page;
- void *vaddr = NULL;
+ unsigned int flags;
+ void *vaddr;
+
+ /* trying to avoid low memory issues */
+ flags = current->flags & PF_MEMALLOC;
+ current->flags |= PF_MEMALLOC;
+ vaddr = kmem_cache_alloc(cachep, GFP_ATOMIC);
+ current->flags &= (~PF_MEMALLOC | flags);
+ return vaddr;
+}
+
- page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
- if (page)
- vaddr = page_address(page);
+static inline void *alloc_pgtable_page(void)
+{
+ unsigned int flags;
+ void *vaddr;
+
+ /* trying to avoid low memory issues */
+ flags = current->flags & PF_MEMALLOC;
+ current->flags |= PF_MEMALLOC;
+ vaddr = (void *)get_zeroed_page(GFP_ATOMIC);
+ current->flags &= (~PF_MEMALLOC | flags);
return vaddr;
}
@@ -405,7 +420,7 @@ static inline void free_pgtable_page(void *vaddr)
static inline void *alloc_domain_mem(void)
{
- return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
+ return iommu_kmem_cache_alloc(iommu_domain_cache);
}
static void free_domain_mem(void *vaddr)
@@ -415,7 +430,7 @@ static void free_domain_mem(void *vaddr)
static inline void * alloc_devinfo_mem(void)
{
- return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
+ return iommu_kmem_cache_alloc(iommu_devinfo_cache);
}
static inline void free_devinfo_mem(void *vaddr)
@@ -425,7 +440,7 @@ static inline void free_devinfo_mem(void *vaddr)
struct iova *alloc_iova_mem(void)
{
- return kmem_cache_alloc(iommu_iova_cache, GFP_ATOMIC);
+ return iommu_kmem_cache_alloc(iommu_iova_cache);
}
void free_iova_mem(struct iova *iova)
@@ -574,8 +589,7 @@ static struct context_entry * device_to_context_entry(struct intel_iommu *iommu,
root = &iommu->root_entry[bus];
context = get_context_addr_from_root(root);
if (!context) {
- context = (struct context_entry *)
- alloc_pgtable_page(iommu->node);
+ context = (struct context_entry *)alloc_pgtable_page();
if (!context) {
spin_unlock_irqrestore(&iommu->lock, flags);
return NULL;
@@ -718,7 +732,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
if (!dma_pte_present(pte)) {
uint64_t pteval;
- tmp_page = alloc_pgtable_page(domain->nid);
+ tmp_page = alloc_pgtable_page();
if (!tmp_page)
return NULL;
@@ -854,7 +868,7 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu)
struct root_entry *root;
unsigned long flags;
- root = (struct root_entry *)alloc_pgtable_page(iommu->node);
+ root = (struct root_entry *)alloc_pgtable_page();
if (!root)
return -ENOMEM;
@@ -1249,7 +1263,6 @@ static struct dmar_domain *alloc_domain(void)
if (!domain)
return NULL;
- domain->nid = -1;
memset(&domain->iommu_bmp, 0, sizeof(unsigned long));
domain->flags = 0;
@@ -1407,10 +1420,9 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
domain->iommu_snooping = 0;
domain->iommu_count = 1;
- domain->nid = iommu->node;
/* always allocate the top pgd */
- domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
+ domain->pgd = (struct dma_pte *)alloc_pgtable_page();
if (!domain->pgd)
return -ENOMEM;
__iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
@@ -1511,15 +1523,12 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
/* Skip top levels of page tables for
* iommu which has less agaw than default.
- * Unnecessary for PT mode.
*/
- if (translation != CONTEXT_TT_PASS_THROUGH) {
- for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
- pgd = phys_to_virt(dma_pte_addr(pgd));
- if (!dma_pte_present(pgd)) {
- spin_unlock_irqrestore(&iommu->lock, flags);
- return -ENOMEM;
- }
+ for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
+ pgd = phys_to_virt(dma_pte_addr(pgd));
+ if (!dma_pte_present(pgd)) {
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ return -ENOMEM;
}
}
}
@@ -1568,8 +1577,6 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
spin_lock_irqsave(&domain->iommu_lock, flags);
if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) {
domain->iommu_count++;
- if (domain->iommu_count == 1)
- domain->nid = iommu->node;
domain_update_iommu_cap(domain);
}
spin_unlock_irqrestore(&domain->iommu_lock, flags);
@@ -1984,16 +1991,6 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
"IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
pci_name(pdev), start, end);
- if (end < start) {
- WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
- dmi_get_system_info(DMI_BIOS_VENDOR),
- dmi_get_system_info(DMI_BIOS_VERSION),
- dmi_get_system_info(DMI_PRODUCT_VERSION));
- ret = -EIO;
- goto error;
- }
-
if (end >> agaw_to_width(domain->agaw)) {
WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
@@ -3231,9 +3228,6 @@ static int device_notifier(struct notifier_block *nb,
struct pci_dev *pdev = to_pci_dev(dev);
struct dmar_domain *domain;
- if (iommu_no_mapping(dev))
- return 0;
-
domain = find_domain(pdev);
if (!domain)
return 0;
@@ -3461,7 +3455,6 @@ static struct dmar_domain *iommu_alloc_vm_domain(void)
return NULL;
domain->id = vm_domid++;
- domain->nid = -1;
memset(&domain->iommu_bmp, 0, sizeof(unsigned long));
domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
@@ -3488,10 +3481,9 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
domain->iommu_coherency = 0;
domain->iommu_snooping = 0;
domain->max_addr = 0;
- domain->nid = -1;
/* always allocate the top pgd */
- domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
+ domain->pgd = (struct dma_pte *)alloc_pgtable_page();
if (!domain->pgd)
return -ENOMEM;
domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
diff --git a/trunk/drivers/pci/intr_remapping.c b/trunk/drivers/pci/intr_remapping.c
index 8b65a489581b..1487bf2be863 100644
--- a/trunk/drivers/pci/intr_remapping.c
+++ b/trunk/drivers/pci/intr_remapping.c
@@ -590,8 +590,7 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
if (!iommu->ir_table)
return -ENOMEM;
- pages = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO,
- INTR_REMAP_PAGE_ORDER);
+ pages = alloc_pages(GFP_ATOMIC | __GFP_ZERO, INTR_REMAP_PAGE_ORDER);
if (!pages) {
printk(KERN_ERR "failed to allocate pages of order %d\n",
diff --git a/trunk/drivers/pnp/pnpbios/proc.c b/trunk/drivers/pnp/pnpbios/proc.c
index 2d8ac43f78e8..b35d921bac6e 100644
--- a/trunk/drivers/pnp/pnpbios/proc.c
+++ b/trunk/drivers/pnp/pnpbios/proc.c
@@ -24,7 +24,6 @@
#include
#include
#include
-#include
#include
#include
@@ -34,65 +33,42 @@
static struct proc_dir_entry *proc_pnp = NULL;
static struct proc_dir_entry *proc_pnp_boot = NULL;
-static int pnpconfig_proc_show(struct seq_file *m, void *v)
+static int proc_read_pnpconfig(char *buf, char **start, off_t pos,
+ int count, int *eof, void *data)
{
struct pnp_isa_config_struc pnps;
if (pnp_bios_isapnp_config(&pnps))
return -EIO;
- seq_printf(m, "structure_revision %d\n"
- "number_of_CSNs %d\n"
- "ISA_read_data_port 0x%x\n",
- pnps.revision, pnps.no_csns, pnps.isa_rd_data_port);
- return 0;
+ return snprintf(buf, count,
+ "structure_revision %d\n"
+ "number_of_CSNs %d\n"
+ "ISA_read_data_port 0x%x\n",
+ pnps.revision, pnps.no_csns, pnps.isa_rd_data_port);
}
-static int pnpconfig_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, pnpconfig_proc_show, NULL);
-}
-
-static const struct file_operations pnpconfig_proc_fops = {
- .owner = THIS_MODULE,
- .open = pnpconfig_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int escd_info_proc_show(struct seq_file *m, void *v)
+static int proc_read_escdinfo(char *buf, char **start, off_t pos,
+ int count, int *eof, void *data)
{
struct escd_info_struc escd;
if (pnp_bios_escd_info(&escd))
return -EIO;
- seq_printf(m, "min_ESCD_write_size %d\n"
+ return snprintf(buf, count,
+ "min_ESCD_write_size %d\n"
"ESCD_size %d\n"
"NVRAM_base 0x%x\n",
escd.min_escd_write_size,
escd.escd_size, escd.nv_storage_base);
- return 0;
}
-static int escd_info_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, escd_info_proc_show, NULL);
-}
-
-static const struct file_operations escd_info_proc_fops = {
- .owner = THIS_MODULE,
- .open = escd_info_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
#define MAX_SANE_ESCD_SIZE (32*1024)
-static int escd_proc_show(struct seq_file *m, void *v)
+static int proc_read_escd(char *buf, char **start, off_t pos,
+ int count, int *eof, void *data)
{
struct escd_info_struc escd;
char *tmpbuf;
- int escd_size;
+ int escd_size, escd_left_to_read, n;
if (pnp_bios_escd_info(&escd))
return -EIO;
@@ -100,7 +76,7 @@ static int escd_proc_show(struct seq_file *m, void *v)
/* sanity check */
if (escd.escd_size > MAX_SANE_ESCD_SIZE) {
printk(KERN_ERR
- "PnPBIOS: %s: ESCD size reported by BIOS escd_info call is too great\n", __func__);
+ "PnPBIOS: proc_read_escd: ESCD size reported by BIOS escd_info call is too great\n");
return -EFBIG;
}
@@ -118,75 +94,56 @@ static int escd_proc_show(struct seq_file *m, void *v)
/* sanity check */
if (escd_size > MAX_SANE_ESCD_SIZE) {
- printk(KERN_ERR "PnPBIOS: %s: ESCD size reported by"
- " BIOS read_escd call is too great\n", __func__);
+ printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size reported by"
+ " BIOS read_escd call is too great\n");
kfree(tmpbuf);
return -EFBIG;
}
- seq_write(m, tmpbuf, escd_size);
+ escd_left_to_read = escd_size - pos;
+ if (escd_left_to_read < 0)
+ escd_left_to_read = 0;
+ if (escd_left_to_read == 0)
+ *eof = 1;
+ n = min(count, escd_left_to_read);
+ memcpy(buf, tmpbuf + pos, n);
kfree(tmpbuf);
- return 0;
+ *start = buf;
+ return n;
}
-static int escd_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, escd_proc_show, NULL);
-}
-
-static const struct file_operations escd_proc_fops = {
- .owner = THIS_MODULE,
- .open = escd_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int pnp_legacyres_proc_show(struct seq_file *m, void *v)
+static int proc_read_legacyres(char *buf, char **start, off_t pos,
+ int count, int *eof, void *data)
{
- void *buf;
-
- buf = kmalloc(65536, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- if (pnp_bios_get_stat_res(buf)) {
- kfree(buf);
+ /* Assume that the following won't overflow the buffer */
+ if (pnp_bios_get_stat_res(buf))
return -EIO;
- }
-
- seq_write(m, buf, 65536);
- kfree(buf);
- return 0;
-}
-static int pnp_legacyres_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, pnp_legacyres_proc_show, NULL);
+ return count; // FIXME: Return actual length
}
-static const struct file_operations pnp_legacyres_proc_fops = {
- .owner = THIS_MODULE,
- .open = pnp_legacyres_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int pnp_devices_proc_show(struct seq_file *m, void *v)
+static int proc_read_devices(char *buf, char **start, off_t pos,
+ int count, int *eof, void *data)
{
struct pnp_bios_node *node;
u8 nodenum;
+ char *p = buf;
+
+ if (pos >= 0xff)
+ return 0;
node = kzalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return -ENOMEM;
- for (nodenum = 0; nodenum < 0xff;) {
+ for (nodenum = pos; nodenum < 0xff;) {
u8 thisnodenum = nodenum;
-
+ /* 26 = the number of characters per line sprintf'ed */
+ if ((p - buf + 26) > count)
+ break;
if (pnp_bios_get_dev_node(&nodenum, PNPMODE_DYNAMIC, node))
break;
- seq_printf(m, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n",
+ p += sprintf(p, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n",
node->handle, node->eisa_id,
node->type_code[0], node->type_code[1],
node->type_code[2], node->flags);
@@ -196,29 +153,20 @@ static int pnp_devices_proc_show(struct seq_file *m, void *v)
"PnPBIOS: proc_read_devices:",
(unsigned int)nodenum,
(unsigned int)thisnodenum);
+ *eof = 1;
break;
}
}
kfree(node);
- return 0;
-}
-
-static int pnp_devices_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, pnp_devices_proc_show, NULL);
+ if (nodenum == 0xff)
+ *eof = 1;
+ *start = (char *)((off_t) nodenum - pos);
+ return p - buf;
}
-static const struct file_operations pnp_devices_proc_fops = {
- .owner = THIS_MODULE,
- .open = pnp_devices_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int pnpbios_proc_show(struct seq_file *m, void *v)
+static int proc_read_node(char *buf, char **start, off_t pos,
+ int count, int *eof, void *data)
{
- void *data = m->private;
struct pnp_bios_node *node;
int boot = (long)data >> 8;
u8 nodenum = (long)data;
@@ -232,20 +180,14 @@ static int pnpbios_proc_show(struct seq_file *m, void *v)
return -EIO;
}
len = node->size - sizeof(struct pnp_bios_node);
- seq_write(m, node->data, len);
+ memcpy(buf, node->data, len);
kfree(node);
- return 0;
-}
-
-static int pnpbios_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, pnpbios_proc_show, PDE(inode)->data);
+ return len;
}
-static ssize_t pnpbios_proc_write(struct file *file, const char __user *buf,
- size_t count, loff_t *pos)
+static int proc_write_node(struct file *file, const char __user * buf,
+ unsigned long count, void *data)
{
- void *data = PDE(file->f_path.dentry->d_inode)->data;
struct pnp_bios_node *node;
int boot = (long)data >> 8;
u8 nodenum = (long)data;
@@ -276,33 +218,34 @@ static ssize_t pnpbios_proc_write(struct file *file, const char __user *buf,
return ret;
}
-static const struct file_operations pnpbios_proc_fops = {
- .owner = THIS_MODULE,
- .open = pnpbios_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = pnpbios_proc_write,
-};
-
int pnpbios_interface_attach_device(struct pnp_bios_node *node)
{
char name[3];
+ struct proc_dir_entry *ent;
sprintf(name, "%02x", node->handle);
if (!proc_pnp)
return -EIO;
if (!pnpbios_dont_use_current_config) {
- proc_create_data(name, 0644, proc_pnp, &pnpbios_proc_fops,
- (void *)(long)(node->handle));
+ ent = create_proc_entry(name, 0, proc_pnp);
+ if (ent) {
+ ent->read_proc = proc_read_node;
+ ent->write_proc = proc_write_node;
+ ent->data = (void *)(long)(node->handle);
+ }
}
if (!proc_pnp_boot)
return -EIO;
- if (proc_create_data(name, 0644, proc_pnp_boot, &pnpbios_proc_fops,
- (void *)(long)(node->handle + 0x100)))
+ ent = create_proc_entry(name, 0, proc_pnp_boot);
+ if (ent) {
+ ent->read_proc = proc_read_node;
+ ent->write_proc = proc_write_node;
+ ent->data = (void *)(long)(node->handle + 0x100);
return 0;
+ }
+
return -EIO;
}
@@ -319,11 +262,14 @@ int __init pnpbios_proc_init(void)
proc_pnp_boot = proc_mkdir("boot", proc_pnp);
if (!proc_pnp_boot)
return -EIO;
- proc_create("devices", 0, proc_pnp, &pnp_devices_proc_fops);
- proc_create("configuration_info", 0, proc_pnp, &pnpconfig_proc_fops);
- proc_create("escd_info", 0, proc_pnp, &escd_info_proc_fops);
- proc_create("escd", S_IRUSR, proc_pnp, &escd_proc_fops);
- proc_create("legacy_device_resources", 0, proc_pnp, &pnp_legacyres_proc_fops);
+ create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL);
+ create_proc_read_entry("configuration_info", 0, proc_pnp,
+ proc_read_pnpconfig, NULL);
+ create_proc_read_entry("escd_info", 0, proc_pnp, proc_read_escdinfo,
+ NULL);
+ create_proc_read_entry("escd", S_IRUSR, proc_pnp, proc_read_escd, NULL);
+ create_proc_read_entry("legacy_device_resources", 0, proc_pnp,
+ proc_read_legacyres, NULL);
return 0;
}
diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig
index 8167e9e6827a..71fbd6e8edf7 100644
--- a/trunk/drivers/rtc/Kconfig
+++ b/trunk/drivers/rtc/Kconfig
@@ -242,15 +242,6 @@ config RTC_DRV_M41T80_WDT
If you say Y here you will get support for the
watchdog timer in the ST M41T60 and M41T80 RTC chips series.
-config RTC_DRV_BQ32K
- tristate "TI BQ32000"
- help
- If you say Y here you will get support for the TI
- BQ32000 I2C RTC chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-bq32k.
-
config RTC_DRV_DM355EVM
tristate "TI DaVinci DM355 EVM RTC"
depends on MFD_DM355EVM_MSP
@@ -601,22 +592,15 @@ config RTC_DRV_AB3100
Select this to enable the ST-Ericsson AB3100 Mixed Signal IC RTC
support. This chip contains a battery- and capacitor-backed RTC.
-config RTC_DRV_NUC900
- tristate "NUC910/NUC920 RTC driver"
- depends on RTC_CLASS && ARCH_W90X900
- help
- If you say yes here you get support for the RTC subsystem of the
- NUC910/NUC920 used in embedded systems.
comment "on-CPU RTC drivers"
config RTC_DRV_OMAP
tristate "TI OMAP1"
- depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX
+ depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730
help
- Say "yes" here to support the real time clock on TI OMAP1 and
- DA8xx/OMAP-L13x chips. This driver can also be built as a
- module called rtc-omap.
+ Say "yes" here to support the real time clock on TI OMAP1 chips.
+ This driver can also be built as a module called rtc-omap.
config RTC_DRV_S3C
tristate "Samsung S3C series SoC RTC"
@@ -862,10 +846,4 @@ config RTC_DRV_PCAP
If you say Y here you will get support for the RTC found on
the PCAP2 ASIC used on some Motorola phones.
-config RTC_DRV_MC13783
- depends on MFD_MC13783
- tristate "Freescale MC13783 RTC"
- help
- This enables support for the Freescale MC13783 PMIC RTC
-
endif # RTC_CLASS
diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile
index e5160fddc446..7da6efb3e953 100644
--- a/trunk/drivers/rtc/Makefile
+++ b/trunk/drivers/rtc/Makefile
@@ -23,7 +23,6 @@ obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o
obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
-obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o
obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o
@@ -53,10 +52,8 @@ obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
obj-$(CONFIG_RTC_MXC) += rtc-mxc.o
obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
-obj-$(CONFIG_RTC_DRV_MC13783) += rtc-mc13783.o
obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
-obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o
obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
diff --git a/trunk/drivers/rtc/rtc-at32ap700x.c b/trunk/drivers/rtc/rtc-at32ap700x.c
index 8825695777df..e1ec33e40e38 100644
--- a/trunk/drivers/rtc/rtc-at32ap700x.c
+++ b/trunk/drivers/rtc/rtc-at32ap700x.c
@@ -256,8 +256,6 @@ static int __init at32_rtc_probe(struct platform_device *pdev)
goto out_iounmap;
}
- platform_set_drvdata(pdev, rtc);
-
rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
&at32_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc)) {
@@ -266,6 +264,7 @@ static int __init at32_rtc_probe(struct platform_device *pdev)
goto out_free_irq;
}
+ platform_set_drvdata(pdev, rtc);
device_init_wakeup(&pdev->dev, 1);
dev_info(&pdev->dev, "Atmel RTC for AT32AP700x at %08lx irq %ld\n",
@@ -274,7 +273,6 @@ static int __init at32_rtc_probe(struct platform_device *pdev)
return 0;
out_free_irq:
- platform_set_drvdata(pdev, NULL);
free_irq(irq, rtc);
out_iounmap:
iounmap(rtc->regs);
diff --git a/trunk/drivers/rtc/rtc-bq32k.c b/trunk/drivers/rtc/rtc-bq32k.c
deleted file mode 100644
index 408cc8f735be..000000000000
--- a/trunk/drivers/rtc/rtc-bq32k.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Driver for TI BQ32000 RTC.
- *
- * Copyright (C) 2009 Semihalf.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include
-#include
-#include
-#include
-#include